Rebuilds lib/ with new name. Updates Cokefile to build dist/limn.js. Adds symlinks...
authorDavid Schoonover <dsc@wikimedia.org>
Mon, 16 Jul 2012 23:02:28 +0000 (16:02 -0700)
committerDavid Schoonover <dsc@wikimedia.org>
Mon, 16 Jul 2012 23:58:25 +0000 (16:58 -0700)
159 files changed:
Cokefile
lib/app.js
lib/app.mod.js [deleted file]
lib/base/asset-manager.js
lib/base/base-mixin.js
lib/base/base-mixin.mod.js
lib/base/base-model.js
lib/base/base-model.mod.js
lib/base/base-view.js
lib/base/base-view.mod.js
lib/base/base.js
lib/base/base.mod.js
lib/base/cascading-model.js
lib/base/cascading-model.mod.js
lib/base/data-binding.js
lib/base/data-binding.mod.js
lib/base/index.js
lib/base/index.mod.js
lib/base/model-cache.js
lib/base/model-cache.mod.js
lib/base/resource-router.js [new file with mode: 0644]
lib/base/scaffold/index.js
lib/base/scaffold/index.mod.js
lib/base/scaffold/scaffold-model.js
lib/base/scaffold/scaffold-model.mod.js
lib/base/scaffold/scaffold-view.js
lib/base/scaffold/scaffold-view.mod.js
lib/chart/chart-type.js
lib/chart/chart-type.mod.js
lib/chart/index.js
lib/chart/index.mod.js
lib/chart/option/chart-option-model.js
lib/chart/option/chart-option-model.mod.js
lib/chart/option/chart-option-view.js
lib/chart/option/chart-option-view.mod.js
lib/chart/option/index.js
lib/chart/option/index.mod.js
lib/chart/type/d3-chart.js
lib/chart/type/d3-chart.mod.js
lib/chart/type/d3/d3-bar-chart-type.js
lib/chart/type/d3/d3-bar-element.js
lib/chart/type/d3/d3-bar-element.mod.js
lib/chart/type/d3/d3-chart-element.js
lib/chart/type/d3/d3-chart-element.mod.js
lib/chart/type/d3/d3-geo-element.js
lib/chart/type/d3/d3-line-element.js
lib/chart/type/d3/d3-line-element.mod.js
lib/chart/type/d3/index.js
lib/chart/type/d3/index.mod.js
lib/chart/type/dygraphs.js
lib/chart/type/dygraphs.mod.js
lib/chart/type/index.mod.js
lib/dashboard/dashboard-model.js
lib/dashboard/dashboard-model.mod.js
lib/dashboard/dashboard-view.js
lib/dashboard/dashboard-view.mod.js
lib/dashboard/index.js
lib/dashboard/index.mod.js
lib/data/data-view.js
lib/data/data-view.mod.js
lib/data/dataset-model.js
lib/data/dataset-model.mod.js
lib/data/dataset-view.js
lib/data/dataset-view.mod.js
lib/data/datasource-model.js
lib/data/datasource-model.mod.js
lib/data/datasource-ui-view.js
lib/data/datasource-ui-view.mod.js
lib/data/datasource-view.js
lib/data/datasource-view.mod.js
lib/data/index.js
lib/data/index.mod.js
lib/data/metric-edit-view.js
lib/data/metric-edit-view.mod.js
lib/data/metric-model.js
lib/data/metric-model.mod.js
lib/data/project-colors.mod.js
lib/graph/graph-display-view.js
lib/graph/graph-display-view.mod.js
lib/graph/graph-edit-view.js
lib/graph/graph-edit-view.mod.js
lib/graph/graph-list-view.js
lib/graph/graph-list-view.mod.js
lib/graph/graph-model.js
lib/graph/graph-model.mod.js
lib/graph/graph-view.js
lib/graph/graph-view.mod.js
lib/graph/index.js
lib/graph/index.mod.js
lib/limn.js [new file with mode: 0644]
lib/limn.mod.js [new file with mode: 0644]
lib/main-dashboard.js [deleted file]
lib/main-display.js [deleted file]
lib/main-edit.js [deleted file]
lib/main-graph-list.js [deleted file]
lib/server/controller.js
lib/server/controllers/dashboard.js
lib/server/controllers/datasource.js
lib/server/controllers/graph.js
lib/server/file-controller.js
lib/server/files.js
lib/server/middleware.js
lib/server/proxy.js
lib/server/server.js
lib/server/view-helpers.js
lib/template/chart/chart-option.jade.mod.js
lib/template/chart/chart-scaffold.jade.mod.js
lib/template/dashboard/dashboard-tab.jade.mod.js
lib/template/dashboard/dashboard.jade.mod.js
lib/template/data/data.jade.mod.js
lib/template/data/dataset-metric.jade.mod.js
lib/template/data/dataset.jade.mod.js
lib/template/data/datasource-ui.jade.js
lib/template/data/datasource-ui.jade.mod.js
lib/template/data/datasource.jade.mod.js
lib/template/data/metric-edit.jade.mod.js
lib/template/graph/graph-display.jade.mod.js
lib/template/graph/graph-edit.jade.js
lib/template/graph/graph-edit.jade.mod.js
lib/template/graph/graph-list.jade.js
lib/template/graph/graph-list.jade.mod.js
lib/util/aliasdict.js
lib/util/backbone.mod.js
lib/util/cascade.js
lib/util/cascade.mod.js
lib/util/event/index.js
lib/util/event/index.mod.js
lib/util/event/ready-emitter.js
lib/util/event/ready-emitter.mod.js
lib/util/event/waiting-emitter.js
lib/util/event/waiting-emitter.mod.js
lib/util/formatters.js
lib/util/formatters.mod.js
lib/util/index.js
lib/util/index.mod.js
lib/util/op.mod.js
lib/util/parser.js
lib/util/parser.mod.js
lib/util/timeseries/csv.js
lib/util/timeseries/csv.mod.js
lib/util/timeseries/index.js
lib/util/timeseries/index.mod.js
lib/util/timeseries/timeseries.js
lib/util/timeseries/timeseries.mod.js
lib/util/underscore/array.mod.js
lib/util/underscore/class.mod.js
lib/util/underscore/function.mod.js
lib/util/underscore/index.js
lib/util/underscore/index.mod.js
lib/util/underscore/kv.mod.js
lib/util/underscore/object.mod.js
lib/util/underscore/string.mod.js
src/version.js [new file with mode: 0644]
static/vendor/browserify.js
static/vendor/underscore.mod.js [new file with mode: 0644]
www/css/graph.css
www/js/limn.js [new symlink]
www/js/limn.min.js [new symlink]
www/modules.yaml

index 949701e..876cf99 100644 (file)
--- a/Cokefile
+++ b/Cokefile
@@ -4,8 +4,14 @@ require 'buildtools/tasks'
 {removeSync:remove} = require 'remove'
 
 
-MODULE_LINK = 'node_modules/limn'
+MODULE_LINK            = 'node_modules/limn'
 
+APP_BUNDLE_PATH        = 'var/js/limn.no-deps.js'
+APP_BUNDLE_MIN_PATH    = APP_BUNDLE_PATH.replace /\.js$/, '.min.js'
+VENDOR_BUNDLE_PATH     = 'var/vendor/vendor-bundle.js'
+VENDOR_BUNDLE_MIN_PATH = VENDOR_BUNDLE_PATH.replace /\.js$/, '.min.js'
+DIST_PATH              = 'dist/limn.js'
+DIST_MIN_PATH          = DIST_PATH.replace /\.js$/, '.min.js'
 
 
 
@@ -25,7 +31,7 @@ task \install 'Install project dependencies.' ->
 task \setup 'Ensure project is set up for development.' ->
     invoke \install
     invoke \link
-    invoke \update_version
+    err, version <- writeVersionFile 'src/version.js'
 
 
 task \server 'Start dev server' ->
@@ -38,7 +44,7 @@ task \build 'Build coco sources' ->
     invoke \setup
     coco <[ -bjc package.co ]>
     
-    {sources} = require 'limn/server/view-helpers'
+    {sources}  = require 'limn/server/view-helpers'
     browserify = require 'browserify'
     Coco       = require 'coco'
     Jade       = require 'jade'
@@ -47,6 +53,7 @@ task \build 'Build coco sources' ->
     yaml       = require 'js-yaml'
     
     matchExt = /((?:\.min)?)\.mod((?:\.min)?)\.js$/i
+    fullExt  = /(\.(min|mod|amd|jade))*\.js$/i
     
     console.log 'Building source...'
     Seq()
@@ -85,11 +92,13 @@ task \build 'Build coco sources' ->
         .set sources("www/modules.yaml", 'development').map -> it.slice 1
         .seqEach (srcfile) ->
             return @ok() unless matchExt.test srcfile
-            outfile = (if _.startsWith srcfile, 'vendor' then 'static' else 'www') + '/' + srcfile
+            outfile = (if _.startsWith srcfile, 'vendor' then 'static' else 'lib') + '/' + srcfile.replace /^js\/limn\//, ''
             infile = outfile.replace matchExt, '$1$2.js'
-            return @ok() unless exists infile
+            unless exists infile
+                console.log "  Wrapping JS in Module:\t Cannot find #infile!"
+                return @ok() 
             return @ok() if _.startsWith(srcfile, 'vendor') and exists outfile
-            parts = infile.replace matchExt, '' .split '/' .slice 2
+            parts = srcfile.replace fullExt, '' .split '/' .slice 1
             parts.pop() if 'index' is _.last parts
             ID = parts.join '/' 
             console.log "  Wrapping JS in Module:\t #infile \t-->\t #outfile"
@@ -128,37 +137,49 @@ task \build 'Build coco sources' ->
 task \bundle 'Build application and vendor bundles' ->
     invoke \bundle_app
     invoke \bundle_vendor
+    invoke \bundle_combine
 
 task \bundle_app 'Build application bundle' ->
     {sources} = require 'limn/server/view-helpers'
     
-    app_bundle_path = 'var/js/limn/app-bundle.js'
     app_sources = sources("www/modules.yaml", 'development')
         .filter -> not _.startsWith it, '/vendor'
         .map -> it.slice 1 .replace /js\/limn/, 'lib'
-    mkdirp dirname app_bundle_path
-    bundle_js app_bundle_path, app_sources, {-minify}
+    mkdirp dirname APP_BUNDLE_PATH
+    bundle_js APP_BUNDLE_PATH, app_sources, {-minify}
     
-    app_bundle_min_path = app_bundle_path.replace /\.js$/, '.min.js'
-    print 'Minifying into', app_bundle_min_path.magenta.bold, '... '
-    write app_bundle_min_path, minify read app_bundle_path
+    APP_BUNDLE_MIN_PATH = APP_BUNDLE_PATH.replace /\.js$/, '.min.js'
+    print 'Minifying into', APP_BUNDLE_MIN_PATH.magenta.bold, '... '
+    write APP_BUNDLE_MIN_PATH, minify read APP_BUNDLE_PATH
     say 'ok.\n'
 
 task \bundle_vendor 'Build vendor bundle' ->
     {sources} = require 'limn/server/view-helpers'
     
-    vendor_bundle_path = 'var/vendor/vendor-bundle.js'
+    VENDOR_BUNDLE_PATH = 'var/vendor/vendor-bundle.js'
     vendor_sources = sources("www/modules.yaml", 'development')
         .filter -> _.startsWith it, '/vendor'
         .map -> "static#it"
-    mkdirp dirname vendor_bundle_path
-    bundle_js vendor_bundle_path, vendor_sources, {-minify}
+    mkdirp dirname VENDOR_BUNDLE_PATH
+    bundle_js VENDOR_BUNDLE_PATH, vendor_sources, {-minify}
     
-    vendor_bundle_min_path = vendor_bundle_path.replace /\.js$/, '.min.js'
-    print 'Minifying into', vendor_bundle_min_path.magenta.bold, '... '
-    write vendor_bundle_min_path, minify read vendor_bundle_path
+    VENDOR_BUNDLE_MIN_PATH = VENDOR_BUNDLE_PATH.replace /\.js$/, '.min.js'
+    print 'Minifying into', VENDOR_BUNDLE_MIN_PATH.magenta.bold, '... '
+    write VENDOR_BUNDLE_MIN_PATH, minify read VENDOR_BUNDLE_PATH
     say 'ok.\n'
 
+task \bundle_combine 'Combine bundles into dist file' ->
+    print 'Writing dist file', DIST_PATH.magenta.bold , '... '
+    mkdirp dirname DIST_PATH
+    write DIST_PATH, "#{read VENDOR_BUNDLE_PATH}\n#{read APP_BUNDLE_PATH}\n"
+    say 'ok.\n'
+    
+    print 'Writing minified dist file', DIST_MIN_PATH.magenta.bold , '... '
+    mkdirp dirname DIST_MIN_PATH
+    write DIST_MIN_PATH, "#{read VENDOR_BUNDLE_MIN_PATH}\n#{read APP_BUNDLE_MIN_PATH}\n"
+    say 'ok.\n'
+    
+
 
 
 task \test 'Rebuild test files and run tests' ->
@@ -194,7 +215,7 @@ task \cleanup_tests 'Removes compiled tests' ->
 
 task \clean 'Clean up environment and artifacts' ->
     invoke \cleanup_tests
-    remove [MODULE_LINK, 'var', 'tmp/dist'], {+ignoreMissing, +verbose}
+    remove [MODULE_LINK, 'lib', 'var', 'dist'], {+ignoreMissing, +verbose}
 
 
 
@@ -207,8 +228,3 @@ task \source_list 'Print a list of the source file paths.' ->
             .join '\n'
 
 
