Literate CofeeScript underway

Literate CofeeScript underway

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

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

  # Non-determinism
  # ---------------

  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)


Fix missing log in console.log

Fix missing log in console.log

    "use strict"

    express     = require 'express'
    raven       = require 'raven'

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

## Init

    app = express()

### Authentication

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

In future versions of the API this routine will also check the request quota and
blocking the user if the quota is full.

    app.use '/', (req, res, next) ->

      key = req.query.api_key

      return res.json 403, message: 'API key missing' if not key
      return res.json 401, message: 'API key invalid' if not apiKeys[key]

      req.key = key
      req.usr = apiKeys[key]

      next()

### Configuration

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

### Error handling

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

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

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

      console.error err.message
      console.error err.stack

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

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

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

### API keys

This is the dirty part. Here are all the keys to the kingdom. These will be
moved to the database and retrieved when the server starts. Just need to find
the time to do it.

    apiKeys =
      dnt: 'DNT'
      nrk: 'DNT'

      '30ad3a3a1d2c7c63102e09e6fe4bb253': 'TurApp'
      'b523ceb5e16fb92b2a999676a87698d1': 'Pingdom'

      '4c802ac2315ab24db9c992cc6eea0278': 'DNT' # ETA
      'de2986ac75c5af9d7f92a26f37dc1b77': 'DNT' # sherpa2.api
      '5dd5a39057cb479c3c4bce7f9eae5e6c': 'DNT' # dev.ut.no
      '146bbe01b477e9e07e85e0ddd3f5095a': 'DNT' # beta.ut.no
      'e6fa27292ffbcc689c49179c47bc708e': 'DNT' # prod.ut.no

## GET /

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

## GET /system

Hsssssj!!! Don't tell anyone about the secret system API endpoint!

    app.get '/system', system.info

## GET /CloudHealthCheck

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

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

    app.get '/CloudHealthCheck', system.check

## GET /objekttyper

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

## ALL /{collection}

    app.param 'collection', collection.param
    app.all '/:collection', (req, res, next) ->
      switch req.method
        when 'OPTIONS' then collection.options req, res, next
        when 'HEAD', 'GET' then collection.get req, res, next
        when 'POST' then collection.post req, res, next
        when 'PUT'  then collection.put req, res, next
        when 'PATCH' then collection.patch req, res, next
        else res.json 405, message: 'HTTP method not supported'

## ALL /{collection}/{objectid}

    app.param 'objectid', document.param
    app.all '/:collection/:objectid', (req, res, next) ->
      switch req.method
        when 'OPTIONS' then document.options req, res, next
        when 'HEAD', 'GET' then document.get req, res, next
        when 'PUT' then document.put req, res, next
        when 'PATCH' then document.patch req, res, next
        when 'DELETE' then document.delete req, res, next
        else res.json 405, message: 'HTTP method not supported'

## Start

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

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

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

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

    else
      module.exports = app

    "use strict"

    express     = require 'express'
    raven       = require 'raven'

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

## Init

    app = express()

### Authentication

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

In future versions of the API this routine will also check the request quota and
blocking the user if the quota is full.

    app.use '/', (req, res, next) ->

      key = req.query.api_key

      return res.json 403, message: 'API key missing' if not key
      return res.json 401, message: 'API key invalid' if not apiKeys[key]

      req.key = key
      req.usr = apiKeys[key]

      next()

### Configuration

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

### Error handling

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

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

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

      console.error err.message
      console.error err.stack

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

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

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

### API keys

This is the dirty part. Here are all the keys to the kingdom. These will be
moved to the database and retrieved when the server starts. Just need to find
the time to do it.

    apiKeys =
      dnt: 'DNT'
      nrk: 'DNT'

      '30ad3a3a1d2c7c63102e09e6fe4bb253': 'TurApp'
      'b523ceb5e16fb92b2a999676a87698d1': 'Pingdom'

      '4c802ac2315ab24db9c992cc6eea0278': 'DNT' # ETA
      'de2986ac75c5af9d7f92a26f37dc1b77': 'DNT' # sherpa2.api
      '5dd5a39057cb479c3c4bce7f9eae5e6c': 'DNT' # dev.ut.no
      '146bbe01b477e9e07e85e0ddd3f5095a': 'DNT' # beta.ut.no
      'e6fa27292ffbcc689c49179c47bc708e': 'DNT' # prod.ut.no

## GET /

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

## GET /system

Hsssssj!!! Don't tell anyone about the secret system API endpoint!

    app.get '/system', system.info

## GET /CloudHealthCheck

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

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

    app.get '/CloudHealthCheck', system.check

## GET /objekttyper

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

## ALL /{collection}

    app.param 'collection', collection.param
    app.all '/:collection', (req, res, next) ->
      switch req.method
        when 'OPTIONS' then collection.options req, res, next
        when 'HEAD', 'GET' then collection.get req, res, next
        when 'POST' then collection.post req, res, next
        when 'PUT'  then collection.put req, res, next
        when 'PATCH' then collection.patch req, res, next
        else res.json 405, message: 'HTTP method not supported'

## ALL /{collection}/{objectid}

    app.param 'objectid', document.param
    app.all '/:collection/:objectid', (req, res, next) ->
      switch req.method
        when 'OPTIONS' then document.options req, res, next
        when 'HEAD', 'GET' then document.get req, res, next
        when 'PUT' then document.put req, res, next
        when 'PATCH' then document.patch req, res, next
        when 'DELETE' then document.delete req, res, next
        else res.json 405, message: 'HTTP method not supported'

## Start

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

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

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

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

    else
      module.exports = app


better index

better index

# Namespace: lib

    module.exports =
      Base      : require './base'
      Event     : require './event'
      Node      : require './node'
      Evented   : require './evented'
      Element   : require './element'
      Shape     : require './shape'
      Component : require './component'
      Pen       : require './pen'
      Style     : require './style'

## Exports

* [lib.Base][Base] - All classes extend this.

* [lib.Event][Event] - Light Event

* [lib.Node][Node] - Parent-Child Aggregation

* [lib.Evented][Evented] - Event Subsytem

* [lib.Element][Element] - Visual Element

* [lib.Shape][Shape] - Drawable Shape

* [lib.Component][Component] - Dragable Component

* [lib.Style][Style] - Element Style

* [lib.Pen][Pen] - Common ancestor for pens

[Base]: ./base.litcoffee
[Event]: ./event.litcoffee
[Node]: ./node.litcoffee
[Evented]: ./evented.litcoffee
[Element]: ./element.litcoffee
[Shape]: ./shape.litcoffee
[Component]: ./component.litcoffee
[Style]: ./style.litcoffee
[Pen]: ./pen.litcoffee

# Namespace: lib

## Exports

    module.exports =

* [lib.Base][Base]

All classes extend this.

      Base      : require './base'

* [lib.Event][Event]

Light Event

      Event     : require './event'

* [lib.Node][Node]

Parent-Child Aggregation

      Node      : require './node'

* [lib.Evented][Evented]

Event Subsytem

      Evented   : require './evented'

* [lib.Element][Element]

Visual Element

      Element   : require './element'

* [lib.Shape][Shape]

Drawable Shape

      Shape     : require './shape'

* [lib.Component][Component]

Dragable Component

      Component : require './component'

* [lib.Style][Style]

Element Style
      Style     : require './style'

* [lib.Pen][Pen]

Common ancestor for pens

      Pen       : require './pen'

[Base]: ./base.litcoffee
[Event]: ./event.litcoffee
[Node]: ./node.litcoffee
[Evented]: ./evented.litcoffee
[Element]: ./element.litcoffee
[Shape]: ./shape.litcoffee
[Component]: ./component.litcoffee
[Style]: ./style.litcoffee
[Pen]: ./pen.litcoffee


Enable source maps with coffee-script.

Enable source maps with coffee-script.

# Configuration

GLP is configured using a specific grammar for explaining how to build a gulp
project. This grammar allows you to easily explain both simple and complicated
build processes in a single configuration file.

The file should be named **glp.yml** and can be placed in your project's root
directory, or it can be placed in an `etc` directory if preferred. You can
also include the configuration in your standard user-level or system-wide
configuration directories.

This document aims to provide a descriptive explanation of all configuration
and best practices for configuration options available to users of GLP.

GLP configuration options can be split up into the following high level
categories:

- **root** tells GLP where to place it's output files.
- **files** with *named groups* and where to find them
- **filters** for introducing new ways to transform files in *file group*
- **plugins** options for changing the way that glp uses them for each *file group*
- **concatenators** for defining which plugins are used for joining files in a *file group*
- **minifiers** for changing how a *file group* is minified
- **extensions** for defining the suffix of output files for each *file group*.
- **liveReload** options for defining changes affect your browser after compiling.
- **static** options for defining routing of built files to a local web server
- **tasks** to overlay different groupings of options based on command-line arguments

The following document will walk you step-by-step through GLP's default
configuration. It should help increase familiarity with all features, and how
to get started with building your own software using GLP and your favorite
programming languages.

## How GLP configuration works

This is a `.litcoffee` file, so we will be using the default configuration as a
practical example of what you can do when writing a configuration file. The
documented values are exactly what is exported to the compiler in GLP.

    module.exports =

These defaults are always overridden with any user-specific settings. When a
configuration file is loaded, GLP will run [lodash.merge][lodashmerge] in order
to merge the user's configuration data over the defaults. Once this is done,
the current *task* is merged in order to define commands which change behavior.

The one exception to this rule is the *files* option, which will be completely
overriden if provided by a user instead of being merged into the default
configuration. The *files* option will still be merged (instead of replaced) if
modified by *tasks*.

Don't  feel discouraged if this seems confusing. It will make more sense as you
read through this document and develop a better understanding of GLP's options.

# Options

## root

This should be a string that contains the name of the directory where you would
like GLP to put build output files.

      root: 'public'

## watch

This should be a boolean. When true, GLP will continue watching for changes to
files after tasks finish. Otherwise, it will not watch for any changes to files.

      watch: no

## debug

If this is set to true, then GLP will provide you with an exhaustive amount of
information describing the build process.

      debug: no

## globOptions

This can be an object which describes the options that should be passed to the
`gulp,watch` and `gulp.src` functions. The keys of the object should be the
name of the task that the options are used with. The value for each task should
be the options as [documented here][gulpsrcopts]. If no options are defined for
the currently active task, then the 'default' options will be used.

      globOptions:
        default:
          options: {}

## cache

Options for controlling how GLP caches files for faster compiling while watching
files for changes.

      cache:

The `cache.enabled` option is false by default, but can be made true if caching
happens to be working as expected with your project. This feature is disabled
by default because it is still experimental.

        enabled: no

## minify

Options for controlling how GLP minifies files.

      minify:

The `minify.enabled` option is false by default. You can set it to true
if you would like to minify built files.

        enabled: no

The `minify.extension` option  can be changed if you'd like to use a custom
prefix extension. For instance, files with the extension **.js** will be
converted to **.min.js** when minification is turned on. If you set
`minify.extension` to an empty string, it will then be converted into.

        extension: '.min'

## ordering

Ordering is disabled by default, but if ordering looks wrong (this shouldn't
ever happen) then you can use this in order to map specific file types to the
ordering you'd want the files to be in. This supports the globbing same format
which is supported by `gulp.src` and `gulp.watch` which is more thoroughly
[documented here][gulpsrcopts].

      ordering: {}

## plugins

The plugins option allows users to define options for gulp all plugins which
are used in the build process. In order to do this, you provide an object
where plugin names are *keys* and the options object is what will be passed
to the related gulp plugin.

Whenever referring to gulp plugins in GLP, you can optionally omit the `gulp-`
prefix. For instance, telling GLP to use a plugin called *cached* is the same
as telling it to use *gulp-cached*. The plugins are standard gulp plugins, so
any standard gulp plugin should work with GLP.

GLP has verify flexible support for easily configuring plugins to be used
through gulp, and tries to be as transparent as possible without sacrificing
usability in the process.

      plugins:

By default, we ask the [gulp-cached][gulpcached] plugin to optimize memory by
storing the files as MD5 instead of the entire file contents.

        cached:
          optimizeMemory: yes

We also want [gulp-uglify][gulpuglify] to output source maps.

        uglify:
          outSourceMap: yes

And while we're developing, we want our templates to be readable. So, we tell
jade to render pretty files instead of spitting them out in a single line.

        jade:
          pretty: yes

We'll also want source maps, so let's enabled those.

        coffee:
          sourceMap: yes

The options provided here can also be overridden per-file-type with the
*filters* option as described in the next section. Every setting can be
overriden on a per-task basis as well. This means that we can tell GLP to not
output source maps, pretty templates, or any other option via the *tasks*
option as will also be defined later.

## filters

It's important to remember that you can use any gulp plugin with GLP by
installing it into your project with [npm][npm]. In order to let users define
arbitrary ways of transforming files, we have filters.

The *filters* option provide a way to transform file contents for different
types of files. Each type of file can be given a number of filters which can
be passed through by defining them with this option.

      filters:

For instance, scripts can be compiled as *coffee*. This example is the least
verbose way to define a new filter. Since an empty settings object is being
mapped to the *coffee* type, GLP will automatically transform using a plugin
called [gulp-coffee][gulpcoffee] and match this plugin against a glob which
will automatically be generated with the filter name. In this case, the glob
pattern would be `\*\*/\*.coffee`.

It's worth noting here that you can install **any** gulp plugin into your
project, and GLP will support it when you just add a new filter option for it.

It is possible that the most powerful feature of GLP is it's ability to let you
configure it for any type of file without needing to touch any source code in
the process. This configuration file is all that you will need.

        scripts:
          coffee: {}

Scripts can also be compiled from jade templates. Since we have grouped
filters with the *scripts* file group, we also know that we want the compiled
files to become scripts in the end. So, we can use the `options` key to
forward options to [gulp-jade][gulpjade] in this case.

          jade:
            options:
              client: true

For the stylesheets group, we set up *sass* and *less* so that they will be
bound to files with matching extensions. We have no special options in these
cases, so we can just assign an empty object to them and let GLP assign
defaults as described before.

        stylesheets:
          sass: {}
          less: {}

There are more specific cases for stylus, though. We want to use the
[gulp-stylus][gulpstylus] module and match it against both *.styl* and
*.stylus* file extensions. A more specific case is that we also want to use the
'nib' module by default, but still allow users to override that choice with the
global *plugins* option. That's what the *hints* option is for.

By default, the *options* in a filter override global *plugins* options. The
*hints* option provides the opposite, where the *plugins* options act as an
override. This isn't an extremely useful feature, but it's helpful here for
users that might not want to use *nib* with their stylus files. They could just
set `use` to an empty array in the *plugins* option to prevent it.

          stylus:
            transforms: 'stylus'

            hints:
              use: ['nib']

            matches: [
              '**/*.styl'
              '**/*.stylus'
            ]

Here we redefine jade, but this time we are defining it as a template. The
reason that we have to define this twice is because we want to give different
options to [gulp-jade][gulpjade] for templates instead of scripts. This allows
us to render *templates* as *HTML* files, but jade files in *scripts* will be
rendered as *js* files as  described previously.

        templates:
          jade:
            options:
              client: false

## concatenators

If you need to use custom concatenation rules, you can define them here. This
can be set to an object which maps types of files to a plugin name. It can also
be set to an array if you need to use multiple concatenators. They will be
streamed through plugins in the order that they are provided.

When a plugin isn't defined in the *concatenators* option for a specific type,
GLP will set it to 'concat' as the default value. GLP will automatically prefix
plugin names with *gulp-*, so you don't need to do that. So, the default
concatenator could be found in [NPM][npm] as [gulp-concat][gulpconcat]

As an example use case, some users might want to compile all of their scripts
to [gulp-commonjs][gulpcommonjs] files and then pass the commonjs output to
[gulp-concat][gulpconcat] afterward. That could be done simply by adding a new
key to *concatenators*, such as: `scripts: ['commonjs', 'concat']` followed by
installing the necessary NPM plugins in your project directory.

      concatenators: {}

## extensions

      extensions:
        scripts: 'js'
        stylesheets: 'css'
        templates: 'html'

## minifiers

The minifiers option tells GLP how to minify files with different file
extensions. As an example, the default would use the [gulp-uglify][gulpuglify]
plugin for *js* files, and the [gulp-minify-css][gulpminifycss] plugin for css
files.

      minifiers:
        js: 'uglify'
        css: 'minify-css'

## files

Options for defining what types of files exist, where they are located, and
where they are placed after they have finished being built. The default
configuration will build many types of files from a directory called `src`,
and place them into the **root** directory (the default root is *public* as
described above) after they have been built.

      files:

Each type of file that needs built is given a name. The names can be whatever
you like, and any number of named types can be created. For instance, the
following files are called *scripts*:

        scripts:

Each type is an object which maps a path to a list of files. If a path ends
with a slash, then the files will be copied into a **directory** containing
an output file for every source file that was built. If the path does not
end with a slash, then the  *concatenators* for this type will be used.

In this case, we are building all files ending with `.js` or `.coffee`. After
they are built, the resulting files will be placed in the directory specified
by the **root** function as separate files. If the output file was not a
**directory** (as denoted by the ending slash) then the files would also be
concatenated and the resulting file would be given the *extension* which
corresponds to this type of file.

          '/': [
            'src/**/*.js'
            'src/**/*.coffee'
          ]

Here, we are doing the same thing for *html* and *jade* files, but we are
outputting them with the `templates` file type.

        templates:
          '/': [
            'src/**/*.html'
            'src/**/*.jade'
          ]

We are doing the same thing here but using different files and associating
them to the *stylesheets* file type.

        stylesheets:
          '/': [
            'src/**/*.css'
            'src/**/*.less'
            'src/**/*.sass'
            'src/**/*.stylus'
          ]

## static

GLP can optionally run a static server. If this is enabled, then the path
specified by the *root* option will be server on the provided static server
port.

      static:

The `static.enabled` function can be true or false. If it is true, then glp
will run it's static server. If false, then the server will not be run.

        enabled: no

The `static.directories` option can be set to true if you want to server
directory indexes, but defaults to false in order to prevent accidental
exposure of file listenings.

        directories: no

The `static.catchAll` option can be set to a string containing a filename. If
set, then all URLs that don't have a static file ready on the server will be
redirected to the given filename. This allows HTML5-style routing without
needing to define every possible route through GLP.

        catchAll: null

The `static.port` option tells GLP what port to serve it's static server on. By
default, the [local server][localserver] will be on port `3333`.

        port: 3333