-# task \dist 'Assemble a distribution package for deploy' ->
-#     invoke \cleanup_tests
-#     ...
-
-
index b4937f3..4b2153d 100644 (file)
@@ -1,6 +1,6 @@
 var Backbone, op, AppView, _ref, _;
 Backbone = require('backbone');
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
 /**
  * @class Application view, automatically attaching to an existing element
  *  found at `appSelector`.
diff --git a/lib/app.mod.js b/lib/app.mod.js
deleted file mode 100644 (file)
index e816fc5..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-require.define('/node_modules/kraken/app.js.js', function(require, module, exports, __dirname, __filename, undefined){
-
-var Backbone, op, AppView, _ref, _;
-Backbone = require('backbone');
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-/**
- * @class Application view, automatically attaching to an existing element
- *  found at `appSelector`.
- * @extends Backbone.View
- */
-AppView = exports.AppView = Backbone.View.extend({
-  appSelector: '#content .inner'
-  /**
-   * @constructor
-   */,
-  constructor: (function(){
-    function AppView(options){
-      var that, _this = this;
-      options == null && (options = {});
-      if (typeof options === 'function') {
-        this.initialize = options;
-        options = {};
-      } else {
-        if (that = options.initialize) {
-          this.initialize = that;
-        }
-      }
-      if (that = options.appSelector) {
-        this.appSelector = that;
-      }
-      options.el || (options.el = jQuery(this.appSelector)[0]);
-      Backbone.View.call(this, options);
-      jQuery(function(){
-        return _this.render();
-      });
-      return this;
-    }
-    return AppView;
-  }())
-  /**
-   * Override to set up your app. This method may be passed
-   * as an option to the constructor.
-   */,
-  initialize: function(){}
-  /**
-   * Append subviews.
-   */,
-  render: function(){
-    var _ref;
-    if (this.view && !((_ref = this.view.$el.parent()) != null && _ref.length)) {
-      return this.$el.append(this.view.el);
-    }
-  },
-  getClassName: function(){
-    return (this.constructor.name || this.constructor.displayName) + "";
-  },
-  toString: function(){
-    return this.getClassName() + "()";
-  }
-});
-
-});
index d65ef1e..777e183 100644 (file)
@@ -1,6 +1,6 @@
 var op, ReadyEmitter, AssetManager, _ref, _;
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-ReadyEmitter = require('kraken/util/event').ReadyEmitter;
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+ReadyEmitter = require('limn/util/event').ReadyEmitter;
 AssetManager = (function(superclass){
   AssetManager.displayName = 'AssetManager';
   var prototype = __extend(AssetManager, superclass).prototype, constructor = AssetManager;
index eba7b88..95e44a0 100644 (file)
@@ -1,6 +1,6 @@
 var Backbone, op, BaseBackboneMixin, Mixin, mixinBase, _ref, _, __slice = [].slice;
 Backbone = require('backbone');
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
 BaseBackboneMixin = exports.BaseBackboneMixin = {
   initialize: function(){
     return this.__apply_bind__();
index e2c68e2..c2ad253 100644 (file)
@@ -1,8 +1,8 @@
-require.define('/node_modules/kraken/base/base-mixin.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/base/base-mixin.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var Backbone, op, BaseBackboneMixin, Mixin, mixinBase, _ref, _, __slice = [].slice;
 Backbone = require('backbone');
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
 BaseBackboneMixin = exports.BaseBackboneMixin = {
   initialize: function(){
     return this.__apply_bind__();
index 7a4a6d6..2d83a61 100644 (file)
@@ -1,7 +1,7 @@
 var Backbone, op, BaseBackboneMixin, mixinBase, BaseModel, BaseList, _ref, _, __slice = [].slice;
 Backbone = require('backbone');
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-_ref = require('kraken/base/base-mixin'), BaseBackboneMixin = _ref.BaseBackboneMixin, mixinBase = _ref.mixinBase;
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+_ref = require('limn/base/base-mixin'), BaseBackboneMixin = _ref.BaseBackboneMixin, mixinBase = _ref.mixinBase;
 /**
  * @class Base model, extending Backbone.Model, used by scaffold and others.
  * @extends Backbone.Model
@@ -220,6 +220,34 @@ BaseList = exports.BaseList = Backbone.Collection.extend(mixinBase({
       return it.id || it.get('id') || it.cid;
     });
   },
+  url: function(){
+    var id;
+    id = this.get('id') || this.get('slug');
+    if (id) {
+      return this.urlRoot + "/" + id + ".json";
+    } else {
+      return this.urlRoot + ".json";
+    }
+  },
+  load: function(){
+    return this.loadCollection();
+  },
+  loadCollection: function(){
+    var _this = this;
+    this.wait();
+    this.trigger('load', this);
+    this.fetch({
+      success: function(){
+        _this.unwait();
+        return _this.trigger('load-success', _this);
+      },
+      error: function(){
+        _this.unwait();
+        return _this.trigger.apply(_this, ['load-error', _this].concat(__slice.call(arguments)));
+      }
+    });
+    return this;
+  },
   toKVPairs: function(){
     return _.collapseObject(this.toJSON());
   },
index 1fdd53b..1c2b0c4 100644 (file)
@@ -1,9 +1,9 @@
-require.define('/node_modules/kraken/base/base-model.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/base/base-model.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var Backbone, op, BaseBackboneMixin, mixinBase, BaseModel, BaseList, _ref, _, __slice = [].slice;
 Backbone = require('backbone');
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-_ref = require('kraken/base/base-mixin'), BaseBackboneMixin = _ref.BaseBackboneMixin, mixinBase = _ref.mixinBase;
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+_ref = require('limn/base/base-mixin'), BaseBackboneMixin = _ref.BaseBackboneMixin, mixinBase = _ref.mixinBase;
 /**
  * @class Base model, extending Backbone.Model, used by scaffold and others.
  * @extends Backbone.Model
@@ -222,6 +222,34 @@ BaseList = exports.BaseList = Backbone.Collection.extend(mixinBase({
       return it.id || it.get('id') || it.cid;
     });
   },
+  url: function(){
+    var id;
+    id = this.get('id') || this.get('slug');
+    if (id) {
+      return this.urlRoot + "/" + id + ".json";
+    } else {
+      return this.urlRoot + ".json";
+    }
+  },
+  load: function(){
+    return this.loadCollection();
+  },
+  loadCollection: function(){
+    var _this = this;
+    this.wait();
+    this.trigger('load', this);
+    this.fetch({
+      success: function(){
+        _this.unwait();
+        return _this.trigger('load-success', _this);
+      },
+      error: function(){
+        _this.unwait();
+        return _this.trigger.apply(_this, ['load-error', _this].concat(__slice.call(arguments)));
+      }
+    });
+    return this;
+  },
   toKVPairs: function(){
     return _.collapseObject(this.toJSON());
   },
index 9dec625..aac1098 100644 (file)
@@ -1,9 +1,9 @@
 var Backbone, op, BaseBackboneMixin, mixinBase, BaseModel, DataBinding, BaseView, ViewList, _ref, _, __slice = [].slice;
 Backbone = require('backbone');
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-_ref = require('kraken/base/base-mixin'), BaseBackboneMixin = _ref.BaseBackboneMixin, mixinBase = _ref.mixinBase;
-BaseModel = require('kraken/base/base-mixin').BaseModel;
-DataBinding = require('kraken/base/data-binding').DataBinding;
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+_ref = require('limn/base/base-mixin'), BaseBackboneMixin = _ref.BaseBackboneMixin, mixinBase = _ref.mixinBase;
+BaseModel = require('limn/base/base-mixin').BaseModel;
+DataBinding = require('limn/base/data-binding').DataBinding;
 /**
  * @class Base view, extending Backbone.View, used by scaffold and others.
  * @extends Backbone.View
index 2105eea..7b3e07f 100644 (file)
@@ -1,11 +1,11 @@
-require.define('/node_modules/kraken/base/base-view.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/base/base-view.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var Backbone, op, BaseBackboneMixin, mixinBase, BaseModel, DataBinding, BaseView, ViewList, _ref, _, __slice = [].slice;
 Backbone = require('backbone');
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-_ref = require('kraken/base/base-mixin'), BaseBackboneMixin = _ref.BaseBackboneMixin, mixinBase = _ref.mixinBase;
-BaseModel = require('kraken/base/base-mixin').BaseModel;
-DataBinding = require('kraken/base/data-binding').DataBinding;
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+_ref = require('limn/base/base-mixin'), BaseBackboneMixin = _ref.BaseBackboneMixin, mixinBase = _ref.mixinBase;
+BaseModel = require('limn/base/base-mixin').BaseModel;
+DataBinding = require('limn/base/data-binding').DataBinding;
 /**
  * @class Base view, extending Backbone.View, used by scaffold and others.
  * @extends Backbone.View
index e3f4bce..a053582 100644 (file)
@@ -2,7 +2,7 @@ var EventEmitter, op, Base, k, _ref, _, _i, _len, __slice = [].slice;
 EventEmitter = require('events').EventEmitter;
 EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
 EventEmitter.prototype.trigger = EventEmitter.prototype.emit;
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
 /**
  * @class Eventful base class.
  * @extends EventEmitter
index 68ac0c5..1be5b75 100644 (file)
@@ -1,10 +1,10 @@
-require.define('/node_modules/kraken/base/base.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/base/base.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var EventEmitter, op, Base, k, _ref, _, _i, _len, __slice = [].slice;
 EventEmitter = require('events').EventEmitter;
 EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
 EventEmitter.prototype.trigger = EventEmitter.prototype.emit;
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
 /**
  * @class Eventful base class.
  * @extends EventEmitter
index 8a1f89c..3fd3f9d 100644 (file)
@@ -1,7 +1,7 @@
 var op, BaseModel, BaseList, Cascade, CascadingModel, _ref, _;
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-_ref = require('kraken/base/base-model'), BaseModel = _ref.BaseModel, BaseList = _ref.BaseList;
-Cascade = require('kraken/util/cascade');
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+_ref = require('limn/base/base-model'), BaseModel = _ref.BaseModel, BaseList = _ref.BaseList;
+Cascade = require('limn/util/cascade');
 /**
  * @class A model that implements cascading lookups for its attributes.
  */
index 5fc62d5..5a19a6d 100644 (file)
@@ -1,9 +1,9 @@
-require.define('/node_modules/kraken/base/cascading-model.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/base/cascading-model.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var op, BaseModel, BaseList, Cascade, CascadingModel, _ref, _;
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-_ref = require('kraken/base/base-model'), BaseModel = _ref.BaseModel, BaseList = _ref.BaseList;
-Cascade = require('kraken/util/cascade');
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+_ref = require('limn/base/base-model'), BaseModel = _ref.BaseModel, BaseList = _ref.BaseList;
+Cascade = require('limn/util/cascade');
 /**
  * @class A model that implements cascading lookups for its attributes.
  */
index 9f1835c..8ddc4a3 100644 (file)
@@ -1,6 +1,6 @@
 var Backbone, op, DataBinding, _ref, _;
 Backbone = require('backbone');
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
 exports.DataBinding = DataBinding = (function(){
   DataBinding.displayName = 'DataBinding';
   var prototype = DataBinding.prototype, constructor = DataBinding;
index 957bc2c..f6c0475 100644 (file)
@@ -1,8 +1,8 @@
-require.define('/node_modules/kraken/base/data-binding.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/base/data-binding.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var Backbone, op, DataBinding, _ref, _;
 Backbone = require('backbone');
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
 exports.DataBinding = DataBinding = (function(){
   DataBinding.displayName = 'DataBinding';
   var prototype = DataBinding.prototype, constructor = DataBinding;
index 1c9458c..62833c4 100644 (file)
@@ -1,11 +1,11 @@
 var mixins, models, views, cache, cascading, data_binding;
-exports.Base = require('kraken/base/base');
-mixins = require('kraken/base/base-mixin');
-models = require('kraken/base/base-model');
-views = require('kraken/base/base-view');
-cache = require('kraken/base/model-cache');
-cascading = require('kraken/base/cascading-model');
-data_binding = require('kraken/base/data-binding');
+exports.Base = require('limn/base/base');
+mixins = require('limn/base/base-mixin');
+models = require('limn/base/base-model');
+views = require('limn/base/base-view');
+cache = require('limn/base/model-cache');
+cascading = require('limn/base/cascading-model');
+data_binding = require('limn/base/data-binding');
 __import(__import(__import(__import(__import(__import(exports, mixins), models), views), cache), cascading), data_binding);
 function __import(obj, src){
   var own = {}.hasOwnProperty;
index a599753..8e7fb07 100644 (file)
@@ -1,13 +1,13 @@
-require.define('/node_modules/kraken/base/index.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/base.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var mixins, models, views, cache, cascading, data_binding;
-exports.Base = require('kraken/base/base');
-mixins = require('kraken/base/base-mixin');
-models = require('kraken/base/base-model');
-views = require('kraken/base/base-view');
-cache = require('kraken/base/model-cache');
-cascading = require('kraken/base/cascading-model');
-data_binding = require('kraken/base/data-binding');
+exports.Base = require('limn/base/base');
+mixins = require('limn/base/base-mixin');
+models = require('limn/base/base-model');
+views = require('limn/base/base-view');
+cache = require('limn/base/model-cache');
+cascading = require('limn/base/cascading-model');
+data_binding = require('limn/base/data-binding');
 __import(__import(__import(__import(__import(__import(exports, mixins), models), views), cache), cascading), data_binding);
 function __import(obj, src){
   var own = {}.hasOwnProperty;
index f07c776..e951ad1 100644 (file)
@@ -1,7 +1,7 @@
 var Seq, ReadyEmitter, ModelCache, _;
 _ = require('underscore');
 Seq = require('seq');
-ReadyEmitter = require('kraken/util/event').ReadyEmitter;
+ReadyEmitter = require('limn/util/event').ReadyEmitter;
 /**
  * @class Caches models and provides static lookups by ID.
  */
index 4e529f9..32dae37 100644 (file)
@@ -1,9 +1,9 @@
-require.define('/node_modules/kraken/base/model-cache.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/base/model-cache.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var Seq, ReadyEmitter, ModelCache, _;
 _ = require('underscore');
 Seq = require('seq');
-ReadyEmitter = require('kraken/util/event').ReadyEmitter;
+ReadyEmitter = require('limn/util/event').ReadyEmitter;
 /**
  * @class Caches models and provides static lookups by ID.
  */
diff --git a/lib/base/resource-router.js b/lib/base/resource-router.js
new file mode 100644 (file)
index 0000000..fd3aa97
--- /dev/null
@@ -0,0 +1,49 @@
+var Backbone, op, BaseBackboneMixin, mixinBase, ResourceRouter, _ref, _;
+Backbone = require('backbone');
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+_ref = require('limn/base/base-mixin'), BaseBackboneMixin = _ref.BaseBackboneMixin, mixinBase = _ref.mixinBase;
+ResourceRouter = exports.ResourceRouter = Backbone.Router.extend(mixinBase({
+  __bind__: []
+  /**
+   * Singular, lowercase resource-noun.
+   * @optional
+   * @type String
+   * @example "user"
+   */,
+  id: null
+  /**
+   * Plural, lowercase resource-noun.
+   * @required
+   * @type String
+   * @example "users"
+   */,
+  name: null,
+  constructor: (function(){
+    function ResourceRouter(opts){
+      opts == null && (opts = {});
+      this.__class__ = this.constructor;
+      this.__superclass__ = this.constructor.__super__.constructor;
+      this.waitingOn = 0;
+      opts.routes || (opts.routes = this.makeRoutes());
+      return Backbone.Router.apply(this, opts);
+    }
+    return ResourceRouter;
+  }()),
+  makeRoutes: function(){
+    var name, id, routes;
+    name = this.name, id = this.id;
+    routes = {};
+    if (typeof this.create === 'function') {
+      routes[name + "/(new|edit)"] = this.create;
+    }
+    if (typeof this.edit === 'function') {
+      routes[name + "/:" + id + "/edit"] = this.edit;
+    }
+    if (typeof this.show === 'function') {
+      routes[name + "/:" + id] = this.show;
+    }
+    if (typeof this.index === 'function') {
+      return routes[name + ""] = this.index;
+    }
+  }
+}));
\ No newline at end of file
index c0ee89d..fecf1b8 100644 (file)
@@ -1,6 +1,6 @@
 var models, views;
-models = require('kraken/base/scaffold/scaffold-model');
-views = require('kraken/base/scaffold/scaffold-view');
+models = require('limn/base/scaffold/scaffold-model');
+views = require('limn/base/scaffold/scaffold-view');
 __import(__import(exports, models), views);
 function __import(obj, src){
   var own = {}.hasOwnProperty;
index 2278e76..9ec5c5e 100644 (file)
@@ -1,8 +1,8 @@
-require.define('/node_modules/kraken/base/scaffold/index.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/base/scaffold.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var models, views;
-models = require('kraken/base/scaffold/scaffold-model');
-views = require('kraken/base/scaffold/scaffold-view');
+models = require('limn/base/scaffold/scaffold-model');
+views = require('limn/base/scaffold/scaffold-view');
 __import(__import(exports, models), views);
 function __import(obj, src){
   var own = {}.hasOwnProperty;
index 948a703..311b975 100644 (file)
@@ -1,7 +1,7 @@
 var op, BaseModel, BaseList, Field, FieldList, _, _ref, __slice = [].slice;
-_ = require('kraken/util/underscore');
-op = require('kraken/util/op');
-_ref = require('kraken/base'), BaseModel = _ref.BaseModel, BaseList = _ref.BaseList;
+_ = require('limn/util/underscore');
+op = require('limn/util/op');
+_ref = require('limn/base'), BaseModel = _ref.BaseModel, BaseList = _ref.BaseList;
 Field = exports.Field = BaseModel.extend({
   valueAttribute: 'value',
   defaults: function(){
index ee06f50..a0b4836 100644 (file)
@@ -1,9 +1,9 @@
-require.define('/node_modules/kraken/base/scaffold/scaffold-model.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/base/scaffold/scaffold-model.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var op, BaseModel, BaseList, Field, FieldList, _, _ref, __slice = [].slice;
-_ = require('kraken/util/underscore');
-op = require('kraken/util/op');
-_ref = require('kraken/base'), BaseModel = _ref.BaseModel, BaseList = _ref.BaseList;
+_ = require('limn/util/underscore');
+op = require('limn/util/op');
+_ref = require('limn/base'), BaseModel = _ref.BaseModel, BaseList = _ref.BaseList;
 Field = exports.Field = BaseModel.extend({
   valueAttribute: 'value',
   defaults: function(){
index 2bc3791..ee47968 100644 (file)
@@ -1,8 +1,8 @@
 var op, BaseView, Field, FieldList, FieldView, Scaffold, _, _ref;
-_ = require('kraken/util/underscore');
-op = require('kraken/util/op');
-BaseView = require('kraken/base').BaseView;
-_ref = require('kraken/base/scaffold/scaffold-model'), Field = _ref.Field, FieldList = _ref.FieldList;
+_ = require('limn/util/underscore');
+op = require('limn/util/op');
+BaseView = require('limn/base').BaseView;
+_ref = require('limn/base/scaffold/scaffold-model'), Field = _ref.Field, FieldList = _ref.FieldList;
 FieldView = exports.FieldView = BaseView.extend({
   tagName: 'div',
   className: 'field',
index f71a8da..070156e 100644 (file)
@@ -1,10 +1,10 @@
-require.define('/node_modules/kraken/base/scaffold/scaffold-view.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/base/scaffold/scaffold-view.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var op, BaseView, Field, FieldList, FieldView, Scaffold, _, _ref;
-_ = require('kraken/util/underscore');
-op = require('kraken/util/op');
-BaseView = require('kraken/base').BaseView;
-_ref = require('kraken/base/scaffold/scaffold-model'), Field = _ref.Field, FieldList = _ref.FieldList;
+_ = require('limn/util/underscore');
+op = require('limn/util/op');
+BaseView = require('limn/base').BaseView;
+_ref = require('limn/base/scaffold/scaffold-model'), Field = _ref.Field, FieldList = _ref.FieldList;
 FieldView = exports.FieldView = BaseView.extend({
   tagName: 'div',
   className: 'field',
index 037682a..b6e1e0b 100644 (file)
@@ -1,9 +1,9 @@
 var moment, Backbone, op, ReadyEmitter, Parsers, ParserMixin, KNOWN_CHART_TYPES, ChartType, _ref, _, __slice = [].slice;
 moment = require('moment');
 Backbone = require('backbone');
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-ReadyEmitter = require('kraken/util/event').ReadyEmitter;
-_ref = require('kraken/util/parser'), Parsers = _ref.Parsers, ParserMixin = _ref.ParserMixin;
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+ReadyEmitter = require('limn/util/event').ReadyEmitter;
+_ref = require('limn/util/parser'), Parsers = _ref.Parsers, ParserMixin = _ref.ParserMixin;
 /**
  * Map of known libraries by name.
  * @type Object
index 40aaea3..8fa3fc0 100644 (file)
@@ -1,11 +1,11 @@
-require.define('/node_modules/kraken/chart/chart-type.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/chart/chart-type.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var moment, Backbone, op, ReadyEmitter, Parsers, ParserMixin, KNOWN_CHART_TYPES, ChartType, _ref, _, __slice = [].slice;
 moment = require('moment');
 Backbone = require('backbone');
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-ReadyEmitter = require('kraken/util/event').ReadyEmitter;
-_ref = require('kraken/util/parser'), Parsers = _ref.Parsers, ParserMixin = _ref.ParserMixin;
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+ReadyEmitter = require('limn/util/event').ReadyEmitter;
+_ref = require('limn/util/parser'), Parsers = _ref.Parsers, ParserMixin = _ref.ParserMixin;
 /**
  * Map of known libraries by name.
  * @type Object
index 21c43f1..21f339f 100644 (file)
@@ -1,9 +1,9 @@
 var chart_type, chart_option, dygraphs, d3_chart, d3_elements;
-chart_type = require('kraken/chart/chart-type');
-chart_option = require('kraken/chart/option');
-dygraphs = require('kraken/chart/type/dygraphs');
-d3_chart = require('kraken/chart/type/d3-chart');
-d3_elements = require('kraken/chart/type/d3');
+chart_type = require('limn/chart/chart-type');
+chart_option = require('limn/chart/option');
+dygraphs = require('limn/chart/type/dygraphs');
+d3_chart = require('limn/chart/type/d3-chart');
+d3_elements = require('limn/chart/type/d3');
 __import(__import(__import(__import(__import(exports, chart_type), chart_option), dygraphs), d3_chart), d3_elements);
 function __import(obj, src){
   var own = {}.hasOwnProperty;
index 7734fba..49ce799 100644 (file)
@@ -1,11 +1,11 @@
-require.define('/node_modules/kraken/chart/index.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/chart.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var chart_type, chart_option, dygraphs, d3_chart, d3_elements;
-chart_type = require('kraken/chart/chart-type');
-chart_option = require('kraken/chart/option');
-dygraphs = require('kraken/chart/type/dygraphs');
-d3_chart = require('kraken/chart/type/d3-chart');
-d3_elements = require('kraken/chart/type/d3');
+chart_type = require('limn/chart/chart-type');
+chart_option = require('limn/chart/option');
+dygraphs = require('limn/chart/type/dygraphs');
+d3_chart = require('limn/chart/type/d3-chart');
+d3_elements = require('limn/chart/type/d3');
 __import(__import(__import(__import(__import(exports, chart_type), chart_option), dygraphs), d3_chart), d3_elements);
 function __import(obj, src){
   var own = {}.hasOwnProperty;
index 4b7382f..91f0180 100644 (file)
@@ -1,7 +1,7 @@
 var op, Parsers, ParserMixin, ParsingModel, ParsingView, BaseModel, BaseList, TagSet, KNOWN_TAGS, ChartOption, ChartOptionList, _ref, _, __slice = [].slice;
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-_ref = require('kraken/util/parser'), Parsers = _ref.Parsers, ParserMixin = _ref.ParserMixin, ParsingModel = _ref.ParsingModel, ParsingView = _ref.ParsingView;
-_ref = require('kraken/base'), BaseModel = _ref.BaseModel, BaseList = _ref.BaseList;
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+_ref = require('limn/util/parser'), Parsers = _ref.Parsers, ParserMixin = _ref.ParserMixin, ParsingModel = _ref.ParsingModel, ParsingView = _ref.ParsingView;
+_ref = require('limn/base'), BaseModel = _ref.BaseModel, BaseList = _ref.BaseList;
 /**
  * @class A set of tags.
  */
index 50446ba..97dde6c 100644 (file)
@@ -1,9 +1,9 @@
-require.define('/node_modules/kraken/chart/option/chart-option-model.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/chart/option/chart-option-model.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var op, Parsers, ParserMixin, ParsingModel, ParsingView, BaseModel, BaseList, TagSet, KNOWN_TAGS, ChartOption, ChartOptionList, _ref, _, __slice = [].slice;
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-_ref = require('kraken/util/parser'), Parsers = _ref.Parsers, ParserMixin = _ref.ParserMixin, ParsingModel = _ref.ParsingModel, ParsingView = _ref.ParsingView;
-_ref = require('kraken/base'), BaseModel = _ref.BaseModel, BaseList = _ref.BaseList;
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+_ref = require('limn/util/parser'), Parsers = _ref.Parsers, ParserMixin = _ref.ParserMixin, ParsingModel = _ref.ParsingModel, ParsingView = _ref.ParsingView;
+_ref = require('limn/base'), BaseModel = _ref.BaseModel, BaseList = _ref.BaseList;
 /**
  * @class A set of tags.
  */
index 99a9a41..549be0f 100644 (file)
@@ -1,7 +1,7 @@
 var op, BaseView, ChartOption, ChartOptionList, DEBOUNCE_RENDER, ChartOptionView, ChartOptionScaffold, _ref, _;
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-BaseView = require('kraken/base').BaseView;
-_ref = require('kraken/chart/option/chart-option-model'), ChartOption = _ref.ChartOption, ChartOptionList = _ref.ChartOptionList;
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+BaseView = require('limn/base').BaseView;
+_ref = require('limn/chart/option/chart-option-model'), ChartOption = _ref.ChartOption, ChartOptionList = _ref.ChartOptionList;
 DEBOUNCE_RENDER = exports.DEBOUNCE_RENDER = 100;
 /**
  * @class View for a single configurable option in a chart type.
@@ -9,7 +9,7 @@ DEBOUNCE_RENDER = exports.DEBOUNCE_RENDER = 100;
 ChartOptionView = exports.ChartOptionView = BaseView.extend({
   tagName: 'section',
   className: 'chart-option field',
-  template: require('kraken/template/chart/chart-option'),
+  template: require('limn/template/chart/chart-option'),
   type: 'string',
   isCollapsed: true,
   events: {
@@ -128,7 +128,7 @@ ChartOptionScaffold = exports.ChartOptionScaffold = BaseView.extend({
   __bind__: ['addField'],
   tagName: 'form',
   className: 'chart-options scaffold',
-  template: require('kraken/template/chart/chart-scaffold'),
+  template: require('limn/template/chart/chart-scaffold'),
   collectionType: ChartOptionList,
   subviewType: ChartOptionView,
   events: {
index 8bf441a..a8f8a19 100644 (file)
@@ -1,9 +1,9 @@
-require.define('/node_modules/kraken/chart/option/chart-option-view.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/chart/option/chart-option-view.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var op, BaseView, ChartOption, ChartOptionList, DEBOUNCE_RENDER, ChartOptionView, ChartOptionScaffold, _ref, _;
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-BaseView = require('kraken/base').BaseView;
-_ref = require('kraken/chart/option/chart-option-model'), ChartOption = _ref.ChartOption, ChartOptionList = _ref.ChartOptionList;
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+BaseView = require('limn/base').BaseView;
+_ref = require('limn/chart/option/chart-option-model'), ChartOption = _ref.ChartOption, ChartOptionList = _ref.ChartOptionList;
 DEBOUNCE_RENDER = exports.DEBOUNCE_RENDER = 100;
 /**
  * @class View for a single configurable option in a chart type.
@@ -11,7 +11,7 @@ DEBOUNCE_RENDER = exports.DEBOUNCE_RENDER = 100;
 ChartOptionView = exports.ChartOptionView = BaseView.extend({
   tagName: 'section',
   className: 'chart-option field',
-  template: require('kraken/template/chart/chart-option'),
+  template: require('limn/template/chart/chart-option'),
   type: 'string',
   isCollapsed: true,
   events: {
@@ -130,7 +130,7 @@ ChartOptionScaffold = exports.ChartOptionScaffold = BaseView.extend({
   __bind__: ['addField'],
   tagName: 'form',
   className: 'chart-options scaffold',
-  template: require('kraken/template/chart/chart-scaffold'),
+  template: require('limn/template/chart/chart-scaffold'),
   collectionType: ChartOptionList,
   subviewType: ChartOptionView,
   events: {
index 09d95b7..b05b991 100644 (file)
@@ -1,6 +1,6 @@
 var model, view;
-model = require('kraken/chart/option/chart-option-model');
-view = require('kraken/chart/option/chart-option-view');
+model = require('limn/chart/option/chart-option-model');
+view = require('limn/chart/option/chart-option-view');
 __import(__import(exports, model), view);
 function __import(obj, src){
   var own = {}.hasOwnProperty;
index 15c866d..aa94c03 100644 (file)
@@ -1,8 +1,8 @@
-require.define('/node_modules/kraken/chart/option/index.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/chart/option.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var model, view;
-model = require('kraken/chart/option/chart-option-model');
-view = require('kraken/chart/option/chart-option-view');
+model = require('limn/chart/option/chart-option-model');
+view = require('limn/chart/option/chart-option-view');
 __import(__import(exports, model), view);
 function __import(obj, src){
   var own = {}.hasOwnProperty;
index adce99c..244a437 100644 (file)
@@ -1,9 +1,9 @@
 var d3, ColorBrewer, op, ChartType, D3ChartElement, root, D3ChartType, _ref, _;
 d3 = require('d3');
 ColorBrewer = require('colorbrewer');
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-ChartType = require('kraken/chart/chart-type').ChartType;
-D3ChartElement = require('kraken/chart/type/d3/d3-chart-element').D3ChartElement;
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+ChartType = require('limn/chart/chart-type').ChartType;
+D3ChartElement = require('limn/chart/type/d3/d3-chart-element').D3ChartElement;
 root = function(){
   return this;
 }();
index f6817e0..324a2ce 100644 (file)
@@ -1,11 +1,11 @@
-require.define('/node_modules/kraken/chart/type/d3-chart.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/chart/type/d3-chart.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var d3, ColorBrewer, op, ChartType, D3ChartElement, root, D3ChartType, _ref, _;
 d3 = require('d3');
 ColorBrewer = require('colorbrewer');
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-ChartType = require('kraken/chart/chart-type').ChartType;
-D3ChartElement = require('kraken/chart/type/d3/d3-chart-element').D3ChartElement;
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+ChartType = require('limn/chart/chart-type').ChartType;
+D3ChartElement = require('limn/chart/type/d3/d3-chart-element').D3ChartElement;
 root = function(){
   return this;
 }();
index fa0746a..d9986f2 100644 (file)
@@ -1,7 +1,7 @@
 var d3, op, ChartType, root, BarChartType, _ref, _;
 d3 = require('d3');
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-ChartType = require('kraken/chart/chart-type').ChartType;
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+ChartType = require('limn/chart/chart-type').ChartType;
 root = function(){
   return this;
 }();
index b1248b2..357f44d 100644 (file)
@@ -1,8 +1,8 @@
 var d3, op, D3ChartElement, root, BarChartType, _ref, _, _fmt;
 d3 = require('d3');
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-D3ChartElement = require('kraken/chart/type/d3/d3-chart-element').D3ChartElement;
-_fmt = require('kraken/util/formatters');
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+D3ChartElement = require('limn/chart/type/d3/d3-chart-element').D3ChartElement;
+_fmt = require('limn/util/formatters');
 root = function(){
   return this;
 }();
index cd8d26a..5316769 100644 (file)
@@ -1,10 +1,10 @@
-require.define('/node_modules/kraken/chart/type/d3/d3-bar-element.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/chart/type/d3/d3-bar-element.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var d3, op, D3ChartElement, root, BarChartType, _ref, _, _fmt;
 d3 = require('d3');
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-D3ChartElement = require('kraken/chart/type/d3/d3-chart-element').D3ChartElement;
-_fmt = require('kraken/util/formatters');
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+D3ChartElement = require('limn/chart/type/d3/d3-chart-element').D3ChartElement;
+_fmt = require('limn/util/formatters');
 root = function(){
   return this;
 }();
index d61b091..3eaac59 100644 (file)
@@ -1,8 +1,8 @@
 var d3, ColorBrewer, op, ReadyEmitter, root, KNOWN_CHART_ELEMENTS, D3ChartElement, _ref, _, __slice = [].slice;
 d3 = require('d3');
 ColorBrewer = require('colorbrewer');
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-ReadyEmitter = require('kraken/util/event').ReadyEmitter;
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+ReadyEmitter = require('limn/util/event').ReadyEmitter;
 root = function(){
   return this;
 }();
index 4a9e29e..bf57c82 100644 (file)
@@ -1,10 +1,10 @@
-require.define('/node_modules/kraken/chart/type/d3/d3-chart-element.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/chart/type/d3/d3-chart-element.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var d3, ColorBrewer, op, ReadyEmitter, root, KNOWN_CHART_ELEMENTS, D3ChartElement, _ref, _, __slice = [].slice;
 d3 = require('d3');
 ColorBrewer = require('colorbrewer');
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-ReadyEmitter = require('kraken/util/event').ReadyEmitter;
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+ReadyEmitter = require('limn/util/event').ReadyEmitter;
 root = function(){
   return this;
 }();
index 64ddb6c..4540cea 100644 (file)
@@ -1,7 +1,7 @@
 var ColorBrewer, op, ChartType, GeoWorldChartType, data, main, _ref, _;
 ColorBrewer = require('colorbrewer');
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-ChartType = require('kraken/chart/chart-type').ChartType;
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+ChartType = require('limn/chart/chart-type').ChartType;
 exports.GeoWorldChartType = GeoWorldChartType = (function(superclass){
   GeoWorldChartType.displayName = 'GeoWorldChartType';
   var prototype = __extend(GeoWorldChartType, superclass).prototype, constructor = GeoWorldChartType;
index c6c5867..f456f80 100644 (file)
@@ -1,9 +1,9 @@
 var d3, ColorBrewer, op, D3ChartElement, root, LineChartElement, _ref, _, _fmt;
 d3 = require('d3');
 ColorBrewer = require('colorbrewer');
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-D3ChartElement = require('kraken/chart/type/d3/d3-chart-element').D3ChartElement;
-_fmt = require('kraken/util/formatters');
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+D3ChartElement = require('limn/chart/type/d3/d3-chart-element').D3ChartElement;
+_fmt = require('limn/util/formatters');
 root = function(){
   return this;
 }();
index c0458f7..b922b97 100644 (file)
@@ -1,11 +1,11 @@
-require.define('/node_modules/kraken/chart/type/d3/d3-line-element.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/chart/type/d3/d3-line-element.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var d3, ColorBrewer, op, D3ChartElement, root, LineChartElement, _ref, _, _fmt;
 d3 = require('d3');
 ColorBrewer = require('colorbrewer');
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-D3ChartElement = require('kraken/chart/type/d3/d3-chart-element').D3ChartElement;
-_fmt = require('kraken/util/formatters');
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+D3ChartElement = require('limn/chart/type/d3/d3-chart-element').D3ChartElement;
+_fmt = require('limn/util/formatters');
 root = function(){
   return this;
 }();
index c1193b7..76a5a17 100644 (file)
@@ -1,7 +1,7 @@
 var d3chart, line, bar;
-d3chart = require('kraken/chart/type/d3/d3-chart-element');
-line = require('kraken/chart/type/d3/d3-line-element');
-bar = require('kraken/chart/type/d3/d3-bar-element');
+d3chart = require('limn/chart/type/d3/d3-chart-element');
+line = require('limn/chart/type/d3/d3-line-element');
+bar = require('limn/chart/type/d3/d3-bar-element');
 __import(__import(__import(exports, line), bar), d3chart);
 function __import(obj, src){
   var own = {}.hasOwnProperty;
index 9c2a284..7791108 100644 (file)
@@ -1,9 +1,9 @@
-require.define('/node_modules/kraken/chart/type/d3/index.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/chart/type/d3.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var d3chart, line, bar;
-d3chart = require('kraken/chart/type/d3/d3-chart-element');
-line = require('kraken/chart/type/d3/d3-line-element');
-bar = require('kraken/chart/type/d3/d3-bar-element');
+d3chart = require('limn/chart/type/d3/d3-chart-element');
+line = require('limn/chart/type/d3/d3-line-element');
+bar = require('limn/chart/type/d3/d3-bar-element');
 __import(__import(__import(exports, line), bar), d3chart);
 function __import(obj, src){
   var own = {}.hasOwnProperty;
index 59865da..681c599 100644 (file)
@@ -1,6 +1,6 @@
 var ChartType, DygraphsChartType, _;
-_ = require('kraken/util/underscore');
-ChartType = require('kraken/chart/chart-type').ChartType;
+_ = require('limn/util/underscore');
+ChartType = require('limn/chart/chart-type').ChartType;
 exports.DygraphsChartType = DygraphsChartType = (function(superclass){
   DygraphsChartType.displayName = 'DygraphsChartType';
   var prototype = __extend(DygraphsChartType, superclass).prototype, constructor = DygraphsChartType;
index 68e7d1f..70b7821 100644 (file)
@@ -1,8 +1,8 @@
-require.define('/node_modules/kraken/chart/type/dygraphs.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/chart/type/dygraphs.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var ChartType, DygraphsChartType, _;
-_ = require('kraken/util/underscore');
-ChartType = require('kraken/chart/chart-type').ChartType;
+_ = require('limn/util/underscore');
+ChartType = require('limn/chart/chart-type').ChartType;
 exports.DygraphsChartType = DygraphsChartType = (function(superclass){
   DygraphsChartType.displayName = 'DygraphsChartType';
   var prototype = __extend(DygraphsChartType, superclass).prototype, constructor = DygraphsChartType;
index c1940bf..ac2813f 100644 (file)
@@ -1,4 +1,4 @@
-require.define('/node_modules/kraken/chart/type/index.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/chart/type.js', function(require, module, exports, __dirname, __filename, undefined){
 
 
 
index 8e26e25..5307c4c 100644 (file)
@@ -1,7 +1,8 @@
-var op, BaseModel, Graph, GraphList, Dashboard, _ref, _;
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-BaseModel = require('kraken/base').BaseModel;
-_ref = require('kraken/graph/graph-model'), Graph = _ref.Graph, GraphList = _ref.GraphList;
+var Seq, op, BaseModel, Graph, GraphList, Dashboard, _ref, _;
+Seq = require('seq');
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+BaseModel = require('limn/base').BaseModel;
+_ref = require('limn/graph/graph-model'), Graph = _ref.Graph, GraphList = _ref.GraphList;
 /**
  * @class
  */
index 7e61eb7..ba65ca3 100644 (file)
@@ -1,9 +1,10 @@
-require.define('/node_modules/kraken/dashboard/dashboard-model.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/dashboard/dashboard-model.js', function(require, module, exports, __dirname, __filename, undefined){
 
-var op, BaseModel, Graph, GraphList, Dashboard, _ref, _;
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-BaseModel = require('kraken/base').BaseModel;
-_ref = require('kraken/graph/graph-model'), Graph = _ref.Graph, GraphList = _ref.GraphList;
+var Seq, op, BaseModel, Graph, GraphList, Dashboard, _ref, _;
+Seq = require('seq');
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+BaseModel = require('limn/base').BaseModel;
+_ref = require('limn/graph/graph-model'), Graph = _ref.Graph, GraphList = _ref.GraphList;
 /**
  * @class
  */
index 37b4d79..7f572b9 100644 (file)
@@ -1,9 +1,9 @@
 var Seq, op, BaseModel, BaseView, Graph, GraphList, GraphDisplayView, Dashboard, DashboardView, DashboardTabView, _ref, _;
 Seq = require('seq');
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-_ref = require('kraken/base'), BaseModel = _ref.BaseModel, BaseView = _ref.BaseView;
-_ref = require('kraken/graph'), Graph = _ref.Graph, GraphList = _ref.GraphList, GraphDisplayView = _ref.GraphDisplayView;
-Dashboard = require('kraken/dashboard/dashboard-model').Dashboard;
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+_ref = require('limn/base'), BaseModel = _ref.BaseModel, BaseView = _ref.BaseView;
+_ref = require('limn/graph'), Graph = _ref.Graph, GraphList = _ref.GraphList, GraphDisplayView = _ref.GraphDisplayView;
+Dashboard = require('limn/dashboard/dashboard-model').Dashboard;
 /**
  * @class
  */
@@ -11,7 +11,7 @@ DashboardView = exports.DashboardView = BaseView.extend({
   __bind__: ['addTab'],
   tagName: 'section',
   className: 'dashboard',
-  template: require('kraken/template/dashboard/dashboard'),
+  template: require('limn/template/dashboard/dashboard'),
   events: {
     'click .graphs.tabbable .nav a': 'onTabClick',
     'shown .graphs.tabbable .nav a': 'render'
@@ -126,7 +126,7 @@ DashboardTabView = exports.DashboardTabView = BaseView.extend({
   __bind__: [],
   className: 'tab-pane',
   tag: 'div',
-  template: require('kraken/template/dashboard/dashboard-tab'),
+  template: require('limn/template/dashboard/dashboard-tab'),
   constructor: (function(){
     function DashboardTabView(){
       return BaseView.apply(this, arguments);
index cc0228a..3aade19 100644 (file)
@@ -1,11 +1,11 @@
-require.define('/node_modules/kraken/dashboard/dashboard-view.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/dashboard/dashboard-view.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var Seq, op, BaseModel, BaseView, Graph, GraphList, GraphDisplayView, Dashboard, DashboardView, DashboardTabView, _ref, _;
 Seq = require('seq');
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-_ref = require('kraken/base'), BaseModel = _ref.BaseModel, BaseView = _ref.BaseView;
-_ref = require('kraken/graph'), Graph = _ref.Graph, GraphList = _ref.GraphList, GraphDisplayView = _ref.GraphDisplayView;
-Dashboard = require('kraken/dashboard/dashboard-model').Dashboard;
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+_ref = require('limn/base'), BaseModel = _ref.BaseModel, BaseView = _ref.BaseView;
+_ref = require('limn/graph'), Graph = _ref.Graph, GraphList = _ref.GraphList, GraphDisplayView = _ref.GraphDisplayView;
+Dashboard = require('limn/dashboard/dashboard-model').Dashboard;
 /**
  * @class
  */
@@ -13,7 +13,7 @@ DashboardView = exports.DashboardView = BaseView.extend({
   __bind__: ['addTab'],
   tagName: 'section',
   className: 'dashboard',
-  template: require('kraken/template/dashboard/dashboard'),
+  template: require('limn/template/dashboard/dashboard'),
   events: {
     'click .graphs.tabbable .nav a': 'onTabClick',
     'shown .graphs.tabbable .nav a': 'render'
@@ -128,7 +128,7 @@ DashboardTabView = exports.DashboardTabView = BaseView.extend({
   __bind__: [],
   className: 'tab-pane',
   tag: 'div',
-  template: require('kraken/template/dashboard/dashboard-tab'),
+  template: require('limn/template/dashboard/dashboard-tab'),
   constructor: (function(){
     function DashboardTabView(){
       return BaseView.apply(this, arguments);
index 078918a..21910cb 100644 (file)
@@ -1,6 +1,6 @@
 var models, views;
-models = require('kraken/dashboard/dashboard-model');
-views = require('kraken/dashboard/dashboard-view');
+models = require('limn/dashboard/dashboard-model');
+views = require('limn/dashboard/dashboard-view');
 __import(__import(exports, models), views);
 function __import(obj, src){
   var own = {}.hasOwnProperty;
index 5471d02..8020112 100644 (file)
@@ -1,8 +1,8 @@
-require.define('/node_modules/kraken/dashboard/index.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/dashboard.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var models, views;
-models = require('kraken/dashboard/dashboard-model');
-views = require('kraken/dashboard/dashboard-view');
+models = require('limn/dashboard/dashboard-model');
+views = require('limn/dashboard/dashboard-view');
 __import(__import(exports, models), views);
 function __import(obj, src){
   var own = {}.hasOwnProperty;
index 08e1688..2d52977 100644 (file)
@@ -1,10 +1,10 @@
 var Seq, op, BaseView, ViewList, DataSetView, MetricEditView, DataSource, DataView, _ref, _;
 Seq = require('seq');
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-_ref = require('kraken/base'), BaseView = _ref.BaseView, ViewList = _ref.ViewList;
-DataSetView = require('kraken/data/dataset-view').DataSetView;
-MetricEditView = require('kraken/data/metric-edit-view').MetricEditView;
-DataSource = require('kraken/data/datasource-model').DataSource;
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+_ref = require('limn/base'), BaseView = _ref.BaseView, ViewList = _ref.ViewList;
+DataSetView = require('limn/data/dataset-view').DataSetView;
+MetricEditView = require('limn/data/metric-edit-view').MetricEditView;
+DataSource = require('limn/data/datasource-model').DataSource;
 /**
  * @class DataSet selection and customization UI (root of the `data` tab).
  */
@@ -12,7 +12,7 @@ DataView = exports.DataView = BaseView.extend({
   __bind__: ['onMetricsChanged'],
   tagName: 'section',
   className: 'data-ui',
-  template: require('kraken/template/data/data'),
+  template: require('limn/template/data/data'),
   datasources: null
   /**
    * @constructor
index 73e06f5..1507b09 100644 (file)
@@ -1,12 +1,12 @@
-require.define('/node_modules/kraken/data/data-view.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/data/data-view.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var Seq, op, BaseView, ViewList, DataSetView, MetricEditView, DataSource, DataView, _ref, _;
 Seq = require('seq');
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-_ref = require('kraken/base'), BaseView = _ref.BaseView, ViewList = _ref.ViewList;
-DataSetView = require('kraken/data/dataset-view').DataSetView;
-MetricEditView = require('kraken/data/metric-edit-view').MetricEditView;
-DataSource = require('kraken/data/datasource-model').DataSource;
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+_ref = require('limn/base'), BaseView = _ref.BaseView, ViewList = _ref.ViewList;
+DataSetView = require('limn/data/dataset-view').DataSetView;
+MetricEditView = require('limn/data/metric-edit-view').MetricEditView;
+DataSource = require('limn/data/datasource-model').DataSource;
 /**
  * @class DataSet selection and customization UI (root of the `data` tab).
  */
@@ -14,7 +14,7 @@ DataView = exports.DataView = BaseView.extend({
   __bind__: ['onMetricsChanged'],
   tagName: 'section',
   className: 'data-ui',
-  template: require('kraken/template/data/data'),
+  template: require('limn/template/data/data'),
   datasources: null
   /**
    * @constructor
index 2f75baa..c9b1045 100644 (file)
@@ -1,10 +1,10 @@
 var Seq, ColorBrewer, op, BaseModel, BaseList, Metric, MetricList, DataSource, DataSourceList, DataSet, _ref, _;
 Seq = require('seq');
 ColorBrewer = require('colorbrewer');
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-_ref = require('kraken/base'), BaseModel = _ref.BaseModel, BaseList = _ref.BaseList;
-_ref = require('kraken/data/metric-model'), Metric = _ref.Metric, MetricList = _ref.MetricList;
-_ref = require('kraken/data/datasource-model'), DataSource = _ref.DataSource, DataSourceList = _ref.DataSourceList;
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+_ref = require('limn/base'), BaseModel = _ref.BaseModel, BaseList = _ref.BaseList;
+_ref = require('limn/data/metric-model'), Metric = _ref.Metric, MetricList = _ref.MetricList;
+_ref = require('limn/data/datasource-model'), DataSource = _ref.DataSource, DataSourceList = _ref.DataSourceList;
 /**
  * @class
  */
index f3c47b1..e32a638 100644 (file)
@@ -1,12 +1,12 @@
-require.define('/node_modules/kraken/data/dataset-model.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/data/dataset-model.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var Seq, ColorBrewer, op, BaseModel, BaseList, Metric, MetricList, DataSource, DataSourceList, DataSet, _ref, _;
 Seq = require('seq');
 ColorBrewer = require('colorbrewer');
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-_ref = require('kraken/base'), BaseModel = _ref.BaseModel, BaseList = _ref.BaseList;
-_ref = require('kraken/data/metric-model'), Metric = _ref.Metric, MetricList = _ref.MetricList;
-_ref = require('kraken/data/datasource-model'), DataSource = _ref.DataSource, DataSourceList = _ref.DataSourceList;
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+_ref = require('limn/base'), BaseModel = _ref.BaseModel, BaseList = _ref.BaseList;
+_ref = require('limn/data/metric-model'), Metric = _ref.Metric, MetricList = _ref.MetricList;
+_ref = require('limn/data/datasource-model'), DataSource = _ref.DataSource, DataSourceList = _ref.DataSourceList;
 /**
  * @class
  */
index d1296fd..da7bab3 100644 (file)
@@ -1,13 +1,13 @@
 var op, BaseView, DataSetView, DataSetMetricView, _ref, _;
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-BaseView = require('kraken/base').BaseView;
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+BaseView = require('limn/base').BaseView;
 /**
  * @class
  */
 DataSetView = exports.DataSetView = BaseView.extend({
   tagName: 'section',
   className: 'dataset-ui dataset',
-  template: require('kraken/template/data/dataset'),
+  template: require('limn/template/data/dataset'),
   events: {
     'click  .new-metric-button': 'onNewMetric',
     'click  .delete-metric-button': 'onDeleteMetric',
@@ -106,7 +106,7 @@ DataSetView = exports.DataSetView = BaseView.extend({
 DataSetMetricView = exports.DataSetMetricView = BaseView.extend({
   tagName: 'tr',
   className: 'dataset-metric metric',
-  template: require('kraken/template/data/dataset-metric'),
+  template: require('limn/template/data/dataset-metric'),
   constructor: (function(){
     function DataSetMetricView(){
       return BaseView.apply(this, arguments);
index b5aec94..09462e5 100644 (file)
@@ -1,15 +1,15 @@
-require.define('/node_modules/kraken/data/dataset-view.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/data/dataset-view.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var op, BaseView, DataSetView, DataSetMetricView, _ref, _;
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-BaseView = require('kraken/base').BaseView;
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+BaseView = require('limn/base').BaseView;
 /**
  * @class
  */
 DataSetView = exports.DataSetView = BaseView.extend({
   tagName: 'section',
   className: 'dataset-ui dataset',
-  template: require('kraken/template/data/dataset'),
+  template: require('limn/template/data/dataset'),
   events: {
     'click  .new-metric-button': 'onNewMetric',
     'click  .delete-metric-button': 'onDeleteMetric',
@@ -108,7 +108,7 @@ DataSetView = exports.DataSetView = BaseView.extend({
 DataSetMetricView = exports.DataSetMetricView = BaseView.extend({
   tagName: 'tr',
   className: 'dataset-metric metric',
-  template: require('kraken/template/data/dataset-metric'),
+  template: require('limn/template/data/dataset-metric'),
   constructor: (function(){
     function DataSetMetricView(){
       return BaseView.apply(this, arguments);
index 8b72068..84b3c78 100644 (file)
@@ -1,8 +1,8 @@
 var op, TimeSeriesData, CSVData, BaseModel, BaseList, ModelCache, Metric, MetricList, DataSource, DataSourceList, ALL_SOURCES, sourceCache, _ref, _;
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-_ref = require('kraken/util/timeseries'), TimeSeriesData = _ref.TimeSeriesData, CSVData = _ref.CSVData;
-_ref = require('kraken/base'), BaseModel = _ref.BaseModel, BaseList = _ref.BaseList, ModelCache = _ref.ModelCache;
-_ref = require('kraken/data/metric-model'), Metric = _ref.Metric, MetricList = _ref.MetricList;
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+_ref = require('limn/util/timeseries'), TimeSeriesData = _ref.TimeSeriesData, CSVData = _ref.CSVData;
+_ref = require('limn/base'), BaseModel = _ref.BaseModel, BaseList = _ref.BaseList, ModelCache = _ref.ModelCache;
+_ref = require('limn/data/metric-model'), Metric = _ref.Metric, MetricList = _ref.MetricList;
 /**
  * @class
  */
index 49b9f7e..2155d0c 100644 (file)
@@ -1,10 +1,10 @@
-require.define('/node_modules/kraken/data/datasource-model.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/data/datasource-model.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var op, TimeSeriesData, CSVData, BaseModel, BaseList, ModelCache, Metric, MetricList, DataSource, DataSourceList, ALL_SOURCES, sourceCache, _ref, _;
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-_ref = require('kraken/util/timeseries'), TimeSeriesData = _ref.TimeSeriesData, CSVData = _ref.CSVData;
-_ref = require('kraken/base'), BaseModel = _ref.BaseModel, BaseList = _ref.BaseList, ModelCache = _ref.ModelCache;
-_ref = require('kraken/data/metric-model'), Metric = _ref.Metric, MetricList = _ref.MetricList;
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+_ref = require('limn/util/timeseries'), TimeSeriesData = _ref.TimeSeriesData, CSVData = _ref.CSVData;
+_ref = require('limn/base'), BaseModel = _ref.BaseModel, BaseList = _ref.BaseList, ModelCache = _ref.ModelCache;
+_ref = require('limn/data/metric-model'), Metric = _ref.Metric, MetricList = _ref.MetricList;
 /**
  * @class
  */
index 0f2b4c7..9328f8a 100644 (file)
@@ -1,6 +1,6 @@
 var op, BaseModel, BaseList, BaseView, DataSourceUIView, _ref, _;
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-_ref = require('kraken/base'), BaseModel = _ref.BaseModel, BaseList = _ref.BaseList, BaseView = _ref.BaseView;
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+_ref = require('limn/base'), BaseModel = _ref.BaseModel, BaseList = _ref.BaseList, BaseView = _ref.BaseView;
 /**
  * @class
  * Model is a Metric.
@@ -9,7 +9,7 @@ DataSourceUIView = exports.DataSourceUIView = BaseView.extend({
   __bind__: [],
   tagName: 'section',
   className: 'datasource-ui',
-  template: require('kraken/template/data/datasource-ui'),
+  template: require('limn/template/data/datasource-ui'),
   events: {
     'click .datasource-summary': 'onHeaderClick',
     'click .datasource-source-metric': 'onSelectMetric'
index b9714f7..e5a57d4 100644 (file)
@@ -1,8 +1,8 @@
-require.define('/node_modules/kraken/data/datasource-ui-view.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/data/datasource-ui-view.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var op, BaseModel, BaseList, BaseView, DataSourceUIView, _ref, _;
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-_ref = require('kraken/base'), BaseModel = _ref.BaseModel, BaseList = _ref.BaseList, BaseView = _ref.BaseView;
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+_ref = require('limn/base'), BaseModel = _ref.BaseModel, BaseList = _ref.BaseList, BaseView = _ref.BaseView;
 /**
  * @class
  * Model is a Metric.
@@ -11,7 +11,7 @@ DataSourceUIView = exports.DataSourceUIView = BaseView.extend({
   __bind__: [],
   tagName: 'section',
   className: 'datasource-ui',
-  template: require('kraken/template/data/datasource-ui'),
+  template: require('limn/template/data/datasource-ui'),
   events: {
     'click .datasource-summary': 'onHeaderClick',
     'click .datasource-source-metric': 'onSelectMetric'
index 3ec50e1..0088fc1 100644 (file)
@@ -1,6 +1,6 @@
 var op, BaseModel, BaseList, BaseView, DataSourceView, _ref, _;
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-_ref = require('kraken/base'), BaseModel = _ref.BaseModel, BaseList = _ref.BaseList, BaseView = _ref.BaseView;
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+_ref = require('limn/base'), BaseModel = _ref.BaseModel, BaseList = _ref.BaseList, BaseView = _ref.BaseView;
 /**
  * @class
  */
@@ -8,7 +8,7 @@ DataSourceView = exports.DataSourceView = BaseView.extend({
   __bind__: [],
   tagName: 'section',
   className: 'datasource',
-  template: require('kraken/template/data/datasource'),
+  template: require('limn/template/data/datasource'),
   constructor: (function(){
     function DataSourceView(){
       return BaseView.apply(this, arguments);
index 7f9c205..0adff99 100644 (file)
@@ -1,8 +1,8 @@
-require.define('/node_modules/kraken/data/datasource-view.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/data/datasource-view.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var op, BaseModel, BaseList, BaseView, DataSourceView, _ref, _;
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-_ref = require('kraken/base'), BaseModel = _ref.BaseModel, BaseList = _ref.BaseList, BaseView = _ref.BaseView;
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+_ref = require('limn/base'), BaseModel = _ref.BaseModel, BaseList = _ref.BaseList, BaseView = _ref.BaseView;
 /**
  * @class
  */
@@ -10,7 +10,7 @@ DataSourceView = exports.DataSourceView = BaseView.extend({
   __bind__: [],
   tagName: 'section',
   className: 'datasource',
-  template: require('kraken/template/data/datasource'),
+  template: require('limn/template/data/datasource'),
   constructor: (function(){
     function DataSourceView(){
       return BaseView.apply(this, arguments);
index 55cb2d2..4eb1308 100644 (file)
@@ -1,12 +1,12 @@
 var metric_model, metric_edit_view, datasource_model, datasource_view, datasource_ui_view, dataset_model, dataset_view, data_view;
-metric_model = require('kraken/data/metric-model');
-metric_edit_view = require('kraken/data/metric-edit-view');
-datasource_model = require('kraken/data/datasource-model');
-datasource_view = require('kraken/data/datasource-view');
-datasource_ui_view = require('kraken/data/datasource-ui-view');
-dataset_model = require('kraken/data/dataset-model');
-dataset_view = require('kraken/data/dataset-view');
-data_view = require('kraken/data/data-view');
+metric_model = require('limn/data/metric-model');
+metric_edit_view = require('limn/data/metric-edit-view');
+datasource_model = require('limn/data/datasource-model');
+datasource_view = require('limn/data/datasource-view');
+datasource_ui_view = require('limn/data/datasource-ui-view');
+dataset_model = require('limn/data/dataset-model');
+dataset_view = require('limn/data/dataset-view');
+data_view = require('limn/data/data-view');
 __import(__import(__import(__import(__import(__import(__import(__import(exports, datasource_model), datasource_view), datasource_ui_view), dataset_model), dataset_view), metric_model), metric_edit_view), data_view);
 function __import(obj, src){
   var own = {}.hasOwnProperty;
index ba4ef66..1ddf4c1 100644 (file)
@@ -1,14 +1,14 @@
-require.define('/node_modules/kraken/data/index.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/data.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var metric_model, metric_edit_view, datasource_model, datasource_view, datasource_ui_view, dataset_model, dataset_view, data_view;
-metric_model = require('kraken/data/metric-model');
-metric_edit_view = require('kraken/data/metric-edit-view');
-datasource_model = require('kraken/data/datasource-model');
-datasource_view = require('kraken/data/datasource-view');
-datasource_ui_view = require('kraken/data/datasource-ui-view');
-dataset_model = require('kraken/data/dataset-model');
-dataset_view = require('kraken/data/dataset-view');
-data_view = require('kraken/data/data-view');
+metric_model = require('limn/data/metric-model');
+metric_edit_view = require('limn/data/metric-edit-view');
+datasource_model = require('limn/data/datasource-model');
+datasource_view = require('limn/data/datasource-view');
+datasource_ui_view = require('limn/data/datasource-ui-view');
+dataset_model = require('limn/data/dataset-model');
+dataset_view = require('limn/data/dataset-view');
+data_view = require('limn/data/data-view');
 __import(__import(__import(__import(__import(__import(__import(__import(exports, datasource_model), datasource_view), datasource_ui_view), dataset_model), dataset_view), metric_model), metric_edit_view), data_view);
 function __import(obj, src){
   var own = {}.hasOwnProperty;
index 15f7c78..af85b30 100644 (file)
@@ -1,8 +1,8 @@
 var op, BaseView, Metric, DataSourceUIView, MetricEditView, _ref, _;
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-BaseView = require('kraken/base').BaseView;
-Metric = require('kraken/data/metric-model').Metric;
-DataSourceUIView = require('kraken/data/datasource-ui-view').DataSourceUIView;
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+BaseView = require('limn/base').BaseView;
+Metric = require('limn/data/metric-model').Metric;
+DataSourceUIView = require('limn/data/datasource-ui-view').DataSourceUIView;
 /**
  * @class
  * Model is a Metric.
@@ -11,7 +11,7 @@ MetricEditView = exports.MetricEditView = BaseView.extend({
   __bind__: ['onChange'],
   tagName: 'section',
   className: 'metric-edit-ui',
-  template: require('kraken/template/data/metric-edit'),
+  template: require('limn/template/data/metric-edit'),
   callOnReturnKeypress: 'onChange',
   events: {
     'keydown .metric-label': 'onReturnKeypress'
index 40d5442..0218ba0 100644 (file)
@@ -1,10 +1,10 @@
-require.define('/node_modules/kraken/data/metric-edit-view.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/data/metric-edit-view.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var op, BaseView, Metric, DataSourceUIView, MetricEditView, _ref, _;
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-BaseView = require('kraken/base').BaseView;
-Metric = require('kraken/data/metric-model').Metric;
-DataSourceUIView = require('kraken/data/datasource-ui-view').DataSourceUIView;
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+BaseView = require('limn/base').BaseView;
+Metric = require('limn/data/metric-model').Metric;
+DataSourceUIView = require('limn/data/datasource-ui-view').DataSourceUIView;
 /**
  * @class
  * Model is a Metric.
@@ -13,7 +13,7 @@ MetricEditView = exports.MetricEditView = BaseView.extend({
   __bind__: ['onChange'],
   tagName: 'section',
   className: 'metric-edit-ui',
-  template: require('kraken/template/data/metric-edit'),
+  template: require('limn/template/data/metric-edit'),
   callOnReturnKeypress: 'onChange',
   events: {
     'keydown .metric-label': 'onReturnKeypress'
index c304e53..853c213 100644 (file)
@@ -1,7 +1,7 @@
 var op, BaseModel, BaseList, ProjectColors, DataSourceList, DataSource, Metric, MetricList, _ref, _;
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-_ref = require('kraken/base'), BaseModel = _ref.BaseModel, BaseList = _ref.BaseList;
-ProjectColors = require('kraken/data/project-colors');
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+_ref = require('limn/base'), BaseModel = _ref.BaseModel, BaseList = _ref.BaseList;
+ProjectColors = require('limn/data/project-colors');
 DataSource = DataSourceList = null;
 /**
  * @class
@@ -176,5 +176,5 @@ MetricList = exports.MetricList = BaseList.extend({
 });
 setTimeout(function(){
   var _ref;
-  return _ref = require('kraken/data/datasource-model'), DataSource = _ref.DataSource, DataSourceList = _ref.DataSourceList, _ref;
+  return _ref = require('limn/data/datasource-model'), DataSource = _ref.DataSource, DataSourceList = _ref.DataSourceList, _ref;
 }, 10);
\ No newline at end of file
index 831825b..053b7f5 100644 (file)
@@ -1,9 +1,9 @@
-require.define('/node_modules/kraken/data/metric-model.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/data/metric-model.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var op, BaseModel, BaseList, ProjectColors, DataSourceList, DataSource, Metric, MetricList, _ref, _;
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-_ref = require('kraken/base'), BaseModel = _ref.BaseModel, BaseList = _ref.BaseList;
-ProjectColors = require('kraken/data/project-colors');
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+_ref = require('limn/base'), BaseModel = _ref.BaseModel, BaseList = _ref.BaseList;
+ProjectColors = require('limn/data/project-colors');
 DataSource = DataSourceList = null;
 /**
  * @class
@@ -178,7 +178,7 @@ MetricList = exports.MetricList = BaseList.extend({
 });
 setTimeout(function(){
   var _ref;
-  return _ref = require('kraken/data/datasource-model'), DataSource = _ref.DataSource, DataSourceList = _ref.DataSourceList, _ref;
+  return _ref = require('limn/data/datasource-model'), DataSource = _ref.DataSource, DataSourceList = _ref.DataSourceList, _ref;
 }, 10);
 
 });
index 674a936..c6dd05d 100644 (file)
@@ -1,4 +1,4 @@
-require.define('/node_modules/kraken/data/project-colors.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/data/project-colors.js', function(require, module, exports, __dirname, __filename, undefined){
 
 /**
  * @fileOverview Applies consistent coloring to language/project Metrics with a null `color` field.
index ed4246f..fdafaeb 100644 (file)
@@ -1,8 +1,8 @@
 var moment, op, Graph, GraphView, root, GraphDisplayView, _ref, _;
 moment = require('moment');
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-Graph = require('kraken/graph/graph-model').Graph;
-GraphView = require('kraken/graph/graph-view').GraphView;
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+Graph = require('limn/graph/graph-model').Graph;
+GraphView = require('limn/graph/graph-view').GraphView;
 root = function(){
   return this;
 }();
@@ -12,14 +12,14 @@ root = function(){
 GraphDisplayView = exports.GraphDisplayView = GraphView.extend({
   tagName: 'section',
   className: 'graph graph-display',
-  template: require('kraken/template/graph/graph-display'),
+  template: require('limn/template/graph/graph-display'),
   events: {
     'focus      .graph-permalink input': 'onPermalinkFocus',
     'click      .export-button': 'exportChart'
   },
   constructor: (function(){
     function GraphDisplayView(){
-      return BaseView.apply(this, arguments);
+      return GraphView.apply(this, arguments);
     }
     return GraphDisplayView;
   }()),
index 76919e9..64bd1c7 100644 (file)
@@ -1,10 +1,10 @@
-require.define('/node_modules/kraken/graph/graph-display-view.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/graph/graph-display-view.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var moment, op, Graph, GraphView, root, GraphDisplayView, _ref, _;
 moment = require('moment');
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-Graph = require('kraken/graph/graph-model').Graph;
-GraphView = require('kraken/graph/graph-view').GraphView;
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+Graph = require('limn/graph/graph-model').Graph;
+GraphView = require('limn/graph/graph-view').GraphView;
 root = function(){
   return this;
 }();
@@ -14,14 +14,14 @@ root = function(){
 GraphDisplayView = exports.GraphDisplayView = GraphView.extend({
   tagName: 'section',
   className: 'graph graph-display',
-  template: require('kraken/template/graph/graph-display'),
+  template: require('limn/template/graph/graph-display'),
   events: {
     'focus      .graph-permalink input': 'onPermalinkFocus',
     'click      .export-button': 'exportChart'
   },
   constructor: (function(){
     function GraphDisplayView(){
-      return BaseView.apply(this, arguments);
+      return GraphView.apply(this, arguments);
     }
     return GraphDisplayView;
   }()),
index 2a562eb..9551a9b 100644 (file)
@@ -1,10 +1,10 @@
 var moment, Graph, GraphView, ChartOptionScaffold, DEBOUNCE_RENDER, DataView, DataSetView, DataSet, root, GraphEditView, _, _ref;
 moment = require('moment');
-_ = require('kraken/util/underscore');
-Graph = require('kraken/graph/graph-model').Graph;
-GraphView = require('kraken/graph/graph-view').GraphView;
-_ref = require('kraken/chart'), ChartOptionScaffold = _ref.ChartOptionScaffold, DEBOUNCE_RENDER = _ref.DEBOUNCE_RENDER;
-_ref = require('kraken/data'), DataView = _ref.DataView, DataSetView = _ref.DataSetView, DataSet = _ref.DataSet;
+_ = require('limn/util/underscore');
+Graph = require('limn/graph/graph-model').Graph;
+GraphView = require('limn/graph/graph-view').GraphView;
+_ref = require('limn/chart'), ChartOptionScaffold = _ref.ChartOptionScaffold, DEBOUNCE_RENDER = _ref.DEBOUNCE_RENDER;
+_ref = require('limn/data'), DataView = _ref.DataView, DataSetView = _ref.DataSetView, DataSet = _ref.DataSet;
 root = function(){
   return this;
 }();
@@ -16,7 +16,7 @@ root = function(){
 GraphEditView = exports.GraphEditView = GraphView.extend({
   __bind__: ['wait', 'unwait', 'onChartTypeReady', 'onScaffoldChange', 'onFirstClickRenderOptionsTab', 'onFirstClickRenderDataTab'],
   className: 'graph-edit graph',
-  template: require('kraken/template/graph/graph-edit'),
+  template: require('limn/template/graph/graph-edit'),
   events: {
     'click    .redraw-button': 'stopAndRender',
     'click    .load-button': 'load',
@@ -30,9 +30,16 @@ GraphEditView = exports.GraphEditView = GraphView.extend({
     'submit   form.chart-options': 'onOptionsSubmit',
     'change   .chart-options input[type="checkbox"]': 'onOptionsSubmit'
   },
+  routes: {
+    'graphs/:graph/edit/info': 'showInfoPane',
+    'graphs/:graph/edit/data/metric/:metric': 'showDataPane',
+    'graphs/:graph/edit/data': 'showDataPane',
+    'graphs/:graph/edit/options/:optionsFilter': 'showOptionsPane',
+    'graphs/:graph/edit/options': 'showOptionsPane'
+  },
   constructor: (function(){
     function GraphEditView(){
-      return BaseView.apply(this, arguments);
+      return GraphView.apply(this, arguments);
     }
     return GraphEditView;
   }()),
index ed45d38..82aa5da 100644 (file)
@@ -1,12 +1,12 @@
-require.define('/node_modules/kraken/graph/graph-edit-view.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/graph/graph-edit-view.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var moment, Graph, GraphView, ChartOptionScaffold, DEBOUNCE_RENDER, DataView, DataSetView, DataSet, root, GraphEditView, _, _ref;
 moment = require('moment');
-_ = require('kraken/util/underscore');
-Graph = require('kraken/graph/graph-model').Graph;
-GraphView = require('kraken/graph/graph-view').GraphView;
-_ref = require('kraken/chart'), ChartOptionScaffold = _ref.ChartOptionScaffold, DEBOUNCE_RENDER = _ref.DEBOUNCE_RENDER;
-_ref = require('kraken/data'), DataView = _ref.DataView, DataSetView = _ref.DataSetView, DataSet = _ref.DataSet;
+_ = require('limn/util/underscore');
+Graph = require('limn/graph/graph-model').Graph;
+GraphView = require('limn/graph/graph-view').GraphView;
+_ref = require('limn/chart'), ChartOptionScaffold = _ref.ChartOptionScaffold, DEBOUNCE_RENDER = _ref.DEBOUNCE_RENDER;
+_ref = require('limn/data'), DataView = _ref.DataView, DataSetView = _ref.DataSetView, DataSet = _ref.DataSet;
 root = function(){
   return this;
 }();
@@ -18,7 +18,7 @@ root = function(){
 GraphEditView = exports.GraphEditView = GraphView.extend({
   __bind__: ['wait', 'unwait', 'onChartTypeReady', 'onScaffoldChange', 'onFirstClickRenderOptionsTab', 'onFirstClickRenderDataTab'],
   className: 'graph-edit graph',
-  template: require('kraken/template/graph/graph-edit'),
+  template: require('limn/template/graph/graph-edit'),
   events: {
     'click    .redraw-button': 'stopAndRender',
     'click    .load-button': 'load',
@@ -32,9 +32,16 @@ GraphEditView = exports.GraphEditView = GraphView.extend({
     'submit   form.chart-options': 'onOptionsSubmit',
     'change   .chart-options input[type="checkbox"]': 'onOptionsSubmit'
   },
+  routes: {
+    'graphs/:graph/edit/info': 'showInfoPane',
+    'graphs/:graph/edit/data/metric/:metric': 'showDataPane',
+    'graphs/:graph/edit/data': 'showDataPane',
+    'graphs/:graph/edit/options/:optionsFilter': 'showOptionsPane',
+    'graphs/:graph/edit/options': 'showOptionsPane'
+  },
   constructor: (function(){
     function GraphEditView(){
-      return BaseView.apply(this, arguments);
+      return GraphView.apply(this, arguments);
     }
     return GraphEditView;
   }()),
index 03f37e4..c5c16f5 100644 (file)
@@ -1,7 +1,7 @@
 var op, BaseView, Graph, GraphList, root, DEBOUNCE_RENDER, GraphListView, _ref, _;
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-BaseView = require('kraken/base').BaseView;
-_ref = require('kraken/graph/graph-model'), Graph = _ref.Graph, GraphList = _ref.GraphList;
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+BaseView = require('limn/base').BaseView;
+_ref = require('limn/graph/graph-model'), Graph = _ref.Graph, GraphList = _ref.GraphList;
 root = function(){
   return this;
 }();
@@ -14,12 +14,19 @@ GraphListView = exports.GraphListView = BaseView.extend({
   __debounce__: ['render'],
   tagName: 'section',
   className: 'graph-list-view',
-  template: require('kraken/template/graph/graph-list'),
+  template: require('limn/template/graph/graph-list'),
   data: {},
   ready: false,
   initialize: function(){
     this.model = this.collection || (this.collection = new GraphList);
-    return BaseView.prototype.initialize.apply(this, arguments);
+    BaseView.prototype.initialize.apply(this, arguments);
+    return this.collection.once('load-success', this.onLoad, this).load();
+  },
+  onLoad: function(){
+    console.log(this + ".onLoad!");
+    this.triggerReady();
+    this.isBuilt = false;
+    return this.render();
   },
   toTemplateLocals: function(){
     var locals;
index b943a49..caf8621 100644 (file)
@@ -1,9 +1,9 @@
-require.define('/node_modules/kraken/graph/graph-list-view.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/graph/graph-list-view.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var op, BaseView, Graph, GraphList, root, DEBOUNCE_RENDER, GraphListView, _ref, _;
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-BaseView = require('kraken/base').BaseView;
-_ref = require('kraken/graph/graph-model'), Graph = _ref.Graph, GraphList = _ref.GraphList;
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
+BaseView = require('limn/base').BaseView;
+_ref = require('limn/graph/graph-model'), Graph = _ref.Graph, GraphList = _ref.GraphList;
 root = function(){
   return this;
 }();
@@ -16,12 +16,19 @@ GraphListView = exports.GraphListView = BaseView.extend({
   __debounce__: ['render'],
   tagName: 'section',
   className: 'graph-list-view',
-  template: require('kraken/template/graph/graph-list'),
+  template: require('limn/template/graph/graph-list'),
   data: {},
   ready: false,
   initialize: function(){
     this.model = this.collection || (this.collection = new GraphList);
-    return BaseView.prototype.initialize.apply(this, arguments);
+    BaseView.prototype.initialize.apply(this, arguments);
+    return this.collection.once('load-success', this.onLoad, this).load();
+  },
+  onLoad: function(){
+    console.log(this + ".onLoad!");
+    this.triggerReady();
+    this.isBuilt = false;
+    return this.render();
   },
   toTemplateLocals: function(){
     var locals;
index cf04dbd..dd6da88 100644 (file)
@@ -1,9 +1,9 @@
 var Seq, Cascade, BaseModel, BaseList, ModelCache, ChartType, DataSet, root, Graph, GraphList, _ref, _;
 Seq = require('seq');
-_ref = require('kraken/util'), _ = _ref._, Cascade = _ref.Cascade;
-_ref = require('kraken/base'), BaseModel = _ref.BaseModel, BaseList = _ref.BaseList, ModelCache = _ref.ModelCache;
-ChartType = require('kraken/chart').ChartType;
-DataSet = require('kraken/data').DataSet;
+_ref = require('limn/util'), _ = _ref._, Cascade = _ref.Cascade;
+_ref = require('limn/base'), BaseModel = _ref.BaseModel, BaseList = _ref.BaseList, ModelCache = _ref.ModelCache;
+ChartType = require('limn/chart').ChartType;
+DataSet = require('limn/data').DataSet;
 root = function(){
   return this;
 }();
index 3953385..725d971 100644 (file)
@@ -1,11 +1,11 @@
-require.define('/node_modules/kraken/graph/graph-model.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/graph/graph-model.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var Seq, Cascade, BaseModel, BaseList, ModelCache, ChartType, DataSet, root, Graph, GraphList, _ref, _;
 Seq = require('seq');
-_ref = require('kraken/util'), _ = _ref._, Cascade = _ref.Cascade;
-_ref = require('kraken/base'), BaseModel = _ref.BaseModel, BaseList = _ref.BaseList, ModelCache = _ref.ModelCache;
-ChartType = require('kraken/chart').ChartType;
-DataSet = require('kraken/data').DataSet;
+_ref = require('limn/util'), _ = _ref._, Cascade = _ref.Cascade;
+_ref = require('limn/base'), BaseModel = _ref.BaseModel, BaseList = _ref.BaseList, ModelCache = _ref.ModelCache;
+ChartType = require('limn/chart').ChartType;
+DataSet = require('limn/data').DataSet;
 root = function(){
   return this;
 }();
index 7c98892..19664e6 100644 (file)
@@ -1,8 +1,9 @@
-var moment, BaseView, Graph, root, DEBOUNCE_RENDER, GraphView, _;
+var Seq, moment, BaseView, Graph, root, DEBOUNCE_RENDER, GraphView, _;
+Seq = require('seq');
 moment = require('moment');
-_ = require('kraken/util/underscore');
-BaseView = require('kraken/base').BaseView;
-Graph = require('kraken/graph/graph-model').Graph;
+_ = require('limn/util/underscore');
+BaseView = require('limn/base').BaseView;
+Graph = require('limn/graph/graph-model').Graph;
 root = function(){
   return this;
 }();
index c3bf4cb..baf0165 100644 (file)
@@ -1,10 +1,11 @@
-require.define('/node_modules/kraken/graph/graph-view.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/graph/graph-view.js', function(require, module, exports, __dirname, __filename, undefined){
 
-var moment, BaseView, Graph, root, DEBOUNCE_RENDER, GraphView, _;
+var Seq, moment, BaseView, Graph, root, DEBOUNCE_RENDER, GraphView, _;
+Seq = require('seq');
 moment = require('moment');
-_ = require('kraken/util/underscore');
-BaseView = require('kraken/base').BaseView;
-Graph = require('kraken/graph/graph-model').Graph;
+_ = require('limn/util/underscore');
+BaseView = require('limn/base').BaseView;
+Graph = require('limn/graph/graph-model').Graph;
 root = function(){
   return this;
 }();
index 8817c26..0247b67 100644 (file)
@@ -1,9 +1,9 @@
 var models, base_views, display_views, edit_views, index_views;
-models = require('kraken/graph/graph-model');
-base_views = require('kraken/graph/graph-view');
-display_views = require('kraken/graph/graph-display-view');
-edit_views = require('kraken/graph/graph-edit-view');
-index_views = require('kraken/graph/graph-list-view');
+models = require('limn/graph/graph-model');
+base_views = require('limn/graph/graph-view');
+display_views = require('limn/graph/graph-display-view');
+edit_views = require('limn/graph/graph-edit-view');
+index_views = require('limn/graph/graph-list-view');
 __import(__import(__import(__import(__import(exports, models), base_views), display_views), edit_views), index_views);
 function __import(obj, src){
   var own = {}.hasOwnProperty;
index f57db69..7fb7d8b 100644 (file)
@@ -1,11 +1,11 @@
-require.define('/node_modules/kraken/graph/index.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/graph.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var models, base_views, display_views, edit_views, index_views;
-models = require('kraken/graph/graph-model');
-base_views = require('kraken/graph/graph-view');
-display_views = require('kraken/graph/graph-display-view');
-edit_views = require('kraken/graph/graph-edit-view');
-index_views = require('kraken/graph/graph-list-view');
+models = require('limn/graph/graph-model');
+base_views = require('limn/graph/graph-view');
+display_views = require('limn/graph/graph-display-view');
+edit_views = require('limn/graph/graph-edit-view');
+index_views = require('limn/graph/graph-list-view');
 __import(__import(__import(__import(__import(exports, models), base_views), display_views), edit_views), index_views);
 function __import(obj, src){
   var own = {}.hasOwnProperty;
diff --git a/lib/limn.js b/lib/limn.js
new file mode 100644 (file)
index 0000000..f887dd0
--- /dev/null
@@ -0,0 +1,150 @@
+var limn, Backbone, op, root, BaseView, BaseModel, BaseList, ChartType, DygraphsChartType, Graph, GraphList, GraphDisplayView, GraphEditView, GraphListView, DashboardView, Dashboard, LimnApp, _ref, _;
+limn = exports;
+Backbone = require('backbone');
+_ref = limn.util = require('limn/util'), _ = _ref._, op = _ref.op, root = _ref.root;
+_ref = limn.base = require('limn/base'), BaseView = _ref.BaseView, BaseModel = _ref.BaseModel, BaseList = _ref.BaseList;
+_ref = limn.chart = require('limn/chart'), ChartType = _ref.ChartType, DygraphsChartType = _ref.DygraphsChartType;
+_ref = limn.graph = require('limn/graph'), Graph = _ref.Graph, GraphList = _ref.GraphList, GraphDisplayView = _ref.GraphDisplayView, GraphEditView = _ref.GraphEditView, GraphListView = _ref.GraphListView;
+_ref = limn.dashboard = require('limn/dashboard'), DashboardView = _ref.DashboardView, Dashboard = _ref.Dashboard;
+/**
+ * @class Sets up root application, automatically attaching to an existing element
+ *  found at `appSelector` and delegating to the appropriate view.
+ * @extends Backbone.Router
+ */
+LimnApp = limn.LimnApp = Backbone.Router.extend({
+  appSelector: '#content .inner',
+  routes: {
+    'graphs/(new|edit)': 'newGraph',
+    'graphs/:graphId/edit': 'editGraph',
+    'graphs/:graphId': 'showGraph',
+    'graphs': 'listGraphs',
+    'dashboards/(new|edit)': 'newDashboard',
+    'dashboards/:dashId/edit': 'editDashboard',
+    'dashboards/:dashId': 'showDashboard',
+    'dashboards': 'listDashboards'
+  }
+  /**
+   * @constructor
+   */,
+  constructor: (function(){
+    function LimnApp(config){
+      var that;
+      this.config = config != null
+        ? config
+        : {};
+      if (that = config.appSelector) {
+        this.appSelector = that;
+      }
+      this.el = config.el || (config.el = jQuery(this.appSelector)[0]);
+      this.$el = jQuery(this.el);
+      Backbone.Router.call(this, config);
+      return this;
+    }
+    return LimnApp;
+  }()),
+  initialize: function(){
+    var _this = this;
+    jQuery(function(){
+      return _this.setup();
+    });
+    return this;
+  },
+  setup: function(){
+    this.route(/^(?:[\?].*)?$/, 'home');
+    return Backbone.history.start({
+      pushState: true,
+      root: this.config.mount
+    });
+  },
+  processData: function(id, data){
+    data == null && (data = {});
+    if (!(id && _(['edit', 'new']).contains(id))) {
+      data.id = data.slug = id;
+    }
+    return data;
+  }
+  /* * * *  Routes  * * * */,
+  home: function(){
+    return this.showDashboard('reportcard');
+  },
+  createGraphModel: function(id){
+    var data, graph;
+    data = this.processData(id);
+    return graph = new Graph(data, {
+      parse: true
+    });
+  },
+  newGraph: function(){
+    return this.editGraph();
+  },
+  editGraph: function(id){
+    this.model = this.createGraphModel(id);
+    return this.view = new GraphEditView({
+      model: this.model
+    }).attach(this.el);
+  },
+  showGraph: function(id){
+    this.model = this.createGraphModel(id);
+    return this.view = new GraphDisplayView({
+      model: this.model
+    }).attach(this.el);
+  },
+  listGraphs: function(){
+    this.collection = new GraphList();
+    return this.view = new GraphListView({
+      collection: this.collection
+    }).attach(this.el);
+  },
+  createDashboardModel: function(id){
+    var data, dashboard;
+    data = this.processData(id);
+    return dashboard = new Dashboard(data, {
+      parse: true
+    });
+  },
+  newDashboard: function(){
+    return console.error('newDashboard!?');
+  },
+  editDashboard: function(id){
+    return console.error('editDashboard!?');
+  },
+  showDashboard: function(id){
+    this.model = this.createDashboardModel(id);
+    return this.view = new DashboardView({
+      model: this.model
+    }).attach(this.el);
+  },
+  listDashboards: function(){
+    return console.error('listDashboards!?');
+  },
+  getClassName: function(){
+    return (this.constructor.name || this.constructor.displayName) + "";
+  },
+  toString: function(){
+    return this.getClassName() + "()";
+  }
+});
+__import(LimnApp, {
+  findConfig: function(){
+    var config;
+    config = root.limn_config || {};
+    config.mount || (config.mount = "/");
+    return config;
+  },
+  main: (function(){
+    function limnMain(){
+      var config;
+      config = limn.config || (limn.config = LimnApp.findConfig());
+      if (!config.libOnly) {
+        return limn.app || (limn.app = new LimnApp(config));
+      }
+    }
+    return limnMain;
+  }())
+});
+jQuery(LimnApp.main);
+function __import(obj, src){
+  var own = {}.hasOwnProperty;
+  for (var key in src) if (own.call(src, key)) obj[key] = src[key];
+  return obj;
+}
\ No newline at end of file
diff --git a/lib/limn.mod.js b/lib/limn.mod.js
new file mode 100644 (file)
index 0000000..a88a916
--- /dev/null
@@ -0,0 +1,154 @@
+require.define('/node_modules/limn/limn.js', function(require, module, exports, __dirname, __filename, undefined){
+
+var limn, Backbone, op, root, BaseView, BaseModel, BaseList, ChartType, DygraphsChartType, Graph, GraphList, GraphDisplayView, GraphEditView, GraphListView, DashboardView, Dashboard, LimnApp, _ref, _;
+limn = exports;
+Backbone = require('backbone');
+_ref = limn.util = require('limn/util'), _ = _ref._, op = _ref.op, root = _ref.root;
+_ref = limn.base = require('limn/base'), BaseView = _ref.BaseView, BaseModel = _ref.BaseModel, BaseList = _ref.BaseList;
+_ref = limn.chart = require('limn/chart'), ChartType = _ref.ChartType, DygraphsChartType = _ref.DygraphsChartType;
+_ref = limn.graph = require('limn/graph'), Graph = _ref.Graph, GraphList = _ref.GraphList, GraphDisplayView = _ref.GraphDisplayView, GraphEditView = _ref.GraphEditView, GraphListView = _ref.GraphListView;
+_ref = limn.dashboard = require('limn/dashboard'), DashboardView = _ref.DashboardView, Dashboard = _ref.Dashboard;
+/**
+ * @class Sets up root application, automatically attaching to an existing element
+ *  found at `appSelector` and delegating to the appropriate view.
+ * @extends Backbone.Router
+ */
+LimnApp = limn.LimnApp = Backbone.Router.extend({
+  appSelector: '#content .inner',
+  routes: {
+    'graphs/(new|edit)': 'newGraph',
+    'graphs/:graphId/edit': 'editGraph',
+    'graphs/:graphId': 'showGraph',
+    'graphs': 'listGraphs',
+    'dashboards/(new|edit)': 'newDashboard',
+    'dashboards/:dashId/edit': 'editDashboard',
+    'dashboards/:dashId': 'showDashboard',
+    'dashboards': 'listDashboards'
+  }
+  /**
+   * @constructor
+   */,
+  constructor: (function(){
+    function LimnApp(config){
+      var that;
+      this.config = config != null
+        ? config
+        : {};
+      if (that = config.appSelector) {
+        this.appSelector = that;
+      }
+      this.el = config.el || (config.el = jQuery(this.appSelector)[0]);
+      this.$el = jQuery(this.el);
+      Backbone.Router.call(this, config);
+      return this;
+    }
+    return LimnApp;
+  }()),
+  initialize: function(){
+    var _this = this;
+    jQuery(function(){
+      return _this.setup();
+    });
+    return this;
+  },
+  setup: function(){
+    this.route(/^(?:[\?].*)?$/, 'home');
+    return Backbone.history.start({
+      pushState: true,
+      root: this.config.mount
+    });
+  },
+  processData: function(id, data){
+    data == null && (data = {});
+    if (!(id && _(['edit', 'new']).contains(id))) {
+      data.id = data.slug = id;
+    }
+    return data;
+  }
+  /* * * *  Routes  * * * */,
+  home: function(){
+    return this.showDashboard('reportcard');
+  },
+  createGraphModel: function(id){
+    var data, graph;
+    data = this.processData(id);
+    return graph = new Graph(data, {
+      parse: true
+    });
+  },
+  newGraph: function(){
+    return this.editGraph();
+  },
+  editGraph: function(id){
+    this.model = this.createGraphModel(id);
+    return this.view = new GraphEditView({
+      model: this.model
+    }).attach(this.el);
+  },
+  showGraph: function(id){
+    this.model = this.createGraphModel(id);
+    return this.view = new GraphDisplayView({
+      model: this.model
+    }).attach(this.el);
+  },
+  listGraphs: function(){
+    this.collection = new GraphList();
+    return this.view = new GraphListView({
+      collection: this.collection
+    }).attach(this.el);
+  },
+  createDashboardModel: function(id){
+    var data, dashboard;
+    data = this.processData(id);
+    return dashboard = new Dashboard(data, {
+      parse: true
+    });
+  },
+  newDashboard: function(){
+    return console.error('newDashboard!?');
+  },
+  editDashboard: function(id){
+    return console.error('editDashboard!?');
+  },
+  showDashboard: function(id){
+    this.model = this.createDashboardModel(id);
+    return this.view = new DashboardView({
+      model: this.model
+    }).attach(this.el);
+  },
+  listDashboards: function(){
+    return console.error('listDashboards!?');
+  },
+  getClassName: function(){
+    return (this.constructor.name || this.constructor.displayName) + "";
+  },
+  toString: function(){
+    return this.getClassName() + "()";
+  }
+});
+__import(LimnApp, {
+  findConfig: function(){
+    var config;
+    config = root.limn_config || {};
+    config.mount || (config.mount = "/");
+    return config;
+  },
+  main: (function(){
+    function limnMain(){
+      var config;
+      config = limn.config || (limn.config = LimnApp.findConfig());
+      if (!config.libOnly) {
+        return limn.app || (limn.app = new LimnApp(config));
+      }
+    }
+    return limnMain;
+  }())
+});
+jQuery(LimnApp.main);
+function __import(obj, src){
+  var own = {}.hasOwnProperty;
+  for (var key in src) if (own.call(src, key)) obj[key] = src[key];
+  return obj;
+}
+
+});
diff --git a/lib/main-dashboard.js b/lib/main-dashboard.js
deleted file mode 100644 (file)
index a9fabe2..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-var Seq, Backbone, op, AppView, BaseView, BaseModel, BaseList, ChartType, DygraphsChartType, Graph, GraphList, GraphDisplayView, DashboardView, Dashboard, root, main, _ref, _;
-Seq = require('seq');
-Backbone = require('backbone');
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-AppView = require('kraken/app').AppView;
-_ref = require('kraken/base'), BaseView = _ref.BaseView, BaseModel = _ref.BaseModel, BaseList = _ref.BaseList;
-_ref = require('kraken/chart'), ChartType = _ref.ChartType, DygraphsChartType = _ref.DygraphsChartType;
-_ref = require('kraken/graph'), Graph = _ref.Graph, GraphList = _ref.GraphList, GraphDisplayView = _ref.GraphDisplayView;
-_ref = require('kraken/dashboard'), DashboardView = _ref.DashboardView, Dashboard = _ref.Dashboard;
-root = this;
-main = function(){
-  var loc, data, match, id;
-  loc = String(root.location);
-  data = {};
-  if (match = /\/dashboards\/([^\/?]+)/i.exec(loc)) {
-    id = match[1];
-    if (!_(['edit', 'new']).contains(id)) {
-      data.id = data.slug = id;
-    }
-  }
-  return root.app = new AppView(function(){
-    this.model = root.dashboard = new Dashboard(data, {
-      parse: true
-    });
-    return this.view = root.view = new DashboardView({
-      model: this.model
-    });
-  });
-};
-jQuery(main);
\ No newline at end of file
diff --git a/lib/main-display.js b/lib/main-display.js
deleted file mode 100644 (file)
index a497afc..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-var Seq, Backbone, op, AppView, BaseView, BaseModel, BaseList, ChartType, DygraphsChartType, Graph, GraphList, GraphDisplayView, root, CHART_OPTIONS_SPEC, CHART_DEFAULT_OPTIONS, main, _ref, _;
-Seq = require('seq');
-Backbone = require('backbone');
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-AppView = require('kraken/app').AppView;
-_ref = require('kraken/base'), BaseView = _ref.BaseView, BaseModel = _ref.BaseModel, BaseList = _ref.BaseList;
-_ref = require('kraken/chart'), ChartType = _ref.ChartType, DygraphsChartType = _ref.DygraphsChartType;
-_ref = require('kraken/graph'), Graph = _ref.Graph, GraphList = _ref.GraphList, GraphDisplayView = _ref.GraphDisplayView;
-root = this;
-CHART_OPTIONS_SPEC = [];
-CHART_DEFAULT_OPTIONS = {};
-main = function(){
-  var loc, data, match, id;
-  History.Adapter.bind(window, 'statechange', function(){});
-  loc = String(root.location);
-  data = {};
-  if (match = /\/graphs\/([^\/?]+)/i.exec(loc)) {
-    id = match[1];
-    if (!_(['edit', 'new']).contains(id)) {
-      data.id = data.slug = id;
-    }
-  }
-  return root.app = new AppView(function(){
-    this.model = root.graph = new Graph(data, {
-      parse: true
-    });
-    return this.view = root.view = new GraphDisplayView({
-      model: this.model
-    });
-  });
-};
-jQuery(main);
\ No newline at end of file
diff --git a/lib/main-edit.js b/lib/main-edit.js
deleted file mode 100644 (file)
index 3d156ab..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-var Seq, Backbone, op, AppView, BaseView, BaseModel, BaseList, ChartType, DataSource, DataSourceList, Graph, GraphList, GraphEditView, root, CHART_OPTIONS_SPEC, CHART_DEFAULT_OPTIONS, main, _ref, _;
-Seq = require('seq');
-Backbone = require('backbone');
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-AppView = require('kraken/app').AppView;
-_ref = require('kraken/base'), BaseView = _ref.BaseView, BaseModel = _ref.BaseModel, BaseList = _ref.BaseList;
-ChartType = require('kraken/chart').ChartType;
-_ref = require('kraken/data'), DataSource = _ref.DataSource, DataSourceList = _ref.DataSourceList;
-_ref = require('kraken/graph'), Graph = _ref.Graph, GraphList = _ref.GraphList, GraphEditView = _ref.GraphEditView;
-root = this;
-CHART_OPTIONS_SPEC = [];
-CHART_DEFAULT_OPTIONS = {};
-main = function(){
-  var loc, data, match, id;
-  History.Adapter.bind(window, 'statechange', function(){});
-  loc = String(root.location);
-  data = {};
-  if (match = /\/graphs\/([^\/?]+)/i.exec(loc)) {
-    id = match[1];
-    if (!_(['edit', 'new']).contains(id)) {
-      data.id = data.slug = id;
-    }
-  }
-  return root.app = new AppView(function(){
-    this.model = root.graph = new Graph(data, {
-      parse: true
-    });
-    return this.view = root.view = new GraphEditView({
-      model: this.model
-    });
-  });
-};
-jQuery(main);
\ No newline at end of file
diff --git a/lib/main-graph-list.js b/lib/main-graph-list.js
deleted file mode 100644 (file)
index 79c0053..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-var op, BaseView, BaseModel, BaseList, Graph, GraphList, GraphListView, main, graph_list_url, _ref, _;
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
-_ref = require('kraken/base'), BaseView = _ref.BaseView, BaseModel = _ref.BaseModel, BaseList = _ref.BaseList;
-_ref = require('kraken/graph'), Graph = _ref.Graph, GraphList = _ref.GraphList, GraphListView = _ref.GraphListView;
-main = function(graph_list_data){
-  var graphs, view;
-  graphs = new GraphList(graph_list_data);
-  view = new GraphListView({
-    'collection': graphs
-  });
-  return $('#content .inner').append(view.el);
-};
-graph_list_url = '/graphs.json';
-jQuery.ajax({
-  url: graph_list_url,
-  dataType: 'json',
-  success: function(res){
-    return jQuery(main.bind(this, res));
-  },
-  error: function(err){
-    return console.error(err);
-  }
-});
\ No newline at end of file
index 2c0f556..28c297c 100644 (file)
@@ -96,8 +96,36 @@ Controller = (function(superclass){
     }
     return this;
   };
+  /**
+   * Boilerplate for creating a error-handling callback that otherwise returns JSON {result:'ok'}.
+   * @param {Response} res Express response object.
+   * @param {String} msg Error message to send on failure.
+   * @param {Number} [code=500] HTTP error code to send on failure.
+   * @returns {Function} Error-handling callback.
+   */
+  prototype.errorHandler = function(res, msg, code){
+    code == null && (code = 500);
+    return function(err){
+      var msg;
+      if (err) {
+        msg || (msg = err.message || String(err));
+        console.error(msg);
+        return res.send({
+          result: "error",
+          message: msg
+        }, code);
+      } else {
+        return res.send({
+          result: "ok"
+        });
+      }
+    };
+  };
+  prototype.getClassName = function(){
+    return (this.constructor.name || this.constructor.displayName) + "";
+  };
   prototype.toString = function(){
-    return this.constructor.name + "('" + this.name + "', base='" + this.base + "', app=" + this.app + ")";
+    return this.getClassName() + "(name='" + this.name + "')";
   };
   return Controller;
 }(Resource));
index 8e48b26..ab2a049 100644 (file)
@@ -17,7 +17,6 @@ DashboardController = (function(superclass){
   prototype.PROTECTED_IDS = ['main', 'reportcard'];
   prototype.PROTECT = true;
   prototype.name = 'dashboards';
-  prototype.dataDir = 'data/dashboards';
   function DashboardController(){
     superclass.apply(this, arguments);
   }
@@ -62,7 +61,7 @@ DashboardController = (function(superclass){
       return res.send({
         result: "error",
         message: "Dashboard '" + data.id + "' already exists!"
-      });
+      }, 409);
     } else {
       return fs.writeFile(file, JSON.stringify(data), "utf8", this.errorHandler(res, "Error writing Dashboard!"));
     }
@@ -89,7 +88,7 @@ DashboardController = (function(superclass){
         message: "Dashboard '" + id + "' is read-only."
       }, 403);
     }
-    return fs.unlink(this.toFile(id), this.errorHandler(res, "Dashboard '" + id + "' does not exist!"));
+    return fs.unlink(this.toFile(id), this.errorHandler(res, "Dashboard '" + id + "' does not exist!", 410));
   };
   return DashboardController;
 }(FileBackedController));
index 3373cfe..defd5be 100644 (file)
-var fs, path, exists, yaml, findit, Seq, Controller, EXT_PAT, YAML_EXT_PAT, YAML_OR_JSON_PAT, DataSourceController, exports, _;
+var fs, path, exists, Seq, glob, yaml, op, readFilesAsync, Controller, FileBackedController, EXT_PAT, YAML_EXT_PAT, YAML_OR_JSON_PAT, DataSourceController, exports, _ref, _;
 fs = require('fs');
 path = require('path');
-exists = path.existsSync;
-_ = require('underscore');
-yaml = require('js-yaml');
-findit = require('findit');
+exists = fs.existsSync || path.existsSync;
 Seq = require('seq');
+glob = require('glob');
+yaml = require('js-yaml');
+_ref = require('../../util'), _ = _ref._, op = _ref.op;
+readFilesAsync = require('../files').readFilesAsync;
 Controller = require('../controller');
+FileBackedController = require('../file-controller');
 EXT_PAT = /\.[^\.]*$/i;
 YAML_EXT_PAT = /\.ya?ml$/i;
 YAML_OR_JSON_PAT = /\.(json|ya?ml)$/i;
 /**
- * @class Resource controller for graph requests.
+ * @class Resource controller for datasource requests.
  */
 DataSourceController = (function(superclass){
   DataSourceController.displayName = 'DataSourceController';
   var prototype = __extend(DataSourceController, superclass).prototype, constructor = DataSourceController;
   prototype.name = 'datasources';
-  prototype.dataDir = 'data/datasources';
   prototype.mapping = {
     all: 'allData'
   };
   function DataSourceController(){
     superclass.apply(this, arguments);
   }
-  prototype.toFile = function(id){
-    return this.dataDir + "/" + id + ".json";
-  };
   /**
-   * Auto-load :id for related requests.
+   * GET /datasources/:datasource
    */
-  prototype.autoload = function(id, cb){
-    var files, pattern, file, parser;
-    files = findit.sync(this.dataDir);
-    pattern = new RegExp(id + ".(json|ya?ml)$", "i");
-    file = _.find(files, function(it){
-      return pattern.test(it);
-    });
-    if (!file) {
-      console.error("Unable to find DataSource for '" + id + "'!");
-      return cb(new Error("Unable to find DataSource for '" + id + "'!"));
-    }
-    if (_.endsWith(file, id + ".json")) {
-      parser = JSON.parse;
-    }
-    if (_.endsWith(file, id + ".yaml")) {
-      parser = yaml.load;
-    }
-    return fs.readFile(file, 'utf8', function(err, data){
-      if ('ENOENT' === (err != null ? err.code : void 8)) {
-        console.error("Unable to find DataSource for '" + id + "'!");
-        return cb(new Error("Unable to find DataSource for '" + id + "'!"));
-      }
-      if (err) {
-        console.error("DataSourceController.autoload(" + id + ", " + typeof cb + ") -->\n", err);
-        return cb(err);
-      }
-      try {
-        return cb(null, parser(data));
-      } catch (err) {
-        console.error("DataSourceController.autoload(" + id + ", " + typeof cb + ") -->\n", err);
-        return cb(err);
-      }
-    });
+  prototype.show = function(req, res){
+    return res.send(req.datasource);
   };
   /**
    * GET /datasources
    * @returns {Object} JSON listing of the datasource metadata files.
    */
   prototype.index = function(req, res, next){
-    var files;
-    files = findit.sync(this.dataDir);
-    return res.send(files.filter(function(it){
-      return YAML_OR_JSON_PAT.test(it);
-    }).map(function(it){
+    return Seq().seq(glob, this.dataDir + "/**/*.@(yaml|json)", {
+      nocase: true,
+      nosort: true
+    }, Seq).map(function(it){
       return (it + "").replace(YAML_EXT_PAT, '.json');
-    }));
-  };
-  /**
-   * GET /datasources/:datasource
-   */
-  prototype.show = function(req, res){
-    return res.send(req.datasource);
+    }).seq(function(it){
+      return res.send(it);
+    });
   };
   /**
    * Returns the aggregated JSON content of the datasource metadata files.
    */
   prototype.allData = function(req, res, next){
-    var data, files, _this = this;
+    var data;
     data = {};
-    files = [];
-    return Seq(findit.sync(this.dataDir)).filter(function(it){
-      return YAML_OR_JSON_PAT.test(it);
-    }).seq(function(){
-      files = this.stack.slice();
-      return this.ok(files);
-    }).flatten().parMap_(function(next, f){
-      return fs.readFile(f, 'utf8', next);
-    }).parMap(function(text, i){
-      var f, k, v, that;
-      f = files[i];
+    return Seq().seq(glob, this.dataDir + "/**/*.@(yaml|json)", {
+      nocase: true,
+      nosort: true
+    }, Seq).seq(function(paths){
+      return readFilesAsync(paths, this);
+    }).seq(function(txts){
+      return this.ok(_.items(txts));
+    }).flatten(false).parMap(function(_arg){
+      var f, text, k, v, that;
+      f = _arg[0], text = _arg[1];
       k = f.replace(YAML_EXT_PAT, '.json');
       v = data[k] = {};
       try {
@@ -110,7 +71,7 @@ DataSourceController = (function(superclass){
         }
         return this.ok(v);
       } catch (err) {
-        console.error("[/datasources] catch! " + err);
+        console.error("[/datasources] Error parsing data!");
         console.error(err);
         if (that = err.stack) {
           console.error(that);
@@ -118,13 +79,13 @@ DataSourceController = (function(superclass){
         return res.send({
           error: String(err),
           partial_data: data
-        });
+        }, 500);
       }
     }).seq(function(){
       return res.send(data);
     })['catch'](function(err){
       var that;
-      console.error('[/datasources] catch!');
+      console.error('[/datasources] Error!');
       console.error(err);
       if (that = err.stack) {
         console.error(that);
@@ -132,11 +93,11 @@ DataSourceController = (function(superclass){
       return res.send({
         error: String(err),
         partial_data: data
-      });
+      }, 500);
     });
   };
   return DataSourceController;
-}(Controller));
+}(FileBackedController));
 module.exports = exports = DataSourceController;
 function __extend(sub, sup){
   function fun(){} fun.prototype = (sub.superclass = sup).prototype;
index 13a89d2..53363cf 100644 (file)
@@ -1,13 +1,15 @@
-var fs, path, exists, Seq, yaml, mkdirp, mkdirpAsync, readJSONFilesAsync, Controller, GraphController, exports, _, _ref;
+var fs, path, exists, Seq, glob, yaml, op, mkdirp, mkdirpAsync, readFilesAsync, readJSONFilesAsync, Controller, FileBackedController, GraphController, exports, _ref, _;
 fs = require('fs');
 path = require('path');
-exists = path.existsSync;
-_ = require('underscore');
+exists = fs.existsSync || path.existsSync;
 Seq = require('seq');
+glob = require('glob');
 yaml = require('js-yaml');
+_ref = require('../../util'), _ = _ref._, op = _ref.op;
 _ref = require('../mkdirp'), mkdirp = _ref.mkdirp, mkdirpAsync = _ref.mkdirpAsync;
-readJSONFilesAsync = require('../files').readJSONFilesAsync;
+_ref = require('../files'), readFilesAsync = _ref.readFilesAsync, readJSONFilesAsync = _ref.readJSONFilesAsync;
 Controller = require('../controller');
+FileBackedController = require('../file-controller');
 /**
  * @class Resource controller for graph requests.
  */
@@ -17,50 +19,17 @@ GraphController = (function(superclass){
   prototype.PROTECTED_GRAPH_IDS = ['unique_visitors', 'pageviews', 'pageviews_mobile', 'reach', 'commons', 'articles', 'articles_per_day', 'edits', 'new_editors', 'active_editors', 'active_editors_target', 'very_active_editors'];
   prototype.PROTECT_GRAPHS = true;
   prototype.name = 'graphs';
-  prototype.dataDir = 'data/graphs';
   function GraphController(){
     superclass.apply(this, arguments);
   }
-  prototype.toFile = function(id){
+  prototype.toFileSimple = function(id){
     return this.dataDir + "/" + id + ".json";
   };
-  /**
-   * Auto-load :id for related requests.
-   */
-  prototype.autoload = function(id, cb){
-    var file, parser, yamlFile;
-    file = this.toFile(id);
-    parser = JSON.parse;
-    yamlFile = file.replace(/\.json$/i, '.yaml');
-    if (exists(yamlFile)) {
-      file = yamlFile;
-      parser = yaml.load;
-    }
-    return fs.readFile(file, 'utf8', function(err, data){
-      if ('ENOENT' === (err != null ? err.code : void 8)) {
-        return cb(null, {});
-      }
-      if (err) {
-        console.error("GraphController.autoload(" + id + ", " + typeof cb + ") -->\nerr");
-        return cb(err);
-      }
-      try {
-        return cb(null, parser(data));
-      } catch (err) {
-        console.error("GraphController.autoload(" + id + ", " + typeof cb + ") -->\nerr");
-        return cb(err);
-      }
-    });
-  };
   prototype.index = function(req, res){
-    var pattern;
     switch (req.format) {
     case 'json':
-      pattern = this.dataDir + "/*.json";
-      return Seq().seq(function(){
-        return readJSONFilesAsync(pattern, this);
-      }).seq(function(graphs){
-        return res.send(_.values(graphs));
+      return Seq().seq(readJSONFilesAsync, this.dataDir + "/**", Seq).seq(function(it){
+        return res.send(_.values(it));
       });
     default:
       return res.render('graph/index');
@@ -84,19 +53,18 @@ GraphController = (function(superclass){
     return res.render('graph/edit');
   };
   prototype.create = function(req, res){
-    var data, file;
+    var data;
     if (!(data = this.processBody(req, res))) {
       return;
     }
-    file = this.toFile(data.id);
-    if (exists(file)) {
+    return Seq().seq(this.findFile, data.id, Seq).seq(function(file){
       return res.send({
         result: "error",
         message: "Graph '" + data.id + "' already exists!"
-      });
-    } else {
-      return fs.writeFile(file, JSON.stringify(data), "utf8", this.errorHandler(res, "Error writing graph!"));
-    }
+      }, 409);
+    })['catch'](function(err){
+      return fs.writeFile(this.toFileSimple(data.id), JSON.stringify(data), "utf8", this.errorHandler(res, "Error writing graph!"));
+    });
   };
   prototype.update = function(req, res){
     var data;
@@ -109,7 +77,11 @@ GraphController = (function(superclass){
         message: "Graph '" + data.id + "' is read-only."
       }, 403);
     }
-    return fs.writeFile(this.toFile(data.id), JSON.stringify(data), "utf8", this.errorHandler(res, "Error writing graph!"));
+    return Seq().seq(this.findFile, data.id, function(err, file){
+      return this.ok(err ? this.toFileSimple(data.id) : file);
+    }).seq(function(file){
+      return fs.writeFile(file, JSON.stringify(data), "utf8", this.errorHandler(res, "Error writing graph!"));
+    });
   };
   prototype.destroy = function(req, res){
     var id;
@@ -120,7 +92,14 @@ GraphController = (function(superclass){
         message: "Graph '" + id + "' is read-only."
       }, 403);
     }
-    return fs.unlink(this.toFile(id), this.errorHandler(res, "Graph '" + id + "' does not exist!"));
+    return Seq().seq(this.findFile, data.id, Seq).seq(function(file){
+      return fs.unlink(file, this.errorHandler(res, "Error destroying Graph '" + id + "'!", 500));
+    })['catch'](function(err){
+      return res.send({
+        result: "error",
+        message: "Graph '" + id + "' does not exist!"
+      }, 410);
+    });
   };
   prototype.processBody = function(req, res){
     var data;
@@ -128,7 +107,7 @@ GraphController = (function(superclass){
       res.send({
         result: "error",
         message: "Data required!"
-      }, 501);
+      }, 400);
       return false;
     }
     data = req.body;
@@ -138,7 +117,7 @@ GraphController = (function(superclass){
       res.send({
         result: "error",
         message: "Slug required!"
-      }, 501);
+      }, 400);
       return false;
     }
     if (!exists(this.dataDir)) {
@@ -146,25 +125,8 @@ GraphController = (function(superclass){
     }
     return data;
   };
-  prototype.errorHandler = function(res, msg){
-    return function(err){
-      var msg;
-      if (err) {
-        msg || (msg = err.message || String(err));
-        console.error(msg);
-        return res.send({
-          result: "error",
-          message: msg
-        }, 501);
-      } else {
-        return res.send({
-          result: "ok"
-        });
-      }
-    };
-  };
   return GraphController;
-}(Controller));
+}(FileBackedController));
 module.exports = exports = GraphController;
 function __extend(sub, sup){
   function fun(){} fun.prototype = (sub.superclass = sup).prototype;
index 2704840..7a7bd0b 100644 (file)
@@ -1,9 +1,10 @@
-var fs, path, exists, Seq, yaml, mkdirp, mkdirpAsync, readJSONFilesAsync, Controller, FileBackedController, exports, _, _ref;
+var fs, path, exists, Seq, glob, yaml, mkdirp, mkdirpAsync, readJSONFilesAsync, Controller, FileBackedController, exports, _, _ref;
 fs = require('fs');
 path = require('path');
-exists = path.existsSync;
+exists = fs.existsSync || path.existsSync;
 _ = require('underscore');
 Seq = require('seq');
+glob = require('glob');
 yaml = require('js-yaml');
 _ref = require('./mkdirp'), mkdirp = _ref.mkdirp, mkdirpAsync = _ref.mkdirpAsync;
 readJSONFilesAsync = require('./files').readJSONFilesAsync;
@@ -16,48 +17,55 @@ FileBackedController = (function(superclass){
   var prototype = __extend(FileBackedController, superclass).prototype, constructor = FileBackedController;
   prototype.name = null;
   prototype.dataDir = null;
+  prototype.noun = null;
   function FileBackedController(){
-    this.dataDir || (this.dataDir = "data/" + this.name);
+    var limnOpts;
     superclass.apply(this, arguments);
+    limnOpts = this.app.set('limn options');
+    this.dataDir = limnOpts.dataDir + "/" + this.name;
+    this.noun == null && (this.noun = this.name.charAt(0).toUpperCase() + this.name.slice(1));
   }
   /**
-   * Override to customize lookup of files by ID.
-   * 
    * @param {String} id ID of this resource.
-   * @returns {String} Path to file for this resource.
+   * @returns {String} Glob path to file for this resource.
    */
   prototype.toFile = function(id){
-    return this.dataDir + "/" + id + ".json";
+    return this.dataDir + "/**/" + id + ".@(yaml|json)";
   };
   /**
-   * Auto-load :id for related requests.
+   * Finds the reified filepath for the resource `id`.
    * 
-   * @param {String} id ID of the resource.
-   * @param {Function} cb Callback to invoke with the loaded object.
+   * @param {String} id ID of this resource.
+   * @param {Function} cb Callback `(err, filepath)`.
    */
-  prototype.autoload = function(id, cb){
-    var file, parser, yamlFile;
-    file = this.toFile(id);
-    parser = JSON.parse;
-    yamlFile = file.replace(/\.json$/i, '.yaml');
-    if (exists(yamlFile)) {
-      file = yamlFile;
-      parser = yaml.load;
-    }
-    return fs.readFile(file, 'utf8', function(err, data){
-      if ('ENOENT' === (err != null ? err.code : void 8)) {
-        return cb(null, {});
-      }
+  prototype.findFile = function(id, cb){
+    return glob(this.toFile(id), {
+      nocase: true,
+      nosort: true
+    }, function(err, files){
       if (err) {
-        console.error(this + ".autoload(" + id + ", " + typeof cb + ") -->\nerr");
         return cb(err);
       }
-      try {
-        return cb(null, parser(data));
-      } catch (err) {
-        console.error(this + ".autoload(" + id + ", " + typeof cb + ") -->\nerr");
-        return cb(err);
+      if (!files.length) {
+        return cb('ENOENT');
       }
+      return cb(null, files[0]);
+    });
+  };
+  /**
+   * Auto-load :id for related requests by looking up the so-named file in the dataDir.
+   * 
+   * @param {String} id ID of the resource.
+   * @param {Function} cb Callback to invoke with the loaded object.
+   */
+  prototype.autoload = function(id, cb){
+    return Seq().seq(readJSONFilesAsync, this.toFile(id), {
+      yaml: true,
+      appendExt: false
+    }, Seq).seq(function(data){
+      return cb(null, _.values(data)[0]);
+    })['catch'](function(err){
+      return cb(err);
     });
   };
   prototype.processBody = function(req, res){
@@ -66,7 +74,7 @@ FileBackedController = (function(superclass){
       res.send({
         result: "error",
         message: "Data required!"
-      }, 501);
+      }, 400);
       return false;
     }
     data = req.body;
@@ -76,7 +84,7 @@ FileBackedController = (function(superclass){
       res.send({
         result: "error",
         message: "Slug required!"
-      }, 501);
+      }, 400);
       return false;
     }
     if (!exists(this.dataDir)) {
@@ -84,23 +92,6 @@ FileBackedController = (function(superclass){
     }
     return data;
   };
-  prototype.errorHandler = function(res, msg){
-    return function(err){
-      var msg;
-      if (err) {
-        msg || (msg = err.message || String(err));
-        console.error(msg);
-        return res.send({
-          result: "error",
-          message: msg
-        }, 501);
-      } else {
-        return res.send({
-          result: "ok"
-        });
-      }
-    };
-  };
   return FileBackedController;
 }(Controller));
 module.exports = exports = FileBackedController;
index f6b2cb5..766e9c9 100644 (file)
@@ -1,27 +1,37 @@
 /**
  * @fileOverview Filesystem utilities.
  */
-var fs, path, Seq, glob, readFilesAsync, readJSONFilesAsync, logErrorsAnd, files, u, paths, _, __slice = [].slice;
+var fs, path, exists, Seq, glob, yaml, readFilesAsync, readJSONFilesAsync, logErrorsAnd, files, u, paths, _, __slice = [].slice;
 fs = require('fs');
 path = require('path');
+exists = fs.existsSync || path.existsSync;
 _ = require('underscore');
 Seq = require('seq');
 glob = require('glob');
+yaml = require('js-yaml');
 /**
  * Asynchronously reads the text for each filepath produced by the
  * globs supplied, returning a map from filepath to contents.
  * 
  * @param {String|Array<String>} patterns List of file-paths and/or glob-patterns to read.
+ * @param {Object} [opts={}] Options:
+ * @param {Boolean} [opts.verbose=false] Be chatty about errors.
  * @param {Function} cb Callback taking `(error, data)` where `data` is a map
  *  from filepath to contents. As always, `error` will be null on success.
  * @returns {Seq} The Seq object representing the async operation chain. (You
  *  can usually ignore this.)
  */
-readFilesAsync = exports.readFilesAsync = function(patterns, cb){
-  var files, data;
+readFilesAsync = exports.readFilesAsync = function(patterns, opts, cb){
+  var files, data, _ref;
   if (typeof patterns === 'string') {
     patterns = [patterns];
   }
+  if (typeof opts === 'function') {
+    _ref = [opts, {}], cb = _ref[0], opts = _ref[1];
+  }
+  opts = (__import({
+    verbose: false
+  }, opts || {}));
   files = [];
   data = {};
   return Seq(patterns).parMap(function(pat){
@@ -49,25 +59,50 @@ readFilesAsync = exports.readFilesAsync = function(patterns, cb){
  * globs supplied, returning a map from filepath to contents.
  * 
  * @param {String|Array<String>} patterns List of filepaths and/or glob-patterns to read.
+ * @param {Object} [opts={}] Options:
+ * @param {Boolean} [opts.verbose=false] Be chatty about errors.
+ * @param {Boolean} [opts.yaml=false] Also search for and include YAML files.
+ * @param {Boolean} [opts.appendExt=true] Treat the patterns as directories, and append
+ *  the appropriate file extension glob-patterns.
  * @param {Function} cb Callback taking `(error, data)` where `data` is a map
  *  from filepath to contents. As always, `error` will be null on success.
  * @returns {Seq} The Seq object representing the async operation chain. (You
  *  can usually ignore this.)
  */
-readJSONFilesAsync = exports.readJSONFilesAsync = function(patterns, cb){
-  var data;
+readJSONFilesAsync = exports.readJSONFilesAsync = function(patterns, opts, cb){
+  var data, ext, _ref;
+  if (typeof patterns === 'string') {
+    patterns = [patterns];
+  }
+  if (typeof opts === 'function') {
+    _ref = [opts, {}], cb = _ref[0], opts = _ref[1];
+  }
+  opts = (__import({
+    yaml: false,
+    appendExt: true,
+    verbose: false
+  }, opts || {}));
   data = {};
-  return Seq().seq(function(){
-    return readFilesAsync(patterns, this);
-  }).seq(function(data){
+  if (opts.appendExt) {
+    ext = opts.yaml ? '@(yaml|json)' : 'json';
+    patterns = patterns.map(function(it){
+      return path.join(it, "*." + ext);
+    });
+  }
+  return Seq().seq(readFilesAsync, patterns, {
+    verbose: opts.verbose
+  }, Seq).seq(function(data){
     return this.ok(_.map(data, function(text, f){
       return [f, text];
     }));
   }).flatten(false).parMap(function(_arg){
-    var f, text;
+    var f, text, parser;
     f = _arg[0], text = _arg[1];
+    parser = /\.yaml$/i.test(f)
+      ? yaml.load
+      : JSON.parse;
     try {
-      data[f] = JSON.parse(text);
+      data[f] = parser(text);
       return this.ok();
     } catch (err) {
       err.file = f;
@@ -97,7 +132,7 @@ logErrorsAnd = exports.logErrorsAnd = function(cb){
 };
 if (require.main === module) {
   files = exports;
-  u = require('kraken/util/underscore');
+  u = require('limn/util/underscore');
   paths = ['package.*', 'deploy.sh'];
   files.readFilesAsync(paths, function(err, data){
     if (err) {
@@ -108,4 +143,9 @@ if (require.main === module) {
       }));
     }
   });
+}
+function __import(obj, src){
+  var own = {}.hasOwnProperty;
+  for (var key in src) if (own.call(src, key)) obj[key] = src[key];
+  return obj;
 }
\ No newline at end of file
index dcb72af..4b979ae 100644 (file)
@@ -1,10 +1,11 @@
-var exists, fs, dirname, path, exec, spawn, subproc, glob, yaml, Seq, express, op, mkdirp, mkdirpAsync, readFilesAsync, Controller, BASE, DATA, LIB, SRC, STATIC, VAR, WWW, NODE_ENV, IS_DEV, IS_PROD, LOG_LEVEL, REV, DEFAULT_OPTIONS, exports, application, _ref, _;
-fs = (_ref = require('fs'), exists = _ref.existsSync, _ref);
+var fs, dirname, path, exec, spawn, subproc, exists, Seq, glob, yaml, express, op, mkdirp, mkdirpAsync, readFilesAsync, Controller, BASE, LIB, SRC, STATIC, WWW, NODE_ENV, IS_DEV, IS_PROD, LOG_LEVEL, REV, DEFAULT_OPTIONS, exports, application, _ref, _;
+fs = require('fs');
 path = (_ref = require('path'), dirname = _ref.dirname, _ref);
 subproc = (_ref = require('child_process'), exec = _ref.exec, spawn = _ref.spawn, _ref);
+exists = fs.existsSync || path.existsSync;
+Seq = require('seq');
 glob = require('glob');
 yaml = require('js-yaml');
-Seq = require('seq');
 express = require('express');
 _ref = require('../util'), _ = _ref._, op = _ref.op;
 _ref = require('./mkdirp'), mkdirp = _ref.mkdirp, mkdirpAsync = _ref.mkdirpAsync;
@@ -14,29 +15,76 @@ Controller = require('./controller');
  * Limn project-internals
  */
 BASE = dirname(dirname(__dirname));
-DATA = BASE + "/data";
-LIB = BASE + "/llb";
+LIB = BASE + "/lib";
 SRC = BASE + "/src";
 STATIC = BASE + "/static";
-VAR = BASE + "/var";
 WWW = BASE + "/www";
 NODE_ENV = process.env.NODE_ENV || 'development';
 IS_DEV = NODE_ENV === 'development';
 IS_PROD = NODE_ENV === 'production';
-LOG_LEVEL = process.env.KRAKEN_LOG_LEVEL;
+LOG_LEVEL = process.env.LIMN_LOG_LEVEL;
 LOG_LEVEL || (LOG_LEVEL = IS_DEV ? 'INFO' : 'WARN');
 LOG_LEVEL = LOG_LEVEL.toUpperCase();
-REV = process.env.KRAKEN_REV || 'HEAD';
+REV = process.env.LIMN_REV || 'HEAD';
 try {
   REV = require('../version');
 } catch (e) {}
+/**
+ * Limn option defaults.
+ */
 DEFAULT_OPTIONS = {
-  dataDir: './data',
+  /**
+   * @name dataDir
+   * @type String
+   * Path to directory where data and metadata files are stored.
+   */
+  dataDir: './data'
+  /**
+   * @name varDir
+   * @type String
+   * Path to directory where derived files are written while in dev-mode.
+   */,
+  varDir: './var'
+  /**
+   * @name proxy
+   * @type Object
+   */,
   proxy: {
-    enabled: false,
-    whitelist: null,
+    /**
+     * @name enabled
+     * @type Boolean
+     * Enables remote dataset proxy. If omitted, the proxy will be enabled
+     * if either `proxy.whitelist` or `proxy.blacklist` are set.
+     */
+    enabled: false
+    /**
+     * @name whitelist
+     * @type Array<String|RegExp>
+     * Array of domain patterns to whitelist for proxy. Strings are matched
+     * via glob syntax, but regular expressions may also be passed. 
+     * If `proxy.enabled` is true but no whitelist is provided, it defaults to `['*']`.
+     */,
+    whitelist: null
+    /**
+     * @name blacklist
+     * @type Array<String|RegExp>
+     * Array of domain patterns to blacklist from proxying. Strings are matched
+     * via glob syntax, but regular expressions may also be passed.
+     */,
     blacklist: null
   }
+  /**
+   * @name staticMaxAge
+   * @type Object
+   * Max-Age of static files served by Limn. Object is a hash from NODE_ENV to
+   * expiry time in miliseconds, with a special key "default" that does what you
+   * expect.
+   */,
+  staticMaxAge: {
+    'default': 0,
+    development: 0,
+    production: 108000000
+  }
 };
 exports = module.exports = limn;
 /**
@@ -47,16 +95,20 @@ function limn(options){
   var app;
   app = express.createServer();
   app = _.extend(app, application);
-  app.init();
+  app.init(options);
   return app;
 }
+/**
+ * Application pseudo-prototype (as we don't actually inherit from the Express server).
+ */
 application = limn.application = {
   /**
    * @constructor
    */
   init: function(opts){
-    var opx, YAML_EXT_PAT, proxy;
+    var app, opx, YAML_EXT_PAT, proxy;
     opts == null && (opts = {});
+    app = this;
     this.REV = REV;
     this.BASE = BASE;
     opts = _.merge({}, DEFAULT_OPTIONS, opts);
@@ -69,6 +121,7 @@ application = limn.application = {
       opx.blacklist || (opx.blacklist = []);
     }
     this.set('limn options', opts);
+    mkdirp(opts.dataDir);
     this.configure(function(){
       this.set('views', WWW);
       this.set('view engine', 'jade');
@@ -81,36 +134,36 @@ application = limn.application = {
       this.use(require('./reqinfo')({}));
       this.use(express.bodyParser());
       this.use(express.methodOverride());
-      this.use(this.router);
-      return this.use(require('browserify')({
-        mount: '/vendor/browserify.js',
-        require: ['seq', 'd3', 'events'],
-        cache: BASE + "/.cache/browserify/cache.json"
-      }));
+      return this.use(this.router);
     });
     this.configure('production', function(){
       this.use(express.logger());
-      this.set('static max age', 108000000);
       return this.use(express.errorHandler());
     });
     this.configure('development', function(){
-      var compiler;
+      var varDir, dataDir, opts, compiler, _ref;
+      opts = (_ref = this.set('limn options'), varDir = _ref.varDir, dataDir = _ref.dataDir, _ref);
       this.use(express.errorHandler({
         dumpExceptions: true,
         showStack: true
       }));
       this.set('view options').pretty = true;
+      this.use(require('browserify')({
+        mount: '/vendor/browserify.js',
+        require: ['seq', 'd3', 'events'],
+        cache: varDir + "/.cache/browserify/cache.json"
+      }));
       compiler = require('connect-compiler-extras');
-      this.use('/js/kraken', compiler({
+      this.use('/js/limn', compiler({
         enabled: 'coco',
         src: SRC,
-        dest: VAR + "/js/kraken",
+        dest: varDir + "/js/limn",
         log_level: LOG_LEVEL
       }));
       this.use(compiler({
         enabled: ['jade-browser', 'stylus', 'yaml'],
         src: WWW,
-        dest: VAR,
+        dest: varDir,
         options: {
           stylus: {
             nib: true,
@@ -121,16 +174,16 @@ application = limn.application = {
       }));
       this.use(compiler({
         enabled: 'yaml',
-        src: DATA,
-        dest: VAR + "/data",
+        src: dataDir,
+        dest: varDir + "/data",
         log_level: LOG_LEVEL
       }));
       this.use(compiler({
-        enabled: 'commonjs_define',
+        enabled: ['amd', 'commonjs_define'],
         src: [STATIC],
-        dest: VAR,
+        dest: varDir,
         options: {
-          commonjs: {
+          amd: {
             drop_path_parts: 1,
             drop_full_ext: false
           },
@@ -142,11 +195,11 @@ application = limn.application = {
         log_level: LOG_LEVEL
       }));
       return this.use(compiler({
-        enabled: 'commonjs_define',
-        src: [VAR, WWW],
-        dest: VAR,
+        enabled: ['amd', 'commonjs_define'],
+        src: [varDir, WWW],
+        dest: varDir,
         options: {
-          commonjs: {
+          amd: {
             drop_path_parts: 1,
             drop_full_ext: true
           },
@@ -159,19 +212,29 @@ application = limn.application = {
       }));
     });
     this.configure(function(){
-      var opts;
-      opts = this.set('static file options') || {};
-      this.use(express['static'](VAR, __clone(opts)));
-      this.use(express['static'](WWW, __clone(opts)));
-      return this.use(express['static'](STATIC, __clone(opts)));
+      var varDir, staticMaxAge, maxAge, _ref;
+      _ref = this.set('limn options'), varDir = _ref.varDir, staticMaxAge = _ref.staticMaxAge;
+      maxAge = (_ref = staticMaxAge[NODE_ENV]) != null
+        ? _ref
+        : staticMaxAge['default'];
+      this.use(express['static'](varDir, {
+        maxAge: maxAge
+      }));
+      this.use(express['static'](WWW, {
+        maxAge: maxAge
+      }));
+      return this.use(express['static'](STATIC, {
+        maxAge: maxAge
+      }));
     });
     this.controller(require('./controllers/graph'));
     this.controller(require('./controllers/dashboard'));
     YAML_EXT_PAT = /\.ya?ml$/i;
     this.get('/datasources/all', function(req, res, next){
-      var data;
+      var varDir, dataDir, opts, data, _ref;
+      opts = (_ref = app.set('limn options'), varDir = _ref.varDir, dataDir = _ref.dataDir, _ref);
       data = {};
-      return Seq().seq(glob, 'data/datasources/**/*.@(yaml|json)', {
+      return Seq().seq(glob, dataDir + "/datasources/**/*.@(yaml|json)", {
         nocase: true,
         nosort: true
       }, Seq).seq(function(paths){
@@ -191,7 +254,7 @@ application = limn.application = {
           }
           return this.ok(v);
         } catch (err) {
-          console.error("[/data/all] catch! " + err);
+          console.error("[/datasources/all] Error parsing data!");
           console.error(err);
           if (that = err.stack) {
             console.error(that);
@@ -199,13 +262,13 @@ application = limn.application = {
           return res.send({
             error: String(err),
             partial_data: data
-          });
+          }, 500);
         }
       }).seq(function(){
         return res.send(data);
       })['catch'](function(err){
         var that;
-        console.error('[/data/all] catch!');
+        console.error('[/datasources/all] Error!');
         console.error(err);
         if (that = err.stack) {
           console.error(that);
@@ -213,15 +276,12 @@ application = limn.application = {
         return res.send({
           error: String(err),
           partial_data: data
-        });
+        }, 500);
       });
     });
     this.controller(require('./controllers/datasource'));
     if (opts.proxy.enabled) {
-      proxy = require('./proxy')({
-        blacklist: opts.proxy.blacklist,
-        whitelist: opts.proxy.whitelist
-      });
+      proxy = require('./proxy')(opts.proxy);
       this.get('/x', proxy);
       this.get('/x/*', proxy);
     }
@@ -256,8 +316,4 @@ function __import(obj, src){
   var own = {}.hasOwnProperty;
   for (var key in src) if (own.call(src, key)) obj[key] = src[key];
   return obj;
-}
-function __clone(it){
-  function fun(){} fun.prototype = it;
-  return new fun;
 }
\ No newline at end of file
index 5accd9a..a407138 100644 (file)
@@ -1,5 +1,4 @@
-var url, minimatch, request, matchesList, ProxyMiddleware, exports, _;
-_ = require('underscore');
+var url, minimatch, request, matchesList, ProxyMiddleware, exports;
 url = require('url');
 minimatch = require('minimatch');
 request = require('request');
@@ -16,15 +15,22 @@ matchesList = function(list, value){
 ProxyMiddleware = function(options){
   var whitelist, blacklist, _ref;
   options == null && (options = {});
-  _ref = options = (__import({
+  options = (_ref = (__import({
+    verbose: false,
     whitelist: [],
     blacklist: []
-  }, options)), whitelist = _ref.whitelist, blacklist = _ref.blacklist;
+  }, options)), whitelist = _ref.whitelist, blacklist = _ref.blacklist, _ref);
+  if (!Array.isArray(whitelist)) {
+    whitelist = [whitelist];
+  }
   whitelist = whitelist.map(function(it){
     return minimatch.filter(it, {
       nocase: true
     });
   });
+  if (!Array.isArray(blacklist)) {
+    blacklist = [blacklist];
+  }
   blacklist = blacklist.map(function(it){
     return minimatch.filter(it, {
       nocase: true
@@ -53,7 +59,9 @@ ProxyMiddleware = function(options){
       }, 403);
     }
     res.header('X-Accel-Buffering', 'no');
-    console.log("[Proxy] " + targetUrl);
+    if (options.verbose) {
+      console.log("[Proxy] " + targetUrl);
+    }
     return request.get(targetUrl).pipe(res);
   };
 };
index 79bf110..19bd503 100644 (file)
@@ -1,12 +1,26 @@
-var fs, path, exec, spawn, exists, express, LimnMiddleware, exports, app, limn, mainfile, PORT, that, NODE_ENV, REV, _ref;
+var fs, dirname, path, exec, spawn, subproc, exists, express, LimnMiddleware, exports, app, limn, mainfile, PORT, that, NODE_ENV, REV, _ref;
 fs = require('fs');
-path = require('path');
-_ref = require('child_process'), exec = _ref.exec, spawn = _ref.spawn;
+path = (_ref = require('path'), dirname = _ref.dirname, _ref);
+subproc = (_ref = require('child_process'), exec = _ref.exec, spawn = _ref.spawn, _ref);
 exists = fs.existsSync || path.existsSync;
 express = require('express');
 LimnMiddleware = require('./middleware');
+/**
+ * Create server
+ */
 app = exports = module.exports = express.createServer();
 /**
+ * Load Limn middleware
+ */
+app.use(limn = app.limn = LimnMiddleware({
+  varDir: './var',
+  dataDir: './var/data',
+  proxy: {
+    enabled: true,
+    whitelist: /.*/
+  }
+}));
+/**
  * Handle webhook notification to pull from origin.
  */
 app.all('/webhook/post-update', function(req, res){
@@ -25,18 +39,14 @@ app.all('/webhook/post-update', function(req, res){
     }
   });
 });
-/**
- * Load Limn middleware
- */
-app.use(limn = app.limn = LimnMiddleware());
 mainfile = path.basename((_ref = require.main) != null ? _ref.filename : void 8);
 if (require.main === module || 'Cokefile' === mainfile) {
   PORT = 8081;
-  if (that = process.env.KRAKEN_PORT) {
+  if (that = process.env.LIMN_PORT) {
     PORT = parseInt(that, 10);
   }
   NODE_ENV = process.env.NODE_ENV || 'development';
-  REV = process.env.KRAKEN_REV || 'HEAD';
+  REV = process.env.LIMN_REV || 'HEAD';
   try {
     REV = require('../version');
   } catch (e) {}
@@ -51,7 +61,7 @@ if (require.main === module || 'Cokefile' === mainfile) {
     if (!REV) {
       REV = stdout.trim();
     }
-    console.log(s = "Kraken Server (port=" + PORT + ", env=" + NODE_ENV + ", rev=" + REV + ", base_dir=" + limn.BASE + ")");
+    console.log(s = "Limn Server (port=" + PORT + ", env=" + NODE_ENV + ", rev=" + REV + ")");
     console.log(__repeatString('=', s.length));
     return app.listen(PORT);
   });
index ed94c9a..13a4874 100644 (file)
@@ -20,7 +20,7 @@ NODE_ENV = exports.NODE_ENV = (process.env.NODE_ENV || 'development').toLowerCas
 IS_PROD = exports.IS_PROD = NODE_ENV === 'production';
 IS_TEST = exports.IS_TEST = NODE_ENV === 'test';
 IS_DEV = exports.IS_DEV = !(IS_PROD || IS_TEST);
-SOURCES_ENV = process.env.KRAKEN_FORCE_BUNDLES ? 'production' : NODE_ENV;
+SOURCES_ENV = process.env.LIMN_FORCE_BUNDLES ? 'production' : NODE_ENV;
 /**
  * Reify a modules.yaml file
  */
index 7d3f16d..9e0d4f1 100644 (file)
@@ -1,4 +1,4 @@
-require.define('/node_modules/kraken/template/chart/chart-option.jade.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/template/chart/chart-option.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var template = function (locals, attrs, escape, rethrow) {
 var attrs = jade.attrs, escape = jade.escape, rethrow = jade.rethrow;
index abf742f..8c83172 100644 (file)
@@ -1,4 +1,4 @@
-require.define('/node_modules/kraken/template/chart/chart-scaffold.jade.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/template/chart/chart-scaffold.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var template = function (locals, attrs, escape, rethrow) {
 var attrs = jade.attrs, escape = jade.escape, rethrow = jade.rethrow;
index 36f1df7..1980050 100644 (file)
@@ -1,4 +1,4 @@
-require.define('/node_modules/kraken/template/dashboard/dashboard-tab.jade.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/template/dashboard/dashboard-tab.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var template = function (locals, attrs, escape, rethrow) {
 var attrs = jade.attrs, escape = jade.escape, rethrow = jade.rethrow;
index 0e58d87..9257ed9 100644 (file)
@@ -1,4 +1,4 @@
-require.define('/node_modules/kraken/template/dashboard/dashboard.jade.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/template/dashboard/dashboard.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var template = function (locals, attrs, escape, rethrow) {
 var attrs = jade.attrs, escape = jade.escape, rethrow = jade.rethrow;
index b15812d..9501178 100644 (file)
@@ -1,4 +1,4 @@
-require.define('/node_modules/kraken/template/data/data.jade.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/template/data/data.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var template = function (locals, attrs, escape, rethrow) {
 var attrs = jade.attrs, escape = jade.escape, rethrow = jade.rethrow;
index e36e2c5..f271c3f 100644 (file)
@@ -1,4 +1,4 @@
-require.define('/node_modules/kraken/template/data/dataset-metric.jade.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/template/data/dataset-metric.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var template = function (locals, attrs, escape, rethrow) {
 var attrs = jade.attrs, escape = jade.escape, rethrow = jade.rethrow;
index ff5a992..a342862 100644 (file)
@@ -1,4 +1,4 @@
-require.define('/node_modules/kraken/template/data/dataset.jade.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/template/data/dataset.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var template = function (locals, attrs, escape, rethrow) {
 var attrs = jade.attrs, escape = jade.escape, rethrow = jade.rethrow;
index a8c8180..62eb3ab 100644 (file)
@@ -17,9 +17,9 @@ buf.push('></i>\n      <ul');
 buf.push(attrs({ "class": ('breadcrumb') }));
 buf.push('>\n        <li>' + escape((interp = source_summary) == null ? '' : interp) + ' <span');
 buf.push(attrs({ "class": ('divider') }));
-buf.push('>\/</span>\n        </li>\n        <li>' + escape((interp = metric_summary) == null ? '' : interp) + ' <span');
+buf.push('>/</span>\n        </li>\n        <li>' + escape((interp = metric_summary) == null ? '' : interp) + ' <span');
 buf.push(attrs({ "class": ('divider') }));
-buf.push('>\/</span>\n        </li>\n        <li>' + escape((interp = timespan_summary) == null ? '' : interp) + '\n        </li>\n      </ul>\n    </section>\n    <section');
+buf.push('>/</span>\n        </li>\n        <li>' + escape((interp = timespan_summary) == null ? '' : interp) + '\n        </li>\n      </ul>\n    </section>\n    <section');
 buf.push(attrs({ "class": ('datasource-selector') + ' ' + ('collapse') }));
 buf.push('>\n      <div');
 buf.push(attrs({ "class": ('datasource-tabs') }));
index b25e11e..46fb8b8 100644 (file)
@@ -1,4 +1,4 @@
-require.define('/node_modules/kraken/template/data/datasource-ui.jade.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/template/data/datasource-ui.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var template = function (locals, attrs, escape, rethrow) {
 var attrs = jade.attrs, escape = jade.escape, rethrow = jade.rethrow;
@@ -19,9 +19,9 @@ buf.push('></i>\n      <ul');
 buf.push(attrs({ "class": ('breadcrumb') }));
 buf.push('>\n        <li>' + escape((interp = source_summary) == null ? '' : interp) + ' <span');
 buf.push(attrs({ "class": ('divider') }));
-buf.push('>\/</span>\n        </li>\n        <li>' + escape((interp = metric_summary) == null ? '' : interp) + ' <span');
+buf.push('>/</span>\n        </li>\n        <li>' + escape((interp = metric_summary) == null ? '' : interp) + ' <span');
 buf.push(attrs({ "class": ('divider') }));
-buf.push('>\/</span>\n        </li>\n        <li>' + escape((interp = timespan_summary) == null ? '' : interp) + '\n        </li>\n      </ul>\n    </section>\n    <section');
+buf.push('>/</span>\n        </li>\n        <li>' + escape((interp = timespan_summary) == null ? '' : interp) + '\n        </li>\n      </ul>\n    </section>\n    <section');
 buf.push(attrs({ "class": ('datasource-selector') + ' ' + ('collapse') }));
 buf.push('>\n      <div');
 buf.push(attrs({ "class": ('datasource-tabs') }));
index 9f14057..91f8356 100644 (file)
@@ -1,4 +1,4 @@
-require.define('/node_modules/kraken/template/data/datasource.jade.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/template/data/datasource.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var template = function (locals, attrs, escape, rethrow) {
 var attrs = jade.attrs, escape = jade.escape, rethrow = jade.rethrow;
index 95fe254..d056a49 100644 (file)
@@ -1,4 +1,4 @@
-require.define('/node_modules/kraken/template/data/metric-edit.jade.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/template/data/metric-edit.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var template = function (locals, attrs, escape, rethrow) {
 var attrs = jade.attrs, escape = jade.escape, rethrow = jade.rethrow;
index baa4084..798b494 100644 (file)
@@ -1,4 +1,4 @@
-require.define('/node_modules/kraken/template/graph/graph-display.jade.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/template/graph/graph-display.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var template = function (locals, attrs, escape, rethrow) {
 var attrs = jade.attrs, escape = jade.escape, rethrow = jade.rethrow;
index 7b13171..675712a 100644 (file)
@@ -79,19 +79,19 @@ buf.push(attrs({ 'for':("" + (graph_id) + "_slug"), "class": ('slug') + ' ' + ('
 buf.push('>Slug\n                  </label>\n                  <div');
 buf.push(attrs({ "class": ('controls') }));
 buf.push('>\n                    <input');
-buf.push(attrs({ 'type':('text'), 'id':("" + (graph_id) + "_slug"), 'name':('slug'), 'placeholder':('graph_slug'), 'value':(slug), "class": ('span3') + ' ' + ('slug') }));
+buf.push(attrs({ 'type':('text'), 'id':("" + (graph_id) + "_slug"), 'name':('slug'), 'placeholder':('graph_slug'), 'value':(slug), "class": ('span11') + ' ' + ('slug') }));
 buf.push('/>\n                    <p');
 buf.push(attrs({ "class": ('help-block') }));
 buf.push('>The slug uniquely identifies this graph and will be displayed in the URL once saved.\n                    </p>\n                  </div>\n                </div>\n                <div');
-buf.push(attrs({ "class": ('control-group') }));
+buf.push(attrs({ "class": ('graph-size-row') + ' ' + ('control-group') }));
 buf.push('>\n                  <label');
 buf.push(attrs({ 'for':("" + (graph_id) + "_width"), "class": ('width') + ' ' + ('control-label') }));
 buf.push('>Size\n                  </label>\n                  <div');
 buf.push(attrs({ "class": ('controls') }));
 buf.push('>\n                    <input');
-buf.push(attrs({ 'type':('text'), 'id':("" + (graph_id) + "_width"), 'name':('width'), 'value':(width), "class": ('span1') + ' ' + ('width') }));
+buf.push(attrs({ 'type':('text'), 'id':("" + (graph_id) + "_width"), 'name':('width'), 'value':(width), "class": ('span3') + ' ' + ('width') }));
 buf.push('/> &times; \n\n                    <input');
-buf.push(attrs({ 'type':('text'), 'id':("" + (graph_id) + "_height"), 'name':('height'), 'value':(height), "class": ('span1') + ' ' + ('height') }));
+buf.push(attrs({ 'type':('text'), 'id':("" + (graph_id) + "_height"), 'name':('height'), 'value':(height), "class": ('span3') + ' ' + ('height') }));
 buf.push('/>\n                    <p');
 buf.push(attrs({ "class": ('help-block') }));
 buf.push('>Choosing \'auto\' will size the graph to the viewport bounds.\n                    </p>\n                  </div>\n                </div>\n              </div>\n              <div');
@@ -100,7 +100,7 @@ buf.push('>\n                <label');
 buf.push(attrs({ 'for':("" + (graph_id) + "_desc"), "class": ('desc') + ' ' + ('control-label') }));
 buf.push('>Description\n                </label>\n                <div');
 buf.push(attrs({ "class": ('controls') }));
-buf.push('><textarea class="span3 desc" id="' + escape((interp = graph_id) == null ? '' : interp) + '_desc" name="desc" placeholder="Graph description.">' + escape((interp = desc) == null ? '' : interp) + '</textarea>\n\n                  <p');
+buf.push('><textarea class="span11 desc" id="' + escape((interp = graph_id) == null ? '' : interp) + '_desc" rows="4" name="desc" placeholder="Graph description.">' + escape((interp = desc) == null ? '' : interp) + '</textarea>\n\n                  <p');
 buf.push(attrs({ "class": ('help-block') }));
 buf.push('>A description of the graph.\n                  </p>\n                </div>\n              </div>\n            </div>\n          </form>\n        </div>\n        <div');
 buf.push(attrs({ 'id':("" + (graph_id) + "-tab-data"), 'data-subview':("DataView"), "class": ('graph-data-pane') + ' ' + ('tab-pane') }));
index ce48362..6169284 100644 (file)
@@ -1,4 +1,4 @@
-require.define('/node_modules/kraken/template/graph/graph-edit.jade.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/template/graph/graph-edit.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var template = function (locals, attrs, escape, rethrow) {
 var attrs = jade.attrs, escape = jade.escape, rethrow = jade.rethrow;
@@ -81,19 +81,19 @@ buf.push(attrs({ 'for':("" + (graph_id) + "_slug"), "class": ('slug') + ' ' + ('
 buf.push('>Slug\n                  </label>\n                  <div');
 buf.push(attrs({ "class": ('controls') }));
 buf.push('>\n                    <input');
-buf.push(attrs({ 'type':('text'), 'id':("" + (graph_id) + "_slug"), 'name':('slug'), 'placeholder':('graph_slug'), 'value':(slug), "class": ('span3') + ' ' + ('slug') }));
+buf.push(attrs({ 'type':('text'), 'id':("" + (graph_id) + "_slug"), 'name':('slug'), 'placeholder':('graph_slug'), 'value':(slug), "class": ('span11') + ' ' + ('slug') }));
 buf.push('/>\n                    <p');
 buf.push(attrs({ "class": ('help-block') }));
 buf.push('>The slug uniquely identifies this graph and will be displayed in the URL once saved.\n                    </p>\n                  </div>\n                </div>\n                <div');
-buf.push(attrs({ "class": ('control-group') }));
+buf.push(attrs({ "class": ('graph-size-row') + ' ' + ('control-group') }));
 buf.push('>\n                  <label');
 buf.push(attrs({ 'for':("" + (graph_id) + "_width"), "class": ('width') + ' ' + ('control-label') }));
 buf.push('>Size\n                  </label>\n                  <div');
 buf.push(attrs({ "class": ('controls') }));
 buf.push('>\n                    <input');
-buf.push(attrs({ 'type':('text'), 'id':("" + (graph_id) + "_width"), 'name':('width'), 'value':(width), "class": ('span1') + ' ' + ('width') }));
+buf.push(attrs({ 'type':('text'), 'id':("" + (graph_id) + "_width"), 'name':('width'), 'value':(width), "class": ('span3') + ' ' + ('width') }));
 buf.push('/> &times; \n\n                    <input');
-buf.push(attrs({ 'type':('text'), 'id':("" + (graph_id) + "_height"), 'name':('height'), 'value':(height), "class": ('span1') + ' ' + ('height') }));
+buf.push(attrs({ 'type':('text'), 'id':("" + (graph_id) + "_height"), 'name':('height'), 'value':(height), "class": ('span3') + ' ' + ('height') }));
 buf.push('/>\n                    <p');
 buf.push(attrs({ "class": ('help-block') }));
 buf.push('>Choosing \'auto\' will size the graph to the viewport bounds.\n                    </p>\n                  </div>\n                </div>\n              </div>\n              <div');
@@ -102,7 +102,7 @@ buf.push('>\n                <label');
 buf.push(attrs({ 'for':("" + (graph_id) + "_desc"), "class": ('desc') + ' ' + ('control-label') }));
 buf.push('>Description\n                </label>\n                <div');
 buf.push(attrs({ "class": ('controls') }));
-buf.push('><textarea class="span3 desc" id="' + escape((interp = graph_id) == null ? '' : interp) + '_desc" name="desc" placeholder="Graph description.">' + escape((interp = desc) == null ? '' : interp) + '</textarea>\n\n                  <p');
+buf.push('><textarea class="span11 desc" id="' + escape((interp = graph_id) == null ? '' : interp) + '_desc" rows="4" name="desc" placeholder="Graph description.">' + escape((interp = desc) == null ? '' : interp) + '</textarea>\n\n                  <p');
 buf.push(attrs({ "class": ('help-block') }));
 buf.push('>A description of the graph.\n                  </p>\n                </div>\n              </div>\n            </div>\n          </form>\n        </div>\n        <div');
 buf.push(attrs({ 'id':("" + (graph_id) + "-tab-data"), 'data-subview':("DataView"), "class": ('graph-data-pane') + ' ' + ('tab-pane') }));
index 986a0b7..25ac1cc 100644 (file)
@@ -16,7 +16,7 @@ buf.push('>\n    <h1>Saved Graphs\n    </h1>\n  </div>\n  <ul>');
 
 buf.push('\n    <li><a');
 buf.push(attrs({ 'href':("" + (graph.toLink()) + "") }));
-buf.push('>' + escape((interp = graph.get('name')) == null ? '' : interp) + '</a>\n    </li>');
+buf.push('>' + escape((interp = graph.get('name') || graph.get('id') || graph.toLink()) == null ? '' : interp) + '</a>\n    </li>');
     }
   } else {
     for (var $index in collection.models) {
@@ -24,7 +24,7 @@ buf.push('>' + escape((interp = graph.get('name')) == null ? '' : interp) + '</a
 
 buf.push('\n    <li><a');
 buf.push(attrs({ 'href':("" + (graph.toLink()) + "") }));
-buf.push('>' + escape((interp = graph.get('name')) == null ? '' : interp) + '</a>\n    </li>');
+buf.push('>' + escape((interp = graph.get('name') || graph.get('id') || graph.toLink()) == null ? '' : interp) + '</a>\n    </li>');
    }
   }
 }).call(this);
index 9d93f7d..28a7dc0 100644 (file)
@@ -1,4 +1,4 @@
-require.define('/node_modules/kraken/template/graph/graph-list.jade.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/template/graph/graph-list.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var template = function (locals, attrs, escape, rethrow) {
 var attrs = jade.attrs, escape = jade.escape, rethrow = jade.rethrow;
@@ -18,7 +18,7 @@ buf.push('>\n    <h1>Saved Graphs\n    </h1>\n  </div>\n  <ul>');
 
 buf.push('\n    <li><a');
 buf.push(attrs({ 'href':("" + (graph.toLink()) + "") }));
-buf.push('>' + escape((interp = graph.get('name')) == null ? '' : interp) + '</a>\n    </li>');
+buf.push('>' + escape((interp = graph.get('name') || graph.get('id') || graph.toLink()) == null ? '' : interp) + '</a>\n    </li>');
     }
   } else {
     for (var $index in collection.models) {
@@ -26,7 +26,7 @@ buf.push('>' + escape((interp = graph.get('name')) == null ? '' : interp) + '</a
 
 buf.push('\n    <li><a');
 buf.push(attrs({ 'href':("" + (graph.toLink()) + "") }));
-buf.push('>' + escape((interp = graph.get('name')) == null ? '' : interp) + '</a>\n    </li>');
+buf.push('>' + escape((interp = graph.get('name') || graph.get('id') || graph.toLink()) == null ? '' : interp) + '</a>\n    </li>');
    }
   }
 }).call(this);
index 0366b19..2b02298 100644 (file)
@@ -1,5 +1,5 @@
 var AliasDict, exports, _, __slice = [].slice;
-_ = require('kraken/util/underscore');
+_ = require('limn/util/underscore');
 /**
  * @class A mapping of key-value pairs supporting key-aliases.
  */
index 1ac7157..5ba1c9a 100644 (file)
@@ -1,4 +1,4 @@
-require.define('/node_modules/kraken/util/backbone.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/util/backbone.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var Backbone, that, methodize, Cls, _, _bb_events, _backbone, _methodized, _i, _ref, _len, __slice = [].slice;
 _ = require('underscore');
index ab6a5d4..608f6e8 100644 (file)
@@ -1,5 +1,5 @@
 var hasOwn, MISSING, TOMBSTONE, Cascade, ALIASES, dest, src, exports, _, __slice = [].slice;
-_ = require('kraken/util/underscore');
+_ = require('limn/util/underscore');
 hasOwn = {}.hasOwnProperty;
 /**
  * Sentinel for missing values.
index 356c618..41e7c1d 100644 (file)
@@ -1,7 +1,7 @@
-require.define('/node_modules/kraken/util/cascade.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/util/cascade.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var hasOwn, MISSING, TOMBSTONE, Cascade, ALIASES, dest, src, exports, _, __slice = [].slice;
-_ = require('kraken/util/underscore');
+_ = require('limn/util/underscore');
 hasOwn = {}.hasOwnProperty;
 /**
  * Sentinel for missing values.
index 7d57333..a4a7138 100644 (file)
@@ -1,2 +1,2 @@
-exports.WaitingEmitter = require('kraken/util/event/waiting-emitter');
-exports.ReadyEmitter = require('kraken/util/event/ready-emitter');
\ No newline at end of file
+exports.WaitingEmitter = require('limn/util/event/waiting-emitter');
+exports.ReadyEmitter = require('limn/util/event/ready-emitter');
\ No newline at end of file
index 175958e..20b7b19 100644 (file)
@@ -1,6 +1,6 @@
-require.define('/node_modules/kraken/util/event/index.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/util/event.js', function(require, module, exports, __dirname, __filename, undefined){
 
-exports.WaitingEmitter = require('kraken/util/event/waiting-emitter');
-exports.ReadyEmitter = require('kraken/util/event/ready-emitter');
+exports.WaitingEmitter = require('limn/util/event/waiting-emitter');
+exports.ReadyEmitter = require('limn/util/event/ready-emitter');
 
 });
index 76b12a5..e668e52 100644 (file)
@@ -1,5 +1,5 @@
 var Base, ReadyEmitter, exports;
-Base = require('kraken/base/base');
+Base = require('limn/base/base');
 /**
  * @class An EventEmitter that auto-triggers new handlers once "ready".
  */
index 19ecfbf..203d7ce 100644 (file)
@@ -1,7 +1,7 @@
-require.define('/node_modules/kraken/util/event/ready-emitter.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/util/event/ready-emitter.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var Base, ReadyEmitter, exports;
-Base = require('kraken/base/base');
+Base = require('limn/base/base');
 /**
  * @class An EventEmitter that auto-triggers new handlers once "ready".
  */
index e87ccd8..f996005 100644 (file)
@@ -1,5 +1,5 @@
 var Base, WaitingEmitter, exports;
-Base = require('kraken/base/base');
+Base = require('limn/base/base');
 /**
  * @class An EventEmitter with a ratchet-up waiting counter.
  * @extends Base
index 4f17042..5665b8b 100644 (file)
@@ -1,7 +1,7 @@
-require.define('/node_modules/kraken/util/event/waiting-emitter.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/util/event/waiting-emitter.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var Base, WaitingEmitter, exports;
-Base = require('kraken/base/base');
+Base = require('limn/base/base');
 /**
  * @class An EventEmitter with a ratchet-up waiting counter.
  * @extends Base
index 4da7c06..15fec32 100644 (file)
@@ -1,6 +1,6 @@
 var moment, op, exports, _ref, _, _fmt;
 moment = require('moment');
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
 _fmt = {
   /**
    * Formats a date for display on an axis: `MM/YYYY`
index 04972b7..c9c1605 100644 (file)
@@ -1,8 +1,8 @@
-require.define('/node_modules/kraken/util/formatters.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/util/formatters.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var moment, op, exports, _ref, _, _fmt;
 moment = require('moment');
-_ref = require('kraken/util'), _ = _ref._, op = _ref.op;
+_ref = require('limn/util'), _ = _ref._, op = _ref.op;
 _fmt = {
   /**
    * Formats a date for display on an axis: `MM/YYYY`
index 2cc464f..c2a4c29 100644 (file)
@@ -1,6 +1,6 @@
 var op, root, backbone, parser, Cascade, _, _ref, __slice = [].slice;
-_ = exports._ = require('kraken/util/underscore');
-op = exports.op = require('kraken/util/op');
+_ = exports._ = require('limn/util/underscore');
+op = exports.op = require('limn/util/op');
 root = exports.root = function(){
   return this;
 }();
@@ -32,10 +32,10 @@ if ((_ref = root.jQuery) != null) {
     return _results;
   };
 }
-__import(exports, require('kraken/util/event'));
-backbone = exports.backbone = require('kraken/util/backbone');
-parser = exports.parser = require('kraken/util/parser');
-Cascade = exports.Cascade = require('kraken/util/cascade');
+__import(exports, require('limn/util/event'));
+backbone = exports.backbone = require('limn/util/backbone');
+parser = exports.parser = require('limn/util/parser');
+Cascade = exports.Cascade = require('limn/util/cascade');
 function __import(obj, src){
   var own = {}.hasOwnProperty;
   for (var key in src) if (own.call(src, key)) obj[key] = src[key];
index 2025d0c..40a8bbe 100644 (file)
@@ -1,8 +1,8 @@
-require.define('/node_modules/kraken/util/index.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/util.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var op, root, backbone, parser, Cascade, _, _ref, __slice = [].slice;
-_ = exports._ = require('kraken/util/underscore');
-op = exports.op = require('kraken/util/op');
+_ = exports._ = require('limn/util/underscore');
+op = exports.op = require('limn/util/op');
 root = exports.root = function(){
   return this;
 }();
@@ -34,10 +34,10 @@ if ((_ref = root.jQuery) != null) {
     return _results;
   };
 }
-__import(exports, require('kraken/util/event'));
-backbone = exports.backbone = require('kraken/util/backbone');
-parser = exports.parser = require('kraken/util/parser');
-Cascade = exports.Cascade = require('kraken/util/cascade');
+__import(exports, require('limn/util/event'));
+backbone = exports.backbone = require('limn/util/backbone');
+parser = exports.parser = require('limn/util/parser');
+Cascade = exports.Cascade = require('limn/util/cascade');
 function __import(obj, src){
   var own = {}.hasOwnProperty;
   for (var key in src) if (own.call(src, key)) obj[key] = src[key];
index a918615..da80201 100644 (file)
@@ -1,4 +1,4 @@
-require.define('/node_modules/kraken/util/op.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/util/op.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var DASH_PATTERN, STRIP_PAT, strip, FALSEY, parseBool, op, __slice = [].slice;
 DASH_PATTERN = /-/g;
index 8a6076d..9022a3e 100644 (file)
@@ -1,7 +1,7 @@
 var op, BaseModel, BaseList, BaseView, Mixin, Parsers, ParserMixin, ParsingModel, ParsingList, ParsingView, _, _ref;
-_ = require('kraken/util/underscore');
-op = require('kraken/util/op');
-_ref = require('kraken/base'), BaseModel = _ref.BaseModel, BaseList = _ref.BaseList, BaseView = _ref.BaseView, Mixin = _ref.Mixin;
+_ = require('limn/util/underscore');
+op = require('limn/util/op');
+_ref = require('limn/base'), BaseModel = _ref.BaseModel, BaseList = _ref.BaseList, BaseView = _ref.BaseView, Mixin = _ref.Mixin;
 /**
  * @namespace Parsers by type.
  */
index 5abf358..d5e191d 100644 (file)
@@ -1,9 +1,9 @@
-require.define('/node_modules/kraken/util/parser.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/util/parser.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var op, BaseModel, BaseList, BaseView, Mixin, Parsers, ParserMixin, ParsingModel, ParsingList, ParsingView, _, _ref;
-_ = require('kraken/util/underscore');
-op = require('kraken/util/op');
-_ref = require('kraken/base'), BaseModel = _ref.BaseModel, BaseList = _ref.BaseList, BaseView = _ref.BaseView, Mixin = _ref.Mixin;
+_ = require('limn/util/underscore');
+op = require('limn/util/op');
+_ref = require('limn/base'), BaseModel = _ref.BaseModel, BaseList = _ref.BaseList, BaseView = _ref.BaseView, Mixin = _ref.Mixin;
 /**
  * @namespace Parsers by type.
  */
index 91b31d4..af0d34b 100644 (file)
@@ -1,6 +1,6 @@
 var TimeSeriesData, DASH_PATTERN, BLANK_LINE_PATTERN, COMMENT_PATTERN, CSVData, exports, _;
-_ = require('kraken/util/underscore');
-TimeSeriesData = require('kraken/util/timeseries/timeseries');
+_ = require('limn/util/underscore');
+TimeSeriesData = require('limn/util/timeseries/timeseries');
 DASH_PATTERN = /-/g;
 BLANK_LINE_PATTERN = /^(\s*)$/;
 COMMENT_PATTERN = /\s*(#|\/\/).*$/;
index 15debc2..c370061 100644 (file)
@@ -1,8 +1,8 @@
-require.define('/node_modules/kraken/util/timeseries/csv.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/util/timeseries/csv.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var TimeSeriesData, DASH_PATTERN, BLANK_LINE_PATTERN, COMMENT_PATTERN, CSVData, exports, _;
-_ = require('kraken/util/underscore');
-TimeSeriesData = require('kraken/util/timeseries/timeseries');
+_ = require('limn/util/underscore');
+TimeSeriesData = require('limn/util/timeseries/timeseries');
 DASH_PATTERN = /-/g;
 BLANK_LINE_PATTERN = /^(\s*)$/;
 COMMENT_PATTERN = /\s*(#|\/\/).*$/;
index bca1a5d..862a85d 100644 (file)
@@ -1,2 +1,2 @@
-exports.TimeSeriesData = require('kraken/util/timeseries/timeseries');
-exports.CSVData = require('kraken/util/timeseries/csv');
\ No newline at end of file
+exports.TimeSeriesData = require('limn/util/timeseries/timeseries');
+exports.CSVData = require('limn/util/timeseries/csv');
\ No newline at end of file
index 8509f3e..59bd841 100644 (file)
@@ -1,6 +1,6 @@
-require.define('/node_modules/kraken/util/timeseries/index.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/util/timeseries.js', function(require, module, exports, __dirname, __filename, undefined){
 
-exports.TimeSeriesData = require('kraken/util/timeseries/timeseries');
-exports.CSVData = require('kraken/util/timeseries/csv');
+exports.TimeSeriesData = require('limn/util/timeseries/timeseries');
+exports.CSVData = require('limn/util/timeseries/csv');
 
 });
index 04b4702..75cf26f 100644 (file)
@@ -1,5 +1,5 @@
 var TimeSeriesData, exports, _;
-_ = require('kraken/util/underscore');
+_ = require('limn/util/underscore');
 /**
  * @class Represents a collection of data columns aligned along a common timeline.
  */
index ca17718..4e2fb78 100644 (file)
@@ -1,7 +1,7 @@
-require.define('/node_modules/kraken/util/timeseries/timeseries.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/util/timeseries/timeseries.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var TimeSeriesData, exports, _;
-_ = require('kraken/util/underscore');
+_ = require('limn/util/underscore');
 /**
  * @class Represents a collection of data columns aligned along a common timeline.
  */
index 4d3740a..2d530e7 100644 (file)
@@ -1,4 +1,4 @@
-require.define('/node_modules/kraken/util/underscore/array.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/util/underscore/array.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var I, defined, _, _array;
 _ = require('underscore');
index 4a00701..0184d1b 100644 (file)
@@ -1,4 +1,4 @@
-require.define('/node_modules/kraken/util/underscore/class.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/util/underscore/class.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var _, _cls;
 _ = require('underscore');
index 04e7948..11e9a36 100644 (file)
@@ -1,4 +1,4 @@
-require.define('/node_modules/kraken/util/underscore/function.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/util/underscore/function.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var _, _fn, __slice = [].slice;
 _ = require('underscore');
index a0f8fd3..7d0a93b 100644 (file)
@@ -2,12 +2,12 @@ var exports, _;
 _ = require('underscore');
 _.str = require('underscore.string');
 _.mixin(_.str.exports());
-_.mixin(require('kraken/util/underscore/function'));
-_.mixin(require('kraken/util/underscore/array'));
-_.mixin(require('kraken/util/underscore/object'));
-_.mixin(require('kraken/util/underscore/class'));
-_.mixin(require('kraken/util/underscore/kv'));
-_.mixin(require('kraken/util/underscore/string'));
+_.mixin(require('limn/util/underscore/function'));
+_.mixin(require('limn/util/underscore/array'));
+_.mixin(require('limn/util/underscore/object'));
+_.mixin(require('limn/util/underscore/class'));
+_.mixin(require('limn/util/underscore/kv'));
+_.mixin(require('limn/util/underscore/string'));
 _.dump = function(o, label, expanded){
   var k, v;
   label == null && (label = 'dump');
index e5fac00..10ccd40 100644 (file)
@@ -1,15 +1,15 @@
-require.define('/node_modules/kraken/util/underscore/index.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/util/underscore.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var exports, _;
 _ = require('underscore');
 _.str = require('underscore.string');
 _.mixin(_.str.exports());
-_.mixin(require('kraken/util/underscore/function'));
-_.mixin(require('kraken/util/underscore/array'));
-_.mixin(require('kraken/util/underscore/object'));
-_.mixin(require('kraken/util/underscore/class'));
-_.mixin(require('kraken/util/underscore/kv'));
-_.mixin(require('kraken/util/underscore/string'));
+_.mixin(require('limn/util/underscore/function'));
+_.mixin(require('limn/util/underscore/array'));
+_.mixin(require('limn/util/underscore/object'));
+_.mixin(require('limn/util/underscore/class'));
+_.mixin(require('limn/util/underscore/kv'));
+_.mixin(require('limn/util/underscore/string'));
 _.dump = function(o, label, expanded){
   var k, v;
   label == null && (label = 'dump');
index ec5e1ff..dda8e9a 100644 (file)
@@ -1,4 +1,4 @@
-require.define('/node_modules/kraken/util/underscore/kv.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/util/underscore/kv.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var _, _kv;
 _ = require('underscore');
index cc21a2e..67f3d81 100644 (file)
@@ -1,4 +1,4 @@
-require.define('/node_modules/kraken/util/underscore/object.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/util/underscore/object.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var getProto, OBJ_PROTO, hasOwn, objToString, DEFAULT_DELEGATE_OPTIONS, TOMBSTONE, DEFAULT_NESTED_OPTIONS, _, _ref, _obj, __slice = [].slice;
 _ = require('underscore');
index 1a38f92..b4e5fe2 100644 (file)
@@ -1,4 +1,4 @@
-require.define('/node_modules/kraken/util/underscore/string.js.js', function(require, module, exports, __dirname, __filename, undefined){
+require.define('/node_modules/limn/util/underscore/string.js', function(require, module, exports, __dirname, __filename, undefined){
 
 var _, _str, _string, __slice = [].slice;
 _ = require('underscore');
diff --git a/src/version.js b/src/version.js
new file mode 100644 (file)
index 0000000..6d4d75a
--- /dev/null
@@ -0,0 +1 @@
+module.exports = exports = '657d6d1';
index a8ef50b..ad964ea 100644 (file)
@@ -349,6 +349,8 @@ var EventEmitter = require('events').EventEmitter;
 var Hash = require('hashish');
 var Chainsaw = require('chainsaw');
 
+var slice = [].slice;
+
 module.exports = Seq;
 function Seq (xs) {
     if (xs && !Array.isArray(xs) || arguments.length > 1) {
@@ -371,6 +373,7 @@ Seq.ap = Seq; // for compatability with versions <0.3
 
 function builder (saw, xs) {
     var context = {
+        dead : false,
         vars : {},
         args : {},
         stack : xs,
@@ -378,28 +381,34 @@ function builder (saw, xs) {
     };
     context.stack_ = context.stack;
     
-    function action (step, key, f, g) {
+    function die(){
+        context.dead = true;
+        saw.step = saw.actions.length+1;
+    }
+    context.die = die;
+    
+    function action (step, key, start, finish){
         var cb = function (err) {
-            var args = [].slice.call(arguments, 1);
-            if (err) {
+            var args = slice.call(arguments, 1);
+            if (context.dead) {
+                saw.step = saw.actions.length+1;
+            } else if (err) {
                 context.error = { message : err, key : key };
                 saw.jump(lastPar);
                 saw.down('catch');
-                g();
-            }
-            else {
+                finish();
+            } else {
                 if (typeof key == 'number') {
                     context.stack_[key] = args[0];
                     context.args[key] = args;
-                }
-                else {
+                } else {
                     context.stack_.push.apply(context.stack_, args);
                     if (key !== undefined) {
                         context.vars[key] = args[0];
                         context.args[key] = args;
                     }
                 }
-                if (g) g(args, key);
+                if (finish) finish(args, key);
             }
         };
         Hash(context).forEach(function (v,k) { cb[k] = v });
@@ -420,14 +429,19 @@ function builder (saw, xs) {
         
         cb.ok = cb.bind(cb, null);
         
-        f.apply(cb, context.stack);
+        cb.die = function (){
+            die();
+            return cb;
+        };
+        
+        start.apply(cb, context.stack);
     }
     
     var running = 0;
     var errors = 0;
     
     this.seq = function (key, cb) {
-        var bound = [].slice.call(arguments, 2);
+        var bound = slice.call(arguments, 2);
         
         if (typeof key === 'function') {
             if (arguments.length > 1) bound.unshift(cb);
@@ -440,7 +454,7 @@ function builder (saw, xs) {
             action(saw.step, key,
                 function () {
                     context.stack_ = [];
-                    var args = [].slice.call(arguments);
+                    var args = slice.call(arguments);
                     args.unshift.apply(args, bound.map(function (arg) {
                         return arg === Seq ? this : arg
                     }, this));
@@ -463,7 +477,7 @@ function builder (saw, xs) {
             context.stack_ = [];
         }
         
-        var bound = [].slice.call(arguments, 2);
+        var bound = slice.call(arguments, 2);
         if (typeof key === 'function') {
             if (arguments.length > 1) bound.unshift(cb);
             cb = key;
@@ -471,7 +485,7 @@ function builder (saw, xs) {
             context.stack_.push(null);
         }
         var cb_ = function () {
-            var args = [].slice.call(arguments);
+            var args = slice.call(arguments);
             args.unshift.apply(args, bound.map(function (arg) {
                 return arg === Seq ? this : arg
             }, this));
@@ -501,13 +515,13 @@ function builder (saw, xs) {
     
     [ 'seq', 'par' ].forEach(function (name) {
         this[name + '_'] = function (key) {
-            var args = [].slice.call(arguments);
+            var args = slice.call(arguments);
             
             var cb = typeof key === 'function'
                 ? args[0] : args[1];
             
             var fn = function () {
-                var argv = [].slice.call(arguments);
+                var argv = slice.call(arguments);
                 argv.unshift(this);
                 cb.apply(this, argv);
             };
@@ -531,18 +545,51 @@ function builder (saw, xs) {
         saw.next();
     };
     
-    this.forEach = function (cb) {
-        this.seq(function () {
-            context.stack_ = context.stack.slice();
-            var end = context.stack.length;
+    this.forEach = function (limit, cb) {
+        if (cb === undefined) { cb = limit; limit = null; }
+        
+        this.seq(function (){
+            if (context.stack.length === 0)
+                return this(null);
             
-            if (end === 0) this(null)
-            else context.stack.forEach(function (x, i) {
-                action(saw.step, i, function () {
-                    cb.call(this, x, i);
-                    if (i == end - 1) saw.next();
-                });
-            });
+            var xs       = context.stack.slice()
+            ,   len      = xs.length
+            ,   active   = 0
+            ,   finished = 0
+            ,   queue    = []
+            ,   visitor
+            ;
+            
+            context.stack_ = xs.slice();
+            
+            if (!limit || limit <= 0)
+                visitor = function (x, i){
+                    action(saw.step, i, function (){
+                        cb.call(this, x, i);
+                        if (i === len - 1)
+                            saw.next();
+                    });
+                }
+            else
+                visitor = function eachCall(x, i){
+                    if (active >= limit)
+                        return queue.push(eachCall.bind(this, x, i));
+                    
+                    active++;
+                    action(saw.step, i,
+                        function (){ cb.call(this, x, i); },
+                        function (){
+                            active--;
+                            finished++;
+                            if (queue.length > 0)
+                                queue.shift()();
+                            else if (i === len - 1)
+                                saw.next();
+                        }
+                    );
+                };
+            
+            xs.forEach(visitor);
         });
     };
     
@@ -627,7 +674,7 @@ function builder (saw, xs) {
                 };
                 
                 next.ok = function () {
-                    var args = [].slice.call(arguments);
+                    var args = slice.call(arguments);
                     args.unshift(null);
                     return next.apply(next, args);
                 };
@@ -671,7 +718,7 @@ function builder (saw, xs) {
             };
             
             next.ok = function () {
-                var args = [].slice.call(arguments);
+                var args = slice.call(arguments);
                 args.unshift(null);
                 return next.apply(next, args);
             };
@@ -721,7 +768,7 @@ function builder (saw, xs) {
                 };
                 
                 next.ok = function () {
-                    var args = [].slice.call(arguments);
+                    var args = slice.call(arguments);
                     args.unshift(null);
                     return next.apply(next, args);
                 };
@@ -776,7 +823,7 @@ function builder (saw, xs) {
             };
             
             next.ok = function () {
-                var args = [].slice.call(arguments);
+                var args = slice.call(arguments);
                 args.unshift(null);
                 return next.apply(next, args);
             };
@@ -785,11 +832,29 @@ function builder (saw, xs) {
         });
     };
     
-    [ 'forEach', 'seqEach', 'parEach', 'seqMap', 'parMap', 'seqFilter', 'parFilter' ]
-        .forEach(function (name) {
-            this[name + '_'] = function (cb) {
-                this[name].call(this, function () {
-                    var args = [].slice.call(arguments);
+    [ 'forEach', 'Each', 'Map', 'Filter' ]
+        .forEach(function (name){
+            var isForEach = !!(name === 'forEach')
+            ,   method ;
+            
+            // the seq functions are straight-forward, other than skipping forEach
+            if (!isForEach) {
+                method = 'seq'+name;
+                this[method+'_'] = function (cb) {
+                    this[method].call(this, function () {
+                        var args = slice.call(arguments);
+                        args.unshift(this);
+                        cb.apply(this, args);
+                    });
+                };
+            }
+            
+            // ...but par functions (anything that takes limit+callback) needs special care
+            method = (isForEach ? name : 'par'+name);
+            this[method+'_'] = function (limit, cb) {
+                if (!cb) { cb = limit; limit = undefined; }
+                this[method].call(this, limit, function (){
+                    var args = slice.call(arguments);
                     args.unshift(this);
                     cb.apply(this, args);
                 });
@@ -802,7 +867,7 @@ function builder (saw, xs) {
             this[name] = function () {
                 context.stack[name].apply(
                     context.stack,
-                    [].slice.call(arguments)
+                    slice.call(arguments)
                 );
                 saw.next();
                 return this;
@@ -815,7 +880,7 @@ function builder (saw, xs) {
             this[name] = function () {
                 var res = context.stack[name].apply(
                     context.stack,
-                    [].slice.call(arguments)
+                    slice.call(arguments)
                 );
                 // stack must be an array, or bad things happen
                 context.stack = (Array.isArray(res) ? res : [res]);
@@ -864,6 +929,7 @@ function builder (saw, xs) {
     this['do'] = function (cb) {
         saw.nest(cb, context);
     };
+    
 }
 
 });
@@ -1043,11 +1109,11 @@ EventEmitter.prototype.listeners = function(type) {
 
 });
 
-require.define("/node_modules/hashish/package.json", function (require, module, exports, __dirname, __filename) {
+require.define("/node_modules/seq/node_modules/hashish/package.json", function (require, module, exports, __dirname, __filename) {
 module.exports = {"main":"./index.js"}
 });
 
-require.define("/node_modules/hashish/index.js", function (require, module, exports, __dirname, __filename) {
+require.define("/node_modules/seq/node_modules/hashish/index.js", function (require, module, exports, __dirname, __filename) {
 module.exports = Hash;
 var Traverse = require('traverse');
 
@@ -1304,16 +1370,14 @@ Hash.compact = function (ref) {
 
 });
 
-require.define("/node_modules/hashish/node_modules/traverse/package.json", function (require, module, exports, __dirname, __filename) {
-module.exports = {"main":"index.js"}
+require.define("/node_modules/seq/node_modules/hashish/node_modules/traverse/package.json", function (require, module, exports, __dirname, __filename) {
+module.exports = {"main":"./index"}
 });
 
-require.define("/node_modules/hashish/node_modules/traverse/index.js", function (require, module, exports, __dirname, __filename) {
-var traverse = module.exports = function (obj) {
-    return new Traverse(obj);
-};
-
+require.define("/node_modules/seq/node_modules/hashish/node_modules/traverse/index.js", function (require, module, exports, __dirname, __filename) {
+module.exports = Traverse;
 function Traverse (obj) {
+    if (!(this instanceof Traverse)) return new Traverse(obj);
     this.value = obj;
 }
 
@@ -1330,18 +1394,6 @@ Traverse.prototype.get = function (ps) {
     return node;
 };
 
-Traverse.prototype.has = function (ps) {
-    var node = this.value;
-    for (var i = 0; i < ps.length; i ++) {
-        var key = ps[i];
-        if (!Object.hasOwnProperty.call(node, key)) {
-            return false;
-        }
-        node = node[key];
-    }
-    return true;
-};
-
 Traverse.prototype.set = function (ps, value) {
     var node = this.value;
     for (var i = 0; i < ps.length - 1; i ++) {
@@ -1405,7 +1457,7 @@ Traverse.prototype.clone = function () {
             parents.push(src);
             nodes.push(dst);
             
-            forEach(objectKeys(src), function (key) {
+            forEach(Object_keys(src), function (key) {
                 dst[key] = clone(src[key]);
             });
             
@@ -1452,7 +1504,7 @@ function walk (root, cb, immutable) {
                 if (stopHere) keepGoing = false;
             },
             remove : function (stopHere) {
-                if (isArray(state.parent.node)) {
+                if (Array_isArray(state.parent.node)) {
                     state.parent.node.splice(state.key, 1);
                 }
                 else {
@@ -1471,31 +1523,24 @@ function walk (root, cb, immutable) {
         
         if (!alive) return state;
         
-        function updateState() {
-            if (typeof state.node === 'object' && state.node !== null) {
-                if (!state.keys || state.node_ !== state.node) {
-                    state.keys = objectKeys(state.node)
-                }
-                
-                state.isLeaf = state.keys.length == 0;
-                
-                for (var i = 0; i < parents.length; i++) {
-                    if (parents[i].node_ === node_) {
-                        state.circular = parents[i];
-                        break;
-                    }
+        if (typeof node === 'object' && node !== null) {
+            state.keys = Object_keys(node);
+            
+            state.isLeaf = state.keys.length == 0;
+            
+            for (var i = 0; i < parents.length; i++) {
+                if (parents[i].node_ === node_) {
+                    state.circular = parents[i];
+                    break;
                 }
             }
-            else {
-                state.isLeaf = true;
-                state.keys = null;
-            }
-            
-            state.notLeaf = !state.isLeaf;
-            state.notRoot = !state.isRoot;
+        }
+        else {
+            state.isLeaf = true;
         }
         
-        updateState();
+        state.notLeaf = !state.isLeaf;
+        state.notRoot = !state.isRoot;
         
         // use return values to update if defined
         var ret = cb.call(state, state.node);
@@ -1509,8 +1554,6 @@ function walk (root, cb, immutable) {
         && state.node !== null && !state.circular) {
             parents.push(state);
             
-            updateState();
-            
             forEach(state.keys, function (key, i) {
                 path.push(key);
                 
@@ -1541,45 +1584,33 @@ function copy (src) {
     if (typeof src === 'object' && src !== null) {
         var dst;
         
-        if (isArray(src)) {
+        if (Array_isArray(src)) {
             dst = [];
         }
-        else if (isDate(src)) {
+        else if (src instanceof Date) {
             dst = new Date(src);
         }
-        else if (isRegExp(src)) {
-            dst = new RegExp(src);
-        }
-        else if (isError(src)) {
-            dst = { message: src.message };
-        }
-        else if (isBoolean(src)) {
+        else if (src instanceof Boolean) {
             dst = new Boolean(src);
         }
-        else if (isNumber(src)) {
+        else if (src instanceof Number) {
             dst = new Number(src);
         }
-        else if (isString(src)) {
+        else if (src instanceof String) {
             dst = new String(src);
         }
         else if (Object.create && Object.getPrototypeOf) {
             dst = Object.create(Object.getPrototypeOf(src));
         }
-        else if (src.constructor === Object) {
-            dst = {};
-        }
-        else {
-            var proto =
-                (src.constructor && src.constructor.prototype)
-                || src.__proto__
-                || {}
-            ;
+        else if (src.__proto__ || src.constructor.prototype) {
+            var proto = src.__proto__ || src.constructor.prototype || {};
             var T = function () {};
             T.prototype = proto;
             dst = new T;
+            if (!dst.__proto__) dst.__proto__ = proto;
         }
         
-        forEach(objectKeys(src), function (key) {
+        forEach(Object_keys(src), function (key) {
             dst[key] = src[key];
         });
         return dst;
@@ -1587,21 +1618,13 @@ function copy (src) {
     else return src;
 }
 
-var objectKeys = Object.keys || function keys (obj) {
+var Object_keys = Object.keys || function keys (obj) {
     var res = [];
     for (var key in obj) res.push(key)
     return res;
 };
 
-function toS (obj) { return Object.prototype.toString.call(obj) }
-function isDate (obj) { return toS(obj) === '[object Date]' }
-function isRegExp (obj) { return toS(obj) === '[object RegExp]' }
-function isError (obj) { return toS(obj) === '[object Error]' }
-function isBoolean (obj) { return toS(obj) === '[object Boolean]' }
-function isNumber (obj) { return toS(obj) === '[object Number]' }
-function isString (obj) { return toS(obj) === '[object String]' }
-
-var isArray = Array.isArray || function isArray (xs) {
+var Array_isArray = Array.isArray || function isArray (xs) {
     return Object.prototype.toString.call(xs) === '[object Array]';
 };
 
@@ -1612,10 +1635,10 @@ var forEach = function (xs, fn) {
     }
 };
 
-forEach(objectKeys(Traverse.prototype), function (key) {
-    traverse[key] = function (obj) {
+forEach(Object_keys(Traverse.prototype), function (key) {
+    Traverse[key] = function (obj) {
         var args = [].slice.call(arguments, 1);
-        var t = new Traverse(obj);
+        var t = Traverse(obj);
         return t[key].apply(t, args);
     };
 });
diff --git a/static/vendor/underscore.mod.js b/static/vendor/underscore.mod.js
new file mode 100644 (file)
index 0000000..8ef7cc1
--- /dev/null
@@ -0,0 +1,1064 @@
+require.define('/node_modules/underscore.js', function(require, module, exports, __dirname, __filename, undefined){
+
+//     Underscore.js 1.3.3
+//     (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
+//     Underscore is freely distributable under the MIT license.
+//     Portions of Underscore are inspired or borrowed from Prototype,
+//     Oliver Steele's Functional, and John Resig's Micro-Templating.
+//     For all details and documentation:
+//     http://documentcloud.github.com/underscore
+
+(function() {
+
+  // Baseline setup
+  // --------------
+
+  // Establish the root object, `window` in the browser, or `global` on the server.
+  var root = this;
+
+  // Save the previous value of the `_` variable.
+  var previousUnderscore = root._;
+
+  // Establish the object that gets returned to break out of a loop iteration.
+  var breaker = {};
+
+  // Save bytes in the minified (but not gzipped) version:
+  var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
+
+  // Create quick reference variables for speed access to core prototypes.
+  var slice            = ArrayProto.slice,
+      unshift          = ArrayProto.unshift,
+      toString         = ObjProto.toString,
+      hasOwnProperty   = ObjProto.hasOwnProperty;
+
+  // All **ECMAScript 5** native function implementations that we hope to use
+  // are declared here.
+  var
+    nativeForEach      = ArrayProto.forEach,
+    nativeMap          = ArrayProto.map,
+    nativeReduce       = ArrayProto.reduce,
+    nativeReduceRight  = ArrayProto.reduceRight,
+    nativeFilter       = ArrayProto.filter,
+    nativeEvery        = ArrayProto.every,
+    nativeSome         = ArrayProto.some,
+    nativeIndexOf      = ArrayProto.indexOf,
+    nativeLastIndexOf  = ArrayProto.lastIndexOf,
+    nativeIsArray      = Array.isArray,
+    nativeKeys         = Object.keys,
+    nativeBind         = FuncProto.bind;
+
+  // Create a safe reference to the Underscore object for use below.
+  var _ = function(obj) { return new wrapper(obj); };
+
+  // Export the Underscore object for **Node.js**, with
+  // backwards-compatibility for the old `require()` API. If we're in
+  // the browser, add `_` as a global object via a string identifier,
+  // for Closure Compiler "advanced" mode.
+  if (typeof exports !== 'undefined') {
+    if (typeof module !== 'undefined' && module.exports) {
+      exports = module.exports = _;
+    }
+    exports._ = _;
+  } else {
+    root['_'] = _;
+  }
+
+  // Current version.
+  _.VERSION = '1.3.3';
+
+  // Collection Functions
+  // --------------------
+
+  // The cornerstone, an `each` implementation, aka `forEach`.
+  // Handles objects with the built-in `forEach`, arrays, and raw objects.
+  // Delegates to **ECMAScript 5**'s native `forEach` if available.
+  var each = _.each = _.forEach = function(obj, iterator, context) {
+    if (obj == null) return;
+    if (nativeForEach && obj.forEach === nativeForEach) {
+      obj.forEach(iterator, context);
+    } else if (obj.length === +obj.length) {
+      for (var i = 0, l = obj.length; i < l; i++) {
+        if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) return;
+      }
+    } else {
+      for (var key in obj) {
+        if (_.has(obj, key)) {
+          if (iterator.call(context, obj[key], key, obj) === breaker) return;
+        }
+      }
+    }
+  };
+
+  // Return the results of applying the iterator to each element.
+  // Delegates to **ECMAScript 5**'s native `map` if available.
+  _.map = _.collect = function(obj, iterator, context) {
+    var results = [];
+    if (obj == null) return results;
+    if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
+    each(obj, function(value, index, list) {
+      results[results.length] = iterator.call(context, value, index, list);
+    });
+    if (obj.length === +obj.length) results.length = obj.length;
+    return results;
+  };
+
+  // **Reduce** builds up a single result from a list of values, aka `inject`,
+  // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
+  _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
+    var initial = arguments.length > 2;
+    if (obj == null) obj = [];
+    if (nativeReduce && obj.reduce === nativeReduce) {
+      if (context) iterator = _.bind(iterator, context);
+      return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
+    }
+    each(obj, function(value, index, list) {
+      if (!initial) {
+        memo = value;
+        initial = true;
+      } else {
+        memo = iterator.call(context, memo, value, index, list);
+      }
+    });
+    if (!initial) throw new TypeError('Reduce of empty array with no initial value');
+    return memo;
+  };
+
+  // The right-associative version of reduce, also known as `foldr`.
+  // Delegates to **ECMAScript 5**'s native `reduceRight` if available.
+  _.reduceRight = _.foldr = function(obj, iterator, memo, context) {
+    var initial = arguments.length > 2;
+    if (obj == null) obj = [];
+    if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
+      if (context) iterator = _.bind(iterator, context);
+      return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
+    }
+    var reversed = _.toArray(obj).reverse();
+    if (context && !initial) iterator = _.bind(iterator, context);
+    return initial ? _.reduce(reversed, iterator, memo, context) : _.reduce(reversed, iterator);
+  };
+
+  // Return the first value which passes a truth test. Aliased as `detect`.
+  _.find = _.detect = function(obj, iterator, context) {
+    var result;
+    any(obj, function(value, index, list) {
+      if (iterator.call(context, value, index, list)) {
+        result = value;
+        return true;
+      }
+    });
+    return result;
+  };
+
+  // Return all the elements that pass a truth test.
+  // Delegates to **ECMAScript 5**'s native `filter` if available.
+  // Aliased as `select`.
+  _.filter = _.select = function(obj, iterator, context) {
+    var results = [];
+    if (obj == null) return results;
+    if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
+    each(obj, function(value, index, list) {
+      if (iterator.call(context, value, index, list)) results[results.length] = value;
+    });
+    return results;
+  };
+
+  // Return all the elements for which a truth test fails.
+  _.reject = function(obj, iterator, context) {
+    var results = [];
+    if (obj == null) return results;
+    each(obj, function(value, index, list) {
+      if (!iterator.call(context, value, index, list)) results[results.length] = value;
+    });
+    return results;
+  };
+
+  // Determine whether all of the elements match a truth test.
+  // Delegates to **ECMAScript 5**'s native `every` if available.
+  // Aliased as `all`.
+  _.every = _.all = function(obj, iterator, context) {
+    var result = true;
+    if (obj == null) return result;
+    if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
+    each(obj, function(value, index, list) {
+      if (!(result = result && iterator.call(context, value, index, list))) return breaker;
+    });
+    return !!result;
+  };
+
+  // Determine if at least one element in the object matches a truth test.
+  // Delegates to **ECMAScript 5**'s native `some` if available.
+  // Aliased as `any`.
+  var any = _.some = _.any = function(obj, iterator, context) {
+    iterator || (iterator = _.identity);
+    var result = false;
+    if (obj == null) return result;
+    if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
+    each(obj, function(value, index, list) {
+      if (result || (result = iterator.call(context, value, index, list))) return breaker;
+    });
+    return !!result;
+  };
+
+  // Determine if a given value is included in the array or object using `===`.
+  // Aliased as `contains`.
+  _.include = _.contains = function(obj, target) {
+    var found = false;
+    if (obj == null) return found;
+    if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
+    found = any(obj, function(value) {
+      return value === target;
+    });
+    return found;
+  };
+
+  // Invoke a method (with arguments) on every item in a collection.
+  _.invoke = function(obj, method) {
+    var args = slice.call(arguments, 2);
+    return _.map(obj, function(value) {
+      return (_.isFunction(method) ? method || value : value[method]).apply(value, args);
+    });
+  };
+
+  // Convenience version of a common use case of `map`: fetching a property.
+  _.pluck = function(obj, key) {
+    return _.map(obj, function(value){ return value[key]; });
+  };
+
+  // Return the maximum element or (element-based computation).
+  _.max = function(obj, iterator, context) {
+    if (!iterator && _.isArray(obj) && obj[0] === +obj[0]) return Math.max.apply(Math, obj);
+    if (!iterator && _.isEmpty(obj)) return -Infinity;
+    var result = {computed : -Infinity};
+    each(obj, function(value, index, list) {
+      var computed = iterator ? iterator.call(context, value, index, list) : value;
+      computed >= result.computed && (result = {value : value, computed : computed});
+    });
+    return result.value;
+  };
+
+  // Return the minimum element (or element-based computation).
+  _.min = function(obj, iterator, context) {
+    if (!iterator && _.isArray(obj) && obj[0] === +obj[0]) return Math.min.apply(Math, obj);
+    if (!iterator && _.isEmpty(obj)) return Infinity;
+    var result = {computed : Infinity};
+    each(obj, function(value, index, list) {
+      var computed = iterator ? iterator.call(context, value, index, list) : value;
+      computed < result.computed && (result = {value : value, computed : computed});
+    });
+    return result.value;
+  };
+
+  // Shuffle an array.
+  _.shuffle = function(obj) {
+    var shuffled = [], rand;
+    each(obj, function(value, index, list) {
+      rand = Math.floor(Math.random() * (index + 1));
+      shuffled[index] = shuffled[rand];
+      shuffled[rand] = value;
+    });
+    return shuffled;
+  };
+
+  // Sort the object's values by a criterion produced by an iterator.
+  _.sortBy = function(obj, val, context) {
+    var iterator = _.isFunction(val) ? val : function(obj) { return obj[val]; };
+    return _.pluck(_.map(obj, function(value, index, list) {
+      return {
+        value : value,
+        criteria : iterator.call(context, value, index, list)
+      };
+    }).sort(function(left, right) {
+      var a = left.criteria, b = right.criteria;
+      if (a === void 0) return 1;
+      if (b === void 0) return -1;
+      return a < b ? -1 : a > b ? 1 : 0;
+    }), 'value');
+  };
+
+  // Groups the object's values by a criterion. Pass either a string attribute
+  // to group by, or a function that returns the criterion.
+  _.groupBy = function(obj, val) {
+    var result = {};
+    var iterator = _.isFunction(val) ? val : function(obj) { return obj[val]; };
+    each(obj, function(value, index) {
+      var key = iterator(value, index);
+      (result[key] || (result[key] = [])).push(value);
+    });
+    return result;
+  };
+
+  // Use a comparator function to figure out at what index an object should
+  // be inserted so as to maintain order. Uses binary search.
+  _.sortedIndex = function(array, obj, iterator) {
+    iterator || (iterator = _.identity);
+    var low = 0, high = array.length;
+    while (low < high) {
+      var mid = (low + high) >> 1;
+      iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid;
+    }
+    return low;
+  };
+
+  // Safely convert anything iterable into a real, live array.
+  _.toArray = function(obj) {
+    if (!obj)                                     return [];
+    if (_.isArray(obj))                           return slice.call(obj);
+    if (_.isArguments(obj))                       return slice.call(obj);
+    if (obj.toArray && _.isFunction(obj.toArray)) return obj.toArray();
+    return _.values(obj);
+  };
+
+  // Return the number of elements in an object.
+  _.size = function(obj) {
+    return _.isArray(obj) ? obj.length : _.keys(obj).length;
+  };
+
+  // Array Functions
+  // ---------------
+
+  // Get the first element of an array. Passing **n** will return the first N
+  // values in the array. Aliased as `head` and `take`. The **guard** check
+  // allows it to work with `_.map`.
+  _.first = _.head = _.take = function(array, n, guard) {
+    return (n != null) && !guard ? slice.call(array, 0, n) : array[0];
+  };
+
+  // Returns everything but the last entry of the array. Especcialy useful on
+  // the arguments object. Passing **n** will return all the values in
+  // the array, excluding the last N. The **guard** check allows it to work with
+  // `_.map`.
+  _.initial = function(array, n, guard) {
+    return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));
+  };
+
+  // Get the last element of an array. Passing **n** will return the last N
+  // values in the array. The **guard** check allows it to work with `_.map`.
+  _.last = function(array, n, guard) {
+    if ((n != null) && !guard) {
+      return slice.call(array, Math.max(array.length - n, 0));
+    } else {
+      return array[array.length - 1];
+    }
+  };
+
+  // Returns everything but the first entry of the array. Aliased as `tail`.
+  // Especially useful on the arguments object. Passing an **index** will return
+  // the rest of the values in the array from that index onward. The **guard**
+  // check allows it to work with `_.map`.
+  _.rest = _.tail = function(array, index, guard) {
+    return slice.call(array, (index == null) || guard ? 1 : index);
+  };
+
+  // Trim out all falsy values from an array.
+  _.compact = function(array) {
+    return _.filter(array, function(value){ return !!value; });
+  };
+
+  // Return a completely flattened version of an array.
+  _.flatten = function(array, shallow) {
+    return _.reduce(array, function(memo, value) {
+      if (_.isArray(value)) return memo.concat(shallow ? value : _.flatten(value));
+      memo[memo.length] = value;
+      return memo;
+    }, []);
+  };
+
+  // Return a version of the array that does not contain the specified value(s).
+  _.without = function(array) {
+    return _.difference(array, slice.call(arguments, 1));
+  };
+
+  // Produce a duplicate-free version of the array. If the array has already
+  // been sorted, you have the option of using a faster algorithm.
+  // Aliased as `unique`.
+  _.uniq = _.unique = function(array, isSorted, iterator) {
+    var initial = iterator ? _.map(array, iterator) : array;
+    var results = [];
+    // The `isSorted` flag is irrelevant if the array only contains two elements.
+    if (array.length < 3) isSorted = true;
+    _.reduce(initial, function (memo, value, index) {
+      if (isSorted ? _.last(memo) !== value || !memo.length : !_.include(memo, value)) {
+        memo.push(value);
+        results.push(array[index]);
+      }
+      return memo;
+    }, []);
+    return results;
+  };
+
+  // Produce an array that contains the union: each distinct element from all of
+  // the passed-in arrays.
+  _.union = function() {
+    return _.uniq(_.flatten(arguments, true));
+  };
+
+  // Produce an array that contains every item shared between all the
+  // passed-in arrays. (Aliased as "intersect" for back-compat.)
+  _.intersection = _.intersect = function(array) {
+    var rest = slice.call(arguments, 1);
+    return _.filter(_.uniq(array), function(item) {
+      return _.every(rest, function(other) {
+        return _.indexOf(other, item) >= 0;
+      });
+    });
+  };
+
+  // Take the difference between one array and a number of other arrays.
+  // Only the elements present in just the first array will remain.
+  _.difference = function(array) {
+    var rest = _.flatten(slice.call(arguments, 1), true);
+    return _.filter(array, function(value){ return !_.include(rest, value); });
+  };
+
+  // Zip together multiple lists into a single array -- elements that share
+  // an index go together.
+  _.zip = function() {
+    var args = slice.call(arguments);
+    var length = _.max(_.pluck(args, 'length'));
+    var results = new Array(length);
+    for (var i = 0; i < length; i++) results[i] = _.pluck(args, "" + i);
+    return results;
+  };
+
+  // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),
+  // we need this function. Return the position of the first occurrence of an
+  // item in an array, or -1 if the item is not included in the array.
+  // Delegates to **ECMAScript 5**'s native `indexOf` if available.
+  // If the array is large and already in sort order, pass `true`
+  // for **isSorted** to use binary search.
+  _.indexOf = function(array, item, isSorted) {
+    if (array == null) return -1;
+    var i, l;
+    if (isSorted) {
+      i = _.sortedIndex(array, item);
+      return array[i] === item ? i : -1;
+    }
+    if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item);
+    for (i = 0, l = array.length; i < l; i++) if (i in array && array[i] === item) return i;
+    return -1;
+  };
+
+  // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
+  _.lastIndexOf = function(array, item) {
+    if (array == null) return -1;
+    if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) return array.lastIndexOf(item);
+    var i = array.length;
+    while (i--) if (i in array && array[i] === item) return i;
+    return -1;
+  };
+
+  // Generate an integer Array containing an arithmetic progression. A port of
+  // the native Python `range()` function. See
+  // [the Python documentation](http://docs.python.org/library/functions.html#range).
+  _.range = function(start, stop, step) {
+    if (arguments.length <= 1) {
+      stop = start || 0;
+      start = 0;
+    }
+    step = arguments[2] || 1;
+
+    var len = Math.max(Math.ceil((stop - start) / step), 0);
+    var idx = 0;
+    var range = new Array(len);
+
+    while(idx < len) {
+      range[idx++] = start;
+      start += step;
+    }
+
+    return range;
+  };
+
+  // Function (ahem) Functions
+  // ------------------
+
+  // Reusable constructor function for prototype setting.
+  var ctor = function(){};
+
+  // Create a function bound to a given object (assigning `this`, and arguments,
+  // optionally). Binding with arguments is also known as `curry`.
+  // Delegates to **ECMAScript 5**'s native `Function.bind` if available.
+  // We check for `func.bind` first, to fail fast when `func` is undefined.
+  _.bind = function bind(func, context) {
+    var bound, args;
+    if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
+    if (!_.isFunction(func)) throw new TypeError;
+    args = slice.call(arguments, 2);
+    return bound = function() {
+      if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
+      ctor.prototype = func.prototype;
+      var self = new ctor;
+      var result = func.apply(self, args.concat(slice.call(arguments)));
+      if (Object(result) === result) return result;
+      return self;
+    };
+  };
+
+  // Bind all of an object's methods to that object. Useful for ensuring that
+  // all callbacks defined on an object belong to it.
+  _.bindAll = function(obj) {
+    var funcs = slice.call(arguments, 1);
+    if (funcs.length == 0) funcs = _.functions(obj);
+    each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
+    return obj;
+  };
+
+  // Memoize an expensive function by storing its results.
+  _.memoize = function(func, hasher) {
+    var memo = {};
+    hasher || (hasher = _.identity);
+    return function() {
+      var key = hasher.apply(this, arguments);
+      return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
+    };
+  };
+
+  // Delays a function for the given number of milliseconds, and then calls
+  // it with the arguments supplied.
+  _.delay = function(func, wait) {
+    var args = slice.call(arguments, 2);
+    return setTimeout(function(){ return func.apply(null, args); }, wait);
+  };
+
+  // Defers a function, scheduling it to run after the current call stack has
+  // cleared.
+  _.defer = function(func) {
+    return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
+  };
+
+  // Returns a function, that, when invoked, will only be triggered at most once
+  // during a given window of time.
+  _.throttle = function(func, wait) {
+    var context, args, timeout, throttling, more, result;
+    var whenDone = _.debounce(function(){ more = throttling = false; }, wait);
+    return function() {
+      context = this; args = arguments;
+      var later = function() {
+        timeout = null;
+        if (more) func.apply(context, args);
+        whenDone();
+      };
+      if (!timeout) timeout = setTimeout(later, wait);
+      if (throttling) {
+        more = true;
+      } else {
+        result = func.apply(context, args);
+      }
+      whenDone();
+      throttling = true;
+      return result;
+    };
+  };
+
+  // Returns a function, that, as long as it continues to be invoked, will not
+  // be triggered. The function will be called after it stops being called for
+  // N milliseconds. If `immediate` is passed, trigger the function on the
+  // leading edge, instead of the trailing.
+  _.debounce = function(func, wait, immediate) {
+    var timeout;
+    return function() {
+      var context = this, args = arguments;
+      var later = function() {
+        timeout = null;
+        if (!immediate) func.apply(context, args);
+      };
+      if (immediate && !timeout) func.apply(context, args);
+      clearTimeout(timeout);
+      timeout = setTimeout(later, wait);
+    };
+  };
+
+  // Returns a function that will be executed at most one time, no matter how
+  // often you call it. Useful for lazy initialization.
+  _.once = function(func) {
+    var ran = false, memo;
+    return function() {
+      if (ran) return memo;
+      ran = true;
+      return memo = func.apply(this, arguments);
+    };
+  };
+
+  // Returns the first function passed as an argument to the second,
+  // allowing you to adjust arguments, run code before and after, and
+  // conditionally execute the original function.
+  _.wrap = function(func, wrapper) {
+    return function() {
+      var args = [func].concat(slice.call(arguments, 0));
+      return wrapper.apply(this, args);
+    };
+  };
+
+  // Returns a function that is the composition of a list of functions, each
+  // consuming the return value of the function that follows.
+  _.compose = function() {
+    var funcs = arguments;
+    return function() {
+      var args = arguments;
+      for (var i = funcs.length - 1; i >= 0; i--) {
+        args = [funcs[i].apply(this, args)];
+      }
+      return args[0];
+    };
+  };
+
+  // Returns a function that will only be executed after being called N times.
+  _.after = function(times, func) {
+    if (times <= 0) return func();
+    return function() {
+      if (--times < 1) { return func.apply(this, arguments); }
+    };
+  };
+
+  // Object Functions
+  // ----------------
+
+  // Retrieve the names of an object's properties.
+  // Delegates to **ECMAScript 5**'s native `Object.keys`
+  _.keys = nativeKeys || function(obj) {
+    if (obj !== Object(obj)) throw new TypeError('Invalid object');
+    var keys = [];
+    for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key;
+    return keys;
+  };
+
+  // Retrieve the values of an object's properties.
+  _.values = function(obj) {
+    return _.map(obj, _.identity);
+  };
+
+  // Return a sorted list of the function names available on the object.
+  // Aliased as `methods`
+  _.functions = _.methods = function(obj) {
+    var names = [];
+    for (var key in obj) {
+      if (_.isFunction(obj[key])) names.push(key);
+    }
+    return names.sort();
+  };
+
+  // Extend a given object with all the properties in passed-in object(s).
+  _.extend = function(obj) {
+    each(slice.call(arguments, 1), function(source) {
+      for (var prop in source) {
+        obj[prop] = source[prop];
+      }
+    });
+    return obj;
+  };
+
+  // Return a copy of the object only containing the whitelisted properties.
+  _.pick = function(obj) {
+    var result = {};
+    each(_.flatten(slice.call(arguments, 1)), function(key) {
+      if (key in obj) result[key] = obj[key];
+    });
+    return result;
+  };
+
+  // Fill in a given object with default properties.
+  _.defaults = function(obj) {
+    each(slice.call(arguments, 1), function(source) {
+      for (var prop in source) {
+        if (obj[prop] == null) obj[prop] = source[prop];
+      }
+    });
+    return obj;
+  };
+
+  // Create a (shallow-cloned) duplicate of an object.
+  _.clone = function(obj) {
+    if (!_.isObject(obj)) return obj;
+    return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
+  };
+
+  // Invokes interceptor with the obj, and then returns obj.
+  // The primary purpose of this method is to "tap into" a method chain, in
+  // order to perform operations on intermediate results within the chain.
+  _.tap = function(obj, interceptor) {
+    interceptor(obj);
+    return obj;
+  };
+
+  // Internal recursive comparison function.
+  function eq(a, b, stack) {
+    // Identical objects are equal. `0 === -0`, but they aren't identical.
+    // See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal.
+    if (a === b) return a !== 0 || 1 / a == 1 / b;
+    // A strict comparison is necessary because `null == undefined`.
+    if (a == null || b == null) return a === b;
+    // Unwrap any wrapped objects.
+    if (a._chain) a = a._wrapped;
+    if (b._chain) b = b._wrapped;
+    // Invoke a custom `isEqual` method if one is provided.
+    if (a.isEqual && _.isFunction(a.isEqual)) return a.isEqual(b);
+    if (b.isEqual && _.isFunction(b.isEqual)) return b.isEqual(a);
+    // Compare `[[Class]]` names.
+    var className = toString.call(a);
+    if (className != toString.call(b)) return false;
+    switch (className) {
+      // Strings, numbers, dates, and booleans are compared by value.
+      case '[object String]':
+        // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
+        // equivalent to `new String("5")`.
+        return a == String(b);
+      case '[object Number]':
+        // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for
+        // other numeric values.
+        return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);
+      case '[object Date]':
+      case '[object Boolean]':
+        // Coerce dates and booleans to numeric primitive values. Dates are compared by their
+        // millisecond representations. Note that invalid dates with millisecond representations
+        // of `NaN` are not equivalent.
+        return +a == +b;
+      // RegExps are compared by their source patterns and flags.
+      case '[object RegExp]':
+        return a.source == b.source &&
+               a.global == b.global &&
+               a.multiline == b.multiline &&
+               a.ignoreCase == b.ignoreCase;
+    }
+    if (typeof a != 'object' || typeof b != 'object') return false;
+    // Assume equality for cyclic structures. The algorithm for detecting cyclic
+    // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
+    var length = stack.length;
+    while (length--) {
+      // Linear search. Performance is inversely proportional to the number of
+      // unique nested structures.
+      if (stack[length] == a) return true;
+    }
+    // Add the first object to the stack of traversed objects.
+    stack.push(a);
+    var size = 0, result = true;
+    // Recursively compare objects and arrays.
+    if (className == '[object Array]') {
+      // Compare array lengths to determine if a deep comparison is necessary.
+      size = a.length;
+      result = size == b.length;
+      if (result) {
+        // Deep compare the contents, ignoring non-numeric properties.
+        while (size--) {
+          // Ensure commutative equality for sparse arrays.
+          if (!(result = size in a == size in b && eq(a[size], b[size], stack))) break;
+        }
+      }
+    } else {
+      // Objects with different constructors are not equivalent.
+      if ('constructor' in a != 'constructor' in b || a.constructor != b.constructor) return false;
+      // Deep compare objects.
+      for (var key in a) {
+        if (_.has(a, key)) {
+          // Count the expected number of properties.
+          size++;
+          // Deep compare each member.
+          if (!(result = _.has(b, key) && eq(a[key], b[key], stack))) break;
+        }
+      }
+      // Ensure that both objects contain the same number of properties.
+      if (result) {
+        for (key in b) {
+          if (_.has(b, key) && !(size--)) break;
+        }
+        result = !size;
+      }
+    }
+    // Remove the first object from the stack of traversed objects.
+    stack.pop();
+    return result;
+  }
+
+  // Perform a deep comparison to check if two objects are equal.
+  _.isEqual = function(a, b) {
+    return eq(a, b, []);
+  };
+
+  // Is a given array, string, or object empty?
+  // An "empty" object has no enumerable own-properties.
+  _.isEmpty = function(obj) {
+    if (obj == null) return true;
+    if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
+    for (var key in obj) if (_.has(obj, key)) return false;
+    return true;
+  };
+
+  // Is a given value a DOM element?
+  _.isElement = function(obj) {
+    return !!(obj && obj.nodeType == 1);
+  };
+
+  // Is a given value an array?
+  // Delegates to ECMA5's native Array.isArray
+  _.isArray = nativeIsArray || function(obj) {
+    return toString.call(obj) == '[object Array]';
+  };
+
+  // Is a given variable an object?
+  _.isObject = function(obj) {
+    return obj === Object(obj);
+  };
+
+  // Is a given variable an arguments object?
+  _.isArguments = function(obj) {
+    return toString.call(obj) == '[object Arguments]';
+  };
+  if (!_.isArguments(arguments)) {
+    _.isArguments = function(obj) {
+      return !!(obj && _.has(obj, 'callee'));
+    };
+  }
+
+  // Is a given value a function?
+  _.isFunction = function(obj) {
+    return toString.call(obj) == '[object Function]';
+  };
+
+  // Is a given value a string?
+  _.isString = function(obj) {
+    return toString.call(obj) == '[object String]';
+  };
+
+  // Is a given value a number?
+  _.isNumber = function(obj) {
+    return toString.call(obj) == '[object Number]';
+  };
+
+  // Is a given object a finite number?
+  _.isFinite = function(obj) {
+    return _.isNumber(obj) && isFinite(obj);
+  };
+
+  // Is the given value `NaN`?
+  _.isNaN = function(obj) {
+    // `NaN` is the only value for which `===` is not reflexive.
+    return obj !== obj;
+  };
+
+  // Is a given value a boolean?
+  _.isBoolean = function(obj) {
+    return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
+  };
+
+  // Is a given value a date?
+  _.isDate = function(obj) {
+    return toString.call(obj) == '[object Date]';
+  };
+
+  // Is the given value a regular expression?
+  _.isRegExp = function(obj) {
+    return toString.call(obj) == '[object RegExp]';
+  };
+
+  // Is a given value equal to null?
+  _.isNull = function(obj) {
+    return obj === null;
+  };
+
+  // Is a given variable undefined?
+  _.isUndefined = function(obj) {
+    return obj === void 0;
+  };
+
+  // Has own property?
+  _.has = function(obj, key) {
+    return hasOwnProperty.call(obj, key);
+  };
+
+  // Utility Functions
+  // -----------------
+
+  // Run Underscore.js in *noConflict* mode, returning the `_` variable to its
+  // previous owner. Returns a reference to the Underscore object.
+  _.noConflict = function() {
+    root._ = previousUnderscore;
+    return this;
+  };
+
+  // Keep the identity function around for default iterators.
+  _.identity = function(value) {
+    return value;
+  };
+
+  // Run a function **n** times.
+  _.times = function (n, iterator, context) {
+    for (var i = 0; i < n; i++) iterator.call(context, i);
+  };
+
+  // Escape a string for HTML interpolation.
+  _.escape = function(string) {
+    return (''+string).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#x27;').replace(/\//g,'&#x2F;');
+  };
+
+  // If the value of the named property is a function then invoke it;
+  // otherwise, return it.
+  _.result = function(object, property) {
+    if (object == null) return null;
+    var value = object[property];
+    return _.isFunction(value) ? value.call(object) : value;
+  };
+
+  // Add your own custom functions to the Underscore object, ensuring that
+  // they're correctly added to the OOP wrapper as well.
+  _.mixin = function(obj) {
+    each(_.functions(obj), function(name){
+      addToWrapper(name, _[name] = obj[name]);
+    });
+  };
+
+  // Generate a unique integer id (unique within the entire client session).
+  // Useful for temporary DOM ids.
+  var idCounter = 0;
+  _.uniqueId = function(prefix) {
+    var id = idCounter++;
+    return prefix ? prefix + id : id;
+  };
+
+  // By default, Underscore uses ERB-style template delimiters, change the
+  // following template settings to use alternative delimiters.
+  _.templateSettings = {
+    evaluate    : /<%([\s\S]+?)%>/g,
+    interpolate : /<%=([\s\S]+?)%>/g,
+    escape      : /<%-([\s\S]+?)%>/g
+  };
+
+  // When customizing `templateSettings`, if you don't want to define an
+  // interpolation, evaluation or escaping regex, we need one that is
+  // guaranteed not to match.
+  var noMatch = /.^/;
+
+  // Certain characters need to be escaped so that they can be put into a
+  // string literal.
+  var escapes = {
+    '\\': '\\',
+    "'": "'",
+    'r': '\r',
+    'n': '\n',
+    't': '\t',
+    'u2028': '\u2028',
+    'u2029': '\u2029'
+  };
+
+  for (var p in escapes) escapes[escapes[p]] = p;
+  var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
+  var unescaper = /\\(\\|'|r|n|t|u2028|u2029)/g;
+
+  // Within an interpolation, evaluation, or escaping, remove HTML escaping
+  // that had been previously added.
+  var unescape = function(code) {
+    return code.replace(unescaper, function(match, escape) {
+      return escapes[escape];
+    });
+  };
+
+  // JavaScript micro-templating, similar to John Resig's implementation.
+  // Underscore templating handles arbitrary delimiters, preserves whitespace,
+  // and correctly escapes quotes within interpolated code.
+  _.template = function(text, data, settings) {
+    settings = _.defaults(settings || {}, _.templateSettings);
+
+    // Compile the template source, taking care to escape characters that
+    // cannot be included in a string literal and then unescape them in code
+    // blocks.
+    var source = "__p+='" + text
+      .replace(escaper, function(match) {
+        return '\\' + escapes[match];
+      })
+      .replace(settings.escape || noMatch, function(match, code) {
+        return "'+\n_.escape(" + unescape(code) + ")+\n'";
+      })
+      .replace(settings.interpolate || noMatch, function(match, code) {
+        return "'+\n(" + unescape(code) + ")+\n'";
+      })
+      .replace(settings.evaluate || noMatch, function(match, code) {
+        return "';\n" + unescape(code) + "\n;__p+='";
+      }) + "';\n";
+
+    // If a variable is not specified, place data values in local scope.
+    if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
+
+    source = "var __p='';" +
+      "var print=function(){__p+=Array.prototype.join.call(arguments, '')};\n" +
+      source + "return __p;\n";
+
+    var render = new Function(settings.variable || 'obj', '_', source);
+    if (data) return render(data, _);
+    var template = function(data) {
+      return render.call(this, data, _);
+    };
+
+    // Provide the compiled function source as a convenience for build time
+    // precompilation.
+    template.source = 'function(' + (settings.variable || 'obj') + '){\n' +
+      source + '}';
+
+    return template;
+  };
+
+  // Add a "chain" function, which will delegate to the wrapper.
+  _.chain = function(obj) {
+    return _(obj).chain();
+  };
+
+  // The OOP Wrapper
+  // ---------------
+
+  // If Underscore is called as a function, it returns a wrapped object that
+  // can be used OO-style. This wrapper holds altered versions of all the
+  // underscore functions. Wrapped objects may be chained.
+  var wrapper = function(obj) { this._wrapped = obj; };
+
+  // Expose `wrapper.prototype` as `_.prototype`
+  _.prototype = wrapper.prototype;
+
+  // Helper function to continue chaining intermediate results.
+  var result = function(obj, chain) {
+    return chain ? _(obj).chain() : obj;
+  };
+
+  // A method to easily add functions to the OOP wrapper.
+  var addToWrapper = function(name, func) {
+    wrapper.prototype[name] = function() {
+      var args = slice.call(arguments);
+      unshift.call(args, this._wrapped);
+      return result(func.apply(_, args), this._chain);
+    };
+  };
+
+  // Add all of the Underscore functions to the wrapper object.
+  _.mixin(_);
+
+  // Add all mutator Array functions to the wrapper.
+  each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
+    var method = ArrayProto[name];
+    wrapper.prototype[name] = function() {
+      var wrapped = this._wrapped;
+      method.apply(wrapped, arguments);
+      var length = wrapped.length;
+      if ((name == 'shift' || name == 'splice') && length === 0) delete wrapped[0];
+      return result(wrapped, this._chain);
+    };
+  });
+
+  // Add all accessor Array functions to the wrapper.
+  each(['concat', 'join', 'slice'], function(name) {
+    var method = ArrayProto[name];
+    wrapper.prototype[name] = function() {
+      return result(method.apply(this._wrapped, arguments), this._chain);
+    };
+  });
+
+  // Start chaining a wrapped Underscore object.
+  wrapper.prototype.chain = function() {
+    this._chain = true;
+    return this;
+  };
+
+  // Extracts the result from a wrapped and chained object.
+  wrapper.prototype.value = function() {
+    return this._wrapped;
+  };
+
+}).call(this);
+
+
+});
index 5914083..675203b 100644 (file)
@@ -165,6 +165,9 @@ section.graph .graph-info-pane .help-block {
   font-size: 11px;
   line-height: 1.3;
 }
+section.graph .graph-info-pane .graph-size-row input[type="text"] {
+  display: inline-block;
+}
 section.graph .graph-settings-row {
   max-width: 900px;
 }
diff --git a/www/js/limn.js b/www/js/limn.js
new file mode 120000 (symlink)
index 0000000..49bb346
--- /dev/null
@@ -0,0 +1 @@
+../../dist/limn.js
\ No newline at end of file
diff --git a/www/js/limn.min.js b/www/js/limn.min.js
new file mode 120000 (symlink)
index 0000000..4ae5317
--- /dev/null
@@ -0,0 +1 @@
+../../dist/limn.min.js
\ No newline at end of file
index 77a9946..8909c72 100644 (file)
@@ -1,10 +1,10 @@
 all: []
 
 production:
--   suffix: .js
+-   suffix: .min.js
     paths:
-    - vendor/vendor-bundle.min
-    - js/limn/app-bundle
+    - vendor/vendor-bundle
+    - js/limn.no-deps
 
 development:
 -   suffix: .js