**NOTE:** Remember that the *watch* option is separated from the *static*
option, so that glp's static server isn't limited to only development
environments.  If *watch* is set to false, then the server will not reflect
your changes until the next time you rebuild the files being served.

## liveReload

The `liveReload` options allow you to change the way that your browser responds
when files are changed.

      liveReload:

You can enable or disable liveReload by setting the `liveReload.enabled` option
to true, or disable it with a value of false.

        enabled: no

You can set the `liveReload.port` to whichever port you want the `liveReload`
server to be listening on if the default value of 35729 is not sufficient.

        port: 35729

If you have `liveReload.enabled` set to a truthy value, you're using the GLP
static server, and you set `liveReload.inject` to a truthy value, then GLP will
automatically inject *livereload.js* into the app from within the static
server. This means that you don't need to change your templates or install any
browser addons in order to get instant feedback of changes in your browser.

        inject: yes

## tasks

Every action in GLP is ran via a *task*. For instance, when you run `glp` you
are actually running the *default* task. This can also be ran with the `glp
default` command if you feel like typing extra. GLP allows you to define any
arbitrary task that you would like.

All tasks can optionally be set to a configuration object. When a configuration
option is provided for a task *it will override* the previously defined
options. Some examples:

      tasks:

You could define a task that is exactly the same as the default task by
providing no option overrides, for instance. This is how the default task
is defined:

        default: {}

You could also request GLP to watch all of your files by overriding the *watch*
option and setting it to yes. This is how the `glp watch` command works:

        watch:
          watch: yes

You could extend this even further by watching files *and* running a static
server with liveReload enabled. Under the hood, this is how the `glp server`
command works:

        server:
          watch: yes

          static:
            enabled: yes

          liveReload:
            enabled: yes

Maybe you don't want to run any servers or watch any files, but you may still
like to make sure that a specific build process outputs it's files in a
different way. This is exactly how `glp release` works:

        release:
          minify:
            enabled: yes

          plugins:
            coffee:
              sourceMap: no

            uglify:
              outSourceMap: no

            jade:
              pretty: no

[npm]: https://www.npmjs.org/
[gulpsrcopts]: https://github.com/gulpjs/gulp/blob/master/docs/API.md#gulpsrcglobs-options
[gulpcoffee]: https://www.npmjs.org/package/gulp-coffee
[gulpjade]: https://www.npmjs.org/package/gulp-jade
[gulpstylus]: https://www.npmjs.org/package/gulp-stylus
[gulpconcat]: https://github.com/wearefractal/gulp-concat
[gulpuglify]: https://www.npmjs.org/package/gulp-uglify
[gulpminifycss]: https://www.npmjs.org/package/gulp-minify-css
[gulpcached]: https://www.npmjs.org/package/gulp-cached
[localserver]: http://localhost:3333/
[lodashmerge]: http://lodash.com/docs#merge

# Configuration

GLP is configured using a specific grammar for explaining how to build a gulp
project. This grammar allows you to easily explain both simple and complicated
build processes in a single configuration file.

The file should be named **glp.yml** and can be placed in your project's root
directory, or it can be placed in an `etc` directory if preferred. You can
also include the configuration in your standard user-level or system-wide
configuration directories.

This document aims to provide a descriptive explanation of all configuration
and best practices for configuration options available to users of GLP.

GLP configuration options can be split up into the following high level
categories:

- **root** tells GLP where to place it's output files.
- **files** with *named groups* and where to find them
- **filters** for introducing new ways to transform files in *file group*
- **plugins** options for changing the way that glp uses them for each *file group*
- **concatenators** for defining which plugins are used for joining files in a *file group*
- **minifiers** for changing how a *file group* is minified
- **extensions** for defining the suffix of output files for each *file group*.
- **liveReload** options for defining changes affect your browser after compiling.
- **static** options for defining routing of built files to a local web server
- **tasks** to overlay different groupings of options based on command-line arguments

The following document will walk you step-by-step through GLP's default
configuration. It should help increase familiarity with all features, and how
to get started with building your own software using GLP and your favorite
programming languages.

## How GLP configuration works

This is a `.litcoffee` file, so we will be using the default configuration as a
practical example of what you can do when writing a configuration file. The
documented values are exactly what is exported to the compiler in GLP.

    module.exports =

These defaults are always overridden with any user-specific settings. When a
configuration file is loaded, GLP will run [lodash.merge][lodashmerge] in order
to merge the user's configuration data over the defaults. Once this is done,
the current *task* is merged in order to define commands which change behavior.

The one exception to this rule is the *files* option, which will be completely
overriden if provided by a user instead of being merged into the default
configuration. The *files* option will still be merged (instead of replaced) if
modified by *tasks*.

Don't  feel discouraged if this seems confusing. It will make more sense as you
read through this document and develop a better understanding of GLP's options.

# Options

## root

This should be a string that contains the name of the directory where you would
like GLP to put build output files.

      root: 'public'

## watch

This should be a boolean. When true, GLP will continue watching for changes to
files after tasks finish. Otherwise, it will not watch for any changes to files.

      watch: no

## debug

If this is set to true, then GLP will provide you with an exhaustive amount of
information describing the build process.

      debug: no

## globOptions

This can be an object which describes the options that should be passed to the
`gulp,watch` and `gulp.src` functions. The keys of the object should be the
name of the task that the options are used with. The value for each task should
be the options as [documented here][gulpsrcopts]. If no options are defined for
the currently active task, then the 'default' options will be used.

      globOptions:
        default:
          options: {}

## cache

Options for controlling how GLP caches files for faster compiling while watching
files for changes.

      cache:

The `cache.enabled` option is false by default, but can be made true if caching
happens to be working as expected with your project. This feature is disabled
by default because it is still experimental.

        enabled: no

## minify

Options for controlling how GLP minifies files.

      minify:

The `minify.enabled` option is false by default. You can set it to true
if you would like to minify built files.

        enabled: no

The `minify.extension` option  can be changed if you'd like to use a custom
prefix extension. For instance, files with the extension **.js** will be
converted to **.min.js** when minification is turned on. If you set
`minify.extension` to an empty string, it will then be converted into.

        extension: '.min'

## ordering

Ordering is disabled by default, but if ordering looks wrong (this shouldn't
ever happen) then you can use this in order to map specific file types to the
ordering you'd want the files to be in. This supports the globbing same format
which is supported by `gulp.src` and `gulp.watch` which is more thoroughly
[documented here][gulpsrcopts].

      ordering: {}

## plugins

The plugins option allows users to define options for gulp all plugins which
are used in the build process. In order to do this, you provide an object
where plugin names are *keys* and the options object is what will be passed
to the related gulp plugin.

Whenever referring to gulp plugins in GLP, you can optionally omit the `gulp-`
prefix. For instance, telling GLP to use a plugin called *cached* is the same
as telling it to use *gulp-cached*. The plugins are standard gulp plugins, so
any standard gulp plugin should work with GLP.

GLP has verify flexible support for easily configuring plugins to be used
through gulp, and tries to be as transparent as possible without sacrificing
usability in the process.

      plugins:

By default, we ask the [gulp-cached][gulpcached] plugin to optimize memory by
storing the files as MD5 instead of the entire file contents.

        cached:
          optimizeMemory: yes

We also want [gulp-uglify][gulpuglify] to output source maps.

        uglify:
          outSourceMap: yes

And while we're developing, we want our templates to be readable. So, we tell
jade to render pretty files instead of spitting them out in a single line.

        jade:
          pretty: yes

The options provided here can also be overridden per-file-type with the
*filters* option as described in the next section. Every setting can be
overriden on a per-task basis as well. This means that we can tell GLP to not
output source maps, pretty templates, or any other option via the *tasks*
option as will also be defined later.

## filters

It's important to remember that you can use any gulp plugin with GLP by
installing it into your project with [npm][npm]. In order to let users define
arbitrary ways of transforming files, we have filters.

The *filters* option provide a way to transform file contents for different
types of files. Each type of file can be given a number of filters which can
be passed through by defining them with this option.

      filters:

For instance, scripts can be compiled as *coffee*. This example is the least
verbose way to define a new filter. Since an empty settings object is being
mapped to the *coffee* type, GLP will automatically transform using a plugin
called [gulp-coffee][gulpcoffee] and match this plugin against a glob which
will automatically be generated with the filter name. In this case, the glob
pattern would be `\*\*/\*.coffee`.

It's worth noting here that you can install **any** gulp plugin into your
project, and GLP will support it when you just add a new filter option for it.

It is possible that the most powerful feature of GLP is it's ability to let you
configure it for any type of file without needing to touch any source code in
the process. This configuration file is all that you will need.

        scripts:
          coffee: {}

Scripts can also be compiled from jade templates. Since we have grouped
filters with the *scripts* file group, we also know that we want the compiled
files to become scripts in the end. So, we can use the `options` key to
forward options to [gulp-jade][gulpjade] in this case.

          jade:
            options:
              client: true

For the stylesheets group, we set up *sass* and *less* so that they will be
bound to files with matching extensions. We have no special options in these
cases, so we can just assign an empty object to them and let GLP assign
defaults as described before.

        stylesheets:
          sass: {}
          less: {}

There are more specific cases for stylus, though. We want to use the
[gulp-stylus][gulpstylus] module and match it against both *.styl* and
*.stylus* file extensions. A more specific case is that we also want to use the
'nib' module by default, but still allow users to override that choice with the
global *plugins* option. That's what the *hints* option is for.

By default, the *options* in a filter override global *plugins* options. The
*hints* option provides the opposite, where the *plugins* options act as an
override. This isn't an extremely useful feature, but it's helpful here for
users that might not want to use *nib* with their stylus files. They could just
set `use` to an empty array in the *plugins* option to prevent it.

          stylus:
            transforms: 'stylus'

            hints:
              use: ['nib']

            matches: [
              '**/*.styl'
              '**/*.stylus'
            ]

Here we redefine jade, but this time we are defining it as a template. The
reason that we have to define this twice is because we want to give different
options to [gulp-jade][gulpjade] for templates instead of scripts. This allows
us to render *templates* as *HTML* files, but jade files in *scripts* will be
rendered as *js* files as  described previously.

        templates:
          jade:
            options:
              client: false

## concatenators

If you need to use custom concatenation rules, you can define them here. This
can be set to an object which maps types of files to a plugin name. It can also
be set to an array if you need to use multiple concatenators. They will be
streamed through plugins in the order that they are provided.

When a plugin isn't defined in the *concatenators* option for a specific type,
GLP will set it to 'concat' as the default value. GLP will automatically prefix
plugin names with *gulp-*, so you don't need to do that. So, the default
concatenator could be found in [NPM][npm] as [gulp-concat][gulpconcat]

As an example use case, some users might want to compile all of their scripts
to [gulp-commonjs][gulpcommonjs] files and then pass the commonjs output to
[gulp-concat][gulpconcat] afterward. That could be done simply by adding a new
key to *concatenators*, such as: `scripts: ['commonjs', 'concat']` followed by
installing the necessary NPM plugins in your project directory.

      concatenators: {}

## extensions

      extensions:
        scripts: 'js'
        stylesheets: 'css'
        templates: 'html'

## minifiers

The minifiers option tells GLP how to minify files with different file
extensions. As an example, the default would use the [gulp-uglify][gulpuglify]
plugin for *js* files, and the [gulp-minify-css][gulpminifycss] plugin for css
files.

      minifiers:
        js: 'uglify'
        css: 'minify-css'

## files

Options for defining what types of files exist, where they are located, and
where they are placed after they have finished being built. The default
configuration will build many types of files from a directory called `src`,
and place them into the **root** directory (the default root is *public* as
described above) after they have been built.

      files:

Each type of file that needs built is given a name. The names can be whatever
you like, and any number of named types can be created. For instance, the
following files are called *scripts*:

        scripts:

Each type is an object which maps a path to a list of files. If a path ends
with a slash, then the files will be copied into a **directory** containing
an output file for every source file that was built. If the path does not
end with a slash, then the  *concatenators* for this type will be used.

In this case, we are building all files ending with `.js` or `.coffee`. After
they are built, the resulting files will be placed in the directory specified
by the **root** function as separate files. If the output file was not a
**directory** (as denoted by the ending slash) then the files would also be
concatenated and the resulting file would be given the *extension* which
corresponds to this type of file.

          '/': [
            'src/**/*.js'
            'src/**/*.coffee'
          ]

Here, we are doing the same thing for *html* and *jade* files, but we are
outputting them with the `templates` file type.

        templates:
          '/': [
            'src/**/*.html'
            'src/**/*.jade'
          ]

We are doing the same thing here but using different files and associating
them to the *stylesheets* file type.

        stylesheets:
          '/': [
            'src/**/*.css'
            'src/**/*.less'
            'src/**/*.sass'
            'src/**/*.stylus'
          ]

## static

GLP can optionally run a static server. If this is enabled, then the path
specified by the *root* option will be server on the provided static server
port.

      static:

The `static.enabled` function can be true or false. If it is true, then glp
will run it's static server. If false, then the server will not be run.

        enabled: no

The `static.directories` option can be set to true if you want to server
directory indexes, but defaults to false in order to prevent accidental
exposure of file listenings.

        directories: no

The `static.catchAll` option can be set to a string containing a filename. If
set, then all URLs that don't have a static file ready on the server will be
redirected to the given filename. This allows HTML5-style routing without
needing to define every possible route through GLP.

        catchAll: null

The `static.port` option tells GLP what port to serve it's static server on. By
default, the [local server][localserver] will be on port `3333`.

        port: 3333

**NOTE:** Remember that the *watch* option is separated from the *static*
option, so that glp's static server isn't limited to only development
environments.  If *watch* is set to false, then the server will not reflect
your changes until the next time you rebuild the files being served.

## liveReload

The `liveReload` options allow you to change the way that your browser responds
when files are changed.

      liveReload:

You can enable or disable liveReload by setting the `liveReload.enabled` option
to true, or disable it with a value of false.

        enabled: no

You can set the `liveReload.port` to whichever port you want the `liveReload`
server to be listening on if the default value of 35729 is not sufficient.

        port: 35729

If you have `liveReload.enabled` set to a truthy value, you're using the GLP
static server, and you set `liveReload.inject` to a truthy value, then GLP will
automatically inject *livereload.js* into the app from within the static
server. This means that you don't need to change your templates or install any
browser addons in order to get instant feedback of changes in your browser.

        inject: yes

## tasks

Every action in GLP is ran via a *task*. For instance, when you run `glp` you
are actually running the *default* task. This can also be ran with the `glp
default` command if you feel like typing extra. GLP allows you to define any
arbitrary task that you would like.

All tasks can optionally be set to a configuration object. When a configuration
option is provided for a task *it will override* the previously defined
options. Some examples:

      tasks:

You could define a task that is exactly the same as the default task by
providing no option overrides, for instance. This is how the default task
is defined:

        default: {}

You could also request GLP to watch all of your files by overriding the *watch*
option and setting it to yes. This is how the `glp watch` command works:

        watch:
          watch: yes

You could extend this even further by watching files *and* running a static
server with liveReload enabled. Under the hood, this is how the `glp server`
command works:

        server:
          watch: yes

          static:
            enabled: yes

          liveReload:
            enabled: yes

Maybe you don't want to run any servers or watch any files, but you may still
like to make sure that a specific build process outputs it's files in a
different way. This is exactly how `glp release` works:

        release:
          minify:
            enabled: yes

          plugins:
            uglify:
              outSourceMap: no

            jade:
              pretty: no

[npm]: https://www.npmjs.org/
[gulpsrcopts]: https://github.com/gulpjs/gulp/blob/master/docs/API.md#gulpsrcglobs-options
[gulpcoffee]: https://www.npmjs.org/package/gulp-coffee
[gulpjade]: https://www.npmjs.org/package/gulp-jade
[gulpstylus]: https://www.npmjs.org/package/gulp-stylus
[gulpconcat]: https://github.com/wearefractal/gulp-concat
[gulpuglify]: https://www.npmjs.org/package/gulp-uglify
[gulpminifycss]: https://www.npmjs.org/package/gulp-minify-css
[gulpcached]: https://www.npmjs.org/package/gulp-cached
[localserver]: http://localhost:3333/
[lodashmerge]: http://lodash.com/docs#merge


markup void fix

markup void fix

Gist of SVG elements

    Tags =
     svg: 'a altGlyph altGlyphDef altGlyphItem animate animateColor
      animateMotion animateTransform circle clipPath color-profile cursor
      defs desc ellipse feBlend feColorMatrix feComponentTransfer
      feComposite feConvolveMatrix feDiffuseLighting feDisplacementMap
      feDistantLight feFlood feFuncA feFuncB feFuncG feFuncR feGaussianBlur
      feImage feMerge feMergeNode feMorphology feOffset fePointLight
      feSpecularLighting feSpotLight feTile feTurbulence
      filter font font-face font-face-format font-face-name font-face-src
      font-face-uri foreignObject g glyph glyphRef hkern image line
      linearGradient marker mask metadata missing-glyph mpath path pattern
      polygon polyline radialGradient rect script set stop style svg symbol
      text textPath title tref tspan use view vkern switch foreignObject'

List of HTML elements

     html: 'a abbr address article aside audio b bdi bdo blockquote body button
      canvas caption cite code colgroup datalist dd del details dfn div dl dt
      em fieldset figcaption figure footer form h1 h2 h3 h4 h5 h6 head header
      hgroup html i iframe ins kbd label legend li main map mark menu meter
      nav noscript object ol optgroup option output p pre progress q rp rt
      ruby s samp script section select small span strong style sub summary
      sup table tbody td textarea tfoot th thead time title tr u ul video'

     htmlVoid: 'area base br col command embed hr img input keygen link meta
      param source track wbr'

Wrapper for browser API

    Api =
     document: @document

Parse id and class string

    parseIdClass = (str) ->
     res =
      id: null
      class: []

     for c, i in str.split "."
      if c.indexOf("#") is 0
       res.id = c.substr 1
      else if c isnt ""
       if not res.class?
        res.class = [c]
       else
        res.class.push c

     return res

    getParameters = (args) ->
     params =
      idClass: null
      text: null
      attrs: null
      func: null

     for arg, i in args
      switch typeof arg
       when 'function' then params.func = arg
       when 'object' then params.attrs = arg
       when 'string'
        if args.length is 1
         params.text = arg
        else
         c = arg.charAt 0

         if i is 0 and (c is '#' or c is '.')
          params.idClass = parseIdClass arg
         else
          params.text = arg

     return params

#Weya DOM

    weyaDomCreate = ->

Weya object to be passed as `this`

     weya =
      _elem: null

Manipulating dom objects

     setStyles = (elem, styles) ->
      for k, v of styles
       if v?
        elem.style.setProperty k, v
       else
        elem.style.removeProperty k

     setEvents = (elem, events) ->
      for k, v of events
       elem.addEventListener k, v, false

     setData = (elem, data) ->
      for k, v of data
       elem[k] = v

     setAttributes = (elem, attrs) ->
      for k, v of attrs
       switch k
        when 'style' then setStyles elem, v
        when 'on' then setEvents elem, v
        when 'data' then setData elem, v
        else
         if v?
          elem.setAttribute k, v
         else
          elem.removeAttribute k

     setIdClass = (elem, idClass) ->
      if idClass.id?
       elem.id = idClass.id

      if idClass.class?
       if elem.classList?
        for c in idClass.class
         elem.classList.add c
       else #For older browsers; does not work with svgs
        className = ''
        for c in idClass.class
         className += ' ' if className isnt ''
         className += "#{c}"
        elem.className = className

Append a child element

     append = (ns, name, args) ->
      params = getParameters args

Keep a reference to parent element

      pElem = @_elem

Keep a reference of `elem` to return at the end of the function

      if ns?
       elem = @_elem = Api.document.createElementNS ns, name
      else
       elem = @_elem = Api.document.createElement name

      if params.idClass?
       setIdClass elem, params.idClass

      if params.attrs?
       setAttributes elem, params.attrs

      if pElem?
       pElem.appendChild elem

      if params.func?
       params.func.call this
      else if params.text?
       elem.textContent = params.text

      @_elem = pElem
      return elem

Wrap `append`

     wrapAppend = (ns, name) ->
      ->
       append.call this, ns, name, arguments

Initialize

     for name in Tags.svg.split ' '
      weya[name] = wrapAppend "http://www.w3.org/2000/svg", name

     for name in Tags.html.split ' '
      weya[name] = wrapAppend "http://www.w3.org/1999/xhtml", name

     for name in Tags.htmlVoid.split ' '
      weya[name] = wrapAppend null, name

     return weya

#Weya Markup

    weyaMarkupCreate = ->

Weya object to be passed as `this`

     weya =
      _buf: null
      _indent: 0

Render components

     setStyles = (buf, styles) ->
      buf.push " style=\""
      for k, v of styles
       buf.push "#{k}:#{v};"
      buf.push "\""

     setEvents = (buf, events) ->
      for k, v of events
       buf.push " on#{k}=\"#{v}\""

     setData = (buf, data) ->
      for k, v of data
       buf.push " data-#{k}=\"#{v}\""

     setAttributes = (buf, attrs) ->
      for k, v of attrs
       switch k
        when 'style' then setStyles buf, v
        when 'on' then setEvents buf, v
        when 'data' then setData buf, v
        else
         buf.push " #{k}=\"#{v}\""

     setIndent = (buf, indent) ->
      for i in [0...indent]
       buf.push " "

Append a child element

     append = (ns, name, isVoid, args) ->
      params = getParameters args

      buf = @_buf

      setIndent buf, @_indent

      buf.push "<#{name}"

      if params.idClass?
       if params.idClass.id?
        buf.push " id=\"#{params.idClass.id}\""
       if params.idClass.class?
        cssClass = ''
        cssClass += "#{c} " for c in params.idClass.class
        buf.push " class=\"#{cssClass}\""

      if params.attrs?
       setAttributes buf, params.attrs

Can close void elements (element that self close) with a `/>`

      if isVoid
       buf.push "/>\n"
       if params.func? or params.text?
        throw new Error 'Void tags cannot have content'

      else
       buf.push ">\n"
       @_indent++

       if params.func?
        params.func.call this
       else if params.text?
        setIndent buf, @_indent
        buf.push params.text
        buf.push "\n"

       @_indent--
       setIndent buf, @_indent
       buf.push "</#{name}>\n"

Wrap `append`

     wrapAppend = (ns, name, isVoid) ->
      ->
       append.call this, ns, name, isVoid, arguments

Initialize

     for name in Tags.svg.split ' '
      weya[name] = wrapAppend "http://www.w3.org/2000/svg", name, false

     for name in Tags.html.split ' '
      weya[name] = wrapAppend null, name, false

     for name in Tags.htmlVoid.split ' '
      weya[name] = wrapAppend null, name, true

     return weya

#Weya API

    weyaDom = weyaDomCreate()
    weyaMarkup = weyaMarkupCreate()

Create and append to `options.elem`. If `options.context` is provied it can be
accessed via `@$`. If `options.elem` is `null`, the element is created but
not appended.

    @Weya = Weya = (options, func) ->
     weya = weyaDom
     pContext = weya.$
     weya.$ = options.context
     helpersAdded = []

     if options.helpers?
      for name, helper of options.helpers
       if not weya[name]?
        helpersAdded.push name
        weya[name] = helper.bind weya

     pElem = weya._elem
     weya._elem = options.elem
     r = func?.call weya
     weya._elem = pElem
     weya.$ = pContext

     for name in helpersAdded
      delete weya[name]

     return r

    Weya.markup = (options, func) ->
     weya = weyaMarkup
     pContext = weya.$
     weya.$ = options.context
     helpersAdded = []

     if options.helpers?
      for name, helper of options.helpers
       if not weya[name]?
        helpersAdded.push name
        weya[name] = helper.bind weya

     pBuf = weya._buf
     weya._buf = []
     r = func?.call weya
     buf = weya._buf
     weya._buf = pBuf
     weya.$ = pContext

     for name in helpersAdded
      delete weya[name]

     return buf.join ''

    Weya.setApi = (api) ->
     for k, v of api
      Api[k] = v

    if module?
     module.exports = Weya

Gist of SVG elements

    Tags =
     svg: 'a altGlyph altGlyphDef altGlyphItem animate animateColor
      animateMotion animateTransform circle clipPath color-profile cursor
      defs desc ellipse feBlend feColorMatrix feComponentTransfer
      feComposite feConvolveMatrix feDiffuseLighting feDisplacementMap
      feDistantLight feFlood feFuncA feFuncB feFuncG feFuncR feGaussianBlur
      feImage feMerge feMergeNode feMorphology feOffset fePointLight
      feSpecularLighting feSpotLight feTile feTurbulence
      filter font font-face font-face-format font-face-name font-face-src
      font-face-uri foreignObject g glyph glyphRef hkern image line
      linearGradient marker mask metadata missing-glyph mpath path pattern
      polygon polyline radialGradient rect script set stop style svg symbol
      text textPath title tref tspan use view vkern switch foreignObject'

List of HTML elements

     html: 'a abbr address article aside audio b bdi bdo blockquote body button
      canvas caption cite code colgroup datalist dd del details dfn div dl dt
      em fieldset figcaption figure footer form h1 h2 h3 h4 h5 h6 head header
      hgroup html i iframe ins kbd label legend li main map mark menu meter
      nav noscript object ol optgroup option output p pre progress q rp rt
      ruby s samp script section select small span strong style sub summary
      sup table tbody td textarea tfoot th thead time title tr u ul video'

     htmlVoid: 'area base br col command embed hr img input keygen link meta
      param source track wbr'

Wrapper for browser API

    Api =
     document: @document

Parse id and class string

    parseIdClass = (str) ->
     res =
      id: null
      class: []

     for c, i in str.split "."
      if c.indexOf("#") is 0
       res.id = c.substr 1
      else if c isnt ""
       if not res.class?
        res.class = [c]
       else
        res.class.push c

     return res

    getParameters = (args) ->
     params =
      idClass: null
      text: null
      attrs: null
      func: null

     for arg, i in args
      switch typeof arg
       when 'function' then params.func = arg
       when 'object' then params.attrs = arg
       when 'string'
        if args.length is 1
         params.text = arg
        else
         c = arg.charAt 0

         if i is 0 and (c is '#' or c is '.')
          params.idClass = parseIdClass arg
         else
          params.text = arg

     return params

#Weya DOM

    weyaDomCreate = ->

Weya object to be passed as `this`

     weya =
      _elem: null

Manipulating dom objects

     setStyles = (elem, styles) ->
      for k, v of styles
       if v?
        elem.style.setProperty k, v
       else
        elem.style.removeProperty k

     setEvents = (elem, events) ->
      for k, v of events
       elem.addEventListener k, v, false

     setData = (elem, data) ->
      for k, v of data
       elem[k] = v

     setAttributes = (elem, attrs) ->
      for k, v of attrs
       switch k
        when 'style' then setStyles elem, v
        when 'on' then setEvents elem, v
        when 'data' then setData elem, v
        else
         if v?
          elem.setAttribute k, v
         else
          elem.removeAttribute k

     setIdClass = (elem, idClass) ->
      if idClass.id?
       elem.id = idClass.id

      if idClass.class?
       if elem.classList?
        for c in idClass.class
         elem.classList.add c
       else #For older browsers; does not work with svgs
        className = ''
        for c in idClass.class
         className += ' ' if className isnt ''
         className += "#{c}"
        elem.className = className

Append a child element

     append = (ns, name, args) ->
      params = getParameters args

Keep a reference to parent element

      pElem = @_elem

Keep a reference of `elem` to return at the end of the function

      if ns?
       elem = @_elem = Api.document.createElementNS ns, name
      else
       elem = @_elem = Api.document.createElement name

      if params.idClass?
       setIdClass elem, params.idClass

      if params.attrs?
       setAttributes elem, params.attrs

      if pElem?
       pElem.appendChild elem

      if params.func?
       params.func.call this
      else if params.text?
       elem.textContent = params.text

      @_elem = pElem
      return elem

Wrap `append`

     wrapAppend = (ns, name) ->
      ->
       append.call this, ns, name, arguments

Initialize

     for name in Tags.svg.split ' '
      weya[name] = wrapAppend "http://www.w3.org/2000/svg", name

     for name in Tags.html.split ' '
      weya[name] = wrapAppend "http://www.w3.org/1999/xhtml", name

     for name in Tags.htmlVoid.split ' '
      weya[name] = wrapAppend null, name

     return weya

#Weya Markup

    weyaMarkupCreate = ->

Weya object to be passed as `this`

     weya =
      _buf: null
      _indent: 0

Render components

     setStyles = (buf, styles) ->
      buf.push " style=\""
      for k, v of styles
       buf.push "#{k}:#{v};"
      buf.push "\""

     setEvents = (buf, events) ->
      for k, v of events
       buf.push " on#{k}=\"#{v}\""

     setData = (buf, data) ->
      for k, v of data
       buf.push " data-#{k}=\"#{v}\""

     setAttributes = (buf, attrs) ->
      for k, v of attrs
       switch k
        when 'style' then setStyles buf, v
        when 'on' then setEvents buf, v
        when 'data' then setData buf, v
        else
         buf.push " #{k}=\"#{v}\""

     setIndent = (buf, indent) ->
      for i in [0...indent]
       buf.push " "

Append a child element

     append = (ns, name, args) ->
      params = getParameters args

      buf = @_buf

      setIndent buf, @_indent

      buf.push "<#{name}"

      if params.idClass?
       if params.idClass.id?
        buf.push " id=\"#{params.idClass.id}\""
       if params.idClass.class?
        cssClass = ''
        cssClass += "#{c} " for c in params.idClass.class
        buf.push " class=\"#{cssClass}\""

      if params.attrs?
       setAttributes buf, params.attrs

Can close void elements (element that self close) with a `/>`

      buf.push ">\n"
      @_indent++

      if params.func?
       params.func.call this
      else if params.text?
       setIndent buf, @_indent
       buf.push params.text
       buf.push "\n"

      @_indent--
      setIndent buf, @_indent
      buf.push "</#{name}>\n"

Wrap `append`

     wrapAppend = (ns, name) ->
      ->
       append.call this, ns, name, arguments

Initialize

     for name in Tags.svg.split ' '
      weya[name] = wrapAppend "http://www.w3.org/2000/svg", name

     for name in Tags.html.split ' '
      weya[name] = wrapAppend null, name

     for name in Tags.htmlVoid.split ' '
      weya[name] = wrapAppend null, name

     return weya

#Weya API

    weyaDom = weyaDomCreate()
    weyaMarkup = weyaMarkupCreate()

Create and append to `options.elem`. If `options.context` is provied it can be
accessed via `@$`. If `options.elem` is `null`, the element is created but
not appended.

    @Weya = Weya = (options, func) ->
     weya = weyaDom
     pContext = weya.$
     weya.$ = options.context
     helpersAdded = []

     if options.helpers?
      for name, helper of options.helpers
       if not weya[name]?
        helpersAdded.push name
        weya[name] = helper.bind weya

     pElem = weya._elem
     weya._elem = options.elem
     r = func?.call weya
     weya._elem = pElem
     weya.$ = pContext

     for name in helpersAdded
      delete weya[name]

     return r

    Weya.markup = (options, func) ->
     weya = weyaMarkup
     pContext = weya.$
     weya.$ = options.context
     helpersAdded = []

     if options.helpers?
      for name, helper of options.helpers
       if not weya[name]?
        helpersAdded.push name
        weya[name] = helper.bind weya

     pBuf = weya._buf
     weya._buf = []
     r = func?.call weya
     buf = weya._buf
     weya._buf = pBuf
     weya.$ = pContext

     for name in helpersAdded
      delete weya[name]

     return buf.join ''

    Weya.setApi = (api) ->
     for k, v of api
      Api[k] = v

    if module?
     module.exports = Weya


update docs

update docs


cyclomatic complexity

cyclomatic complexity

List of SVG elements

    Tags =
     svg: 'a altGlyph altGlyphDef altGlyphItem animate animateColor
      animateMotion animateTransform circle clipPath color-profile cursor
      defs desc ellipse feBlend feColorMatrix feComponentTransfer
      feComposite feConvolveMatrix feDiffuseLighting feDisplacementMap
      feDistantLight feFlood feFuncA feFuncB feFuncG feFuncR feGaussianBlur
      feImage feMerge feMergeNode feMorphology feOffset fePointLight
      feSpecularLighting feSpotLight feTile feTurbulence
      filter font font-face font-face-format font-face-name font-face-src
      font-face-uri foreignObject g glyph glyphRef hkern image line
      linearGradient marker mask metadata missing-glyph mpath path pattern
      polygon polyline radialGradient rect script set stop style svg symbol
      text textPath title tref tspan use view vkern switch foreignObject'

List of HTML elements

     html: 'a abbr address article aside audio b bdi bdo blockquote body button
      canvas caption cite code colgroup datalist dd del details dfn div dl dt
      em fieldset figcaption figure footer form h1 h2 h3 h4 h5 h6 head header
      hgroup html i iframe ins kbd label legend li main map mark menu meter
      nav noscript object ol optgroup option output p pre progress q rp rt
      ruby s samp script section select small span strong style sub summary
      sup table tbody td textarea tfoot th thead time title tr u ul video'

     htmlVoid: 'area base br col command embed hr img input keygen link meta
      param source track wbr'

Wrapper for browser API

    Api =
     document: @document

Parse id and class string

    parseIdClass = (str) ->
     res =
      id: null
      class: []

     for c, i in str.split "."
      if c.indexOf("#") is 0
       res.id = c.substr 1
      else if c isnt ""
       if not res.class?
        res.class = [c]
       else
        res.class.push c

     return res

    getParameters = (args) ->
     params =
      idClass: null
      text: null
      attrs: null
      func: null

     for arg, i in args
      switch typeof arg
       when 'function' then params.func = arg
       when 'object' then params.attrs = arg
       when 'string'
        if args.length is 1
         params.text = arg
        else
         c = arg.charAt 0

         if i is 0 and (c is '#' or c is '.')
          params.idClass = parseIdClass arg
         else
          params.text = arg

     return params

#Weya DOM

    weyaDomCreate = ->

Weya object to be passed as `this`

     weya =
      _elem: null

Manipulating dom objects

     setStyles = (elem, styles) ->
      for k, v of styles
       if v?
        elem.style.setProperty k, v
       else
        elem.style.removeProperty k

     setEvents = (elem, events) ->
      for k, v of events
       elem.addEventListener k, v, false

     setAttributes = (elem, attrs) ->
      for k, v of attrs
       switch k
        when 'style' then setStyles elem, v
        when 'on' then setEvents elem, v
        else
         if v?
          elem.setAttribute k, v
         else
          elem.removeAttribute k

Append a child element

     append = (ns, name, args) ->
      params = getParameters args

Keep a reference to parent element

      pElem = @_elem

Keep a reference of `elem` to return at the end of the function

      if ns?
       elem = @_elem = Api.document.createElementNS ns, name
      else
       elem = @_elem = Api.document.createElement name

      if params.idClass?
       if params.idClass.id?
        elem.id = params.idClass.id
       if params.idClass.class?
        if elem.classList?
         for c in params.idClass.class
          elem.classList.add c
        else #For older browsers; does not work with svgs
         className = ''
         for c in params.idClass.class
          className += ' ' if className isnt ''
          className += "#{c}"
         elem.className = className

      if params.attrs?
       setAttributes elem, params.attrs

      if pElem?
       pElem.appendChild elem

      if params.func?
       params.func.call this
      else if params.text?
       elem.textContent = params.text

      @_elem = pElem
      return elem

Wrap `append`

     wrapAppend = (ns, name) ->
      ->
       append.call this, ns, name, arguments

Initialize

     for name in Tags.svg.split ' '
      weya[name] = wrapAppend "http://www.w3.org/2000/svg", name

     for name in Tags.html.split ' '
      weya[name] = wrapAppend "http://www.w3.org/1999/xhtml", name

     for name in Tags.htmlVoid.split ' '
      weya[name] = wrapAppend null, name

     return weya

#Weya Markup

    weyaMarkupCreate = ->

Weya object to be passed as `this`

     weya =
      _buf: null
      _indent: 0

Render components

     setStyles = (buf, styles) ->
      buf.push " style=\""
      for k, v of styles
       buf.push "#{k}:#{v};"
      buf.push "\""

     setEvents = (buf, events) ->
      for k, v of events
       buf.push " on#{k}=\"#{v}\""

     setAttributes = (buf, attrs) ->
      for k, v of attrs
       switch k
        when 'style' then setStyles buf, v
        when 'on' then setEvents buf, v
        else
         buf.push " #{k}=\"#{v}\""

     setIndent = (buf, indent) ->
      for i in [0...indent]
       buf.push " "

Append a child element

     append = (ns, name, args) ->
      params = getParameters args

      buf = @_buf

      setIndent buf, @_indent

      buf.push "<#{name}"

      if params.idClass?
       if params.idClass.id?
        buf.push " id=\"#{params.idClass.id}\""
       if params.idClass.class?
        buf.push " class=\"#{params.idClass.class}\""

      if params.attrs?
       setAttributes buf, params.attrs

Can close void elements (element that self close) with a `/>`

      buf.push ">\n"
      @_indent++

      if params.func?
       params.func.call this
      else if params.text?
       setIndent buf, @_indent
       buf.push params.text
       buf.push "\n"

      @_indent--
      setIndent buf, @_indent
      buf.push "</#{name}>\n"

Wrap `append`

     wrapAppend = (ns, name) ->
      ->
       append.call this, ns, name, arguments

Initialize

     for name in Tags.svg.split ' '
      weya[name] = wrapAppend "http://www.w3.org/2000/svg", name

     for name in Tags.html.split ' '
      weya[name] = wrapAppend null, name

     for name in Tags.htmlVoid.split ' '
      weya[name] = wrapAppend null, name

     return weya

#Weya API

    weyaDom = weyaDomCreate()
    weyaMarkup = weyaMarkupCreate()

Create and append to `options.elem`. If `options.context` is provied it can be
accessed via `@$`. If `options.elem` is `null`, the element is created but
not appended.

    @Weya = Weya = (options, func) ->
     weya = weyaDom
     pContext = weya.$
     weya.$ = options.context
     pElem = weya._elem
     weya._elem = options.elem
     r = func?.call weya
     weya._elem = pElem
     weya.$ = pContext
     return r

    Weya.markup = (options, func) ->
     weya = weyaMarkup
     pContext = weya.$
     weya.$ = options.context
     pBuf = weya._buf
     weya._buf = []
     r = func?.call weya
     buf = weya._buf
     weya._buf = pBuf
     weya.$ = pContext
     return buf.join ''

    Weya.setApi = (api) ->
     for k, v of api
      Api[k] = v

    if module?
     module.exports = Weya

List of SVG elements

    Tags =
     svg: 'a altGlyph altGlyphDef altGlyphItem animate animateColor
      animateMotion animateTransform circle clipPath color-profile cursor
      defs desc ellipse feBlend feColorMatrix feComponentTransfer
      feComposite feConvolveMatrix feDiffuseLighting feDisplacementMap
      feDistantLight feFlood feFuncA feFuncB feFuncG feFuncR feGaussianBlur
      feImage feMerge feMergeNode feMorphology feOffset fePointLight
      feSpecularLighting feSpotLight feTile feTurbulence
      filter font font-face font-face-format font-face-name font-face-src
      font-face-uri foreignObject g glyph glyphRef hkern image line
      linearGradient marker mask metadata missing-glyph mpath path pattern
      polygon polyline radialGradient rect script set stop style svg symbol
      text textPath title tref tspan use view vkern switch foreignObject'

List of HTML elements

     html: 'a abbr address article aside audio b bdi bdo blockquote body button
      canvas caption cite code colgroup datalist dd del details dfn div dl dt
      em fieldset figcaption figure footer form h1 h2 h3 h4 h5 h6 head header
      hgroup html i iframe ins kbd label legend li main map mark menu meter
      nav noscript object ol optgroup option output p pre progress q rp rt
      ruby s samp script section select small span strong style sub summary
      sup table tbody td textarea tfoot th thead time title tr u ul video'

     htmlVoid: 'area base br col command embed hr img input keygen link meta
      param source track wbr'

Wrapper for browser API

    Api =
     document: @document

#Weya DOM

    weyaDomCreate = ->

Weya object to be passed as `this`

     weya =
      _elem: null

Manipulating dom objects

     setStyles = (elem, styles) ->
      for k, v of styles
       if v?
        elem.style.setProperty k, v
       else
        elem.style.removeProperty k

     setEvents = (elem, events) ->
      for k, v of events
       elem.addEventListener k, v, false

     setAttributes = (elem, attrs) ->
      for k, v of attrs
       switch k
        when 'style' then setStyles elem, v
        when 'on' then setEvents elem, v
        else
         if v?
          elem.setAttribute k, v
         else
          elem.removeAttribute k

Parse id and class string

     parseIdClass = (str) ->
      res =
       id: null
       class: []

      for c, i in str.split "."
       if c.indexOf("#") is 0
        res.id = c.substr 1
       else if c isnt ""
        if not res.class?
         res.class = [c]
        else
         res.class.push c

      return res

Append a child element

     append = (ns, name, args) ->
      idClass = null
      contentText = null
      attrs = null
      contentFunction = null

      for arg, i in args
       switch typeof arg
        when 'function' then contentFunction = arg
        when 'object' then attrs = arg
        when 'string'
         if args.length is 1
          contentText = arg
         else
          c = arg.charAt 0

          if i is 0 and (c is '#' or c is '.')
           idClass = arg
          else
           contentText = arg

Keep a reference to parent element

      pElem = @_elem

Keep a reference of `elem` to return at the end of the function

      if ns?
       elem = @_elem = Api.document.createElementNS ns, name
      else
       elem = @_elem = Api.document.createElement name

      if idClass?
       idClass = parseIdClass idClass
       if idClass.id?
        elem.id = idClass.id
       if idClass.class?
        if elem.classList?
         for c in idClass.class
          elem.classList.add c
        else #For older browsers; does not work with svgs
         className = ''
         for c in idClass.class
          className += ' ' if className isnt ''
          className += "#{c}"
         elem.className = className

      if attrs?
       setAttributes elem, attrs

      if pElem?
       pElem.appendChild elem

      if contentFunction?
       contentFunction.call this
      else if contentText?
       elem.textContent = contentText

      @_elem = pElem
      return elem

Wrap `append`

     wrapAppend = (ns, name) ->
      ->
       append.call this, ns, name, arguments

Initialize

     for name in Tags.svg.split ' '
      weya[name] = wrapAppend "http://www.w3.org/2000/svg", name

     for name in Tags.html.split ' '
      weya[name] = wrapAppend "http://www.w3.org/1999/xhtml", name

     for name in Tags.htmlVoid.split ' '
      weya[name] = wrapAppend null, name

     return weya

#Weya Markup

    weyaMarkupCreate = ->

Weya object to be passed as `this`

     weya =
      _buf: null
      _indent: 0

Render components

     setStyles = (buf, styles) ->
      buf.push " style=\""
      for k, v of styles
       buf.push "#{k}:#{v};"
      buf.push "\""

     setEvents = (buf, events) ->
      for k, v of events
       buf.push " on#{k}=\"#{v}\""

     setAttributes = (buf, attrs) ->
      for k, v of attrs
       switch k
        when 'style' then setStyles buf, v
        when 'on' then setEvents buf, v
        else
         buf.push " #{k}=\"#{v}\""

     setIndent = (buf, indent) ->
      for i in [0...indent]
       buf.push " "

Parse id and class string

     parseIdClass = (str) ->
      res =
       id: null
       class: null

      for c, i in str.split "."
       if c.indexOf("#") is 0
        res.id = c.substr 1
       else if c isnt ""
        if not res.class?
         res.class = c
        else
         res.class += " #{c}"

      return res

Append a child element

     append = (ns, name, args) ->
      idClass = null
      contentText = null
      attrs = null
      contentFunction = null

      for arg, i in args
       switch typeof arg
        when 'function' then contentFunction = arg
        when 'object' then attrs = arg
        when 'string'
         if args.length is 1
          contentText = arg
         else
          c = arg.charAt 0

          if i is 0 and (c is '#' or c is '.')
           idClass = arg
          else
           contentText = arg

      buf = @_buf

      setIndent buf, @_indent

      buf.push "<#{name}"

      if idClass?
       idClass = parseIdClass idClass
       if idClass.id?
        buf.push " id=\"#{idClass.id}\""
       if idClass.class?
        buf.push " class=\"#{idClass.class}\""

      if attrs?
       setAttributes buf, attrs

Can close void elements (element that self close) with a `/>`

      buf.push ">\n"
      @_indent++

      if contentFunction?
       contentFunction.call this
      else if contentText?
       setIndent buf, @_indent
       buf.push contentText
       buf.push "\n"

      @_indent--
      setIndent buf, @_indent
      buf.push "</#{name}>\n"

Wrap `append`

     wrapAppend = (ns, name) ->
      ->
       append.call this, ns, name, arguments

Initialize

     for name in Tags.svg.split ' '
      weya[name] = wrapAppend "http://www.w3.org/2000/svg", name

     for name in Tags.html.split ' '
      weya[name] = wrapAppend null, name

     for name in Tags.htmlVoid.split ' '
      weya[name] = wrapAppend null, name

     return weya

#Weya API

    weyaDom = weyaDomCreate()
    weyaMarkup = weyaMarkupCreate()

Create and append to `options.elem`. If `options.context` is provied it can be
accessed via `@$`. If `options.elem` is `null`, the element is created but
not appended.

    @Weya = Weya = (options, func) ->
     weya = weyaDom
     pContext = weya.$
     weya.$ = options.context
     pElem = weya._elem
     weya._elem = options.elem
     r = func?.call weya
     weya._elem = pElem
     weya.$ = pContext
     return r

    Weya.markup = (options, func) ->
     weya = weyaMarkup
     pContext = weya.$
     weya.$ = options.context
     pBuf = weya._buf
     weya._buf = []
     r = func?.call weya
     buf = weya._buf
     weya._buf = pBuf
     weya.$ = pContext
     return buf.join ''

    Weya.setApi = (api) ->
     for k, v of api
      Api[k] = v

    if module?
     module.exports = Weya


Dissable server methodOverride

Dissable server methodOverride

    "use strict"

    express     = require 'express'
    raven       = require 'raven'

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

## Init

    app = express()

### Authentication

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

In future versions of the API this routine will also check the request quota and
blocking the user if the quota is full.

    app.use '/', (req, res, next) ->

      key = req.query.api_key

      return res.json 403, message: 'API key missing' if not key
      return res.json 401, message: 'API key invalid' if not apiKeys[key]

      req.key = key
      req.usr = apiKeys[key]

      next()

### Configuration

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

### Error handling

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

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

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

      console.error err.message
      console.error err.stack

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

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

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

### API keys

This is the dirty part. Here are all the keys to the kingdom. These will be
moved to the database and retrieved when the server starts. Just need to find
the time to do it.

    apiKeys =
      dnt: 'DNT'
      nrk: 'DNT'

      '30ad3a3a1d2c7c63102e09e6fe4bb253': 'TurApp'
      'b523ceb5e16fb92b2a999676a87698d1': 'Pingdom'

      '4c802ac2315ab24db9c992cc6eea0278': 'DNT' # ETA
      'de2986ac75c5af9d7f92a26f37dc1b77': 'DNT' # sherpa2.api
      '5dd5a39057cb479c3c4bce7f9eae5e6c': 'DNT' # dev.ut.no
      '146bbe01b477e9e07e85e0ddd3f5095a': 'DNT' # beta.ut.no
      'e6fa27292ffbcc689c49179c47bc708e': 'DNT' # prod.ut.no

## GET /

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

## GET /system

Hsssssj!!! Don't tell anyone about the secret system API endpoint!

    app.get '/system', system.info

## GET /CloudHealthCheck

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

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

    app.get '/CloudHealthCheck', system.check

## GET /objekttyper

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

## ALL /{collection}

    app.param 'collection', collection.param
    app.all '/:collection', (req, res, next) ->
      switch req.method
        when 'OPTIONS' then collection.options req, res, next
        when 'HEAD', 'GET' then collection.get req, res, next
        when 'POST' then collection.post req, res, next
        when 'PUT'  then collection.put req, res, next
        when 'PATCH' then collection.patch req, res, next
        else res.json 405, message: 'HTTP method not supported'

## ALL /{collection}/{objectid}

    app.param 'objectid', document.param
    app.all '/:collection/:objectid', (req, res, next) ->
      switch req.method
        when 'OPTIONS' then document.options req, res, next
        when 'HEAD', 'GET' then document.get req, res, next
        when 'PUT' then document.put req, res, next
        when 'PATCH' then document.patch req, res, next
        when 'DELETE' then document.delete req, res, next
        else res.json 405, message: 'HTTP method not supported'

## Start

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

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

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

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

    else
      module.exports = app

    "use strict"

    express     = require 'express'
    raven       = require 'raven'

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

## Init

    app = express()

### Authentication

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

In future versions of the API this routine will also check the request quota and
blocking the user if the quota is full.

    app.use '/', (req, res, next) ->

      key = req.query.api_key

      return res.json 403, message: 'API key missing' if not key
      return res.json 401, message: 'API key invalid' if not apiKeys[key]

      req.key = key
      req.usr = apiKeys[key]

      next()

### Configuration

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

### Error handling

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

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

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

      console.error err.message
      console.error err.stack

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

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

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

### API keys

This is the dirty part. Here are all the keys to the kingdom. These will be
moved to the database and retrieved when the server starts. Just need to find
the time to do it.

    apiKeys =
      dnt: 'DNT'
      nrk: 'DNT'

      '30ad3a3a1d2c7c63102e09e6fe4bb253': 'TurApp'
      'b523ceb5e16fb92b2a999676a87698d1': 'Pingdom'

      '4c802ac2315ab24db9c992cc6eea0278': 'DNT' # ETA
      'de2986ac75c5af9d7f92a26f37dc1b77': 'DNT' # sherpa2.api
      '5dd5a39057cb479c3c4bce7f9eae5e6c': 'DNT' # dev.ut.no
      '146bbe01b477e9e07e85e0ddd3f5095a': 'DNT' # beta.ut.no
      'e6fa27292ffbcc689c49179c47bc708e': 'DNT' # prod.ut.no

## GET /

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

## GET /system

Hsssssj!!! Don't tell anyone about the secret system API endpoint!

    app.get '/system', system.info

## GET /CloudHealthCheck

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

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

    app.get '/CloudHealthCheck', system.check

## GET /objekttyper

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

## ALL /{collection}

    app.param 'collection', collection.param
    app.all '/:collection', (req, res, next) ->
      switch req.method
        when 'OPTIONS' then collection.options req, res, next
        when 'HEAD', 'GET' then collection.get req, res, next
        when 'POST' then collection.post req, res, next
        when 'PUT'  then collection.put req, res, next
        when 'PATCH' then collection.patch req, res, next
        else res.json 405, message: 'HTTP method not supported'

## ALL /{collection}/{objectid}

    app.param 'objectid', document.param
    app.all '/:collection/:objectid', (req, res, next) ->
      switch req.method
        when 'OPTIONS' then document.options req, res, next
        when 'HEAD', 'GET' then document.get req, res, next
        when 'PUT' then document.put req, res, next
        when 'PATCH' then document.patch req, res, next
        when 'DELETE' then document.delete req, res, next
        else res.json 405, message: 'HTTP method not supported'

## Start

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

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

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

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

    else
      module.exports = app


Formatting

Formatting

   EventEmitter      = require('events').EventEmitter
    _                 = require 'underscore'
    log               = require 'simplog'
    AwesomeWebSocket  = require('awesome-websocket').AwesomeWebSocket

EpiClient
=========
This is the base client for communicating with epiquery2.

    class EpiClient extends EventEmitter

The @url constructor argument can be either a singular string or an array of strings that represent the
epiquery2 endpoint(s).

      constructor: (@url) ->
        @connect()

Under the hood, we're using the [AwesomeWebSocket](https://github.com/glg/awesome-websocket) to ensure auto-reconnect
on interruptions and endpoint hunting to find the fastest connection.

      connect: =>
        @ws = new AwesomeWebSocket(@url)
        @queryId = 0
        @ws.onmessage = @onMessage
        @ws.onclose = @onClose
        @ws.onopen = () ->
          log.debug "Epiclient connection opened"
        @ws.onerror = (err) ->
          log.error "EpiClient socket error: ", err

The **query** function kicks off the processing of a query.  While the function is called query, epiquery may actually be executing multiple queries against a data source.

**connectionName** - The string key that maps to an epiquery2 named connection e.g. 'mysql', 'mssql', 'file'.  See more [here](https://github.com/igroff/epiquery2#configuration).
**template** - The path to the template you're querying.  The path is relative to the root of the template directory defined in epiquery2.
**data** - This is a just javascript object you can pass that contains any data you want to use in your epiquery template.
**queryId** - A unique identifier used to refer to the query throughout it's Active period. It will be included with all messages generated during it's processing. It is the caller's responsibility to generate a unique id for each query requested.

      query: (connectionName, template, data, queryId=null) =>
        req =
          templateName: template
          connectionName: connectionName
          data: data
        req.queryId = null || queryId
        req.closeOnEnd = data.closeOnEnd if data
        # if someone has asked us to close on end, we want our fancy
        # underlying reconnectint sockets to not reconnect
        @ws.forceClose = req.closeOnEnd

        log.debug "executing query: #{template} data:#{JSON.stringify(data)}"
        @ws.send JSON.stringify(req)

Echoes events returned from epiquery.

      onMessage: (message) =>
        # if the browser has wrapped this for use, we'll be interested in its
        # 'data' element
        message = message.data if message.type? and message.type = 'message'
        message = JSON.parse(message) if typeof message is 'string'
        handler = @['on' + message.message]
        if handler
          handler(message)

      onClose: () =>
        @emit 'close'

## Events
They're all pretty self explanatory.  The messages provided to the events have the optional field **queryId** that corresponds to the  queryId that was provided to the **query** function.  Use that to track a particular request in the query's lifecycle.

Invoked at the start of the query's lifecycle.  No query has occurred yet.

      onbeginquery: (msg) => @emit 'beginquery', msg

Invoked when a new row set is began.  Row sets are the result of executing a singular query.  For example, if you executed two SQL statements, each would be its own row set.

      onbeginrowset: (msg) => @emit 'beginrowset', msg

Invoked every time a row of data is returned from a row set.

      onrow: (msg) => @emit 'row', msg

Invoked at the end of a row set.

      onendrowset: (msg) => @emit 'endrowset', msg

Invoked at the end of the query's overall lifecycle.

      onendquery: (msg) => @emit 'endquery', msg

Invoked if an error is encountered while processing the query.

      onerror: (msg) => @emit 'error', msg

    module.exports = EpiClient