Browse Source

Merge pull request #258 from AtomicGameEngine/JME-ATOMIC-JAKE

Adding Jake + Jakefile
JoshEngebretson 10 years ago
parent
commit
825318198e
100 changed files with 17176 additions and 0 deletions
  1. 3 0
      Build/Windows/Compile.bat
  2. 48 0
      Build/node_modules/jake/Jakefile
  3. 44 0
      Build/node_modules/jake/Makefile
  4. 10 0
      Build/node_modules/jake/README.md
  5. 25 0
      Build/node_modules/jake/bin/cli.js
  6. 382 0
      Build/node_modules/jake/lib/api.js
  7. 329 0
      Build/node_modules/jake/lib/jake.js
  8. 106 0
      Build/node_modules/jake/lib/loader.js
  9. 74 0
      Build/node_modules/jake/lib/namespace.js
  10. 408 0
      Build/node_modules/jake/lib/package_task.js
  11. 134 0
      Build/node_modules/jake/lib/parseargs.js
  12. 257 0
      Build/node_modules/jake/lib/program.js
  13. 307 0
      Build/node_modules/jake/lib/publish_task.js
  14. 327 0
      Build/node_modules/jake/lib/rule.js
  15. 29 0
      Build/node_modules/jake/lib/task/directory_task.js
  16. 136 0
      Build/node_modules/jake/lib/task/file_task.js
  17. 9 0
      Build/node_modules/jake/lib/task/index.js
  18. 314 0
      Build/node_modules/jake/lib/task/task.js
  19. 277 0
      Build/node_modules/jake/lib/test_task.js
  20. 258 0
      Build/node_modules/jake/lib/utils/index.js
  21. 24 0
      Build/node_modules/jake/lib/utils/logger.js
  22. 99 0
      Build/node_modules/jake/lib/watch_task.js
  23. 5 0
      Build/node_modules/jake/node_modules/async/.travis.yml
  24. 19 0
      Build/node_modules/jake/node_modules/async/LICENSE
  25. 1647 0
      Build/node_modules/jake/node_modules/async/README.md
  26. 38 0
      Build/node_modules/jake/node_modules/async/bower.json
  27. 16 0
      Build/node_modules/jake/node_modules/async/component.json
  28. 1123 0
      Build/node_modules/jake/node_modules/async/lib/async.js
  29. 84 0
      Build/node_modules/jake/node_modules/async/package.json
  30. 53 0
      Build/node_modules/jake/node_modules/async/support/sync-package-managers.js
  31. 63 0
      Build/node_modules/jake/node_modules/chalk/index.js
  32. 1 0
      Build/node_modules/jake/node_modules/chalk/node_modules/.bin/strip-ansi
  33. 38 0
      Build/node_modules/jake/node_modules/chalk/node_modules/ansi-styles/ansi-styles.js
  34. 75 0
      Build/node_modules/jake/node_modules/chalk/node_modules/ansi-styles/package.json
  35. 65 0
      Build/node_modules/jake/node_modules/chalk/node_modules/ansi-styles/readme.md
  36. 32 0
      Build/node_modules/jake/node_modules/chalk/node_modules/has-color/index.js
  37. 71 0
      Build/node_modules/jake/node_modules/chalk/node_modules/has-color/package.json
  38. 30 0
      Build/node_modules/jake/node_modules/chalk/node_modules/has-color/readme.md
  39. 27 0
      Build/node_modules/jake/node_modules/chalk/node_modules/strip-ansi/cli.js
  40. 4 0
      Build/node_modules/jake/node_modules/chalk/node_modules/strip-ansi/index.js
  41. 81 0
      Build/node_modules/jake/node_modules/chalk/node_modules/strip-ansi/package.json
  42. 46 0
      Build/node_modules/jake/node_modules/chalk/node_modules/strip-ansi/readme.md
  43. 78 0
      Build/node_modules/jake/node_modules/chalk/package.json
  44. 158 0
      Build/node_modules/jake/node_modules/chalk/readme.md
  45. 14 0
      Build/node_modules/jake/node_modules/filelist/Jakefile
  46. 84 0
      Build/node_modules/jake/node_modules/filelist/README.md
  47. 319 0
      Build/node_modules/jake/node_modules/filelist/index.js
  48. 1 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/.npmignore
  49. 23 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/LICENSE
  50. 218 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/README.md
  51. 1061 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/minimatch.js
  52. 1 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/lru-cache/.npmignore
  53. 8 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/lru-cache/.travis.yml
  54. 14 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/lru-cache/CONTRIBUTORS
  55. 15 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/lru-cache/LICENSE
  56. 109 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/lru-cache/README.md
  57. 274 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/lru-cache/lib/lru-cache.js
  58. 58 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/lru-cache/package.json
  59. 395 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/lru-cache/test/basic.js
  60. 120 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/lru-cache/test/foreach.js
  61. 51 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/lru-cache/test/memory-leak.js
  62. 15 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/sigmund/LICENSE
  63. 53 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/sigmund/README.md
  64. 283 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/sigmund/bench.js
  65. 60 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/sigmund/package.json
  66. 39 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/sigmund/sigmund.js
  67. 24 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/sigmund/test/basic.js
  68. 31 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/package.json
  69. 399 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/test/basic.js
  70. 33 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/test/brace-expand.js
  71. 14 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/test/caching.js
  72. 274 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/test/defaults.js
  73. 8 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/test/extglob-ending-with-state-char.js
  74. 42 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/Jakefile
  75. 6 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/README.md
  76. 94 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/array.js
  77. 298 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/async.js
  78. 128 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/core.js
  79. 928 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/date.js
  80. 109 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/event_buffer.js
  81. 557 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/file.js
  82. 73 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/i18n.js
  83. 59 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/index.js
  84. 222 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/inflection.js
  85. 69 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/log.js
  86. 72 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/network.js
  87. 108 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/object.js
  88. 143 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/request.js
  89. 558 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/sorted_collection.js
  90. 810 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/string.js
  91. 238 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/uri.js
  92. 282 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/xml.js
  93. 55 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/package.json
  94. 71 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/test/array.js
  95. 97 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/test/core.js
  96. 84 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/test/date.js
  97. 45 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/test/event_buffer.js
  98. 228 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/test/file.js
  99. 60 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/test/i18n.js
  100. 388 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/test/inflection.js

+ 3 - 0
Build/Windows/Compile.bat

@@ -0,0 +1,3 @@
+call "%VS140COMNTOOLS%..\..\VC\bin\vcvars32.bat"
+cmake ..\\..\\  -DATOMIC_DEV_BUILD=0 -G "Visual Studio 14 2015"
+msbuild /m Atomic.sln /p:Configuration=Release /p:Platform=Win32

+ 48 - 0
Build/node_modules/jake/Jakefile

@@ -0,0 +1,48 @@
+var fs = require('fs')
+  , path = require('path');
+
+testTask('Jake', function () {
+  this.testFiles.include('test/*.js');
+  this.testFiles.exclude('test/helpers.js');
+});
+
+namespace('doc', function () {
+  task('generate', ['doc:clobber'], function () {
+    var cmd = '../node-jsdoc-toolkit/app/run.js -n -r=100 ' +
+        '-t=../node-jsdoc-toolkit/templates/codeview -d=./doc/ ./lib';
+    jake.logger.log('Generating docs ...');
+    jake.exec([cmd], function () {
+      jake.logger.log('Done.');
+      complete();
+    });
+  }, {async: true});
+
+  task('clobber', function () {
+    var cmd = 'rm -fr ./doc/*';
+    jake.exec([cmd], function () {
+      jake.logger.log('Clobbered old docs.');
+      complete();
+    });
+  }, {async: true});
+
+});
+
+desc('Generate docs for Jake');
+task('doc', ['doc:generate']);
+
+npmPublishTask('jake', function () {
+  this.packageFiles.include([
+    'Makefile'
+  , 'Jakefile'
+  , 'README.md'
+  , 'package.json'
+  , 'lib/**'
+  , 'bin/**'
+  , 'test/**'
+    ]);
+  this.packageFiles.exclude([
+    'test/tmp'
+  ]);
+});
+
+

+ 44 - 0
Build/node_modules/jake/Makefile

@@ -0,0 +1,44 @@
+#
+# Jake JavaScript build tool
+# Copyright 2112 Matthew Eernisse ([email protected])
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+.PHONY: all build install clean uninstall
+
+PREFIX=/usr/local
+DESTDIR=
+
+all: build
+
+build:
+	@echo 'Jake built.'
+
+install:
+	@mkdir -p $(DESTDIR)$(PREFIX)/bin && \
+    mkdir -p $(DESTDIR)$(PREFIX)/lib/node_modules/jake && \
+    mkdir -p ./node_modules && \
+    npm install utilities minimatch && \
+		cp -R ./* $(DESTDIR)$(PREFIX)/lib/node_modules/jake/ && \
+		ln -snf ../lib/node_modules/jake/bin/cli.js $(DESTDIR)$(PREFIX)/bin/jake && \
+		chmod 755 $(DESTDIR)$(PREFIX)/lib/node_modules/jake/bin/cli.js && \
+		echo 'Jake installed.'
+
+clean:
+	@true
+
+uninstall:
+	@rm -f $(DESTDIR)$(PREFIX)/bin/jake && \
+		rm -fr $(DESTDIR)$(PREFIX)/lib/node_modules/jake/ && \
+		echo 'Jake uninstalled.'

+ 10 - 0
Build/node_modules/jake/README.md

@@ -0,0 +1,10 @@
+### Jake -- the JavaScript build tool for Node.js
+
+[![Build Status](https://api.travis-ci.org/jakejs/jake.png)](https://travis-ci.org/mde/jake)
+
+Documentation site at [http://jakejs.com](http://jakejs.com/)
+
+### License
+
+Licensed under the Apache License, Version 2.0
+(<http://www.apache.org/licenses/LICENSE-2.0>)

+ 25 - 0
Build/node_modules/jake/bin/cli.js

@@ -0,0 +1,25 @@
+#!/usr/bin/env node
+/*
+ * Jake JavaScript build tool
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+// Load `jake` global
+require('../lib/jake');
+
+var args = process.argv.slice(2);
+
+jake.run.apply(jake, args);

+ 382 - 0
Build/node_modules/jake/lib/api.js

@@ -0,0 +1,382 @@
+/*
+ * Jake JavaScript build tool
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+var api = new (function () {
+  /**
+    @name task
+    @static
+    @function
+    @description Creates a Jake Task
+    `
+    @param {String} name The name of the Task
+    @param {Array} [prereqs] Prerequisites to be run before this task
+    @param {Function} [action] The action to perform for this task
+    @param {Object} [opts]
+      @param {Boolean} [opts.asyc=false] Perform this task asynchronously.
+      If you flag a task with this option, you must call the global
+      `complete` method inside the task's action, for execution to proceed
+      to the next task.
+
+    @example
+    desc('This is the default task.');
+    task('default', function (params) {
+      console.log('This is the default task.');
+    });
+
+    desc('This task has prerequisites.');
+    task('hasPrereqs', ['foo', 'bar', 'baz'], function (params) {
+      console.log('Ran some prereqs first.');
+    });
+
+    desc('This is an asynchronous task.');
+    task('asyncTask', function () {
+      setTimeout(complete, 1000);
+    }, {async: true});
+   */
+  this.task = function (name, prereqs, action, opts) {
+    var args = Array.prototype.slice.call(arguments)
+      , type
+      , createdTask;
+    args.unshift('task');
+    createdTask = jake.createTask.apply(global, args);
+    jake.currentTaskDescription = null;
+    return createdTask;
+  };
+
+  /**
+    @name rule
+    @static
+    @function
+    @description Creates a Jake Suffix Rule
+    `
+    @param {String} pattern The suffix name of the objective
+    @param {String} source The suffix name of the objective
+    @param {Array} [prereqs] Prerequisites to be run before this task
+    @param {Function} [action] The action to perform for this task
+    @param {Object} [opts]
+      @param {Boolean} [opts.asyc=false] Perform this task asynchronously.
+      If you flag a task with this option, you must call the global
+      `complete` method inside the task's action, for execution to proceed
+      to the next task.
+    @example
+    desc('This is a rule, which does not support namespace or pattern.');
+    rule('.o', '.c', {async: true}, function () {
+      var cmd = util.format('gcc -o %s %s', this.name, this.source);
+      jake.exec([cmd], function () {
+        complete();
+      }, {printStdout: true});
+    });
+
+    desc('This rule has prerequisites.');
+    rule('.o', '.c', ['util.h'], {async: true}, function () {
+      var cmd = util.format('gcc -o %s %s', this.name, this.source);
+      jake.exec([cmd], function () {
+        complete();
+      }, {printStdout: true});
+    });
+
+    desc('This is a rule with patterns.');
+    rule('%.o', '%.c', {async: true}, function () {
+      var cmd = util.format('gcc -o %s %s', this.name, this.source);
+      jake.exec([cmd], function () {
+        complete();
+      }, {printStdout: true});
+    });
+
+    desc('This is another rule with patterns.');
+    rule('obj/%.o', 'src/%.c', {async: true}, function () {
+      var cmd = util.format('gcc -o %s %s', this.name, this.source);
+      jake.exec([cmd], function () {
+        complete();
+      }, {printStdout: true});
+    });
+
+    desc('This is an example with chain rules.');
+    rule('%.pdf', '%.dvi', {async: true}, function () {
+      var cmd = util.format('dvipdfm %s',this.source);
+      jake.exec([cmd], function () {
+        complete();
+      }, {printStdout: true});
+    });
+
+    rule('%.dvi', '%.tex', {async: true}, function () {
+      var cmd = util.format('latex %s',this.source);
+      jake.exec([cmd], function () {
+        complete();
+      }, {printStdout: true});
+    });
+
+    desc('This rule has a namespace.');
+    task('default', ['debug:obj/main.o]);
+
+    namespace('debug', {async: true}, function() {
+      rule('obj/%.o', 'src/%.c', function () {
+        // ...
+      });
+    }
+   */
+  this.rule = function () {
+    var args = Array.prototype.slice.call(arguments)
+      , arg
+      , pattern = args.shift()
+      , source = args.shift()
+      , prereqs = []
+      , action = function () {}
+      , opts = {}
+      , key = pattern.toString(); // May be a RegExp
+
+    while ((arg = args.shift())) {
+      if (typeof arg == 'function') {
+        action = arg;
+      }
+      else if (Array.isArray(arg)) {
+        prereqs = arg;
+      }
+      else {
+        opts = arg;
+      }
+    }
+
+    jake.currentNamespace.rules[key] = new jake.Rule({
+      pattern: pattern
+    , source: source
+    , prereqs: prereqs
+    , action: action
+    , opts: opts
+    , desc: jake.currentTaskDescription
+    , ns: jake.currentNamespace
+    });
+    jake.currentTaskDescription = null;
+  };
+
+  /**
+    @name directory
+    @static
+    @function
+    @description Creates a Jake DirectoryTask. Can be used as a prerequisite
+    for FileTasks, or for simply ensuring a directory exists for use with a
+    Task's action.
+    `
+    @param {String} name The name of the DiretoryTask
+
+    @example
+
+    // Creates the package directory for distribution
+    directory('pkg');
+   */
+  this.directory = function (name) {
+    var args = Array.prototype.slice.call(arguments)
+      , createdTask;
+    args.unshift('directory');
+    createdTask = jake.createTask.apply(global, args);
+    jake.currentTaskDescription = null;
+    return createdTask;
+  };
+
+  /**
+    @name file
+    @static
+    @function
+    @description Creates a Jake FileTask.
+    `
+    @param {String} name The name of the FileTask
+    @param {Array} [prereqs] Prerequisites to be run before this task
+    @param {Function} [action] The action to create this file, if it doesn't
+    exist already.
+    @param {Object} [opts]
+      @param {Array} [opts.asyc=false] Perform this task asynchronously.
+      If you flag a task with this option, you must call the global
+      `complete` method inside the task's action, for execution to proceed
+      to the next task.
+
+   */
+  this.file = function (name, prereqs, action, opts) {
+    var args = Array.prototype.slice.call(arguments)
+      , createdTask;
+    args.unshift('file');
+    createdTask = jake.createTask.apply(global, args);
+    jake.currentTaskDescription = null;
+    return createdTask;
+  };
+
+  /**
+    @name desc
+    @static
+    @function
+    @description Creates a description for a Jake Task (or FileTask,
+    DirectoryTask). When invoked, the description that iscreated will
+    be associated with whatever Task is created next.
+    `
+    @param {String} description The description for the Task
+   */
+  this.desc = function (description) {
+    jake.currentTaskDescription = description;
+  };
+
+  /**
+    @name namespace
+    @static
+    @function
+    @description Creates a namespace which allows logical grouping
+    of tasks, and prevents name-collisions with task-names. Namespaces
+    can be nested inside of other namespaces.
+    `
+    @param {String} name The name of the namespace
+    @param {Function} scope The enclosing scope for the namespaced tasks
+
+    @example
+    namespace('doc', function () {
+      task('generate', ['doc:clobber'], function () {
+        // Generate some docs
+      });
+
+      task('clobber', function () {
+        // Clobber the doc directory first
+      });
+    });
+   */
+  this.namespace = function (name, closure) {
+    var curr = jake.currentNamespace
+      , ns = curr.childNamespaces[name] || new jake.Namespace(name, curr);
+    curr.childNamespaces[name] = ns;
+    jake.currentNamespace = ns;
+    closure();
+    jake.currentNamespace = curr;
+    jake.currentTaskDescription = null;
+    return ns;
+  };
+
+  /**
+    @name complete
+    @static
+    @function
+    @description Completes an asynchronous task, allowing Jake's
+    execution to proceed to the next task. Calling complete globally or without
+    arguments completes the last task on the invocationChain. If you use parallel
+    execution of prereqs this will probably complete a wrong task. You should call this
+    function with this task as the first argument, before the optional return value.
+    Alternatively you can call task.complete()
+    `
+    @example
+    task('generate', ['doc:clobber'], function () {
+      exec('./generate_docs.sh', function (err, stdout, stderr) {
+        if (err || stderr) {
+          fail(err || stderr);
+        }
+        else {
+          console.log(stdout);
+          complete();
+        }
+      });
+    }, {async: true});
+   */
+  this.complete = function (task, val) {
+    //this should detect if the first arg is a task, but I guess it should be more thorough
+    if(task && task. _currentPrereqIndex >=0 ) {
+      task.complete(val);
+    } else {
+      val = task;
+      if(jake._invocationChain.length > 0) {
+        jake._invocationChain[jake._invocationChain.length-1].complete(val);
+      } else {
+      }
+    }
+  };
+
+  /**
+    @name fail
+    @static
+    @function
+    @description Causes Jake execution to abort with an error.
+    Allows passing an optional error code, which will be used to
+    set the exit-code of exiting process.
+    `
+    @param {Error|String} err The error to thow when aborting execution.
+    If this argument is an Error object, it will simply be thrown. If
+    a String, it will be used as the error-message. (If it is a multi-line
+    String, the first line will be used as the Error message, and the
+    remaining lines will be used as the error-stack.)
+
+    @example
+    task('createTests, function () {
+      if (!fs.existsSync('./tests')) {
+        fail('Test directory does not exist.');
+      }
+      else {
+        // Do some testing stuff ...
+      }
+    });
+   */
+  this.fail = function (err, code) {
+    var msg
+      , errObj;
+    if (code) {
+      jake.errorCode = code;
+    }
+    if (err) {
+      if (typeof err == 'string') {
+        // Use the initial or only line of the error as the error-message
+        // If there was a multi-line error, use the rest as the stack
+        msg = err.split('/n');
+        errObj = new Error(msg.shift());
+        if (msg.length) {
+          errObj.stack = msg.join('\n');
+        }
+        throw errObj;
+      }
+      else if (err instanceof Error) {
+        throw err;
+      }
+      else {
+        throw new Error(err.toString());
+      }
+    }
+    else {
+      throw new Error();
+    }
+  };
+
+  this.packageTask = function (name, version, definition) {
+    return new jake.PackageTask(name, version, definition);
+  };
+
+  this.publishTask = function (name, prereqs, opts, definition) {
+    return new jake.PublishTask(name, prereqs, opts, definition);
+  };
+
+  // Backward-compat
+  this.npmPublishTask = function (name, prereqs, opts, definition) {
+    return new jake.PublishTask(name, prereqs, opts, definition);
+  };
+
+  this.watchTask = function (name, taskNames, definition) {
+    return new jake.WatchTask(name, taskNames, definition);
+  };
+
+  this.testTask = function () {
+    var ctor = function () {}
+      , t;
+    ctor.prototype = jake.TestTask.prototype;
+    t = new ctor();
+    jake.TestTask.apply(t, arguments);
+    return t;
+  };
+
+})();
+
+module.exports = api;

+ 329 - 0
Build/node_modules/jake/lib/jake.js

@@ -0,0 +1,329 @@
+/*
+ * Jake JavaScript build tool
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+var EventEmitter = require('events').EventEmitter;
+// And so it begins
+global.jake = new EventEmitter();
+
+var fs = require('fs')
+  , path = require('path')
+  , chalk = require('chalk')
+  , taskNs = require('./task')
+  , Task = taskNs.Task
+  , FileTask = taskNs.FileTask
+  , DirectoryTask = taskNs.DirectoryTask
+  , Rule = require('./rule').Rule
+  , Namespace = require('./namespace').Namespace
+  , api = require('./api')
+  , utils = require('./utils')
+  , Program = require('./program').Program
+  , Loader = require('./loader').Loader
+  , pkg = JSON.parse(fs.readFileSync(__dirname + '/../package.json').toString());
+
+var MAX_RULE_RECURSION_LEVEL = 16;
+
+var Invocation = function (taskName, args) {
+  this.taskName = taskName;
+  this.args = args;
+};
+
+// Globalize jake and top-level API methods (e.g., `task`, `desc`)
+utils.mixin(global, api);
+
+// Copy utils onto base jake
+utils.mixin(jake, utils);
+// File utils should be aliased directly on base jake as well
+utils.mixin(jake, utils.file);
+
+utils.mixin(jake, new (function () {
+
+  this._invocationChain = [];
+
+  // Private variables
+  // =================
+  // Local reference for scopage
+  var self = this;
+
+  // Public properties
+  // =================
+  this.version = pkg.version;
+  // Used when Jake exits with a specific error-code
+  this.errorCode = undefined;
+  // Loads Jakefiles/jakelibdirs
+  this.loader = new Loader();
+  // Name/value map of all the various tasks defined in a Jakefile.
+  // Non-namespaced tasks are placed into 'default.'
+  this.defaultNamespace = new Namespace('default', null);
+  // For namespaced tasks -- tasks with no namespace are put into the
+  // 'default' namespace so lookup code can work the same for both
+  // namespaced and non-namespaced.
+  this.currentNamespace = this.defaultNamespace;
+  // Saves the description created by a 'desc' call that prefaces a
+  // 'task' call that defines a task.
+  this.currentTaskDescription = null;
+  this.program = new Program();
+  this.FileList = require('filelist').FileList;
+  this.PackageTask = require('./package_task').PackageTask;
+  this.PublishTask = require('./publish_task').PublishTask;
+  this.WatchTask = require('./watch_task').WatchTask;
+  this.TestTask = require('./test_task').TestTask;
+  this.Task = Task;
+  this.FileTask = FileTask;
+  this.DirectoryTask = DirectoryTask;
+  this.Namespace = Namespace;
+  this.Rule = Rule;
+
+  this.parseAllTasks = function () {
+    var _parseNs = function (name, ns) {
+      var nsTasks = ns.tasks
+        , task
+        , nsNamespaces = ns.childNamespaces
+        , fullName;
+      // Iterate through the tasks in each namespace
+      for (var q in nsTasks) {
+        task = nsTasks[q];
+        // Prefix namespaced tasks
+        fullName = name == 'default' ? q : name + ':' + q;
+        // Save with 'taskname' or 'namespace:taskname' key
+        task.fullName = fullName;
+        jake.Task[fullName] = task;
+      }
+      for (var p in nsNamespaces) {
+        fullName = (name == 'default') ? p : name + ':' + p;
+        _parseNs(fullName, nsNamespaces[p]);
+      }
+    };
+
+    _parseNs('default', jake.defaultNamespace);
+  };
+
+  /**
+   * Displays the list of descriptions avaliable for tasks defined in
+   * a Jakefile
+   */
+  this.showAllTaskDescriptions = function (f) {
+    var p
+      , maxTaskNameLength = 0
+      , task
+      , str = ''
+      , padding
+      , name
+      , descr
+      , filter = typeof f == 'string' ? f : null;
+
+    for (p in jake.Task) {
+      task = jake.Task[p];
+      // Record the length of the longest task name -- used for
+      // pretty alignment of the task descriptions
+      maxTaskNameLength = p.length > maxTaskNameLength ?
+        p.length : maxTaskNameLength;
+    }
+    // Print out each entry with descriptions neatly aligned
+    for (p in jake.Task) {
+      if (filter && p.indexOf(filter) == -1) {
+        continue;
+      }
+      task = jake.Task[p];
+
+      //name = '\033[32m' + p + '\033[39m ';
+      name = chalk.green(p);
+
+      // Create padding-string with calculated length
+      padding = (new Array(maxTaskNameLength - p.length + 2)).join(' ');
+
+      descr = task.description;
+      if (descr) {
+        descr = chalk.gray(descr);
+        console.log('jake ' + name + padding + descr);
+      }
+    }
+  };
+
+  this.createTask = function () {
+    var args = Array.prototype.slice.call(arguments)
+      , arg
+      , obj
+      , task
+      , type
+      , name
+      , action
+      , opts = {}
+      , prereqs = [];
+
+      type = args.shift();
+
+    // name, [deps], [action]
+    // Name (string) + deps (array) format
+    if (typeof args[0] == 'string') {
+      name = args.shift();
+      if (Array.isArray(args[0])) {
+        prereqs = args.shift();
+      }
+    }
+    // name:deps, [action]
+    // Legacy object-literal syntax, e.g.: {'name': ['depA', 'depB']}
+    else {
+      obj = args.shift();
+      for (var p in obj) {
+        prereqs = prereqs.concat(obj[p]);
+        name = p;
+      }
+    }
+
+    // Optional opts/callback or callback/opts
+    while ((arg = args.shift())) {
+      if (typeof arg == 'function') {
+        action = arg;
+      }
+      else {
+        opts = arg;
+      }
+    }
+
+    task = jake.currentNamespace.resolveTask(name);
+    if (task && !action) {
+      // Task already exists and no action, just update prereqs, and return it.
+      task.prereqs = task.prereqs.concat(prereqs);
+      return task;
+    }
+
+    switch (type) {
+      case 'directory':
+        action = function () {
+          jake.mkdirP(name);
+        };
+        task = new DirectoryTask(name, prereqs, action, opts);
+        break;
+      case 'file':
+        task = new FileTask(name, prereqs, action, opts);
+        break;
+      default:
+        task = new Task(name, prereqs, action, opts);
+    }
+
+    if (jake.currentTaskDescription) {
+      task.description = jake.currentTaskDescription;
+      jake.currentTaskDescription = null;
+    }
+    jake.currentNamespace.tasks[name] = task;
+    task.namespace = jake.currentNamespace;
+
+    // FIXME: Should only need to add a new entry for the current
+    // task-definition, not reparse the entire structure
+    jake.parseAllTasks();
+
+    return task;
+  };
+
+  this.attemptRule = function (name, ns, level) {
+    var prereqRule
+      , prereq;
+    if (level > MAX_RULE_RECURSION_LEVEL) {
+      return null;
+    }
+    // Check Rule
+    prereqRule = ns.matchRule(name);
+    if (prereqRule) {
+      prereq = prereqRule.createTask(name, level);
+    }
+    return prereq || null;
+  };
+
+  this.createPlaceholderFileTask = function (name, namespace) {
+    var nsPath = ''
+      , filePath = name.split(':').pop() // Strip any namespace
+      , parts
+      , fileTaskName
+      , task
+      , stats;
+
+    if (namespace) {
+      if (typeof namespace == 'string') {
+        nsPath = namespace;
+      }
+      else {
+        nsPath = namespace.path;
+      }
+    }
+
+    parts = nsPath.length ? nsPath.split(':') : [];
+    parts.push(filePath);
+    fileTaskName = parts.join(':');
+
+    task = jake.Task[fileTaskName];
+
+    // If there's not already an existing dummy FileTask for it,
+    // create one
+    if (!task) {
+      // Create a dummy FileTask only if file actually exists
+      if (fs.existsSync(filePath)) {
+        stats = fs.statSync(filePath);
+        task = new jake.FileTask(filePath);
+        task.fullName = fileTaskName;
+        task.modTime = stats.mtime;
+        task.dummy = true;
+        // Put this dummy Task in the global Tasks list so
+        // modTime will be eval'd correctly
+        jake.Task[fileTaskName] = task;
+      }
+    }
+
+    return task || null;
+  };
+
+
+  this.init = function () {
+    var self = this;
+    process.addListener('uncaughtException', function (err) {
+      self.program.handleErr(err);
+    });
+
+  };
+
+  this.run = function () {
+    var args = Array.prototype.slice.call(arguments)
+      , program = this.program
+      , loader = this.loader
+      , preempt
+      , opts;
+
+    program.parseArgs(args);
+    program.init();
+
+    preempt = program.firstPreemptiveOption();
+    if (preempt) {
+      preempt();
+    }
+    else {
+      opts = program.opts;
+      // Load Jakefile and jakelibdir files
+      var jakefileLoaded = loader.loadFile(opts.jakefile);
+      var jakelibdirLoaded = loader.loadDirectory(opts.jakelibdir);
+
+      if(!jakefileLoaded && !jakelibdirLoaded) {
+        fail('No Jakefile. Specify a valid path with -f/--jakefile, ' +
+            'or place one in the current directory.');
+      }
+
+      program.run();
+    }
+  };
+
+})());
+
+module.exports = jake;

+ 106 - 0
Build/node_modules/jake/lib/loader.js

@@ -0,0 +1,106 @@
+/*
+ * Jake JavaScript build tool
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+var path = require('path')
+  , fs = require('fs')
+  , existsSync = typeof fs.existsSync == 'function' ?
+      fs.existsSync : path.existsSync
+  , utils = require('utilities')
+  , CoffeeScript
+  , Loader;
+
+
+Loader = function () {
+
+  var JAKEFILE_PAT = /\.jake(\.js|\.coffee)?$/;
+
+  var _requireCoffee = function () {
+        try {
+          var cs = require('coffee-script');
+          // Ensure we support CoffeeScript versions older than 1.7.0
+          if (typeof cs.register == 'function') {
+            cs.register();
+          }
+        }
+        catch (e) {
+          fail('CoffeeScript is missing! Try `npm install coffee-script`');
+        }
+        return(cs);
+      };
+
+  this.loadFile = function (file) {
+    var jakefile = file ?
+            file.replace(/\.js$/, '').replace(/\.coffee$/, '') : 'Jakefile'
+      , fileSpecified = !!file
+      // Dear God, why?
+      , isCoffee = false
+      // Warning, recursive
+      , exists
+      , oldCwd = process.cwd();
+
+    exists = function () {
+      var cwd = process.cwd();
+      if (existsSync(jakefile) || existsSync(jakefile + '.js') ||
+        existsSync(jakefile + '.coffee')) {
+        return true;
+      }
+      if (!fileSpecified) {
+        process.chdir("..");
+        if (cwd === process.cwd()) {
+          // Restore the working directory on failure
+          process.chdir(oldCwd);
+          return false;
+        }
+        return exists();
+      }
+    };
+
+    if (!exists()) {
+      return false;
+    }
+
+    isCoffee = existsSync(jakefile + '.coffee');
+    if (isCoffee) {
+      CoffeeScript = _requireCoffee();
+    }
+    require(utils.file.absolutize(jakefile));
+    return true;
+  };
+
+  this.loadDirectory = function (d) {
+    var dirname = d || 'jakelib'
+      , dirlist;
+    dirname = utils.file.absolutize(dirname);
+    if (existsSync(dirname)) {
+      dirlist = fs.readdirSync(dirname);
+      dirlist.forEach(function (filePath) {
+        if (JAKEFILE_PAT.test(filePath)) {
+          if (/\.coffee$/.test(filePath)) {
+            CoffeeScript = _requireCoffee();
+          }
+          require(path.join(dirname, filePath));
+        }
+      });
+      return true;
+    }
+
+    return false;
+  };
+};
+
+module.exports.Loader = Loader;

+ 74 - 0
Build/node_modules/jake/lib/namespace.js

@@ -0,0 +1,74 @@
+
+var Namespace = function (name, parentNamespace) {
+  this.name = name;
+  this.parentNamespace = parentNamespace;
+  this.childNamespaces = {};
+  this.tasks = {};
+  this.rules = {};
+  this.path = this.getPath();
+};
+
+Namespace.prototype = new (function () {
+
+  this.resolveTask = function(relativeName) {
+    var parts = relativeName.split(':')
+      , name = parts.pop()
+      , ns = this.resolveNamespace(parts.join(':'));
+
+    return (ns && ns.tasks[name]) ||
+        (this.parentNamespace &&
+        this.parentNamespace.resolveTask(relativeName));
+  };
+
+  this.resolveNamespace = function(relativeName) {
+    var parts = relativeName.split(':')
+      , ns;
+
+    if (!relativeName) {
+      return this;
+    }
+
+    ns = this;
+    for (var i = 0, ii = parts.length; ns && i < ii; i++) {
+      ns = ns.childNamespaces[parts[i]];
+    }
+
+    return (ns || (this.parentNamespace &&
+        this.parentNamespace.resolveNamespace(relativeName)));
+  };
+
+  this.matchRule = function(relativeName) {
+    var parts = relativeName.split(':')
+      , name = parts.pop()
+      , ns = this.resolveNamespace(parts.join(':'))
+      , rules = ns ? ns.rules : []
+      , r
+      , match;
+
+    for (var p in rules) {
+      r = rules[p];
+      if (r.match(relativeName)) {
+        match = r;
+      }
+    }
+
+    return (ns && match) ||
+        (this.parentNamespace &&
+        this.parentNamespace.matchRule(relativeName));
+  };
+
+  this.getPath = function () {
+    var parts = []
+      , next = this;
+    while (!!next) {
+      parts.push(next.name);
+      next = next.parentNamespace;
+    }
+    parts.pop(); // Remove 'default'
+    return parts.reverse().join(':');
+  };
+
+})();
+
+module.exports.Namespace = Namespace;
+

+ 408 - 0
Build/node_modules/jake/lib/package_task.js

@@ -0,0 +1,408 @@
+/*
+ * Jake JavaScript build tool
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+var path = require('path')
+  , fs = require('fs')
+  , exec = require('child_process').exec
+  , FileList = require('filelist').FileList;
+
+/**
+  @name jake
+  @namespace jake
+*/
+/**
+  @name jake.PackageTask
+  @constructor
+  @description Instantiating a PackageTask creates a number of Jake
+  Tasks that make packaging and distributing your software easy.
+
+  @param {String} name The name of the project
+  @param {String} version The current project version (will be
+  appended to the project-name in the package-archive
+  @param {Function} definition Defines the contents of the package,
+  and format of the package-archive. Will be executed on the instantiated
+  PackageTask (i.e., 'this', will be the PackageTask instance),
+  to set the various instance-propertiess.
+
+  @example
+  var t = new jake.PackageTask('rous', 'v' + version, function () {
+    var files = [
+      'Capfile'
+    , 'Jakefile'
+    , 'README.md'
+    , 'package.json'
+    , 'app/*'
+    , 'bin/*'
+    , 'config/*'
+    , 'lib/*'
+    , 'node_modules/*'
+    ];
+    this.packageFiles.include(files);
+    this.packageFiles.exclude('node_modules/foobar');
+    this.needTarGz = true;
+  });
+
+ */
+var PackageTask = function () {
+  var args = Array.prototype.slice.call(arguments)
+    , name = args.shift()
+    , version = args.shift()
+    , definition = args.pop()
+    , prereqs = args.pop() || []; // Optional
+
+    prereqs = [].concat(prereqs); // Accept string or list
+
+  /**
+    @name jake.PackageTask#name
+    @public
+    @type {String}
+    @description The name of the project
+   */
+  this.name = name;
+  /**
+    @name jake.PackageTask#version
+    @public
+    @type {String}
+    @description The project version-string
+   */
+  this.version = version;
+  /**
+    @name jake.PackageTask#prereqs
+    @public
+    @type {Array}
+    @description Tasks to run before packaging
+   */
+  this.prereqs = prereqs;
+  /**
+    @name jake.PackageTask#version
+    @public
+    @type {String='pkg'}
+    @description The directory-name to use for packaging the software
+   */
+  this.packageDir = 'pkg';
+  /**
+    @name jake.PackageTask#packageFiles
+    @public
+    @type {jake.FileList}
+    @description The list of files and directories to include in the
+    package-archive
+   */
+  this.packageFiles = new FileList();
+  /**
+    @name jake.PackageTask#needTar
+    @public
+    @type {Boolean=false}
+    @description If set to true, uses the `tar` utility to create
+    a gzip .tgz archive of the package
+   */
+  this.needTar = false;
+  /**
+    @name jake.PackageTask#needTar
+    @public
+    @type {Boolean=false}
+    @description If set to true, uses the `tar` utility to create
+    a gzip .tar.gz archive of the package
+   */
+  this.needTarGz = false;
+  /**
+    @name jake.PackageTask#needTarBz2
+    @public
+    @type {Boolean=false}
+    @description If set to true, uses the `tar` utility to create
+    a bzip2 .bz2 archive of the package
+   */
+  this.needTarBz2 = false;
+  /**
+    @name jake.PackageTask#needJar
+    @public
+    @type {Boolean=false}
+    @description If set to true, uses the `jar` utility to create
+    a .jar archive of the package
+   */
+  this.needJar = false;
+  /**
+    @name jake.PackageTask#needZip
+    @public
+    @type {Boolean=false}
+    @description If set to true, uses the `zip` utility to create
+    a .zip archive of the package
+   */
+  this.needZip = false;
+  /**
+    @name jake.PackageTask#manifestFile
+    @public
+    @type {String=null}
+    @description Can be set to point the `jar` utility at a manifest
+    file to use in a .jar archive. If unset, one will be automatically
+    created by the `jar` utility. This path should be relative to the
+    root of the package directory (this.packageDir above, likely 'pkg')
+   */
+  this.manifestFile = null;
+  /**
+    @name jake.PackageTask#tarCommand
+    @public
+    @type {String='tar'}
+    @description The shell-command to use for creating tar archives.
+   */
+  this.tarCommand = 'tar';
+  /**
+    @name jake.PackageTask#jarCommand
+    @public
+    @type {String='jar'}
+    @description The shell-command to use for creating jar archives.
+   */
+  this.jarCommand = 'jar';
+  /**
+    @name jake.PackageTask#zipCommand
+    @public
+    @type {String='zip'}
+    @description The shell-command to use for creating zip archives.
+   */
+  this.zipCommand = 'zip';
+  /**
+    @name jake.PackageTask#archiveNoBaseDir
+    @public
+    @type {Boolean=false}
+    @description Simple option for performing the archive on the
+    contents of the directory instead of the directory itself
+   */
+  this.archiveNoBaseDir = false;
+  /**
+    @name jake.PackageTask#archiveChangeDir
+    @public
+    @type {String=null}
+    @description Equivalent to the '-C' command for the `tar` and `jar`
+    commands. ("Change to this directory before adding files.")
+   */
+  this.archiveChangeDir = null;
+  /**
+    @name jake.PackageTask#archiveContentDir
+    @public
+    @type {String=null}
+    @description Specifies the files and directories to include in the
+    package-archive. If unset, this will default to the main package
+    directory -- i.e., name + version.
+   */
+  this.archiveContentDir = null;
+
+  if (typeof definition == 'function') {
+    definition.call(this);
+  }
+  this.define();
+};
+
+PackageTask.prototype = new (function () {
+
+  var _compressOpts = {
+        Tar: {
+          ext: '.tgz'
+        , flags: 'cvzf'
+        , cmd: 'tar'
+        }
+      , TarGz: {
+          ext: '.tar.gz'
+        , flags: 'cvzf'
+        , cmd: 'tar'
+        }
+      , TarBz2: {
+          ext: '.tar.bz2'
+        , flags: 'cvjf'
+        , cmd: 'tar'
+        }
+      , Jar: {
+          ext: '.jar'
+        , flags: 'cf'
+        , cmd: 'jar'
+        }
+      , Zip: {
+          ext: '.zip'
+        , flags: 'r'
+        , cmd: 'zip'
+        }
+      };
+
+  this.define = function () {
+    var self = this
+      , packageDirPath = this.packageDirPath()
+      , compressTaskArr = [];
+
+    desc('Build the package for distribution');
+    task('package', self.prereqs.concat(['clobberPackage', 'buildPackage']));
+    // Backward-compat alias
+    task('repackage', ['package']);
+
+    task('clobberPackage', function () {
+      jake.rmRf(self.packageDir, {silent: true});
+    });
+
+    desc('Remove the package');
+    task('clobber', ['clobberPackage']);
+
+    var doCommand = function (p) {
+      var filename = path.resolve(self.packageDir + '/' + self.packageName() +
+                                  _compressOpts[p].ext);
+      if (process.platform == 'win32') {
+          // Windows full path may have drive letter, which is going to cause
+          // namespace problems, so strip it.
+          if (filename.length > 2 && filename[1] == ':') {
+            filename = filename.substr(2);
+          }
+      }
+      compressTaskArr.push(filename);
+
+      file(filename, [packageDirPath], function () {
+        var cmd
+        , opts = _compressOpts[p]
+        // Directory to move to when doing the compression-task
+        // Changes in the case of zip for emulating -C option
+        , chdir = self.packageDir
+        // Save the current dir so it's possible to pop back up
+        // after compressing
+        , currDir = process.cwd()
+        , archiveChangeDir
+        , archiveContentDir;
+
+        if (self.archiveNoBaseDir) {
+          archiveChangeDir = self.packageName();
+          archiveContentDir = '.* -x "../*"';
+        }
+        else {
+          archiveChangeDir = self.archiveChangeDir;
+          archiveContentDir = self.archiveContentDir;
+        }
+
+        cmd = self[opts.cmd + 'Command'];
+        cmd += ' -' + opts.flags;
+        if (opts.cmd == 'jar' && self.manifestFile) {
+          cmd += 'm';
+        }
+
+        // The name of the archive to create -- use full path
+        // so compression can be performed from a different dir
+        // if needed
+        cmd += ' ' + filename;
+
+        if (opts.cmd == 'jar' && self.manifestFile) {
+          cmd += ' ' + self.manifestFile;
+        }
+
+        // Where to perform the compression -- -C option isn't
+        // supported in zip, so actually do process.chdir for this
+        if (archiveChangeDir) {
+          if (opts.cmd == 'zip') {
+            chdir = path.join(chdir, archiveChangeDir);
+          }
+          else {
+            cmd += ' -C ' + archiveChangeDir;
+          }
+        }
+
+        // Where to get the archive content
+        if (archiveContentDir) {
+          cmd += ' ' + archiveContentDir;
+        }
+        else {
+          cmd += ' ' + self.packageName();
+        }
+
+        // Move into the desired dir (usually packageDir) to compress
+        // Return back up to the current dir after the exec
+        process.chdir(chdir);
+
+        exec(cmd, function (err, stdout, stderr) {
+          if (err) { throw err; }
+
+          // Return back up to the starting directory (see above,
+          // before exec)
+          process.chdir(currDir);
+
+          complete();
+        });
+      }, {async: true});
+    };
+
+    for (var p in _compressOpts) {
+      if (this['need' + p]) {
+        doCommand(p);
+      }
+    }
+
+    task('buildPackage', compressTaskArr, function () {});
+
+    directory(this.packageDir);
+
+    file(packageDirPath, this.packageFiles, function () {
+      jake.mkdirP(packageDirPath);
+      var fileList = [];
+      self.packageFiles.forEach(function (name) {
+        var f = path.join(self.packageDirPath(), name)
+          , fDir = path.dirname(f)
+          , stats;
+        jake.mkdirP(fDir, {silent: true});
+
+        // Add both files and directories
+        fileList.push({
+          from: name
+        , to: f
+        });
+      });
+      var _copyFile = function () {
+        var cmd
+          , file = fileList.pop()
+          , stat;
+        if (file) {
+          stat = fs.statSync(file.from);
+          // Target is a directory, just create it
+          if (stat.isDirectory()) {
+            jake.mkdirP(file.to, {silent: true});
+            _copyFile();
+          }
+          // Otherwise copy the file
+          else {
+            jake.cpR(file.from, file.to, {silent: true});
+            _copyFile();
+          }
+        }
+        else {
+          complete();
+        }
+      };
+      _copyFile();
+    }, {async: true});
+
+
+  };
+
+  this.packageName = function () {
+    if (this.version) {
+      return this.name + '-' + this.version;
+    }
+    else {
+      return this.name;
+    }
+  };
+
+  this.packageDirPath = function () {
+    return this.packageDir + '/' + this.packageName();
+  };
+
+})();
+
+jake.PackageTask = PackageTask;
+exports.PackageTask = PackageTask;
+

+ 134 - 0
Build/node_modules/jake/lib/parseargs.js

@@ -0,0 +1,134 @@
+/*
+ * Jake JavaScript build tool
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+var parseargs = {};
+
+/**
+ * @constructor
+ * Parses a list of command-line args into a key/value object of
+ * options and an array of positional commands.
+ * @ param {Array} opts A list of options in the following format:
+ * [{full: 'foo', abbr: 'f'}, {full: 'bar', abbr: 'b'}]]
+ */
+parseargs.Parser = function (opts) {
+  // A key/value object of matching options parsed out of the args
+  this.opts = {};
+  this.taskNames = null;
+  this.envVars = null;
+
+  // Data structures used for parsing
+  this.reg = [];
+  this.shortOpts = {};
+  this.longOpts = {};
+
+  var item;
+  for (var i = 0, ii = opts.length; i < ii; i++) {
+    item = opts[i];
+    this.shortOpts[item.abbr] = item;
+    this.longOpts[item.full] = item;
+  }
+  this.reg = opts;
+};
+
+parseargs.Parser.prototype = new function () {
+
+  var _trueOrNextVal = function (argParts, args) {
+        if (argParts[1]) {
+          return argParts[1];
+        }
+        else {
+          return (!args[0] || (args[0].indexOf('-') === 0)) ?
+              true : args.shift();
+        }
+      };
+
+  /**
+   * Parses an array of arguments into options and positional commands
+   * @param {Array} args The command-line args to parse
+   */
+  this.parse = function (args) {
+    var cmds = []
+      , cmd
+      , envVars = {}
+      , opts = {}
+      , arg
+      , argItem
+      , argParts
+      , cmdItems
+      , taskNames = []
+      , preempt;
+
+    while (args.length) {
+      arg = args.shift();
+
+      if (arg.indexOf('-') === 0) {
+        arg = arg.replace(/^--/, '').replace(/^-/, '');
+        argParts = arg.split('=');
+        argItem = this.longOpts[argParts[0]] || this.shortOpts[argParts[0]];
+        if (argItem) {
+          // First-encountered preemptive opt takes precedence -- no further opts
+          // or possibility of ambiguity, so just look for a value, or set to
+          // true and then bail
+          if (argItem.preempts) {
+            opts[argItem.full] = _trueOrNextVal(argParts, args);
+            preempt = true;
+            break;
+          }
+          // If the opt requires a value, see if we can get a value from the
+          // next arg, or infer true from no-arg -- if it's followed by another
+          // opt, throw an error
+          if (argItem.expectValue) {
+            opts[argItem.full] = _trueOrNextVal(argParts, args);
+            if (!opts[argItem.full]) {
+              throw new Error(argItem.full + ' option expects a value.');
+            }
+          }
+          else {
+            opts[argItem.full] = true;
+          }
+        }
+      }
+      else {
+        cmds.unshift(arg);
+      }
+    }
+
+    if (!preempt) {
+      // Parse out any env-vars and task-name
+      while (!!(cmd = cmds.pop())) {
+        cmdItems = cmd.split('=');
+        if (cmdItems.length > 1) {
+          envVars[cmdItems[0]] = cmdItems[1];
+        }
+        else {
+          taskNames.push(cmd);
+        }
+      }
+
+    }
+
+    return {
+      opts: opts
+    , envVars: envVars
+    , taskNames: taskNames
+    };
+  };
+
+};
+
+module.exports = parseargs;

+ 257 - 0
Build/node_modules/jake/lib/program.js

@@ -0,0 +1,257 @@
+/*
+ * Jake JavaScript build tool
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+var fs = require('fs')
+  , parseargs = require('./parseargs')
+  , utils = require('./utils')
+  , Program
+  , optsReg
+  , preempts
+  , usage
+  , die;
+
+optsReg = [
+  { full: 'jakefile'
+  , abbr: 'f'
+  , preempts: false
+  , expectValue: true
+  }
+, { full: 'quiet'
+  , abbr: 'q'
+  , preempts: false
+  , expectValue: false
+  }
+, { full: 'directory'
+  , abbr: 'C'
+  , preempts: false
+  , expectValue: true
+  }
+, { full: 'always-make'
+  , abbr: 'B'
+  , preempts: false
+  , expectValue: false
+  }
+, { full: 'tasks'
+  , abbr: 'T'
+  , preempts: true
+  }
+// Alias ls
+, { full: 'tasks'
+  , abbr: 'ls'
+  , preempts: true
+  }
+, { full: 'trace'
+  , abbr: 't'
+  , preempts: false
+  , expectValue: false
+  }
+, { full: 'help'
+  , abbr: 'h'
+  , preempts: true
+  }
+, { full: 'version'
+  , abbr: 'V'
+  , preempts: true
+  }
+  // Alias lowercase v
+, { full: 'version'
+  , abbr: 'v'
+  , preempts: true
+  }
+, { full: 'jakelibdir'
+  , abbr: 'J'
+  , preempts: false
+  , expectValue: true
+  }
+];
+
+preempts = {
+  version: function () {
+    die(jake.version);
+  }
+, help: function () {
+    die(usage);
+  }
+};
+
+usage = ''
+    + 'Jake JavaScript build tool\n'
+    + '********************************************************************************\n'
+    + 'If no flags are given, Jake looks for a Jakefile or Jakefile.js in the current directory.\n'
+    + '********************************************************************************\n'
+    + '{Usage}: jake [options ...] [env variables ...] target\n'
+    + '\n'
+    + '{Options}:\n'
+    + '  -f,     --jakefile FILE            Use FILE as the Jakefile.\n'
+    + '  -C,     --directory DIRECTORY      Change to DIRECTORY before running tasks.\n'
+    + '  -q,     --quiet                    Do not log messages to standard output.\n'
+    + '  -B,     --always-make              Unconditionally make all targets.\n'
+    + '  -T/ls,  --tasks                 Display the tasks (matching optional PATTERN) with descriptions, then exit.\n'
+    + '  -J,     --jakelibdir JAKELIBDIR    Auto-import any .jake files in JAKELIBDIR. (default is \'jakelib\')\n'
+    + '  -t,     --trace                    Enable full backtrace.\n'
+    + '  -h,     --help                     Display this help message.\n'
+    + '  -V/v,   --version                  Display the Jake version.\n'
+    + '';
+
+Program = function () {
+  this.opts = {};
+  this.taskNames = null;
+  this.taskArgs = null;
+  this.envVars = null;
+};
+
+Program.prototype = new (function () {
+
+  this.handleErr = function (err) {
+    if(jake.listeners('error').length !== 0) {
+      jake.emit('error', err);
+      return;
+    }
+
+    var msg;
+
+    if (jake.listeners('error').length) {
+      jake.emit('error', err);
+      return;
+    }
+
+    utils.logger.error('jake aborted.');
+    if (this.opts.trace && err.stack) {
+      utils.logger.error(err.stack);
+    }
+    else {
+      if (err.stack) {
+        msg = err.stack.split('\n').slice(0, 3).join('\n');
+        utils.logger.error(msg);
+        utils.logger.error('(See full trace by running task with --trace)');
+      }
+      else {
+        utils.logger.error(err.message);
+      }
+    }
+    process.stdout.write('', function() {
+      process.stderr.write('', function() {
+        jake.errorCode = jake.errorCode || 1;
+        process.exit(jake.errorCode);
+      });
+    });
+  };
+
+  this.parseArgs = function (args) {
+    var result = (new parseargs.Parser(optsReg)).parse(args);
+    this.setOpts(result.opts);
+    this.setTaskNames(result.taskNames);
+    this.setEnvVars(result.envVars);
+  };
+
+  this.setOpts = function (options) {
+    var opts = options || {};
+    utils.mixin(this.opts, opts);
+  };
+
+  this.setTaskNames = function (names) {
+    if (names && !Array.isArray(names)) {
+      throw new Error('Task names must be an array');
+    }
+    this.taskNames = (names && names.length) ? names : ['default'];
+  };
+
+  this.setEnvVars = function (vars) {
+    this.envVars = vars || null;
+  };
+
+  this.firstPreemptiveOption = function () {
+    var opts = this.opts;
+    for (var p in opts) {
+      if (preempts[p]) {
+        return preempts[p];
+      }
+    }
+    return false;
+  };
+
+  this.init = function (configuration) {
+    var self = this
+      , config = configuration || {};
+    if (config.options) {
+      this.setOpts(config.options);
+    }
+    if (config.taskNames) {
+      this.setTaskNames(config.taskNames);
+    }
+    if (config.envVars) {
+      this.setEnvVars(config.envVars);
+    }
+    process.addListener('uncaughtException', function (err) {
+      self.handleErr(err);
+    });
+    if (this.envVars) {
+      utils.mixin(process.env, this.envVars);
+    }
+  };
+
+  this.run = function () {
+    var rootTask
+      , taskNames
+      , dirname
+      , opts = this.opts;
+
+    // Run with `jake -T`, just show descriptions
+    if (opts.tasks) {
+      return jake.showAllTaskDescriptions(opts.tasks);
+    }
+
+    taskNames = this.taskNames;
+    if (!(Array.isArray(taskNames) && taskNames.length)) {
+      throw new Error('Please pass jake.runTasks an array of task-names');
+    }
+
+    // Set working dir
+    dirname = opts.directory;
+    if (dirname) {
+      if (utils.file.existsSync(dirname) &&
+        fs.statSync(dirname).isDirectory()) {
+        process.chdir(dirname);
+      }
+      else {
+        throw new Error(dirname + ' is not a valid directory path');
+      }
+    }
+
+    task('__root__', taskNames, function () {});
+
+    rootTask = jake.Task.__root__;
+    rootTask.once('complete', function () {
+      jake.emit('complete');
+    });
+    jake.emit('start');
+    rootTask.invoke();
+  };
+
+})();
+
+die = function (msg) {
+  console.log(msg);
+  process.stdout.write('', function() {
+    process.stderr.write('', function() {
+      process.exit();
+	});
+  });
+};
+
+module.exports.Program = Program;

+ 307 - 0
Build/node_modules/jake/lib/publish_task.js

@@ -0,0 +1,307 @@
+/*
+ * Jake JavaScript build tool
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+var fs = require('fs')
+  , path = require('path')
+  , exec = require('child_process').exec
+  , utils = require('utilities')
+  , FileList = require('filelist').FileList;
+
+var PublishTask = function () {
+  var args = Array.prototype.slice.call(arguments).filter(function (item) {
+        return typeof item != 'undefined';
+      })
+    , arg
+    , opts = {}
+    , definition
+    , prereqs = []
+    , createDef = function (arg) {
+        return function () {
+          this.packageFiles.include(arg);
+        };
+      };
+
+  this.name = args.shift();
+
+  // Old API, just name + list of files
+  if (args.length == 1 && (Array.isArray(args[0]) || typeof args[0] == 'string')) {
+    definition = createDef(args.pop());
+  }
+  // Current API, name + [prereqs] + [opts] + definition
+  else {
+    while ((arg = args.pop())) {
+      // Definition func
+      if (typeof arg == 'function') {
+        definition = arg;
+      }
+      // Prereqs
+      else if (Array.isArray(arg) || typeof arg == 'string') {
+        prereqs = arg;
+      }
+      // Opts
+      else {
+        opts = arg;
+      }
+    }
+  }
+
+  this.prereqs = prereqs;
+  this.packageFiles = new FileList();
+  this.publishCmd = opts.publishCmd || 'npm publish %filename';
+  this.gitCmd = opts.gitCmd || 'git';
+  this.versionFiles = opts.versionFiles || ['package.json'];
+  this.scheduleDelay = 5000;
+
+  // Override utility funcs for testing
+  this._ensureRepoClean = function (stdout) {
+    if (stdout.length) {
+      fail(new Error('Git repository is not clean.'));
+    }
+  };
+  this._getCurrentBranch = function (stdout) {
+    return utils.string.trim(stdout);
+  };
+
+  if (typeof definition == 'function') {
+    definition.call(this);
+  }
+  this.define();
+};
+
+
+PublishTask.prototype = new (function () {
+
+  var _currentBranch = null;
+
+  var getPackage = function () {
+        var pkg = JSON.parse(fs.readFileSync(path.join(process.cwd(),
+            '/package.json')).toString());
+        return pkg;
+      }
+    , getPackageVersionNumber = function () {
+        return getPackage().version;
+      };
+
+  this.define = function () {
+    var self = this;
+
+    namespace('publish', function () {
+      task('fetchTags', {async: true}, function () {
+        // Make sure local tags are up to date
+        var cmds = [
+          self.gitCmd + ' fetch --tags'
+        ];
+        jake.exec(cmds, function () {
+          console.log('Fetched remote tags.');
+          complete();
+        });
+      });
+
+      task('getCurrentBranch', {async: true}, function () {
+        // Figure out what branch to push to
+        exec(self.gitCmd + ' symbolic-ref --short HEAD',
+            function (err, stdout, stderr) {
+          if (err) {
+            fail(err);
+          }
+          if (stderr) {
+            fail(new Error(stderr));
+          }
+          if (!stdout) {
+            fail(new Error('No current Git branch found'));
+          }
+          _currentBranch = self._getCurrentBranch(stdout);
+          console.log('On branch ' + _currentBranch);
+          complete();
+        });
+      });
+
+      task('ensureClean', {async: true}, function () {
+        // Only bump, push, and tag if the Git repo is clean
+        exec(self.gitCmd + ' status --porcelain --untracked-files=no',
+            function (err, stdout, stderr) {
+          if (err) {
+            fail(err);
+          }
+          if (stderr) {
+            fail(new Error(stderr));
+          }
+
+          // Throw if there's output
+          self._ensureRepoClean(stdout);
+
+          complete();
+        });
+      });
+
+      task('updateVersionFiles', function () {
+        var pkg
+          , version
+          , arr
+          , patch;
+
+        // Grab the current version-string
+        pkg = getPackage();
+        version = pkg.version;
+        // Increment the patch-number for the version
+        arr = version.split('.');
+        patch = parseInt(arr.pop(), 10) + 1;
+        arr.push(patch);
+        version = arr.join('.');
+
+        // Update package.json or other files with the new version-info
+        self.versionFiles.forEach(function (file) {
+          var p = path.join(process.cwd(), file)
+            , data = JSON.parse(fs.readFileSync(p).toString());
+          data.version = version;
+          fs.writeFileSync(p, JSON.stringify(data, true, 2) + '\n');
+        });
+        // Return the version string so that listeners for the 'complete' event
+        // for this task can use it (e.g., to update other files before pushing
+        // to Git)
+        return version;
+      });
+
+      task('pushVersion', ['ensureClean', 'updateVersionFiles'], {async: true},
+          function () {
+        var version = getPackageVersionNumber()
+          , message = 'Version ' + version
+          , cmds = [
+              self.gitCmd + ' commit -a -m "' + message + '"'
+            , self.gitCmd + ' push origin ' + _currentBranch
+            , self.gitCmd + ' tag -a v' + version + ' -m "' + message + '"'
+            , self.gitCmd + ' push --tags'
+            ];
+
+        var execOpts = {};
+        if (process.platform == 'win32') {
+          // Windows won't like the quotes in our cmdline
+          execOpts.windowsVerbatimArguments = true;
+        }
+
+        jake.exec(cmds, function () {
+          var version = getPackageVersionNumber();
+          console.log('Bumped version number to v' + version + '.');
+          complete();
+        }, execOpts);
+
+      });
+
+      task('definePackage', function () {
+        var version = getPackageVersionNumber()
+          , t;
+        t = new jake.PackageTask(self.name, 'v' + version, self.prereqs, function () {
+          // Replace the PackageTask's FileList with the PublishTask's FileList
+          this.packageFiles = self.packageFiles;
+          this.needTarGz = true; // Default to tar.gz
+          // If any of the need<CompressionFormat> or archive opts are set
+          // proxy them to the PackageTask
+          for (var p in this) {
+            if (p.indexOf('need') === 0 || p.indexOf('archive') === 0) {
+              if (typeof self[p] != 'undefined') {
+                this[p] = self[p];
+              }
+            }
+          }
+        });
+      });
+
+      task('package', {async: true}, function () {
+        var definePack = jake.Task['publish:definePackage']
+          , pack = jake.Task.package
+          , version = getPackageVersionNumber();
+
+        // May have already been run
+        definePack.reenable(true);
+        definePack.addListener('complete', function () {
+          pack.addListener('complete', function () {
+            console.log('Created package for ' + self.name + ' v' + version);
+            complete();
+          });
+          pack.invoke();
+        });
+        definePack.invoke();
+      });
+
+      task('publish', {async: true}, function () {
+        var version = getPackageVersionNumber()
+          , filename
+          , cmd;
+
+        console.log('Publishing ' + self.name + ' v' + version);
+
+        if (typeof self.createPublishCommand == 'function') {
+          cmd = self.createPublishCommand(version);
+        }
+        else {
+          filename = 'pkg/' + self.name + '-v' + version + '.tar.gz';
+          cmd = self.publishCmd.replace(/%filename/gi, filename);
+        }
+
+        // Hackity hack -- NPM publish sometimes returns errror like:
+        // Error sending version data\nnpm ERR!
+        // Error: forbidden 0.2.4 is modified, should match modified time
+        setTimeout(function () {
+          jake.exec(cmd, function () {
+            console.log('BOOM! Published.');
+            complete();
+          }, {printStdout: true, printStderr: true});
+        }, self.scheduleDelay);
+      });
+
+      task('cleanup', {async: true}, function () {
+        var clobber = jake.Task.clobber;
+        clobber.reenable(true);
+        clobber.on('complete', function () {
+          console.log('Cleaned up package');
+          complete();
+        });
+        clobber.invoke();
+      });
+
+    });
+
+    var prefixNs = function (item) {
+      return 'publish:' + item;
+    };
+
+    // Create aliases in the default namespace
+    desc('Create a new version and release.');
+    task('publish', self.prereqs.concat(['version', 'release']
+        .map(prefixNs)));
+
+    desc('Release the existing version.');
+    task('publishExisting', self.prereqs.concat(['release']
+        .map(prefixNs)));
+
+    task('version', ['fetchTags', 'getCurrentBranch', 'pushVersion']
+        .map(prefixNs));
+
+    task('release', ['package', 'publish', 'cleanup']
+        .map(prefixNs));
+
+    // Invoke proactively so there will be a callable 'package' task
+    // which can be used apart from 'publish'
+    jake.Task['publish:definePackage'].invoke();
+  };
+
+})();
+
+jake.PublishTask = PublishTask;
+exports.PublishTask = PublishTask;
+

+ 327 - 0
Build/node_modules/jake/lib/rule.js

@@ -0,0 +1,327 @@
+var path = require('path')
+  , fs = require('fs')
+  , Task = require('./task/task').Task
+  , Matcher
+  , rule = {}
+  , Rule;
+
+// Define a helper object with some utility functions
+Matcher = new (function () {
+
+  // Split a task to two parts, name space and task name.
+  // For example, given 'foo:bin/a%.c', return an object with
+  // - 'ns'     : foo
+  // - 'name'   : bin/a%.c
+  this.split = function(task) {
+    var parts = task.split(':')
+    , name  = parts.pop()
+    , ns    = this.resolveNS( parts );
+    return {
+      'name' : name,
+      'ns'   : ns
+    };
+  };
+
+  // Return the namespace based on an array of names.
+  // For example, given ['foo', 'baz' ], return the namespace
+  //
+  //   default -> foo -> baz
+  //
+  // where default is the global root namespace
+  // and -> means child namespace.
+  this.resolveNS = function(parts) {
+    var  ns    = jake.defaultNamespace;
+    for(var i = 0, l = parts.length; ns && i < l; i++) {
+      ns = ns.childNamespaces[parts[i]];
+    }
+    return ns;
+  };
+
+  // Given a pattern p, say 'foo:bin/a%.c'
+  // Return an object with
+  // - 'ns'     : foo
+  // - 'dir'    : bin
+  // - 'prefix' : a
+  // - 'suffix' : .c
+  this.resolve = function(p) {
+    var task = this.split(p),
+        name  = task.name,
+        ns    = task.ns;
+    var split = path.basename(name).split('%');
+    return {
+      ns: ns
+    , dir: path.dirname(name)
+    , prefix: split[0]
+    , suffix: split[1]
+    };
+  };
+
+  // Test whether string a is a suffix of string b
+  this.stringEndWith = function (a,b) {
+    var l;
+    return (l = b.lastIndexOf(a)) == -1 ? false : l + a.length == b.length;
+  };
+
+  // Replace the suffix a of the string s with b.
+  // Note that, it is assumed a is a suffix of s.
+  this.stringReplaceSuffix = function (s, a, b) {
+    return s.slice(0,s.lastIndexOf(a)) + b;
+  };
+
+  // Test wether the a prerequisite matchs the pattern.
+  // The arg 'pattern' does not have namespace as prefix.
+  // For example, the following tests are true
+  //
+  //   pattern      |    name
+  //   bin/%.o      |    bin/main.o
+  //   bin/%.o      |    foo:bin/main.o
+  //
+  // The following tests are false (trivally)
+  //
+  //   pattern      |    name
+  //   bin/%.o      |    foobin/main.o
+  //   bin/%.o      |    bin/main.oo
+  this.match = function(pattern, name) {
+    var p
+      , task
+      , ns
+      , obj
+      , filename;
+
+    if (pattern instanceof RegExp) {
+      return pattern.test(name);
+    }
+    else if (pattern.indexOf('%') == -1) {
+      // No Pattern. No Folder. No Namespace.
+      // A Simple Suffix Rule. Just test suffix
+      return this.stringEndWith(pattern, name);
+    }
+    else {
+      // Resolve the dir, prefix and suffix of pattern
+      p = this.resolve(pattern);
+
+      // Resolve the namespace and task-name
+      task = this.split(name);
+      name = task.name;
+      ns = task.ns;
+
+      // Set the objective as the task-name
+      obj = name;
+
+      // Namespace is already matched.
+
+      // Check dir
+      if (path.dirname(obj) != p.dir) {
+        return false;
+      }
+
+      filename = path.basename(obj);
+
+      // Check file name length
+      if ((p.prefix.length + p.suffix.length + 1) > filename.length) {
+        // Length does not match.
+        return false;
+      }
+
+      // Check prefix
+      if (filename.indexOf(p.prefix) !== 0) {
+        return false;
+      }
+
+      // Check suffix
+      if (!this.stringEndWith(p.suffix, filename)) {
+        return false;
+      }
+
+      // OK. Find a match.
+      return true;
+    }
+  };
+
+  // Generate the source based on
+  //  - name    name for the synthesized task
+  //  - pattern    pattern for the objective
+  //  - source    pattern for the source
+  //
+  // Return the source with properties
+  //  - dep      the prerequisite of source
+  //             (with the namespace)
+  //
+  //  - file     the file name of source
+  //             (without the namespace)
+  //
+  // For example, given
+  //
+  //  - name   foo:bin/main.o
+  //  - pattern    bin/%.o
+  //  - source    src/%.c
+  //
+  //    return 'foo:src/main.c',
+  //
+  this.getSource = function(name, pattern, source) {
+    var dep
+      , pat
+      , match
+      , file
+      , src;
+
+    // Regex pattern -- use to look up the extension
+    if (pattern instanceof RegExp) {
+      match = pattern.exec(name);
+      if (match) {
+        if (typeof source == 'function') {
+          src = source(name);
+        }
+        else {
+          src = this.stringReplaceSuffix(name, match[0], source);
+        }
+      }
+    }
+    // Assume string
+    else {
+      // Simple string suffix replacement
+      if (pattern.indexOf('%') == -1) {
+        if (typeof source == 'function') {
+          src = source(name);
+        }
+        else {
+          src = this.stringReplaceSuffix(name, pattern, source);
+        }
+      }
+      // Percent-based substitution
+      else {
+        pat = pattern.replace('%', '(.*?)');
+        pat = new RegExp(pat);
+        match = pat.exec(name);
+        if (match) {
+          if (typeof source == 'function') {
+            src = source(name);
+          }
+          else {
+            file = match[1];
+            file = source.replace('%', file);
+            dep = match[0];
+            src = name.replace(dep, file);
+          }
+        }
+      }
+    }
+
+    return src;
+  };
+
+})();
+
+
+Rule = function (opts) {
+  this.pattern = opts.pattern;
+  this.source = opts.source;
+  this.prereqs = opts.prereqs;
+  this.action = opts.action;
+  this.opts = opts.opts;
+  this.desc =  opts.desc;
+  this.ns = opts.ns;
+};
+
+Rule.prototype = new (function () {
+  // Create a file task based on this rule for the specified
+  // task-name
+  // ======
+  // FIXME: Right now this just throws away any passed-in args
+  // for the synthsized task (taskArgs param)
+  // ======
+  this.createTask = function (fullName, level) {
+    var self = this
+      , pattern
+      , source
+      , action
+      , opts
+      , prereqs
+      , parts
+      , valid
+      , src
+      , tNs
+      , createdTask
+      , name = Task.getBaseTaskName(fullName)
+      , nsPath = Task.getBaseNamespacePath(fullName)
+      , ns = this.ns.resolveNamespace(nsPath);
+
+    pattern = this.pattern;
+    source = this.source;
+
+    if (typeof source == 'string') {
+      src = Matcher.getSource(name, pattern, source);
+    }
+    else {
+      src = source(name);
+    }
+
+    // TODO: Write a utility function that appends a
+    // taskname to a namespace path
+    src = nsPath.split(':').filter(function (item) {
+      return !!item;
+    }).concat(src).join(':');
+
+    // Generate the prerequisite for the matching task.
+    //    It is the original prerequisites plus the prerequisite
+    //    representing source file, i.e.,
+    //
+    //      rule( '%.o', '%.c', ['some.h'] ...
+    //
+    //    If the objective is main.o, then new task should be
+    //
+    //      file( 'main.o', ['main.c', 'some.h' ] ...
+    prereqs = this.prereqs.slice(); // Get a copy to work with
+    prereqs.unshift(src);
+
+    // Prereq should be:
+    // 1. an existing task
+    // 2. an existing file on disk
+    // 3. a valid rule (i.e., not at too deep a level)
+    valid = prereqs.some(function (p) {
+      var ns = self.ns;
+      return ns.resolveTask(p) ||
+        fs.existsSync(Task.getBaseTaskName(p)) ||
+        jake.attemptRule(p, ns, level + 1);
+    });
+
+    // If any of the prereqs aren't valid, the rule isn't valid
+    if (!valid) {
+      return null;
+    }
+    // Otherwise, hunky-dory, finish creating the task for the rule
+    else {
+      // Create the action for the task
+      action = function () {
+        var task = this;
+        self.action.apply(task);
+      };
+
+      opts = this.opts;
+
+      // Insert the file task into Jake
+      //
+      // Since createTask function stores the task as a child task
+      // of currentNamespace. Here we temporariliy switch the namespace.
+      // FIXME: Should allow optional ns passed in instead of this hack
+      tNs = jake.currentNamespace;
+      jake.currentNamespace = ns;
+      createdTask = jake.createTask('file', name, prereqs, action, opts);
+      createdTask.source = src.split(':').pop();
+      jake.currentNamespace = tNs;
+
+      return createdTask;
+    }
+
+  };
+
+  this.match = function (name) {
+    return Matcher.match(this.pattern, name);
+  };
+
+})();
+
+rule.Rule = Rule;
+rule.Matcher = Matcher;
+
+module.exports = rule;

+ 29 - 0
Build/node_modules/jake/lib/task/directory_task.js

@@ -0,0 +1,29 @@
+var DirectoryTask
+  , FileTask = require('./file_task').FileTask;
+
+/**
+  @name jake
+  @namespace jake
+*/
+/**
+  @name jake.DirectoryTask
+  @constructor
+  @augments EventEmitter
+  @augments jake.Task
+  @augments jake.FileTask
+  @description A Jake DirectoryTask
+
+  @param {String} name The name of the directory to create.
+ */
+DirectoryTask = function (name) {
+  this.modTime = null;
+  // Do constructor-work only on actual instances, not when used
+  // for inheritance
+  if (arguments.length) {
+    this.init.apply(this, arguments);
+  }
+};
+DirectoryTask.prototype = new FileTask();
+DirectoryTask.prototype.constructor = DirectoryTask;
+
+exports.DirectoryTask = DirectoryTask;

+ 136 - 0
Build/node_modules/jake/lib/task/file_task.js

@@ -0,0 +1,136 @@
+var fs = require('fs')
+  , Task = require('./task').Task
+  , FileTask
+  , FileBase
+  , DirectoryTask
+  , utils = require('../utils');
+
+FileBase = new (function () {
+  var isFileOrDirectory = function (t) {
+        return (t instanceof FileTask ||
+            t instanceof DirectoryTask);
+      }
+    , isFile = function (t) {
+        return (t instanceof FileTask && !(t instanceof DirectoryTask));
+      };
+
+  this.isNeeded = function () {
+    var runAction = false
+      , prereqs = this.prereqs
+      , prereqName
+      , prereqTask;
+
+    // No repeatsies
+    if (this.taskStatus === Task.runStatuses.DONE) {
+      return false;
+    }
+    // The always-make override
+    else if (jake.program.opts['always-make']) {
+      // Run if there actually is an action
+      if (typeof this.action == 'function') {
+        return true;
+      }
+      else {
+        return false;
+      }
+    }
+    // Default case
+    else {
+      // We need either an existing file, or an action to create one.
+      // First try grabbing the actual mod-time of the file
+      try {
+        this.updateModTime();
+      }
+      // Then fall back to looking for an action
+      catch(e) {
+        if (typeof this.action == 'function') {
+          return true;
+        }
+        else {
+          throw new Error('File-task ' + this.fullName + ' has no ' +
+            'existing file, and no action to create one.');
+        }
+      }
+
+      // Compare mod-time of all the prereqs with its mod-time
+      // If any prereqs are newer, need to run the action to update
+      if (prereqs && prereqs.length) {
+        for (var i = 0, ii = prereqs.length; i < ii; i++) {
+          prereqName = prereqs[i];
+          prereqTask = this.namespace.resolveTask(prereqName) ||
+            jake.createPlaceholderFileTask(prereqName, this.namespace);
+          // Run the action if:
+          // 1. The prereq is a normal task (not file/dir)
+          // 2. The prereq is a file-task with a mod-date more recent than
+          // the one for this file/dir
+          if (prereqTask) {
+            if (!isFileOrDirectory(prereqTask) ||
+                (isFile(prereqTask) && prereqTask.modTime > this.modTime)) {
+              return true;
+            }
+          }
+        }
+      }
+      // File/dir has no prereqs, and exists -- no need to run
+      else {
+        return false;
+      }
+    }
+  };
+
+  this.updateModTime = function () {
+    var stats = fs.statSync(this.name);
+    this.modTime = stats.mtime;
+  };
+
+  this.complete = function () {
+    jake._invocationChain.splice(jake._invocationChain.indexOf(this),1);
+    if (!this.dummy) {
+      this.updateModTime();
+    }
+    this._currentPrereqIndex = 0;
+    this.taskStatus = Task.runStatuses.DONE;
+    this.emit('complete');
+  };
+
+})();
+
+/**
+  @name jake
+  @namespace jake
+*/
+/**
+  @name jake.FileTask
+  @constructor
+  @augments EventEmitter
+  @augments jake.Task
+  @description A Jake FileTask
+
+  @param {String} name The name of the Task
+  @param {Array} [prereqs] Prerequisites to be run before this task
+  @param {Function} [action] The action to perform to create this file
+  @param {Object} [opts]
+    @param {Array} [opts.asyc=false] Perform this task asynchronously.
+    If you flag a task with this option, you must call the global
+    `complete` method inside the task's action, for execution to proceed
+    to the next task.
+ */
+FileTask = function (name, prereqs, action, opts) {
+  this.modTime = null;
+  this.dummy = false;
+  // Do constructor-work only on actual instances, not when used
+  // for inheritance
+  if (arguments.length) {
+    this.init.apply(this, arguments);
+  }
+};
+FileTask.prototype = new Task();
+FileTask.prototype.constructor = FileTask;
+utils.mixin(FileTask.prototype, FileBase);
+
+exports.FileTask = FileTask;
+
+// DirectoryTask is a subclass of FileTask, depends on it
+// being defined
+DirectoryTask = require('./directory_task').DirectoryTask;
+

+ 9 - 0
Build/node_modules/jake/lib/task/index.js

@@ -0,0 +1,9 @@
+
+var Task = require('./task').Task
+  , FileTask = require('./file_task').FileTask
+  , DirectoryTask = require('./directory_task').DirectoryTask;
+
+exports.Task = Task;
+exports.FileTask = FileTask;
+exports.DirectoryTask = DirectoryTask;
+

+ 314 - 0
Build/node_modules/jake/lib/task/task.js

@@ -0,0 +1,314 @@
+var util = require('util') // Native Node util module
+  , path = require('path')
+  , EventEmitter = require('events').EventEmitter
+  , Task
+  , TaskBase
+  , utils = require('../utils')
+  , async = require('async')
+  , rule; // Lazy-require this at the bottom
+
+var UNDEFINED_VALUE;
+
+/**
+  @name jake
+  @namespace jake
+*/
+/**
+  @name jake.Task
+  @constructor
+  @augments EventEmitter
+  @description A Jake Task
+
+  @param {String} name The name of the Task
+  @param {Array} [prereqs] Prerequisites to be run before this task
+  @param {Function} [action] The action to perform for this task
+  @param {Object} [opts]
+    @param {Array} [opts.asyc=false] Perform this task asynchronously.
+    If you flag a task with this option, you must call the global
+    `complete` method inside the task's action, for execution to proceed
+    to the next task.
+ */
+Task = function () {
+  // Do constructor-work only on actual instances, not when used
+  // for inheritance
+  if (arguments.length) {
+    this.init.apply(this, arguments);
+  }
+};
+
+util.inherits(Task, EventEmitter);
+
+TaskBase = new (function () {
+
+  // Parse any positional args attached to the task-name
+  var parsePrereqName = function (name) {
+        var taskArr = name.split('[')
+          , taskName = taskArr[0]
+          , taskArgs = [];
+        if (taskArr[1]) {
+          taskArgs = taskArr[1].replace(/\]$/, '');
+          taskArgs = taskArgs.split(',');
+        }
+        return {
+          name: taskName
+        , args: taskArgs
+        };
+      };
+
+  /**
+    @name jake.Task#event:complete
+    @event
+   */
+
+  this.init = function (name, prereqs, action, options) {
+    var opts = options || {};
+
+    this._currentPrereqIndex = 0;
+
+    this.name = name;
+    this.prereqs = prereqs;
+    this.action = action;
+    this.async = false;
+    this.taskStatus = Task.runStatuses.UNSTARTED;
+    this.fullName = null;
+    this.description = null;
+    this.args = [];
+    this.value = UNDEFINED_VALUE;
+    this.namespace = null;
+    this.parallelLimit = 1;
+
+    // Support legacy async-flag -- if not explicitly passed or falsy, will
+    // be set to empty-object
+    if (typeof opts == 'boolean' && opts === true) {
+      this.async = true;
+    }
+    else {
+      if (opts.async) {
+        this.async = true;
+      }
+      if (opts.parallelLimit) {
+        this.parallelLimit = opts.parallelLimit;
+      }
+    }
+  };
+
+  /**
+    @name jake.Task#invoke
+    @function
+    @description Runs prerequisites, then this task. If the task has already
+    been run, will not run the task again.
+   */
+  this.invoke = function () {
+    jake._invocationChain.push(this);
+    this.args = Array.prototype.slice.call(arguments);
+    this.runPrereqs();
+  };
+
+  /**
+    @name jake.Task#execute
+    @function
+    @description Runs prerequisites, then this task. If the task has already
+    been run, will not run the task again.
+   */
+  this.execute = function () {
+    jake._invocationChain.push(this);
+    this.args = Array.prototype.slice.call(arguments);
+    this.reenable();
+    this.run();
+  };
+
+  this.runPrereqs = function () {
+    if (this.prereqs && this.prereqs.length) {
+      if(this.parallelLimit > 1) {
+        var currenttask = this;
+        async.eachLimit(currenttask.prereqs,currenttask.parallelLimit,function(name, cb) {
+
+          var parsed = parsePrereqName(name);
+
+          var prereq = currenttask.namespace.resolveTask(parsed.name) ||
+          jake.attemptRule(name, currenttask.namespace, 0) ||
+          jake.createPlaceholderFileTask(name, currenttask.namespace);
+
+          if (!prereq) {
+            throw new Error('Unknown task "' + name + '"');
+          }
+
+          if (prereq.taskStatus === Task.runStatuses.DONE) {
+            //prereq already done, return
+            cb();
+          } else {
+            //wait for complete before calling cb
+            prereq.once('complete', function () {
+              cb();
+            });
+            //start te prereq if we are the first to encounter it
+            if(prereq.taskStatus === Task.runStatuses.UNSTARTED) {
+              prereq.taskStatus = Task.runStatuses.RUNNING;
+              prereq.invoke.apply(prereq, parsed.args);
+            }
+          }
+        }, function(err) {
+          //async callback is called after all prereqs have run.
+          currenttask.run();
+        });
+      } else {
+        this.nextPrereq();
+      }
+    }
+    else {
+      this.run();
+    }
+  };
+
+  this.nextPrereq = function () {
+    var self = this
+      , index = this._currentPrereqIndex
+      , name = this.prereqs[index]
+      , prereq
+      , parsed
+      , filePath
+      , stats;
+
+    if (name) {
+
+      parsed = parsePrereqName(name);
+
+      prereq = this.namespace.resolveTask(parsed.name) ||
+          jake.attemptRule(name, this.namespace, 0) ||
+          jake.createPlaceholderFileTask(name, this.namespace);
+
+      if (!prereq) {
+        throw new Error('Unknown task "' + name + '"');
+      }
+
+      // Do when done
+      if (prereq.taskStatus === Task.runStatuses.DONE) {
+        self.handlePrereqComplete(prereq);
+      } else {
+        prereq.once('complete', function () {
+          self.handlePrereqComplete(prereq);
+        });
+        if(prereq.taskStatus === Task.runStatuses.UNSTARTED) {
+           prereq.taskStatus = Task.runStatuses.RUNNING;
+           prereq.invoke.apply(prereq, parsed.args);
+        }
+      }
+    }
+  };
+
+  /**
+    @name jake.Task#reenable
+    @function
+    @description Reenables a task so that it can be run again.
+   */
+  this.reenable = function (deep) {
+    var prereqs
+      , prereq;
+    this.taskStatus = Task.runStatuses.UNSTARTED;
+    this.value = UNDEFINED_VALUE;
+    if (deep && this.prereqs) {
+      prereqs = this.prereqs;
+      for (var i = 0, ii = prereqs.length; i < ii; i++) {
+        prereq = jake.Task[prereqs[i]];
+        if (prereq) {
+          prereq.reenable(deep);
+        }
+      }
+    }
+  };
+
+  this.handlePrereqComplete = function (prereq) {
+    var self = this;
+    this._currentPrereqIndex++;
+    if (this._currentPrereqIndex < this.prereqs.length) {
+      setTimeout(function () {
+        self.nextPrereq();
+      }, 0);
+    }
+    else {
+      this.run();
+    }
+  };
+
+  this.isNeeded = function () {
+    if (this.taskStatus === Task.runStatuses.DONE || typeof this.action != 'function') {
+      return false;
+    }
+    return true;
+  };
+
+  this.run = function () {
+    var runAction = this.isNeeded()
+      , val;
+
+    if (runAction) {
+      this.emit('start');
+      try {
+        val = this.action.apply(this, this.args);
+
+        if (typeof val == 'object' && typeof val.then == 'function') {
+          this.async = true;
+
+          val.then(
+            function(result) {
+              setTimeout(function() {
+                  complete(result);
+                },
+                0);
+            },
+            function(err) {
+              setTimeout(function() {
+                  fail(err);
+                },
+                0);
+            });
+        }
+      }
+      catch (e) {
+        this.emit('error', e);
+        return; // Bail out, not complete
+      }
+    }
+    else {
+      this.emit('skip');
+    }
+
+    if (!(runAction && this.async)) {
+      this.complete(val);
+    }
+  };
+
+  this.complete = function (val) {
+    jake._invocationChain.splice(jake._invocationChain.indexOf(this),1);
+
+    this._currentPrereqIndex = 0;
+    this.taskStatus = Task.runStatuses.DONE;
+
+    // If 'complete' getting called because task has been
+    // run already, value will not be passed -- leave in place
+    if (typeof val != 'undefined') {
+      this.value = val;
+    }
+
+    this.emit('complete', this.value);
+  };
+
+})();
+utils.mixin(Task.prototype, TaskBase);
+
+Task.getBaseNamespacePath = function (fullName) {
+  return fullName.split(':').slice(0, -1).join(':');
+};
+
+Task.getBaseTaskName = function (fullName) {
+  return fullName.split(':').pop();
+};
+
+//The task is in one of three states
+Task.runStatuses = {UNSTARTED: 'unstarted', DONE: 'done', STARTED: 'started'};
+
+exports.Task = Task;
+
+// Lazy-require
+rule = require('../rule');
+

+ 277 - 0
Build/node_modules/jake/lib/test_task.js

@@ -0,0 +1,277 @@
+/*
+ * Jake JavaScript build tool
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+var path = require('path')
+  , fs = require('fs')
+  , exec = require('child_process').exec
+  , currDir = process.cwd();
+
+/**
+  @name jake
+  @namespace jake
+*/
+/**
+  @name jake.TestTask
+  @constructor
+  @description Instantiating a TestTask creates a number of Jake
+  Tasks that make running tests for your software easy.
+
+  @param {String} name The name of the project
+  @param {Function} definition Defines the list of files containing the tests,
+  and the name of the namespace/task for running them. Will be executed on the
+  instantiated TestTask (i.e., 'this', will be the TestTask instance), to set
+  the various instance-propertiess.
+
+  @example
+  var t = new jake.TestTask('bij-js', function () {
+    this.testName = 'testSpecial';
+    this.testFiles.include('test/**');
+  });
+
+ */
+var TestTask = function () {
+  var self = this
+    , args = Array.prototype.slice.call(arguments)
+    , name = args.shift()
+    , definition = args.pop()
+    , prereqs = args.pop() || [];
+
+  /**
+    @name jake.TestTask#testNam
+    @public
+    @type {String}
+    @description The name of the namespace to place the tests in, and
+    the top-level task for running tests. Defaults to "test"
+   */
+  this.testName = 'test';
+
+  /**
+    @name jake.TestTask#testFiles
+    @public
+    @type {jake.FileList}
+    @description The list of files containing tests to load
+   */
+  this.testFiles = new jake.FileList();
+
+  /**
+    @name jake.TestTask#showDescription
+    @public
+    @type {Boolean}
+    @description Show the created task when doing Jake -T
+   */
+  this.showDescription = true;
+
+  /*
+    @name jake.TestTask#totalTests
+    @public
+    @type {Number}
+    @description The total number of tests to run
+  */
+  this.totalTests = 0;
+
+  /*
+    @name jake.TestTask#executedTests
+    @public
+    @type {Number}
+    @description The number of tests successfully run
+  */
+  this.executedTests = 0;
+
+  if (typeof definition == 'function') {
+    definition.call(this);
+  }
+
+  if (this.showDescription) {
+    desc('Run the tests for ' + name);
+  }
+
+  task(this.testName, prereqs, {async: true}, function () {
+    var t = jake.Task[self.testName + ':run'];
+    t.on('complete', function () {
+      complete();
+    });
+    // Pass args to the namespaced test
+    t.invoke.apply(t, arguments);
+  });
+
+  namespace(self.testName, function () {
+
+    task('run', {async: true}, function (pat) {
+      var p = pat || '.*'
+        , re
+        , testFiles;
+
+      // Don't nest; make a top-level namespace. Don't want
+      // re-calling from inside to nest infinitely
+     jake.currentNamespace = jake.defaultNamespace;
+
+      re = new RegExp(pat);
+      // Get test files that match the passed-in pattern
+      testFiles = self.testFiles.toArray()
+          .filter(function (f) {
+        return (re).test(f);
+      }) // Don't load the same file multiple times -- should this be in FileList?
+          .reduce(function(p, c) {
+        if (p.indexOf(c) < 0) {
+          p.push(c);
+        }
+        return p;
+      }, []);
+
+      // Create a namespace for all the testing tasks to live in
+      namespace(self.testName + 'Exec', function () {
+        // Each test will be a prereq for the dummy top-level task
+        var prereqs = []
+        // Continuation to pass to the async tests, wrapping `continune`
+          , next = function () {
+              complete();
+            }
+        // Create the task for this test-function
+          , createTask = function (name, action) {
+              // If the test-function is defined with a continuation
+              // param, flag the task as async
+              var t
+                , isAsync = !!action.length;
+
+              // Define the actual namespaced task with the name, the
+              // wrapped action, and the correc async-flag
+              t = task(name, createAction(name, action), {
+                async: isAsync
+              });
+              t.once('complete', function () {
+                self.executedTests++;
+              });
+            }
+        // Used as the action for the defined task for each test.
+          , createAction = function (n, a) {
+              // A wrapped function that passes in the `next` function
+              // for any tasks that run asynchronously
+              return function () {
+                var cb
+                  , msg;
+                if (a.length) {
+                  cb = next;
+                }
+                if (!(n == 'before' || n == 'after' ||
+                    /_beforeEach$/.test(n) || /_afterEach$/.test(n))) {
+                  if (n.toLowerCase().indexOf('test') === 0) {
+                    msg = n;
+                  }
+                  else {
+                    msg = 'test ' + n;
+                  }
+                  jake.logger.log(n);
+                }
+                // 'this' will be the task when action is run
+                return a.call(this, cb);
+              };
+            }
+          // Dummy top-level task for everything to be prereqs for
+          , topLevel;
+
+        // Pull in each test-file, and iterate over any exported
+        // test-functions. Register each test-function as a prereq task
+        testFiles.forEach(function (file) {
+          var exp = require(path.join(currDir, file))
+            , name
+            , action
+            , isAsync;
+
+          // Create a namespace for each filename, so test-name collisions
+          // won't be a problem
+          namespace(file, function () {
+            var testPrefix = self.testName + 'Exec:' + file + ':'
+              , testName;
+            // Dummy task for displaying file banner
+            testName = '*** Running ' + file + ' ***';
+            prereqs.push(testPrefix + testName);
+            createTask(testName, function () {});
+
+            // 'before' setup
+            if (typeof exp.before == 'function') {
+              prereqs.push(testPrefix + 'before');
+              // Create the task
+              createTask('before', exp.before);
+            }
+
+            // Walk each exported function, and create a task for each
+            for (var p in exp) {
+              if (p == 'before' || p == 'after' ||
+                  p == 'beforeEach' || p == 'afterEach') {
+                continue;
+              }
+
+              if (typeof exp.beforeEach == 'function') {
+                prereqs.push(testPrefix + p + '_beforeEach');
+                // Create the task
+                createTask(p + '_beforeEach', exp.beforeEach);
+              }
+
+              // Add the namespace:name of this test to the list of prereqs
+              // for the dummy top-level task
+              prereqs.push(testPrefix + p);
+              // Create the task
+              createTask(p, exp[p]);
+
+              if (typeof exp.afterEach == 'function') {
+                prereqs.push(testPrefix + p + '_afterEach');
+                // Create the task
+                createTask(p + '_afterEach', exp.afterEach);
+              }
+            }
+
+            // 'after' teardown
+            if (typeof exp.after == 'function') {
+              prereqs.push(testPrefix + 'after');
+              // Create the task
+              createTask('after', exp.after);
+            }
+
+          });
+        });
+
+        self.totalTests = prereqs.length;
+        process.on('exit', function () {
+          // Throw in the case where the process exits without
+          // finishing tests, but no error was thrown
+          if (!jake.errorCode && (self.totalTests > self.executedTests)) {
+            throw new Error('Process exited without all tests completing.');
+          }
+        });
+
+        // Create the dummy top-level task. When calling a task internally
+        // with `invoke` that is async (or has async prereqs), have to listen
+        // for the 'complete' event to know when it's done
+        topLevel = task('__top__', prereqs);
+        topLevel.addListener('complete', function () {
+          jake.logger.log('All tests ran successfully');
+          complete();
+        });
+
+        topLevel.invoke(); // Do the thing!
+      });
+
+    });
+  });
+
+
+};
+
+jake.TestTask = TestTask;
+exports.TestTask = TestTask;
+

+ 258 - 0
Build/node_modules/jake/lib/utils/index.js

@@ -0,0 +1,258 @@
+/*
+ * Jake JavaScript build tool
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+
+var util = require('util') // Native Node util module
+  , exec = require('child_process').exec
+  , spawn = require('child_process').spawn
+  , EventEmitter = require('events').EventEmitter
+  , utils = require('utilities')
+  , logger = require('./logger')
+  , Exec;
+
+var parseArgs = function (argumentsObj) {
+    var args
+      , arg
+      , cmds
+      , callback
+      , opts = {
+          interactive: false
+        , printStdout: false
+        , printStderr: false
+        , breakOnError: true
+        };
+
+    args = Array.prototype.slice.call(argumentsObj);
+
+    cmds = args.shift();
+    // Arrayize if passed a single string command
+    if (typeof cmds == 'string') {
+      cmds = [cmds];
+    }
+    // Make a copy if it's an actual list
+    else {
+      cmds = cmds.slice();
+    }
+
+    // Get optional callback or opts
+    while((arg = args.shift())) {
+      if (typeof arg == 'function') {
+        callback = arg;
+      }
+      else if (typeof arg == 'object') {
+        utils.mixin(opts, arg);
+      }
+    }
+
+    // Backward-compat shim
+    if (typeof opts.stdout != 'undefined') {
+      opts.printStdout = opts.stdout;
+      delete opts.stdout;
+    }
+    if (typeof opts.stderr != 'undefined') {
+      opts.printStderr = opts.stderr;
+      delete opts.stderr;
+    }
+
+    return {
+      cmds: cmds
+    , opts: opts
+    , callback: callback
+    };
+};
+
+/**
+  @name jake
+  @namespace jake
+*/
+utils.mixin(utils, new (function () {
+  /**
+    @name jake.exec
+    @static
+    @function
+    @description Executes shell-commands asynchronously with an optional
+    final callback.
+    `
+    @param {String[]} cmds The list of shell-commands to execute
+    @param {Object} [opts]
+      @param {Boolean} [opts.printStdout=false] Print stdout from each command
+      @param {Boolean} [opts.printStderr=false] Print stderr from each command
+      @param {Boolean} [opts.breakOnError=true] Stop further execution on
+      the first error.
+      @param {Boolean} [opts.windowsVerbatimArguments=false] Don't translate
+      arguments on Windows.
+    @param {Function} [callback] Callback to run after executing  the
+    commands
+
+    @example
+    var cmds = [
+          'echo "showing directories"'
+        , 'ls -al | grep ^d'
+        , 'echo "moving up a directory"'
+        , 'cd ../'
+        ]
+      , callback = function () {
+          console.log('Finished running commands.');
+        }
+    jake.exec(cmds, {stdout: true}, callback);
+   */
+  this.exec = function (a, b, c) {
+    var parsed = parseArgs(arguments)
+      , cmds = parsed.cmds
+      , opts = parsed.opts
+      , callback = parsed.callback;
+
+    var ex = new Exec(cmds, opts, callback);
+
+    ex.addListener('error', function (msg, code) {
+      if (opts.breakOnError) {
+        fail(msg, code);
+      }
+    });
+    ex.run();
+
+    return ex;
+  };
+
+  this.createExec = function (a, b, c) {
+    return new Exec(a, b, c);
+  };
+
+})());
+
+Exec = function () {
+  var parsed = parseArgs(arguments)
+    , cmds = parsed.cmds
+    , opts = parsed.opts
+    , callback = parsed.callback;
+
+  this._cmds = cmds;
+  this._callback = callback;
+  this._config = opts;
+};
+
+util.inherits(Exec, EventEmitter);
+
+utils.mixin(Exec.prototype, new (function () {
+
+  var _run = function () {
+        var self = this
+          , sh
+          , cmd
+          , args
+          , next = this._cmds.shift()
+          , config = this._config
+          , errData = ''
+          , shStdio
+          , handleStdoutData = function (data) {
+              self.emit('stdout', data);
+            }
+          , handleStderrData = function (data) {
+              var d = data.toString();
+              self.emit('stderr', data);
+              // Accumulate the error-data so we can use it as the
+              // stack if the process exits with an error
+              errData += d;
+            };
+
+        // Keep running as long as there are commands in the array
+        if (next) {
+          var spawnOpts = {};
+          this.emit('cmdStart', next);
+
+          // Ganking part of Node's child_process.exec to get cmdline args parsed
+          if (process.platform == 'win32') {
+            cmd = 'cmd';
+            args = ['/c', next];
+            if (config.windowsVerbatimArguments) {
+              spawnOpts.windowsVerbatimArguments = true;
+            }
+          }
+          else {
+            cmd = '/bin/sh';
+            args = ['-c', next];
+          }
+
+          if (config.interactive) {
+            spawnOpts.stdio = 'inherit';
+            sh = spawn(cmd, args, spawnOpts);
+          }
+          else {
+            shStdio = [
+              process.stdin
+            ];
+            if (config.printStdout) {
+              shStdio.push(process.stdout);
+            }
+            else {
+              shStdio.push('pipe');
+            }
+            if (config.printStderr) {
+              shStdio.push(process.stderr);
+            }
+            else {
+              shStdio.push('pipe');
+            }
+            spawnOpts.stdio = shStdio;
+            sh = spawn(cmd, args, spawnOpts);
+            if (!config.printStdout) {
+              sh.stdout.addListener('data', handleStdoutData);
+            }
+            if (!config.printStderr) {
+              sh.stderr.addListener('data', handleStderrData);
+            }
+          }
+
+          // Exit, handle err or run next
+          sh.on('exit', function (code) {
+            var msg;
+            if (code !== 0) {
+              msg = errData || 'Process exited with error.';
+              msg = utils.string.trim(msg);
+              self.emit('error', msg, code);
+            }
+            if (code === 0 || !config.breakOnError) {
+              self.emit('cmdEnd', next);
+              setTimeout(function () { _run.call(self); }, 0);
+            }
+          });
+
+        }
+        else {
+          self.emit('end');
+          if (typeof self._callback == 'function') {
+            self._callback();
+          }
+        }
+      };
+
+  this.append = function (cmd) {
+    this._cmds.push(cmd);
+  };
+
+  this.run = function () {
+    _run.call(this);
+  };
+
+})());
+
+utils.Exec = Exec;
+utils.logger = logger;
+
+module.exports = utils;
+

+ 24 - 0
Build/node_modules/jake/lib/utils/logger.js

@@ -0,0 +1,24 @@
+var util = require('util');
+
+var logger = new (function () {
+  var _output = function (type, out) {
+    var quiet = typeof jake != 'undefined' && jake.program &&
+        jake.program.opts && jake.program.opts.quiet
+      , msg;
+    if (!quiet) {
+      msg = typeof out == 'string' ? out : util.inspect(out);
+      console[type](msg);
+    }
+  };
+
+  this.log = function (out) {
+    _output('log', out);
+  };
+
+  this.error = function (out) {
+    _output('error', out);
+  };
+
+})();
+
+module.exports = logger;

+ 99 - 0
Build/node_modules/jake/lib/watch_task.js

@@ -0,0 +1,99 @@
+var fs = require('fs')
+  , FileList = require('filelist').FileList;
+
+var THROTTLE = 5000;
+
+/**
+  @name WatchTask
+  @constructor
+  @description  Watches specified files for changes, and runs a
+      set of tasks each time there's a change
+  @param {String} [name] Name of the WatchTask -- defaults to 'watch'
+      if not specified
+  @param {Array} taskNames The list of tasks to run with each change
+  @param {Function} definition Function to set up the WatchTask --
+      invoked on `this` after the initial construction
+*/
+var WatchTask = function () {
+  var self = this
+    , args = Array.prototype.slice.call(arguments)
+    , arg
+    , definition
+    , taskNames
+    , name
+    , last = (new Date()).getTime() - THROTTLE;
+
+  args = args.filter(function (a) {
+    return !!a;
+  });
+
+  while ((arg = args.shift())) {
+    if (typeof arg == 'string') {
+      name = arg;
+    }
+    else if (typeof arg == 'object' && Array.isArray(arg)) {
+      taskNames = arg;
+    }
+    else if (typeof arg == 'function') {
+      definition = arg;
+    }
+  }
+
+  if (!(taskNames && taskNames.length)) {
+    throw new Error('Watch task needs some tasks to run');
+  }
+
+  name = name || 'watch';
+  definition = definition || function () {};
+
+  if (jake.Task[name]) {
+    throw new Error('WatchTask named "' + name + '" already exists. ' +
+      'Please use a different name.');
+  }
+
+  this.watchTasks = Array.isArray(taskNames) ? taskNames : [taskNames];
+  this.watchFiles = new FileList();
+  this.rootTask = task('watchTasks', this.watchTasks);
+  this.throttle = THROTTLE;
+
+  this.watchFiles.include(WatchTask.DEFAULT_INCLUDE_FILES);
+  this.watchFiles.exclude(WatchTask.DEFAULT_EXCLUDE_FILES);
+
+  if (typeof definition == 'function') {
+    definition.call(this);
+  }
+
+  desc('Runs these tasks: ' + this.watchTasks.join(', '));
+  task(name, function () {
+    console.log('WatchTask started for: ' + self.watchTasks.join(', '));
+    jake.watch('.', {includePattern: /.+/}, function (filePath) {
+      var fileMatch = self.watchFiles.toArray().some(function (item) {
+        return item == filePath;
+      });
+      if (fileMatch && ((new Date()).getTime() - last) > self.throttle) {
+        last = (new Date()).getTime();
+        self.rootTask.reenable(true);
+        self.rootTask.invoke();
+      }
+    });
+  });
+};
+
+WatchTask.DEFAULT_INCLUDE_FILES = [
+  './**/*.js'
+, './**/*.coffee'
+, './**/*.css'
+, './**/*.less'
+, './**/*.scss'
+];
+
+WatchTask.DEFAULT_EXCLUDE_FILES = [];
+if (fs.existsSync('node_modules')) {
+  WatchTask.DEFAULT_EXCLUDE_FILES.push('node_modules/**');
+}
+if (fs.existsSync('.git')) {
+  WatchTask.DEFAULT_EXCLUDE_FILES.push('.git/**');
+}
+
+exports.WatchTask = WatchTask;
+

+ 5 - 0
Build/node_modules/jake/node_modules/async/.travis.yml

@@ -0,0 +1,5 @@
+language: node_js
+node_js:
+  - "0.10"
+  - "0.12"
+  - "iojs"

+ 19 - 0
Build/node_modules/jake/node_modules/async/LICENSE

@@ -0,0 +1,19 @@
+Copyright (c) 2010-2014 Caolan McMahon
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.

+ 1647 - 0
Build/node_modules/jake/node_modules/async/README.md

@@ -0,0 +1,1647 @@
+# Async.js
+
+[![Build Status via Travis CI](https://travis-ci.org/caolan/async.svg?branch=master)](https://travis-ci.org/caolan/async)
+
+
+Async is a utility module which provides straight-forward, powerful functions
+for working with asynchronous JavaScript. Although originally designed for
+use with [Node.js](http://nodejs.org) and installable via `npm install async`,
+it can also be used directly in the browser.
+
+Async is also installable via:
+
+- [bower](http://bower.io/): `bower install async`
+- [component](https://github.com/component/component): `component install
+  caolan/async`
+- [jam](http://jamjs.org/): `jam install async`
+- [spm](http://spmjs.io/): `spm install async`
+
+Async provides around 20 functions that include the usual 'functional'
+suspects (`map`, `reduce`, `filter`, `each`…) as well as some common patterns
+for asynchronous control flow (`parallel`, `series`, `waterfall`…). All these
+functions assume you follow the Node.js convention of providing a single
+callback as the last argument of your `async` function.
+
+
+## Quick Examples
+
+```javascript
+async.map(['file1','file2','file3'], fs.stat, function(err, results){
+    // results is now an array of stats for each file
+});
+
+async.filter(['file1','file2','file3'], fs.exists, function(results){
+    // results now equals an array of the existing files
+});
+
+async.parallel([
+    function(){ ... },
+    function(){ ... }
+], callback);
+
+async.series([
+    function(){ ... },
+    function(){ ... }
+]);
+```
+
+There are many more functions available so take a look at the docs below for a
+full list. This module aims to be comprehensive, so if you feel anything is
+missing please create a GitHub issue for it.
+
+## Common Pitfalls
+
+### Binding a context to an iterator
+
+This section is really about `bind`, not about `async`. If you are wondering how to
+make `async` execute your iterators in a given context, or are confused as to why
+a method of another library isn't working as an iterator, study this example:
+
+```js
+// Here is a simple object with an (unnecessarily roundabout) squaring method
+var AsyncSquaringLibrary = {
+  squareExponent: 2,
+  square: function(number, callback){ 
+    var result = Math.pow(number, this.squareExponent);
+    setTimeout(function(){
+      callback(null, result);
+    }, 200);
+  }
+};
+
+async.map([1, 2, 3], AsyncSquaringLibrary.square, function(err, result){
+  // result is [NaN, NaN, NaN]
+  // This fails because the `this.squareExponent` expression in the square
+  // function is not evaluated in the context of AsyncSquaringLibrary, and is
+  // therefore undefined.
+});
+
+async.map([1, 2, 3], AsyncSquaringLibrary.square.bind(AsyncSquaringLibrary), function(err, result){
+  // result is [1, 4, 9]
+  // With the help of bind we can attach a context to the iterator before
+  // passing it to async. Now the square function will be executed in its 
+  // 'home' AsyncSquaringLibrary context and the value of `this.squareExponent`
+  // will be as expected.
+});
+```
+
+## Download
+
+The source is available for download from
+[GitHub](http://github.com/caolan/async).
+Alternatively, you can install using Node Package Manager (`npm`):
+
+    npm install async
+
+__Development:__ [async.js](https://github.com/caolan/async/raw/master/lib/async.js) - 29.6kb Uncompressed
+
+## In the Browser
+
+So far it's been tested in IE6, IE7, IE8, FF3.6 and Chrome 5. 
+
+Usage:
+
+```html
+<script type="text/javascript" src="async.js"></script>
+<script type="text/javascript">
+
+    async.map(data, asyncProcess, function(err, results){
+        alert(results);
+    });
+
+</script>
+```
+
+## Documentation
+
+### Collections
+
+* [`each`](#each)
+* [`eachSeries`](#eachSeries)
+* [`eachLimit`](#eachLimit)
+* [`map`](#map)
+* [`mapSeries`](#mapSeries)
+* [`mapLimit`](#mapLimit)
+* [`filter`](#filter)
+* [`filterSeries`](#filterSeries)
+* [`reject`](#reject)
+* [`rejectSeries`](#rejectSeries)
+* [`reduce`](#reduce)
+* [`reduceRight`](#reduceRight)
+* [`detect`](#detect)
+* [`detectSeries`](#detectSeries)
+* [`sortBy`](#sortBy)
+* [`some`](#some)
+* [`every`](#every)
+* [`concat`](#concat)
+* [`concatSeries`](#concatSeries)
+
+### Control Flow
+
+* [`series`](#seriestasks-callback)
+* [`parallel`](#parallel)
+* [`parallelLimit`](#parallellimittasks-limit-callback)
+* [`whilst`](#whilst)
+* [`doWhilst`](#doWhilst)
+* [`until`](#until)
+* [`doUntil`](#doUntil)
+* [`forever`](#forever)
+* [`waterfall`](#waterfall)
+* [`compose`](#compose)
+* [`seq`](#seq)
+* [`applyEach`](#applyEach)
+* [`applyEachSeries`](#applyEachSeries)
+* [`queue`](#queue)
+* [`priorityQueue`](#priorityQueue)
+* [`cargo`](#cargo)
+* [`auto`](#auto)
+* [`retry`](#retry)
+* [`iterator`](#iterator)
+* [`apply`](#apply)
+* [`nextTick`](#nextTick)
+* [`times`](#times)
+* [`timesSeries`](#timesSeries)
+
+### Utils
+
+* [`memoize`](#memoize)
+* [`unmemoize`](#unmemoize)
+* [`log`](#log)
+* [`dir`](#dir)
+* [`noConflict`](#noConflict)
+
+
+## Collections
+
+<a name="forEach" />
+<a name="each" />
+### each(arr, iterator, callback)
+
+Applies the function `iterator` to each item in `arr`, in parallel.
+The `iterator` is called with an item from the list, and a callback for when it
+has finished. If the `iterator` passes an error to its `callback`, the main
+`callback` (for the `each` function) is immediately called with the error.
+
+Note, that since this function applies `iterator` to each item in parallel,
+there is no guarantee that the iterator functions will complete in order.
+
+__Arguments__
+
+* `arr` - An array to iterate over.
+* `iterator(item, callback)` - A function to apply to each item in `arr`.
+  The iterator is passed a `callback(err)` which must be called once it has 
+  completed. If no error has occurred, the `callback` should be run without 
+  arguments or with an explicit `null` argument.
+* `callback(err)` - A callback which is called when all `iterator` functions
+  have finished, or an error occurs.
+
+__Examples__
+
+
+```js
+// assuming openFiles is an array of file names and saveFile is a function
+// to save the modified contents of that file:
+
+async.each(openFiles, saveFile, function(err){
+    // if any of the saves produced an error, err would equal that error
+});
+```
+
+```js
+// assuming openFiles is an array of file names 
+
+async.each(openFiles, function(file, callback) {
+  
+  // Perform operation on file here.
+  console.log('Processing file ' + file);
+  
+  if( file.length > 32 ) {
+    console.log('This file name is too long');
+    callback('File name too long');
+  } else {
+    // Do work to process file here
+    console.log('File processed');
+    callback();
+  }
+}, function(err){
+    // if any of the file processing produced an error, err would equal that error
+    if( err ) {
+      // One of the iterations produced an error.
+      // All processing will now stop.
+      console.log('A file failed to process');
+    } else {
+      console.log('All files have been processed successfully');
+    }
+});
+```
+
+---------------------------------------
+
+<a name="forEachSeries" />
+<a name="eachSeries" />
+### eachSeries(arr, iterator, callback)
+
+The same as [`each`](#each), only `iterator` is applied to each item in `arr` in
+series. The next `iterator` is only called once the current one has completed. 
+This means the `iterator` functions will complete in order.
+
+
+---------------------------------------
+
+<a name="forEachLimit" />
+<a name="eachLimit" />
+### eachLimit(arr, limit, iterator, callback)
+
+The same as [`each`](#each), only no more than `limit` `iterator`s will be simultaneously 
+running at any time.
+
+Note that the items in `arr` are not processed in batches, so there is no guarantee that 
+the first `limit` `iterator` functions will complete before any others are started.
+
+__Arguments__
+
+* `arr` - An array to iterate over.
+* `limit` - The maximum number of `iterator`s to run at any time.
+* `iterator(item, callback)` - A function to apply to each item in `arr`.
+  The iterator is passed a `callback(err)` which must be called once it has 
+  completed. If no error has occurred, the callback should be run without 
+  arguments or with an explicit `null` argument.
+* `callback(err)` - A callback which is called when all `iterator` functions
+  have finished, or an error occurs.
+
+__Example__
+
+```js
+// Assume documents is an array of JSON objects and requestApi is a
+// function that interacts with a rate-limited REST api.
+
+async.eachLimit(documents, 20, requestApi, function(err){
+    // if any of the saves produced an error, err would equal that error
+});
+```
+
+---------------------------------------
+
+<a name="map" />
+### map(arr, iterator, callback)
+
+Produces a new array of values by mapping each value in `arr` through
+the `iterator` function. The `iterator` is called with an item from `arr` and a
+callback for when it has finished processing. Each of these callback takes 2 arguments: 
+an `error`, and the transformed item from `arr`. If `iterator` passes an error to his 
+callback, the main `callback` (for the `map` function) is immediately called with the error.
+
+Note, that since this function applies the `iterator` to each item in parallel,
+there is no guarantee that the `iterator` functions will complete in order. 
+However, the results array will be in the same order as the original `arr`.
+
+__Arguments__
+
+* `arr` - An array to iterate over.
+* `iterator(item, callback)` - A function to apply to each item in `arr`.
+  The iterator is passed a `callback(err, transformed)` which must be called once 
+  it has completed with an error (which can be `null`) and a transformed item.
+* `callback(err, results)` - A callback which is called when all `iterator`
+  functions have finished, or an error occurs. Results is an array of the
+  transformed items from the `arr`.
+
+__Example__
+
+```js
+async.map(['file1','file2','file3'], fs.stat, function(err, results){
+    // results is now an array of stats for each file
+});
+```
+
+---------------------------------------
+
+<a name="mapSeries" />
+### mapSeries(arr, iterator, callback)
+
+The same as [`map`](#map), only the `iterator` is applied to each item in `arr` in
+series. The next `iterator` is only called once the current one has completed. 
+The results array will be in the same order as the original.
+
+
+---------------------------------------
+
+<a name="mapLimit" />
+### mapLimit(arr, limit, iterator, callback)
+
+The same as [`map`](#map), only no more than `limit` `iterator`s will be simultaneously 
+running at any time.
+
+Note that the items are not processed in batches, so there is no guarantee that 
+the first `limit` `iterator` functions will complete before any others are started.
+
+__Arguments__
+
+* `arr` - An array to iterate over.
+* `limit` - The maximum number of `iterator`s to run at any time.
+* `iterator(item, callback)` - A function to apply to each item in `arr`.
+  The iterator is passed a `callback(err, transformed)` which must be called once 
+  it has completed with an error (which can be `null`) and a transformed item.
+* `callback(err, results)` - A callback which is called when all `iterator`
+  calls have finished, or an error occurs. The result is an array of the
+  transformed items from the original `arr`.
+
+__Example__
+
+```js
+async.mapLimit(['file1','file2','file3'], 1, fs.stat, function(err, results){
+    // results is now an array of stats for each file
+});
+```
+
+---------------------------------------
+
+<a name="select" />
+<a name="filter" />
+### filter(arr, iterator, callback)
+
+__Alias:__ `select`
+
+Returns a new array of all the values in `arr` which pass an async truth test.
+_The callback for each `iterator` call only accepts a single argument of `true` or
+`false`; it does not accept an error argument first!_ This is in-line with the
+way node libraries work with truth tests like `fs.exists`. This operation is
+performed in parallel, but the results array will be in the same order as the
+original.
+
+__Arguments__
+
+* `arr` - An array to iterate over.
+* `iterator(item, callback)` - A truth test to apply to each item in `arr`.
+  The `iterator` is passed a `callback(truthValue)`, which must be called with a 
+  boolean argument once it has completed.
+* `callback(results)` - A callback which is called after all the `iterator`
+  functions have finished.
+
+__Example__
+
+```js
+async.filter(['file1','file2','file3'], fs.exists, function(results){
+    // results now equals an array of the existing files
+});
+```
+
+---------------------------------------
+
+<a name="selectSeries" />
+<a name="filterSeries" />
+### filterSeries(arr, iterator, callback)
+
+__Alias:__ `selectSeries`
+
+The same as [`filter`](#filter) only the `iterator` is applied to each item in `arr` in
+series. The next `iterator` is only called once the current one has completed. 
+The results array will be in the same order as the original.
+
+---------------------------------------
+
+<a name="reject" />
+### reject(arr, iterator, callback)
+
+The opposite of [`filter`](#filter). Removes values that pass an `async` truth test.
+
+---------------------------------------
+
+<a name="rejectSeries" />
+### rejectSeries(arr, iterator, callback)
+
+The same as [`reject`](#reject), only the `iterator` is applied to each item in `arr`
+in series.
+
+
+---------------------------------------
+
+<a name="reduce" />
+### reduce(arr, memo, iterator, callback)
+
+__Aliases:__ `inject`, `foldl`
+
+Reduces `arr` into a single value using an async `iterator` to return
+each successive step. `memo` is the initial state of the reduction. 
+This function only operates in series. 
+
+For performance reasons, it may make sense to split a call to this function into 
+a parallel map, and then use the normal `Array.prototype.reduce` on the results. 
+This function is for situations where each step in the reduction needs to be async; 
+if you can get the data before reducing it, then it's probably a good idea to do so.
+
+__Arguments__
+
+* `arr` - An array to iterate over.
+* `memo` - The initial state of the reduction.
+* `iterator(memo, item, callback)` - A function applied to each item in the
+  array to produce the next step in the reduction. The `iterator` is passed a
+  `callback(err, reduction)` which accepts an optional error as its first 
+  argument, and the state of the reduction as the second. If an error is 
+  passed to the callback, the reduction is stopped and the main `callback` is 
+  immediately called with the error.
+* `callback(err, result)` - A callback which is called after all the `iterator`
+  functions have finished. Result is the reduced value.
+
+__Example__
+
+```js
+async.reduce([1,2,3], 0, function(memo, item, callback){
+    // pointless async:
+    process.nextTick(function(){
+        callback(null, memo + item)
+    });
+}, function(err, result){
+    // result is now equal to the last value of memo, which is 6
+});
+```
+
+---------------------------------------
+
+<a name="reduceRight" />
+### reduceRight(arr, memo, iterator, callback)
+
+__Alias:__ `foldr`
+
+Same as [`reduce`](#reduce), only operates on `arr` in reverse order.
+
+
+---------------------------------------
+
+<a name="detect" />
+### detect(arr, iterator, callback)
+
+Returns the first value in `arr` that passes an async truth test. The
+`iterator` is applied in parallel, meaning the first iterator to return `true` will
+fire the detect `callback` with that result. That means the result might not be
+the first item in the original `arr` (in terms of order) that passes the test.
+
+If order within the original `arr` is important, then look at [`detectSeries`](#detectSeries).
+
+__Arguments__
+
+* `arr` - An array to iterate over.
+* `iterator(item, callback)` - A truth test to apply to each item in `arr`.
+  The iterator is passed a `callback(truthValue)` which must be called with a 
+  boolean argument once it has completed.
+* `callback(result)` - A callback which is called as soon as any iterator returns
+  `true`, or after all the `iterator` functions have finished. Result will be
+  the first item in the array that passes the truth test (iterator) or the
+  value `undefined` if none passed.
+
+__Example__
+
+```js
+async.detect(['file1','file2','file3'], fs.exists, function(result){
+    // result now equals the first file in the list that exists
+});
+```
+
+---------------------------------------
+
+<a name="detectSeries" />
+### detectSeries(arr, iterator, callback)
+
+The same as [`detect`](#detect), only the `iterator` is applied to each item in `arr`
+in series. This means the result is always the first in the original `arr` (in
+terms of array order) that passes the truth test.
+
+
+---------------------------------------
+
+<a name="sortBy" />
+### sortBy(arr, iterator, callback)
+
+Sorts a list by the results of running each `arr` value through an async `iterator`.
+
+__Arguments__
+
+* `arr` - An array to iterate over.
+* `iterator(item, callback)` - A function to apply to each item in `arr`.
+  The iterator is passed a `callback(err, sortValue)` which must be called once it
+  has completed with an error (which can be `null`) and a value to use as the sort
+  criteria.
+* `callback(err, results)` - A callback which is called after all the `iterator`
+  functions have finished, or an error occurs. Results is the items from
+  the original `arr` sorted by the values returned by the `iterator` calls.
+
+__Example__
+
+```js
+async.sortBy(['file1','file2','file3'], function(file, callback){
+    fs.stat(file, function(err, stats){
+        callback(err, stats.mtime);
+    });
+}, function(err, results){
+    // results is now the original array of files sorted by
+    // modified date
+});
+```
+
+__Sort Order__
+
+By modifying the callback parameter the sorting order can be influenced:
+
+```js
+//ascending order
+async.sortBy([1,9,3,5], function(x, callback){
+    callback(null, x);
+}, function(err,result){
+    //result callback
+} );
+
+//descending order
+async.sortBy([1,9,3,5], function(x, callback){
+    callback(null, x*-1);    //<- x*-1 instead of x, turns the order around
+}, function(err,result){
+    //result callback
+} );
+```
+
+---------------------------------------
+
+<a name="some" />
+### some(arr, iterator, callback)
+
+__Alias:__ `any`
+
+Returns `true` if at least one element in the `arr` satisfies an async test.
+_The callback for each iterator call only accepts a single argument of `true` or
+`false`; it does not accept an error argument first!_ This is in-line with the
+way node libraries work with truth tests like `fs.exists`. Once any iterator
+call returns `true`, the main `callback` is immediately called.
+
+__Arguments__
+
+* `arr` - An array to iterate over.
+* `iterator(item, callback)` - A truth test to apply to each item in the array
+  in parallel. The iterator is passed a callback(truthValue) which must be 
+  called with a boolean argument once it has completed.
+* `callback(result)` - A callback which is called as soon as any iterator returns
+  `true`, or after all the iterator functions have finished. Result will be
+  either `true` or `false` depending on the values of the async tests.
+
+__Example__
+
+```js
+async.some(['file1','file2','file3'], fs.exists, function(result){
+    // if result is true then at least one of the files exists
+});
+```
+
+---------------------------------------
+
+<a name="every" />
+### every(arr, iterator, callback)
+
+__Alias:__ `all`
+
+Returns `true` if every element in `arr` satisfies an async test.
+_The callback for each `iterator` call only accepts a single argument of `true` or
+`false`; it does not accept an error argument first!_ This is in-line with the
+way node libraries work with truth tests like `fs.exists`.
+
+__Arguments__
+
+* `arr` - An array to iterate over.
+* `iterator(item, callback)` - A truth test to apply to each item in the array
+  in parallel. The iterator is passed a callback(truthValue) which must be 
+  called with a  boolean argument once it has completed.
+* `callback(result)` - A callback which is called after all the `iterator`
+  functions have finished. Result will be either `true` or `false` depending on
+  the values of the async tests.
+
+__Example__
+
+```js
+async.every(['file1','file2','file3'], fs.exists, function(result){
+    // if result is true then every file exists
+});
+```
+
+---------------------------------------
+
+<a name="concat" />
+### concat(arr, iterator, callback)
+
+Applies `iterator` to each item in `arr`, concatenating the results. Returns the
+concatenated list. The `iterator`s are called in parallel, and the results are
+concatenated as they return. There is no guarantee that the results array will
+be returned in the original order of `arr` passed to the `iterator` function.
+
+__Arguments__
+
+* `arr` - An array to iterate over.
+* `iterator(item, callback)` - A function to apply to each item in `arr`.
+  The iterator is passed a `callback(err, results)` which must be called once it 
+  has completed with an error (which can be `null`) and an array of results.
+* `callback(err, results)` - A callback which is called after all the `iterator`
+  functions have finished, or an error occurs. Results is an array containing
+  the concatenated results of the `iterator` function.
+
+__Example__
+
+```js
+async.concat(['dir1','dir2','dir3'], fs.readdir, function(err, files){
+    // files is now a list of filenames that exist in the 3 directories
+});
+```
+
+---------------------------------------
+
+<a name="concatSeries" />
+### concatSeries(arr, iterator, callback)
+
+Same as [`concat`](#concat), but executes in series instead of parallel.
+
+
+## Control Flow
+
+<a name="series" />
+### series(tasks, [callback])
+
+Run the functions in the `tasks` array in series, each one running once the previous
+function has completed. If any functions in the series pass an error to its
+callback, no more functions are run, and `callback` is immediately called with the value of the error. 
+Otherwise, `callback` receives an array of results when `tasks` have completed.
+
+It is also possible to use an object instead of an array. Each property will be
+run as a function, and the results will be passed to the final `callback` as an object
+instead of an array. This can be a more readable way of handling results from
+[`series`](#series).
+
+**Note** that while many implementations preserve the order of object properties, the
+[ECMAScript Language Specifcation](http://www.ecma-international.org/ecma-262/5.1/#sec-8.6) 
+explicitly states that
+
+> The mechanics and order of enumerating the properties is not specified.
+
+So if you rely on the order in which your series of functions are executed, and want
+this to work on all platforms, consider using an array. 
+
+__Arguments__
+
+* `tasks` - An array or object containing functions to run, each function is passed
+  a `callback(err, result)` it must call on completion with an error `err` (which can
+  be `null`) and an optional `result` value.
+* `callback(err, results)` - An optional callback to run once all the functions
+  have completed. This function gets a results array (or object) containing all 
+  the result arguments passed to the `task` callbacks.
+
+__Example__
+
+```js
+async.series([
+    function(callback){
+        // do some stuff ...
+        callback(null, 'one');
+    },
+    function(callback){
+        // do some more stuff ...
+        callback(null, 'two');
+    }
+],
+// optional callback
+function(err, results){
+    // results is now equal to ['one', 'two']
+});
+
+
+// an example using an object instead of an array
+async.series({
+    one: function(callback){
+        setTimeout(function(){
+            callback(null, 1);
+        }, 200);
+    },
+    two: function(callback){
+        setTimeout(function(){
+            callback(null, 2);
+        }, 100);
+    }
+},
+function(err, results) {
+    // results is now equal to: {one: 1, two: 2}
+});
+```
+
+---------------------------------------
+
+<a name="parallel" />
+### parallel(tasks, [callback])
+
+Run the `tasks` array of functions in parallel, without waiting until the previous
+function has completed. If any of the functions pass an error to its
+callback, the main `callback` is immediately called with the value of the error.
+Once the `tasks` have completed, the results are passed to the final `callback` as an
+array.
+
+It is also possible to use an object instead of an array. Each property will be
+run as a function and the results will be passed to the final `callback` as an object
+instead of an array. This can be a more readable way of handling results from
+[`parallel`](#parallel).
+
+
+__Arguments__
+
+* `tasks` - An array or object containing functions to run. Each function is passed 
+  a `callback(err, result)` which it must call on completion with an error `err` 
+  (which can be `null`) and an optional `result` value.
+* `callback(err, results)` - An optional callback to run once all the functions
+  have completed. This function gets a results array (or object) containing all 
+  the result arguments passed to the task callbacks.
+
+__Example__
+
+```js
+async.parallel([
+    function(callback){
+        setTimeout(function(){
+            callback(null, 'one');
+        }, 200);
+    },
+    function(callback){
+        setTimeout(function(){
+            callback(null, 'two');
+        }, 100);
+    }
+],
+// optional callback
+function(err, results){
+    // the results array will equal ['one','two'] even though
+    // the second function had a shorter timeout.
+});
+
+
+// an example using an object instead of an array
+async.parallel({
+    one: function(callback){
+        setTimeout(function(){
+            callback(null, 1);
+        }, 200);
+    },
+    two: function(callback){
+        setTimeout(function(){
+            callback(null, 2);
+        }, 100);
+    }
+},
+function(err, results) {
+    // results is now equals to: {one: 1, two: 2}
+});
+```
+
+---------------------------------------
+
+<a name="parallelLimit" />
+### parallelLimit(tasks, limit, [callback])
+
+The same as [`parallel`](#parallel), only `tasks` are executed in parallel 
+with a maximum of `limit` tasks executing at any time.
+
+Note that the `tasks` are not executed in batches, so there is no guarantee that 
+the first `limit` tasks will complete before any others are started.
+
+__Arguments__
+
+* `tasks` - An array or object containing functions to run, each function is passed 
+  a `callback(err, result)` it must call on completion with an error `err` (which can
+  be `null`) and an optional `result` value.
+* `limit` - The maximum number of `tasks` to run at any time.
+* `callback(err, results)` - An optional callback to run once all the functions
+  have completed. This function gets a results array (or object) containing all 
+  the result arguments passed to the `task` callbacks.
+
+---------------------------------------
+
+<a name="whilst" />
+### whilst(test, fn, callback)
+
+Repeatedly call `fn`, while `test` returns `true`. Calls `callback` when stopped,
+or an error occurs.
+
+__Arguments__
+
+* `test()` - synchronous truth test to perform before each execution of `fn`.
+* `fn(callback)` - A function which is called each time `test` passes. The function is
+  passed a `callback(err)`, which must be called once it has completed with an 
+  optional `err` argument.
+* `callback(err)` - A callback which is called after the test fails and repeated
+  execution of `fn` has stopped.
+
+__Example__
+
+```js
+var count = 0;
+
+async.whilst(
+    function () { return count < 5; },
+    function (callback) {
+        count++;
+        setTimeout(callback, 1000);
+    },
+    function (err) {
+        // 5 seconds have passed
+    }
+);
+```
+
+---------------------------------------
+
+<a name="doWhilst" />
+### doWhilst(fn, test, callback)
+
+The post-check version of [`whilst`](#whilst). To reflect the difference in 
+the order of operations, the arguments `test` and `fn` are switched. 
+
+`doWhilst` is to `whilst` as `do while` is to `while` in plain JavaScript.
+
+---------------------------------------
+
+<a name="until" />
+### until(test, fn, callback)
+
+Repeatedly call `fn` until `test` returns `true`. Calls `callback` when stopped,
+or an error occurs.
+
+The inverse of [`whilst`](#whilst).
+
+---------------------------------------
+
+<a name="doUntil" />
+### doUntil(fn, test, callback)
+
+Like [`doWhilst`](#doWhilst), except the `test` is inverted. Note the argument ordering differs from `until`.
+
+---------------------------------------
+
+<a name="forever" />
+### forever(fn, errback)
+
+Calls the asynchronous function `fn` with a callback parameter that allows it to
+call itself again, in series, indefinitely.
+
+If an error is passed to the callback then `errback` is called with the
+error, and execution stops, otherwise it will never be called.
+
+```js
+async.forever(
+    function(next) {
+        // next is suitable for passing to things that need a callback(err [, whatever]);
+        // it will result in this function being called again.
+    },
+    function(err) {
+        // if next is called with a value in its first parameter, it will appear
+        // in here as 'err', and execution will stop.
+    }
+);
+```
+
+---------------------------------------
+
+<a name="waterfall" />
+### waterfall(tasks, [callback])
+
+Runs the `tasks` array of functions in series, each passing their results to the next in
+the array. However, if any of the `tasks` pass an error to their own callback, the
+next function is not executed, and the main `callback` is immediately called with
+the error.
+
+__Arguments__
+
+* `tasks` - An array of functions to run, each function is passed a 
+  `callback(err, result1, result2, ...)` it must call on completion. The first
+  argument is an error (which can be `null`) and any further arguments will be 
+  passed as arguments in order to the next task.
+* `callback(err, [results])` - An optional callback to run once all the functions
+  have completed. This will be passed the results of the last task's callback.
+
+
+
+__Example__
+
+```js
+async.waterfall([
+    function(callback) {
+        callback(null, 'one', 'two');
+    },
+    function(arg1, arg2, callback) {
+      // arg1 now equals 'one' and arg2 now equals 'two'
+        callback(null, 'three');
+    },
+    function(arg1, callback) {
+        // arg1 now equals 'three'
+        callback(null, 'done');
+    }
+], function (err, result) {
+    // result now equals 'done'    
+});
+```
+
+---------------------------------------
+<a name="compose" />
+### compose(fn1, fn2...)
+
+Creates a function which is a composition of the passed asynchronous
+functions. Each function consumes the return value of the function that
+follows. Composing functions `f()`, `g()`, and `h()` would produce the result of
+`f(g(h()))`, only this version uses callbacks to obtain the return values.
+
+Each function is executed with the `this` binding of the composed function.
+
+__Arguments__
+
+* `functions...` - the asynchronous functions to compose
+
+
+__Example__
+
+```js
+function add1(n, callback) {
+    setTimeout(function () {
+        callback(null, n + 1);
+    }, 10);
+}
+
+function mul3(n, callback) {
+    setTimeout(function () {
+        callback(null, n * 3);
+    }, 10);
+}
+
+var add1mul3 = async.compose(mul3, add1);
+
+add1mul3(4, function (err, result) {
+   // result now equals 15
+});
+```
+
+---------------------------------------
+<a name="seq" />
+### seq(fn1, fn2...)
+
+Version of the compose function that is more natural to read.
+Each function consumes the return value of the previous function.
+It is the equivalent of [`compose`](#compose) with the arguments reversed.
+
+Each function is executed with the `this` binding of the composed function.
+
+__Arguments__
+
+* functions... - the asynchronous functions to compose
+
+
+__Example__
+
+```js
+// Requires lodash (or underscore), express3 and dresende's orm2.
+// Part of an app, that fetches cats of the logged user.
+// This example uses `seq` function to avoid overnesting and error 
+// handling clutter.
+app.get('/cats', function(request, response) {
+  var User = request.models.User;
+  async.seq(
+    _.bind(User.get, User),  // 'User.get' has signature (id, callback(err, data))
+    function(user, fn) {
+      user.getCats(fn);      // 'getCats' has signature (callback(err, data))
+    }
+  )(req.session.user_id, function (err, cats) {
+    if (err) {
+      console.error(err);
+      response.json({ status: 'error', message: err.message });
+    } else {
+      response.json({ status: 'ok', message: 'Cats found', data: cats });
+    }
+  });
+});
+```
+
+---------------------------------------
+<a name="applyEach" />
+### applyEach(fns, args..., callback)
+
+Applies the provided arguments to each function in the array, calling 
+`callback` after all functions have completed. If you only provide the first
+argument, then it will return a function which lets you pass in the
+arguments as if it were a single function call.
+
+__Arguments__
+
+* `fns` - the asynchronous functions to all call with the same arguments
+* `args...` - any number of separate arguments to pass to the function
+* `callback` - the final argument should be the callback, called when all
+  functions have completed processing
+
+
+__Example__
+
+```js
+async.applyEach([enableSearch, updateSchema], 'bucket', callback);
+
+// partial application example:
+async.each(
+    buckets,
+    async.applyEach([enableSearch, updateSchema]),
+    callback
+);
+```
+
+---------------------------------------
+
+<a name="applyEachSeries" />
+### applyEachSeries(arr, iterator, callback)
+
+The same as [`applyEach`](#applyEach) only the functions are applied in series.
+
+---------------------------------------
+
+<a name="queue" />
+### queue(worker, concurrency)
+
+Creates a `queue` object with the specified `concurrency`. Tasks added to the
+`queue` are processed in parallel (up to the `concurrency` limit). If all
+`worker`s are in progress, the task is queued until one becomes available. 
+Once a `worker` completes a `task`, that `task`'s callback is called.
+
+__Arguments__
+
+* `worker(task, callback)` - An asynchronous function for processing a queued
+  task, which must call its `callback(err)` argument when finished, with an 
+  optional `error` as an argument.
+* `concurrency` - An `integer` for determining how many `worker` functions should be
+  run in parallel.
+
+__Queue objects__
+
+The `queue` object returned by this function has the following properties and
+methods:
+
+* `length()` - a function returning the number of items waiting to be processed.
+* `started` - a function returning whether or not any items have been pushed and processed by the queue
+* `running()` - a function returning the number of items currently being processed.
+* `idle()` - a function returning false if there are items waiting or being processed, or true if not.
+* `concurrency` - an integer for determining how many `worker` functions should be
+  run in parallel. This property can be changed after a `queue` is created to
+  alter the concurrency on-the-fly.
+* `push(task, [callback])` - add a new task to the `queue`. Calls `callback` once 
+  the `worker` has finished processing the task. Instead of a single task, a `tasks` array
+  can be submitted. The respective callback is used for every task in the list.
+* `unshift(task, [callback])` - add a new task to the front of the `queue`.
+* `saturated` - a callback that is called when the `queue` length hits the `concurrency` limit, 
+   and further tasks will be queued.
+* `empty` - a callback that is called when the last item from the `queue` is given to a `worker`.
+* `drain` - a callback that is called when the last item from the `queue` has returned from the `worker`.
+* `paused` - a boolean for determining whether the queue is in a paused state
+* `pause()` - a function that pauses the processing of tasks until `resume()` is called.
+* `resume()` - a function that resumes the processing of queued tasks when the queue is paused.
+* `kill()` - a function that removes the `drain` callback and empties remaining tasks from the queue forcing it to go idle.
+
+__Example__
+
+```js
+// create a queue object with concurrency 2
+
+var q = async.queue(function (task, callback) {
+    console.log('hello ' + task.name);
+    callback();
+}, 2);
+
+
+// assign a callback
+q.drain = function() {
+    console.log('all items have been processed');
+}
+
+// add some items to the queue
+
+q.push({name: 'foo'}, function (err) {
+    console.log('finished processing foo');
+});
+q.push({name: 'bar'}, function (err) {
+    console.log('finished processing bar');
+});
+
+// add some items to the queue (batch-wise)
+
+q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function (err) {
+    console.log('finished processing item');
+});
+
+// add some items to the front of the queue
+
+q.unshift({name: 'bar'}, function (err) {
+    console.log('finished processing bar');
+});
+```
+
+
+---------------------------------------
+
+<a name="priorityQueue" />
+### priorityQueue(worker, concurrency)
+
+The same as [`queue`](#queue) only tasks are assigned a priority and completed in ascending priority order. There are two differences between `queue` and `priorityQueue` objects:
+
+* `push(task, priority, [callback])` - `priority` should be a number. If an array of
+  `tasks` is given, all tasks will be assigned the same priority.
+* The `unshift` method was removed.
+
+---------------------------------------
+
+<a name="cargo" />
+### cargo(worker, [payload])
+
+Creates a `cargo` object with the specified payload. Tasks added to the
+cargo will be processed altogether (up to the `payload` limit). If the
+`worker` is in progress, the task is queued until it becomes available. Once
+the `worker` has completed some tasks, each callback of those tasks is called.
+Check out [this animation](https://camo.githubusercontent.com/6bbd36f4cf5b35a0f11a96dcd2e97711ffc2fb37/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130382f62626330636662302d356632392d313165322d393734662d3333393763363464633835382e676966) for how `cargo` and `queue` work.
+
+While [queue](#queue) passes only one task to one of a group of workers
+at a time, cargo passes an array of tasks to a single worker, repeating
+when the worker is finished.
+
+__Arguments__
+
+* `worker(tasks, callback)` - An asynchronous function for processing an array of
+  queued tasks, which must call its `callback(err)` argument when finished, with 
+  an optional `err` argument.
+* `payload` - An optional `integer` for determining how many tasks should be
+  processed per round; if omitted, the default is unlimited.
+
+__Cargo objects__
+
+The `cargo` object returned by this function has the following properties and
+methods:
+
+* `length()` - A function returning the number of items waiting to be processed.
+* `payload` - An `integer` for determining how many tasks should be
+  process per round. This property can be changed after a `cargo` is created to
+  alter the payload on-the-fly.
+* `push(task, [callback])` - Adds `task` to the `queue`. The callback is called
+  once the `worker` has finished processing the task. Instead of a single task, an array of `tasks` 
+  can be submitted. The respective callback is used for every task in the list.
+* `saturated` - A callback that is called when the `queue.length()` hits the concurrency and further tasks will be queued.
+* `empty` - A callback that is called when the last item from the `queue` is given to a `worker`.
+* `drain` - A callback that is called when the last item from the `queue` has returned from the `worker`.
+
+__Example__
+
+```js
+// create a cargo object with payload 2
+
+var cargo = async.cargo(function (tasks, callback) {
+    for(var i=0; i<tasks.length; i++){
+      console.log('hello ' + tasks[i].name);
+    }
+    callback();
+}, 2);
+
+
+// add some items
+
+cargo.push({name: 'foo'}, function (err) {
+    console.log('finished processing foo');
+});
+cargo.push({name: 'bar'}, function (err) {
+    console.log('finished processing bar');
+});
+cargo.push({name: 'baz'}, function (err) {
+    console.log('finished processing baz');
+});
+```
+
+---------------------------------------
+
+<a name="auto" />
+### auto(tasks, [callback])
+
+Determines the best order for running the functions in `tasks`, based on their 
+requirements. Each function can optionally depend on other functions being completed 
+first, and each function is run as soon as its requirements are satisfied. 
+
+If any of the functions pass an error to their callback, it will not 
+complete (so any other functions depending on it will not run), and the main 
+`callback` is immediately called with the error. Functions also receive an 
+object containing the results of functions which have completed so far.
+
+Note, all functions are called with a `results` object as a second argument, 
+so it is unsafe to pass functions in the `tasks` object which cannot handle the
+extra argument. 
+
+For example, this snippet of code:
+
+```js
+async.auto({
+  readData: async.apply(fs.readFile, 'data.txt', 'utf-8')
+}, callback);
+```
+
+will have the effect of calling `readFile` with the results object as the last
+argument, which will fail:
+
+```js
+fs.readFile('data.txt', 'utf-8', cb, {});
+```
+
+Instead, wrap the call to `readFile` in a function which does not forward the 
+`results` object:
+
+```js
+async.auto({
+  readData: function(cb, results){
+    fs.readFile('data.txt', 'utf-8', cb);
+  }
+}, callback);
+```
+
+__Arguments__
+
+* `tasks` - An object. Each of its properties is either a function or an array of
+  requirements, with the function itself the last item in the array. The object's key
+  of a property serves as the name of the task defined by that property,
+  i.e. can be used when specifying requirements for other tasks.
+  The function receives two arguments: (1) a `callback(err, result)` which must be 
+  called when finished, passing an `error` (which can be `null`) and the result of 
+  the function's execution, and (2) a `results` object, containing the results of
+  the previously executed functions.
+* `callback(err, results)` - An optional callback which is called when all the
+  tasks have been completed. It receives the `err` argument if any `tasks` 
+  pass an error to their callback. Results are always returned; however, if 
+  an error occurs, no further `tasks` will be performed, and the results
+  object will only contain partial results.
+
+
+__Example__
+
+```js
+async.auto({
+    get_data: function(callback){
+        console.log('in get_data');
+        // async code to get some data
+        callback(null, 'data', 'converted to array');
+    },
+    make_folder: function(callback){
+        console.log('in make_folder');
+        // async code to create a directory to store a file in
+        // this is run at the same time as getting the data
+        callback(null, 'folder');
+    },
+    write_file: ['get_data', 'make_folder', function(callback, results){
+        console.log('in write_file', JSON.stringify(results));
+        // once there is some data and the directory exists,
+        // write the data to a file in the directory
+        callback(null, 'filename');
+    }],
+    email_link: ['write_file', function(callback, results){
+        console.log('in email_link', JSON.stringify(results));
+        // once the file is written let's email a link to it...
+        // results.write_file contains the filename returned by write_file.
+        callback(null, {'file':results.write_file, 'email':'[email protected]'});
+    }]
+}, function(err, results) {
+    console.log('err = ', err);
+    console.log('results = ', results);
+});
+```
+
+This is a fairly trivial example, but to do this using the basic parallel and
+series functions would look like this:
+
+```js
+async.parallel([
+    function(callback){
+        console.log('in get_data');
+        // async code to get some data
+        callback(null, 'data', 'converted to array');
+    },
+    function(callback){
+        console.log('in make_folder');
+        // async code to create a directory to store a file in
+        // this is run at the same time as getting the data
+        callback(null, 'folder');
+    }
+],
+function(err, results){
+    async.series([
+        function(callback){
+            console.log('in write_file', JSON.stringify(results));
+            // once there is some data and the directory exists,
+            // write the data to a file in the directory
+            results.push('filename');
+            callback(null);
+        },
+        function(callback){
+            console.log('in email_link', JSON.stringify(results));
+            // once the file is written let's email a link to it...
+            callback(null, {'file':results.pop(), 'email':'[email protected]'});
+        }
+    ]);
+});
+```
+
+For a complicated series of `async` tasks, using the [`auto`](#auto) function makes adding
+new tasks much easier (and the code more readable).
+
+
+---------------------------------------
+
+<a name="retry" />
+### retry([times = 5], task, [callback])
+
+Attempts to get a successful response from `task` no more than `times` times before
+returning an error. If the task is successful, the `callback` will be passed the result
+of the successful task. If all attempts fail, the callback will be passed the error and
+result (if any) of the final attempt.
+
+__Arguments__
+
+* `times` - An integer indicating how many times to attempt the `task` before giving up. Defaults to 5.
+* `task(callback, results)` - A function which receives two arguments: (1) a `callback(err, result)`
+  which must be called when finished, passing `err` (which can be `null`) and the `result` of 
+  the function's execution, and (2) a `results` object, containing the results of
+  the previously executed functions (if nested inside another control flow).
+* `callback(err, results)` - An optional callback which is called when the
+  task has succeeded, or after the final failed attempt. It receives the `err` and `result` arguments of the last attempt at completing the `task`.
+
+The [`retry`](#retry) function can be used as a stand-alone control flow by passing a
+callback, as shown below:
+
+```js
+async.retry(3, apiMethod, function(err, result) {
+    // do something with the result
+});
+```
+
+It can also be embeded within other control flow functions to retry individual methods
+that are not as reliable, like this:
+
+```js
+async.auto({
+    users: api.getUsers.bind(api),
+    payments: async.retry(3, api.getPayments.bind(api))
+}, function(err, results) {
+  // do something with the results
+});
+```
+
+
+---------------------------------------
+
+<a name="iterator" />
+### iterator(tasks)
+
+Creates an iterator function which calls the next function in the `tasks` array,
+returning a continuation to call the next one after that. It's also possible to
+“peek” at the next iterator with `iterator.next()`.
+
+This function is used internally by the `async` module, but can be useful when
+you want to manually control the flow of functions in series.
+
+__Arguments__
+
+* `tasks` - An array of functions to run.
+
+__Example__
+
+```js
+var iterator = async.iterator([
+    function(){ sys.p('one'); },
+    function(){ sys.p('two'); },
+    function(){ sys.p('three'); }
+]);
+
+node> var iterator2 = iterator();
+'one'
+node> var iterator3 = iterator2();
+'two'
+node> iterator3();
+'three'
+node> var nextfn = iterator2.next();
+node> nextfn();
+'three'
+```
+
+---------------------------------------
+
+<a name="apply" />
+### apply(function, arguments..)
+
+Creates a continuation function with some arguments already applied. 
+
+Useful as a shorthand when combined with other control flow functions. Any arguments
+passed to the returned function are added to the arguments originally passed
+to apply.
+
+__Arguments__
+
+* `function` - The function you want to eventually apply all arguments to.
+* `arguments...` - Any number of arguments to automatically apply when the
+  continuation is called.
+
+__Example__
+
+```js
+// using apply
+
+async.parallel([
+    async.apply(fs.writeFile, 'testfile1', 'test1'),
+    async.apply(fs.writeFile, 'testfile2', 'test2'),
+]);
+
+
+// the same process without using apply
+
+async.parallel([
+    function(callback){
+        fs.writeFile('testfile1', 'test1', callback);
+    },
+    function(callback){
+        fs.writeFile('testfile2', 'test2', callback);
+    }
+]);
+```
+
+It's possible to pass any number of additional arguments when calling the
+continuation:
+
+```js
+node> var fn = async.apply(sys.puts, 'one');
+node> fn('two', 'three');
+one
+two
+three
+```
+
+---------------------------------------
+
+<a name="nextTick" />
+### nextTick(callback), setImmediate(callback)
+
+Calls `callback` on a later loop around the event loop. In Node.js this just
+calls `process.nextTick`; in the browser it falls back to `setImmediate(callback)`
+if available, otherwise `setTimeout(callback, 0)`, which means other higher priority
+events may precede the execution of `callback`.
+
+This is used internally for browser-compatibility purposes.
+
+__Arguments__
+
+* `callback` - The function to call on a later loop around the event loop.
+
+__Example__
+
+```js
+var call_order = [];
+async.nextTick(function(){
+    call_order.push('two');
+    // call_order now equals ['one','two']
+});
+call_order.push('one')
+```
+
+<a name="times" />
+### times(n, callback)
+
+Calls the `callback` function `n` times, and accumulates results in the same manner
+you would use with [`map`](#map).
+
+__Arguments__
+
+* `n` - The number of times to run the function.
+* `callback` - The function to call `n` times.
+
+__Example__
+
+```js
+// Pretend this is some complicated async factory
+var createUser = function(id, callback) {
+  callback(null, {
+    id: 'user' + id
+  })
+}
+// generate 5 users
+async.times(5, function(n, next){
+    createUser(n, function(err, user) {
+      next(err, user)
+    })
+}, function(err, users) {
+  // we should now have 5 users
+});
+```
+
+<a name="timesSeries" />
+### timesSeries(n, callback)
+
+The same as [`times`](#times), only the iterator is applied to each item in `arr` in
+series. The next `iterator` is only called once the current one has completed. 
+The results array will be in the same order as the original.
+
+
+## Utils
+
+<a name="memoize" />
+### memoize(fn, [hasher])
+
+Caches the results of an `async` function. When creating a hash to store function
+results against, the callback is omitted from the hash and an optional hash
+function can be used.
+
+The cache of results is exposed as the `memo` property of the function returned
+by `memoize`.
+
+__Arguments__
+
+* `fn` - The function to proxy and cache results from.
+* `hasher` - Tn optional function for generating a custom hash for storing
+  results. It has all the arguments applied to it apart from the callback, and
+  must be synchronous.
+
+__Example__
+
+```js
+var slow_fn = function (name, callback) {
+    // do something
+    callback(null, result);
+};
+var fn = async.memoize(slow_fn);
+
+// fn can now be used as if it were slow_fn
+fn('some name', function () {
+    // callback
+});
+```
+
+<a name="unmemoize" />
+### unmemoize(fn)
+
+Undoes a [`memoize`](#memoize)d function, reverting it to the original, unmemoized
+form. Handy for testing.
+
+__Arguments__
+
+* `fn` - the memoized function
+
+<a name="log" />
+### log(function, arguments)
+
+Logs the result of an `async` function to the `console`. Only works in Node.js or
+in browsers that support `console.log` and `console.error` (such as FF and Chrome).
+If multiple arguments are returned from the async function, `console.log` is
+called on each argument in order.
+
+__Arguments__
+
+* `function` - The function you want to eventually apply all arguments to.
+* `arguments...` - Any number of arguments to apply to the function.
+
+__Example__
+
+```js
+var hello = function(name, callback){
+    setTimeout(function(){
+        callback(null, 'hello ' + name);
+    }, 1000);
+};
+```
+```js
+node> async.log(hello, 'world');
+'hello world'
+```
+
+---------------------------------------
+
+<a name="dir" />
+### dir(function, arguments)
+
+Logs the result of an `async` function to the `console` using `console.dir` to
+display the properties of the resulting object. Only works in Node.js or
+in browsers that support `console.dir` and `console.error` (such as FF and Chrome).
+If multiple arguments are returned from the async function, `console.dir` is
+called on each argument in order.
+
+__Arguments__
+
+* `function` - The function you want to eventually apply all arguments to.
+* `arguments...` - Any number of arguments to apply to the function.
+
+__Example__
+
+```js
+var hello = function(name, callback){
+    setTimeout(function(){
+        callback(null, {hello: name});
+    }, 1000);
+};
+```
+```js
+node> async.dir(hello, 'world');
+{hello: 'world'}
+```
+
+---------------------------------------
+
+<a name="noConflict" />
+### noConflict()
+
+Changes the value of `async` back to its original value, returning a reference to the
+`async` object.

+ 38 - 0
Build/node_modules/jake/node_modules/async/bower.json

@@ -0,0 +1,38 @@
+{
+  "name": "async",
+  "description": "Higher-order functions and common patterns for asynchronous code",
+  "version": "0.9.2",
+  "main": "lib/async.js",
+  "keywords": [
+    "async",
+    "callback",
+    "utility",
+    "module"
+  ],
+  "license": "MIT",
+  "repository": {
+    "type": "git",
+    "url": "https://github.com/caolan/async.git"
+  },
+  "devDependencies": {
+    "nodeunit": ">0.0.0",
+    "uglify-js": "1.2.x",
+    "nodelint": ">0.0.0",
+    "lodash": ">=2.4.1"
+  },
+  "moduleType": [
+    "amd",
+    "globals",
+    "node"
+  ],
+  "ignore": [
+    "**/.*",
+    "node_modules",
+    "bower_components",
+    "test",
+    "tests"
+  ],
+  "authors": [
+    "Caolan McMahon"
+  ]
+}

+ 16 - 0
Build/node_modules/jake/node_modules/async/component.json

@@ -0,0 +1,16 @@
+{
+  "name": "async",
+  "description": "Higher-order functions and common patterns for asynchronous code",
+  "version": "0.9.2",
+  "keywords": [
+    "async",
+    "callback",
+    "utility",
+    "module"
+  ],
+  "license": "MIT",
+  "repository": "caolan/async",
+  "scripts": [
+    "lib/async.js"
+  ]
+}

+ 1123 - 0
Build/node_modules/jake/node_modules/async/lib/async.js

@@ -0,0 +1,1123 @@
+/*!
+ * async
+ * https://github.com/caolan/async
+ *
+ * Copyright 2010-2014 Caolan McMahon
+ * Released under the MIT license
+ */
+/*jshint onevar: false, indent:4 */
+/*global setImmediate: false, setTimeout: false, console: false */
+(function () {
+
+    var async = {};
+
+    // global on the server, window in the browser
+    var root, previous_async;
+
+    root = this;
+    if (root != null) {
+      previous_async = root.async;
+    }
+
+    async.noConflict = function () {
+        root.async = previous_async;
+        return async;
+    };
+
+    function only_once(fn) {
+        var called = false;
+        return function() {
+            if (called) throw new Error("Callback was already called.");
+            called = true;
+            fn.apply(root, arguments);
+        }
+    }
+
+    //// cross-browser compatiblity functions ////
+
+    var _toString = Object.prototype.toString;
+
+    var _isArray = Array.isArray || function (obj) {
+        return _toString.call(obj) === '[object Array]';
+    };
+
+    var _each = function (arr, iterator) {
+        for (var i = 0; i < arr.length; i += 1) {
+            iterator(arr[i], i, arr);
+        }
+    };
+
+    var _map = function (arr, iterator) {
+        if (arr.map) {
+            return arr.map(iterator);
+        }
+        var results = [];
+        _each(arr, function (x, i, a) {
+            results.push(iterator(x, i, a));
+        });
+        return results;
+    };
+
+    var _reduce = function (arr, iterator, memo) {
+        if (arr.reduce) {
+            return arr.reduce(iterator, memo);
+        }
+        _each(arr, function (x, i, a) {
+            memo = iterator(memo, x, i, a);
+        });
+        return memo;
+    };
+
+    var _keys = function (obj) {
+        if (Object.keys) {
+            return Object.keys(obj);
+        }
+        var keys = [];
+        for (var k in obj) {
+            if (obj.hasOwnProperty(k)) {
+                keys.push(k);
+            }
+        }
+        return keys;
+    };
+
+    //// exported async module functions ////
+
+    //// nextTick implementation with browser-compatible fallback ////
+    if (typeof process === 'undefined' || !(process.nextTick)) {
+        if (typeof setImmediate === 'function') {
+            async.nextTick = function (fn) {
+                // not a direct alias for IE10 compatibility
+                setImmediate(fn);
+            };
+            async.setImmediate = async.nextTick;
+        }
+        else {
+            async.nextTick = function (fn) {
+                setTimeout(fn, 0);
+            };
+            async.setImmediate = async.nextTick;
+        }
+    }
+    else {
+        async.nextTick = process.nextTick;
+        if (typeof setImmediate !== 'undefined') {
+            async.setImmediate = function (fn) {
+              // not a direct alias for IE10 compatibility
+              setImmediate(fn);
+            };
+        }
+        else {
+            async.setImmediate = async.nextTick;
+        }
+    }
+
+    async.each = function (arr, iterator, callback) {
+        callback = callback || function () {};
+        if (!arr.length) {
+            return callback();
+        }
+        var completed = 0;
+        _each(arr, function (x) {
+            iterator(x, only_once(done) );
+        });
+        function done(err) {
+          if (err) {
+              callback(err);
+              callback = function () {};
+          }
+          else {
+              completed += 1;
+              if (completed >= arr.length) {
+                  callback();
+              }
+          }
+        }
+    };
+    async.forEach = async.each;
+
+    async.eachSeries = function (arr, iterator, callback) {
+        callback = callback || function () {};
+        if (!arr.length) {
+            return callback();
+        }
+        var completed = 0;
+        var iterate = function () {
+            iterator(arr[completed], function (err) {
+                if (err) {
+                    callback(err);
+                    callback = function () {};
+                }
+                else {
+                    completed += 1;
+                    if (completed >= arr.length) {
+                        callback();
+                    }
+                    else {
+                        iterate();
+                    }
+                }
+            });
+        };
+        iterate();
+    };
+    async.forEachSeries = async.eachSeries;
+
+    async.eachLimit = function (arr, limit, iterator, callback) {
+        var fn = _eachLimit(limit);
+        fn.apply(null, [arr, iterator, callback]);
+    };
+    async.forEachLimit = async.eachLimit;
+
+    var _eachLimit = function (limit) {
+
+        return function (arr, iterator, callback) {
+            callback = callback || function () {};
+            if (!arr.length || limit <= 0) {
+                return callback();
+            }
+            var completed = 0;
+            var started = 0;
+            var running = 0;
+
+            (function replenish () {
+                if (completed >= arr.length) {
+                    return callback();
+                }
+
+                while (running < limit && started < arr.length) {
+                    started += 1;
+                    running += 1;
+                    iterator(arr[started - 1], function (err) {
+                        if (err) {
+                            callback(err);
+                            callback = function () {};
+                        }
+                        else {
+                            completed += 1;
+                            running -= 1;
+                            if (completed >= arr.length) {
+                                callback();
+                            }
+                            else {
+                                replenish();
+                            }
+                        }
+                    });
+                }
+            })();
+        };
+    };
+
+
+    var doParallel = function (fn) {
+        return function () {
+            var args = Array.prototype.slice.call(arguments);
+            return fn.apply(null, [async.each].concat(args));
+        };
+    };
+    var doParallelLimit = function(limit, fn) {
+        return function () {
+            var args = Array.prototype.slice.call(arguments);
+            return fn.apply(null, [_eachLimit(limit)].concat(args));
+        };
+    };
+    var doSeries = function (fn) {
+        return function () {
+            var args = Array.prototype.slice.call(arguments);
+            return fn.apply(null, [async.eachSeries].concat(args));
+        };
+    };
+
+
+    var _asyncMap = function (eachfn, arr, iterator, callback) {
+        arr = _map(arr, function (x, i) {
+            return {index: i, value: x};
+        });
+        if (!callback) {
+            eachfn(arr, function (x, callback) {
+                iterator(x.value, function (err) {
+                    callback(err);
+                });
+            });
+        } else {
+            var results = [];
+            eachfn(arr, function (x, callback) {
+                iterator(x.value, function (err, v) {
+                    results[x.index] = v;
+                    callback(err);
+                });
+            }, function (err) {
+                callback(err, results);
+            });
+        }
+    };
+    async.map = doParallel(_asyncMap);
+    async.mapSeries = doSeries(_asyncMap);
+    async.mapLimit = function (arr, limit, iterator, callback) {
+        return _mapLimit(limit)(arr, iterator, callback);
+    };
+
+    var _mapLimit = function(limit) {
+        return doParallelLimit(limit, _asyncMap);
+    };
+
+    // reduce only has a series version, as doing reduce in parallel won't
+    // work in many situations.
+    async.reduce = function (arr, memo, iterator, callback) {
+        async.eachSeries(arr, function (x, callback) {
+            iterator(memo, x, function (err, v) {
+                memo = v;
+                callback(err);
+            });
+        }, function (err) {
+            callback(err, memo);
+        });
+    };
+    // inject alias
+    async.inject = async.reduce;
+    // foldl alias
+    async.foldl = async.reduce;
+
+    async.reduceRight = function (arr, memo, iterator, callback) {
+        var reversed = _map(arr, function (x) {
+            return x;
+        }).reverse();
+        async.reduce(reversed, memo, iterator, callback);
+    };
+    // foldr alias
+    async.foldr = async.reduceRight;
+
+    var _filter = function (eachfn, arr, iterator, callback) {
+        var results = [];
+        arr = _map(arr, function (x, i) {
+            return {index: i, value: x};
+        });
+        eachfn(arr, function (x, callback) {
+            iterator(x.value, function (v) {
+                if (v) {
+                    results.push(x);
+                }
+                callback();
+            });
+        }, function (err) {
+            callback(_map(results.sort(function (a, b) {
+                return a.index - b.index;
+            }), function (x) {
+                return x.value;
+            }));
+        });
+    };
+    async.filter = doParallel(_filter);
+    async.filterSeries = doSeries(_filter);
+    // select alias
+    async.select = async.filter;
+    async.selectSeries = async.filterSeries;
+
+    var _reject = function (eachfn, arr, iterator, callback) {
+        var results = [];
+        arr = _map(arr, function (x, i) {
+            return {index: i, value: x};
+        });
+        eachfn(arr, function (x, callback) {
+            iterator(x.value, function (v) {
+                if (!v) {
+                    results.push(x);
+                }
+                callback();
+            });
+        }, function (err) {
+            callback(_map(results.sort(function (a, b) {
+                return a.index - b.index;
+            }), function (x) {
+                return x.value;
+            }));
+        });
+    };
+    async.reject = doParallel(_reject);
+    async.rejectSeries = doSeries(_reject);
+
+    var _detect = function (eachfn, arr, iterator, main_callback) {
+        eachfn(arr, function (x, callback) {
+            iterator(x, function (result) {
+                if (result) {
+                    main_callback(x);
+                    main_callback = function () {};
+                }
+                else {
+                    callback();
+                }
+            });
+        }, function (err) {
+            main_callback();
+        });
+    };
+    async.detect = doParallel(_detect);
+    async.detectSeries = doSeries(_detect);
+
+    async.some = function (arr, iterator, main_callback) {
+        async.each(arr, function (x, callback) {
+            iterator(x, function (v) {
+                if (v) {
+                    main_callback(true);
+                    main_callback = function () {};
+                }
+                callback();
+            });
+        }, function (err) {
+            main_callback(false);
+        });
+    };
+    // any alias
+    async.any = async.some;
+
+    async.every = function (arr, iterator, main_callback) {
+        async.each(arr, function (x, callback) {
+            iterator(x, function (v) {
+                if (!v) {
+                    main_callback(false);
+                    main_callback = function () {};
+                }
+                callback();
+            });
+        }, function (err) {
+            main_callback(true);
+        });
+    };
+    // all alias
+    async.all = async.every;
+
+    async.sortBy = function (arr, iterator, callback) {
+        async.map(arr, function (x, callback) {
+            iterator(x, function (err, criteria) {
+                if (err) {
+                    callback(err);
+                }
+                else {
+                    callback(null, {value: x, criteria: criteria});
+                }
+            });
+        }, function (err, results) {
+            if (err) {
+                return callback(err);
+            }
+            else {
+                var fn = function (left, right) {
+                    var a = left.criteria, b = right.criteria;
+                    return a < b ? -1 : a > b ? 1 : 0;
+                };
+                callback(null, _map(results.sort(fn), function (x) {
+                    return x.value;
+                }));
+            }
+        });
+    };
+
+    async.auto = function (tasks, callback) {
+        callback = callback || function () {};
+        var keys = _keys(tasks);
+        var remainingTasks = keys.length
+        if (!remainingTasks) {
+            return callback();
+        }
+
+        var results = {};
+
+        var listeners = [];
+        var addListener = function (fn) {
+            listeners.unshift(fn);
+        };
+        var removeListener = function (fn) {
+            for (var i = 0; i < listeners.length; i += 1) {
+                if (listeners[i] === fn) {
+                    listeners.splice(i, 1);
+                    return;
+                }
+            }
+        };
+        var taskComplete = function () {
+            remainingTasks--
+            _each(listeners.slice(0), function (fn) {
+                fn();
+            });
+        };
+
+        addListener(function () {
+            if (!remainingTasks) {
+                var theCallback = callback;
+                // prevent final callback from calling itself if it errors
+                callback = function () {};
+
+                theCallback(null, results);
+            }
+        });
+
+        _each(keys, function (k) {
+            var task = _isArray(tasks[k]) ? tasks[k]: [tasks[k]];
+            var taskCallback = function (err) {
+                var args = Array.prototype.slice.call(arguments, 1);
+                if (args.length <= 1) {
+                    args = args[0];
+                }
+                if (err) {
+                    var safeResults = {};
+                    _each(_keys(results), function(rkey) {
+                        safeResults[rkey] = results[rkey];
+                    });
+                    safeResults[k] = args;
+                    callback(err, safeResults);
+                    // stop subsequent errors hitting callback multiple times
+                    callback = function () {};
+                }
+                else {
+                    results[k] = args;
+                    async.setImmediate(taskComplete);
+                }
+            };
+            var requires = task.slice(0, Math.abs(task.length - 1)) || [];
+            var ready = function () {
+                return _reduce(requires, function (a, x) {
+                    return (a && results.hasOwnProperty(x));
+                }, true) && !results.hasOwnProperty(k);
+            };
+            if (ready()) {
+                task[task.length - 1](taskCallback, results);
+            }
+            else {
+                var listener = function () {
+                    if (ready()) {
+                        removeListener(listener);
+                        task[task.length - 1](taskCallback, results);
+                    }
+                };
+                addListener(listener);
+            }
+        });
+    };
+
+    async.retry = function(times, task, callback) {
+        var DEFAULT_TIMES = 5;
+        var attempts = [];
+        // Use defaults if times not passed
+        if (typeof times === 'function') {
+            callback = task;
+            task = times;
+            times = DEFAULT_TIMES;
+        }
+        // Make sure times is a number
+        times = parseInt(times, 10) || DEFAULT_TIMES;
+        var wrappedTask = function(wrappedCallback, wrappedResults) {
+            var retryAttempt = function(task, finalAttempt) {
+                return function(seriesCallback) {
+                    task(function(err, result){
+                        seriesCallback(!err || finalAttempt, {err: err, result: result});
+                    }, wrappedResults);
+                };
+            };
+            while (times) {
+                attempts.push(retryAttempt(task, !(times-=1)));
+            }
+            async.series(attempts, function(done, data){
+                data = data[data.length - 1];
+                (wrappedCallback || callback)(data.err, data.result);
+            });
+        }
+        // If a callback is passed, run this as a controll flow
+        return callback ? wrappedTask() : wrappedTask
+    };
+
+    async.waterfall = function (tasks, callback) {
+        callback = callback || function () {};
+        if (!_isArray(tasks)) {
+          var err = new Error('First argument to waterfall must be an array of functions');
+          return callback(err);
+        }
+        if (!tasks.length) {
+            return callback();
+        }
+        var wrapIterator = function (iterator) {
+            return function (err) {
+                if (err) {
+                    callback.apply(null, arguments);
+                    callback = function () {};
+                }
+                else {
+                    var args = Array.prototype.slice.call(arguments, 1);
+                    var next = iterator.next();
+                    if (next) {
+                        args.push(wrapIterator(next));
+                    }
+                    else {
+                        args.push(callback);
+                    }
+                    async.setImmediate(function () {
+                        iterator.apply(null, args);
+                    });
+                }
+            };
+        };
+        wrapIterator(async.iterator(tasks))();
+    };
+
+    var _parallel = function(eachfn, tasks, callback) {
+        callback = callback || function () {};
+        if (_isArray(tasks)) {
+            eachfn.map(tasks, function (fn, callback) {
+                if (fn) {
+                    fn(function (err) {
+                        var args = Array.prototype.slice.call(arguments, 1);
+                        if (args.length <= 1) {
+                            args = args[0];
+                        }
+                        callback.call(null, err, args);
+                    });
+                }
+            }, callback);
+        }
+        else {
+            var results = {};
+            eachfn.each(_keys(tasks), function (k, callback) {
+                tasks[k](function (err) {
+                    var args = Array.prototype.slice.call(arguments, 1);
+                    if (args.length <= 1) {
+                        args = args[0];
+                    }
+                    results[k] = args;
+                    callback(err);
+                });
+            }, function (err) {
+                callback(err, results);
+            });
+        }
+    };
+
+    async.parallel = function (tasks, callback) {
+        _parallel({ map: async.map, each: async.each }, tasks, callback);
+    };
+
+    async.parallelLimit = function(tasks, limit, callback) {
+        _parallel({ map: _mapLimit(limit), each: _eachLimit(limit) }, tasks, callback);
+    };
+
+    async.series = function (tasks, callback) {
+        callback = callback || function () {};
+        if (_isArray(tasks)) {
+            async.mapSeries(tasks, function (fn, callback) {
+                if (fn) {
+                    fn(function (err) {
+                        var args = Array.prototype.slice.call(arguments, 1);
+                        if (args.length <= 1) {
+                            args = args[0];
+                        }
+                        callback.call(null, err, args);
+                    });
+                }
+            }, callback);
+        }
+        else {
+            var results = {};
+            async.eachSeries(_keys(tasks), function (k, callback) {
+                tasks[k](function (err) {
+                    var args = Array.prototype.slice.call(arguments, 1);
+                    if (args.length <= 1) {
+                        args = args[0];
+                    }
+                    results[k] = args;
+                    callback(err);
+                });
+            }, function (err) {
+                callback(err, results);
+            });
+        }
+    };
+
+    async.iterator = function (tasks) {
+        var makeCallback = function (index) {
+            var fn = function () {
+                if (tasks.length) {
+                    tasks[index].apply(null, arguments);
+                }
+                return fn.next();
+            };
+            fn.next = function () {
+                return (index < tasks.length - 1) ? makeCallback(index + 1): null;
+            };
+            return fn;
+        };
+        return makeCallback(0);
+    };
+
+    async.apply = function (fn) {
+        var args = Array.prototype.slice.call(arguments, 1);
+        return function () {
+            return fn.apply(
+                null, args.concat(Array.prototype.slice.call(arguments))
+            );
+        };
+    };
+
+    var _concat = function (eachfn, arr, fn, callback) {
+        var r = [];
+        eachfn(arr, function (x, cb) {
+            fn(x, function (err, y) {
+                r = r.concat(y || []);
+                cb(err);
+            });
+        }, function (err) {
+            callback(err, r);
+        });
+    };
+    async.concat = doParallel(_concat);
+    async.concatSeries = doSeries(_concat);
+
+    async.whilst = function (test, iterator, callback) {
+        if (test()) {
+            iterator(function (err) {
+                if (err) {
+                    return callback(err);
+                }
+                async.whilst(test, iterator, callback);
+            });
+        }
+        else {
+            callback();
+        }
+    };
+
+    async.doWhilst = function (iterator, test, callback) {
+        iterator(function (err) {
+            if (err) {
+                return callback(err);
+            }
+            var args = Array.prototype.slice.call(arguments, 1);
+            if (test.apply(null, args)) {
+                async.doWhilst(iterator, test, callback);
+            }
+            else {
+                callback();
+            }
+        });
+    };
+
+    async.until = function (test, iterator, callback) {
+        if (!test()) {
+            iterator(function (err) {
+                if (err) {
+                    return callback(err);
+                }
+                async.until(test, iterator, callback);
+            });
+        }
+        else {
+            callback();
+        }
+    };
+
+    async.doUntil = function (iterator, test, callback) {
+        iterator(function (err) {
+            if (err) {
+                return callback(err);
+            }
+            var args = Array.prototype.slice.call(arguments, 1);
+            if (!test.apply(null, args)) {
+                async.doUntil(iterator, test, callback);
+            }
+            else {
+                callback();
+            }
+        });
+    };
+
+    async.queue = function (worker, concurrency) {
+        if (concurrency === undefined) {
+            concurrency = 1;
+        }
+        function _insert(q, data, pos, callback) {
+          if (!q.started){
+            q.started = true;
+          }
+          if (!_isArray(data)) {
+              data = [data];
+          }
+          if(data.length == 0) {
+             // call drain immediately if there are no tasks
+             return async.setImmediate(function() {
+                 if (q.drain) {
+                     q.drain();
+                 }
+             });
+          }
+          _each(data, function(task) {
+              var item = {
+                  data: task,
+                  callback: typeof callback === 'function' ? callback : null
+              };
+
+              if (pos) {
+                q.tasks.unshift(item);
+              } else {
+                q.tasks.push(item);
+              }
+
+              if (q.saturated && q.tasks.length === q.concurrency) {
+                  q.saturated();
+              }
+              async.setImmediate(q.process);
+          });
+        }
+
+        var workers = 0;
+        var q = {
+            tasks: [],
+            concurrency: concurrency,
+            saturated: null,
+            empty: null,
+            drain: null,
+            started: false,
+            paused: false,
+            push: function (data, callback) {
+              _insert(q, data, false, callback);
+            },
+            kill: function () {
+              q.drain = null;
+              q.tasks = [];
+            },
+            unshift: function (data, callback) {
+              _insert(q, data, true, callback);
+            },
+            process: function () {
+                if (!q.paused && workers < q.concurrency && q.tasks.length) {
+                    var task = q.tasks.shift();
+                    if (q.empty && q.tasks.length === 0) {
+                        q.empty();
+                    }
+                    workers += 1;
+                    var next = function () {
+                        workers -= 1;
+                        if (task.callback) {
+                            task.callback.apply(task, arguments);
+                        }
+                        if (q.drain && q.tasks.length + workers === 0) {
+                            q.drain();
+                        }
+                        q.process();
+                    };
+                    var cb = only_once(next);
+                    worker(task.data, cb);
+                }
+            },
+            length: function () {
+                return q.tasks.length;
+            },
+            running: function () {
+                return workers;
+            },
+            idle: function() {
+                return q.tasks.length + workers === 0;
+            },
+            pause: function () {
+                if (q.paused === true) { return; }
+                q.paused = true;
+            },
+            resume: function () {
+                if (q.paused === false) { return; }
+                q.paused = false;
+                // Need to call q.process once per concurrent
+                // worker to preserve full concurrency after pause
+                for (var w = 1; w <= q.concurrency; w++) {
+                    async.setImmediate(q.process);
+                }
+            }
+        };
+        return q;
+    };
+
+    async.priorityQueue = function (worker, concurrency) {
+
+        function _compareTasks(a, b){
+          return a.priority - b.priority;
+        };
+
+        function _binarySearch(sequence, item, compare) {
+          var beg = -1,
+              end = sequence.length - 1;
+          while (beg < end) {
+            var mid = beg + ((end - beg + 1) >>> 1);
+            if (compare(item, sequence[mid]) >= 0) {
+              beg = mid;
+            } else {
+              end = mid - 1;
+            }
+          }
+          return beg;
+        }
+
+        function _insert(q, data, priority, callback) {
+          if (!q.started){
+            q.started = true;
+          }
+          if (!_isArray(data)) {
+              data = [data];
+          }
+          if(data.length == 0) {
+             // call drain immediately if there are no tasks
+             return async.setImmediate(function() {
+                 if (q.drain) {
+                     q.drain();
+                 }
+             });
+          }
+          _each(data, function(task) {
+              var item = {
+                  data: task,
+                  priority: priority,
+                  callback: typeof callback === 'function' ? callback : null
+              };
+
+              q.tasks.splice(_binarySearch(q.tasks, item, _compareTasks) + 1, 0, item);
+
+              if (q.saturated && q.tasks.length === q.concurrency) {
+                  q.saturated();
+              }
+              async.setImmediate(q.process);
+          });
+        }
+
+        // Start with a normal queue
+        var q = async.queue(worker, concurrency);
+
+        // Override push to accept second parameter representing priority
+        q.push = function (data, priority, callback) {
+          _insert(q, data, priority, callback);
+        };
+
+        // Remove unshift function
+        delete q.unshift;
+
+        return q;
+    };
+
+    async.cargo = function (worker, payload) {
+        var working     = false,
+            tasks       = [];
+
+        var cargo = {
+            tasks: tasks,
+            payload: payload,
+            saturated: null,
+            empty: null,
+            drain: null,
+            drained: true,
+            push: function (data, callback) {
+                if (!_isArray(data)) {
+                    data = [data];
+                }
+                _each(data, function(task) {
+                    tasks.push({
+                        data: task,
+                        callback: typeof callback === 'function' ? callback : null
+                    });
+                    cargo.drained = false;
+                    if (cargo.saturated && tasks.length === payload) {
+                        cargo.saturated();
+                    }
+                });
+                async.setImmediate(cargo.process);
+            },
+            process: function process() {
+                if (working) return;
+                if (tasks.length === 0) {
+                    if(cargo.drain && !cargo.drained) cargo.drain();
+                    cargo.drained = true;
+                    return;
+                }
+
+                var ts = typeof payload === 'number'
+                            ? tasks.splice(0, payload)
+                            : tasks.splice(0, tasks.length);
+
+                var ds = _map(ts, function (task) {
+                    return task.data;
+                });
+
+                if(cargo.empty) cargo.empty();
+                working = true;
+                worker(ds, function () {
+                    working = false;
+
+                    var args = arguments;
+                    _each(ts, function (data) {
+                        if (data.callback) {
+                            data.callback.apply(null, args);
+                        }
+                    });
+
+                    process();
+                });
+            },
+            length: function () {
+                return tasks.length;
+            },
+            running: function () {
+                return working;
+            }
+        };
+        return cargo;
+    };
+
+    var _console_fn = function (name) {
+        return function (fn) {
+            var args = Array.prototype.slice.call(arguments, 1);
+            fn.apply(null, args.concat([function (err) {
+                var args = Array.prototype.slice.call(arguments, 1);
+                if (typeof console !== 'undefined') {
+                    if (err) {
+                        if (console.error) {
+                            console.error(err);
+                        }
+                    }
+                    else if (console[name]) {
+                        _each(args, function (x) {
+                            console[name](x);
+                        });
+                    }
+                }
+            }]));
+        };
+    };
+    async.log = _console_fn('log');
+    async.dir = _console_fn('dir');
+    /*async.info = _console_fn('info');
+    async.warn = _console_fn('warn');
+    async.error = _console_fn('error');*/
+
+    async.memoize = function (fn, hasher) {
+        var memo = {};
+        var queues = {};
+        hasher = hasher || function (x) {
+            return x;
+        };
+        var memoized = function () {
+            var args = Array.prototype.slice.call(arguments);
+            var callback = args.pop();
+            var key = hasher.apply(null, args);
+            if (key in memo) {
+                async.nextTick(function () {
+                    callback.apply(null, memo[key]);
+                });
+            }
+            else if (key in queues) {
+                queues[key].push(callback);
+            }
+            else {
+                queues[key] = [callback];
+                fn.apply(null, args.concat([function () {
+                    memo[key] = arguments;
+                    var q = queues[key];
+                    delete queues[key];
+                    for (var i = 0, l = q.length; i < l; i++) {
+                      q[i].apply(null, arguments);
+                    }
+                }]));
+            }
+        };
+        memoized.memo = memo;
+        memoized.unmemoized = fn;
+        return memoized;
+    };
+
+    async.unmemoize = function (fn) {
+      return function () {
+        return (fn.unmemoized || fn).apply(null, arguments);
+      };
+    };
+
+    async.times = function (count, iterator, callback) {
+        var counter = [];
+        for (var i = 0; i < count; i++) {
+            counter.push(i);
+        }
+        return async.map(counter, iterator, callback);
+    };
+
+    async.timesSeries = function (count, iterator, callback) {
+        var counter = [];
+        for (var i = 0; i < count; i++) {
+            counter.push(i);
+        }
+        return async.mapSeries(counter, iterator, callback);
+    };
+
+    async.seq = function (/* functions... */) {
+        var fns = arguments;
+        return function () {
+            var that = this;
+            var args = Array.prototype.slice.call(arguments);
+            var callback = args.pop();
+            async.reduce(fns, args, function (newargs, fn, cb) {
+                fn.apply(that, newargs.concat([function () {
+                    var err = arguments[0];
+                    var nextargs = Array.prototype.slice.call(arguments, 1);
+                    cb(err, nextargs);
+                }]))
+            },
+            function (err, results) {
+                callback.apply(that, [err].concat(results));
+            });
+        };
+    };
+
+    async.compose = function (/* functions... */) {
+      return async.seq.apply(null, Array.prototype.reverse.call(arguments));
+    };
+
+    var _applyEach = function (eachfn, fns /*args...*/) {
+        var go = function () {
+            var that = this;
+            var args = Array.prototype.slice.call(arguments);
+            var callback = args.pop();
+            return eachfn(fns, function (fn, cb) {
+                fn.apply(that, args.concat([cb]));
+            },
+            callback);
+        };
+        if (arguments.length > 2) {
+            var args = Array.prototype.slice.call(arguments, 2);
+            return go.apply(this, args);
+        }
+        else {
+            return go;
+        }
+    };
+    async.applyEach = doParallel(_applyEach);
+    async.applyEachSeries = doSeries(_applyEach);
+
+    async.forever = function (fn, callback) {
+        function next(err) {
+            if (err) {
+                if (callback) {
+                    return callback(err);
+                }
+                throw err;
+            }
+            fn(next);
+        }
+        next();
+    };
+
+    // Node.js
+    if (typeof module !== 'undefined' && module.exports) {
+        module.exports = async;
+    }
+    // AMD / RequireJS
+    else if (typeof define !== 'undefined' && define.amd) {
+        define([], function () {
+            return async;
+        });
+    }
+    // included directly via <script> tag
+    else {
+        root.async = async;
+    }
+
+}());

+ 84 - 0
Build/node_modules/jake/node_modules/async/package.json

@@ -0,0 +1,84 @@
+{
+  "name": "async",
+  "description": "Higher-order functions and common patterns for asynchronous code",
+  "main": "lib/async.js",
+  "author": {
+    "name": "Caolan McMahon"
+  },
+  "version": "0.9.2",
+  "keywords": [
+    "async",
+    "callback",
+    "utility",
+    "module"
+  ],
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/caolan/async.git"
+  },
+  "bugs": {
+    "url": "https://github.com/caolan/async/issues"
+  },
+  "license": "MIT",
+  "devDependencies": {
+    "nodeunit": ">0.0.0",
+    "uglify-js": "1.2.x",
+    "nodelint": ">0.0.0",
+    "lodash": ">=2.4.1"
+  },
+  "jam": {
+    "main": "lib/async.js",
+    "include": [
+      "lib/async.js",
+      "README.md",
+      "LICENSE"
+    ],
+    "categories": [
+      "Utilities"
+    ]
+  },
+  "scripts": {
+    "test": "nodeunit test/test-async.js"
+  },
+  "spm": {
+    "main": "lib/async.js"
+  },
+  "volo": {
+    "main": "lib/async.js",
+    "ignore": [
+      "**/.*",
+      "node_modules",
+      "bower_components",
+      "test",
+      "tests"
+    ]
+  },
+  "gitHead": "de3a16091d5125384eff4a54deb3998b13c3814c",
+  "homepage": "https://github.com/caolan/async#readme",
+  "_id": "[email protected]",
+  "_shasum": "aea74d5e61c1f899613bf64bda66d4c78f2fd17d",
+  "_from": "async@>=0.9.0 <0.10.0",
+  "_npmVersion": "2.9.0",
+  "_nodeVersion": "2.0.1",
+  "_npmUser": {
+    "name": "beaugunderson",
+    "email": "[email protected]"
+  },
+  "maintainers": [
+    {
+      "name": "caolan",
+      "email": "[email protected]"
+    },
+    {
+      "name": "beaugunderson",
+      "email": "[email protected]"
+    }
+  ],
+  "dist": {
+    "shasum": "aea74d5e61c1f899613bf64bda66d4c78f2fd17d",
+    "tarball": "http://registry.npmjs.org/async/-/async-0.9.2.tgz"
+  },
+  "directories": {},
+  "_resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz",
+  "readme": "ERROR: No README data found!"
+}

+ 53 - 0
Build/node_modules/jake/node_modules/async/support/sync-package-managers.js

@@ -0,0 +1,53 @@
+#!/usr/bin/env node
+
+// This should probably be its own module but complaints about bower/etc.
+// support keep coming up and I'd rather just enable the workflow here for now
+// and figure out where this should live later. -- @beaugunderson
+
+var fs = require('fs');
+var _ = require('lodash');
+
+var packageJson = require('../package.json');
+
+var IGNORES = ['**/.*', 'node_modules', 'bower_components', 'test', 'tests'];
+var INCLUDES = ['lib/async.js', 'README.md', 'LICENSE'];
+var REPOSITORY_NAME = 'caolan/async';
+
+packageJson.jam = {
+  main: packageJson.main,
+  include: INCLUDES,
+  categories: ['Utilities']
+};
+
+packageJson.spm = {
+  main: packageJson.main
+};
+
+packageJson.volo = {
+  main: packageJson.main,
+  ignore: IGNORES
+};
+
+var bowerSpecific = {
+  moduleType: ['amd', 'globals', 'node'],
+  ignore: IGNORES,
+  authors: [packageJson.author]
+};
+
+var bowerInclude = ['name', 'description', 'version', 'main', 'keywords',
+  'license', 'homepage', 'repository', 'devDependencies'];
+
+var componentSpecific = {
+  repository: REPOSITORY_NAME,
+  scripts: [packageJson.main]
+};
+
+var componentInclude = ['name', 'description', 'version', 'keywords',
+  'license'];
+
+var bowerJson = _.merge({}, _.pick(packageJson, bowerInclude), bowerSpecific);
+var componentJson = _.merge({}, _.pick(packageJson, componentInclude), componentSpecific);
+
+fs.writeFileSync('./bower.json', JSON.stringify(bowerJson, null, 2));
+fs.writeFileSync('./component.json', JSON.stringify(componentJson, null, 2));
+fs.writeFileSync('./package.json', JSON.stringify(packageJson, null, 2));

+ 63 - 0
Build/node_modules/jake/node_modules/chalk/index.js

@@ -0,0 +1,63 @@
+'use strict';
+var ansi = require('ansi-styles');
+var stripAnsi = require('strip-ansi');
+var hasColor = require('has-color');
+var defineProps = Object.defineProperties;
+var chalk = module.exports;
+
+var styles = (function () {
+	var ret = {};
+
+	ansi.grey = ansi.gray;
+
+	Object.keys(ansi).forEach(function (key) {
+		ret[key] = {
+			get: function () {
+				this._styles.push(key);
+				return this;
+			}
+		};
+	});
+
+	return ret;
+})();
+
+function init() {
+	var ret = {};
+
+	Object.keys(styles).forEach(function (name) {
+		ret[name] = {
+			get: function () {
+				var obj = defineProps(function self() {
+					var str = [].slice.call(arguments).join(' ');
+
+					if (!chalk.enabled) {
+						return str;
+					}
+
+					return self._styles.reduce(function (str, name) {
+						var code = ansi[name];
+						return str ? code.open + str + code.close : '';
+					}, str);
+				}, styles);
+
+				obj._styles = [];
+
+				return obj[name];
+			}
+		}
+	});
+
+	return ret;
+}
+
+defineProps(chalk, init());
+
+chalk.styles = ansi;
+chalk.stripColor = stripAnsi;
+chalk.supportsColor = hasColor;
+
+// detect mode if not set manually
+if (chalk.enabled === undefined) {
+	chalk.enabled = chalk.supportsColor;
+}

+ 1 - 0
Build/node_modules/jake/node_modules/chalk/node_modules/.bin/strip-ansi

@@ -0,0 +1 @@
+../strip-ansi/cli.js

+ 38 - 0
Build/node_modules/jake/node_modules/chalk/node_modules/ansi-styles/ansi-styles.js

@@ -0,0 +1,38 @@
+'use strict';
+var styles = module.exports;
+
+var codes = {
+	reset: [0, 0],
+
+	bold: [1, 22],
+	italic: [3, 23],
+	underline: [4, 24],
+	inverse: [7, 27],
+	strikethrough: [9, 29],
+
+	black: [30, 39],
+	red: [31, 39],
+	green: [32, 39],
+	yellow: [33, 39],
+	blue: [34, 39],
+	magenta: [35, 39],
+	cyan: [36, 39],
+	white: [37, 39],
+	gray: [90, 39],
+
+	bgBlack: [40, 49],
+	bgRed: [41, 49],
+	bgGreen: [42, 49],
+	bgYellow: [43, 49],
+	bgBlue: [44, 49],
+	bgMagenta: [45, 49],
+	bgCyan: [46, 49],
+	bgWhite: [47, 49]
+};
+
+Object.keys(codes).forEach(function (key) {
+	var val = codes[key];
+	var style = styles[key] = {};
+	style.open = '\x1b[' + val[0] + 'm';
+	style.close = '\x1b[' + val[1] + 'm';
+});

+ 75 - 0
Build/node_modules/jake/node_modules/chalk/node_modules/ansi-styles/package.json

@@ -0,0 +1,75 @@
+{
+  "name": "ansi-styles",
+  "version": "1.0.0",
+  "description": "ANSI escape codes for colorizing strings in the terminal",
+  "keywords": [
+    "ansi",
+    "styles",
+    "color",
+    "colour",
+    "colors",
+    "terminal",
+    "console",
+    "cli",
+    "string",
+    "tty",
+    "escape",
+    "formatting",
+    "rgb",
+    "256",
+    "shell",
+    "xterm",
+    "log",
+    "logging",
+    "command-line",
+    "text"
+  ],
+  "homepage": "https://github.com/sindresorhus/ansi-styles",
+  "bugs": {
+    "url": "https://github.com/sindresorhus/ansi-styles/issues"
+  },
+  "license": "MIT",
+  "author": {
+    "name": "Sindre Sorhus",
+    "email": "[email protected]",
+    "url": "http://sindresorhus.com"
+  },
+  "files": [
+    "ansi-styles.js"
+  ],
+  "main": "ansi-styles",
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/sindresorhus/ansi-styles.git"
+  },
+  "scripts": {
+    "test": "mocha"
+  },
+  "devDependencies": {
+    "mocha": "~1.12.0"
+  },
+  "engines": {
+    "node": ">=0.8.0"
+  },
+  "_id": "[email protected]",
+  "dist": {
+    "shasum": "cb102df1c56f5123eab8b67cd7b98027a0279178",
+    "tarball": "http://registry.npmjs.org/ansi-styles/-/ansi-styles-1.0.0.tgz"
+  },
+  "_from": "ansi-styles@>=1.0.0 <1.1.0",
+  "_npmVersion": "1.3.15",
+  "_npmUser": {
+    "name": "sindresorhus",
+    "email": "[email protected]"
+  },
+  "maintainers": [
+    {
+      "name": "sindresorhus",
+      "email": "[email protected]"
+    }
+  ],
+  "directories": {},
+  "_shasum": "cb102df1c56f5123eab8b67cd7b98027a0279178",
+  "_resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.0.0.tgz",
+  "readme": "ERROR: No README data found!"
+}

+ 65 - 0
Build/node_modules/jake/node_modules/chalk/node_modules/ansi-styles/readme.md

@@ -0,0 +1,65 @@
+# ansi-styles [![Build Status](https://secure.travis-ci.org/sindresorhus/ansi-styles.png?branch=master)](http://travis-ci.org/sindresorhus/ansi-styles)
+
+> [ANSI escape codes](http://en.wikipedia.org/wiki/ANSI_escape_code#Colors_and_Styles) for colorizing strings in the terminal.
+
+You probably want the higher-level [chalk](https://github.com/sindresorhus/chalk) module for styling your strings.
+
+![screenshot](screenshot.png)
+
+
+## Install
+
+Install with [npm](https://npmjs.org/package/ansi-styles): `npm install --save ansi-styles`
+
+
+## Example
+
+```js
+var ansi = require('ansi-styles');
+
+console.log(ansi.green.open + 'Hello world!' + ansi.green.close);
+```
+
+## API
+
+Each style has an `open` and `close` property.
+
+
+## Styles
+
+### General
+
+- reset
+- bold
+- italic
+- underline
+- inverse
+- strikethrough
+
+### Text colors
+
+- black
+- red
+- green
+- yellow
+- blue
+- magenta
+- cyan
+- white
+- gray
+
+### Background colors
+
+- bgBlack
+- bgRed
+- bgGreen
+- bgYellow
+- bgBlue
+- bgMagenta
+- bgCyan
+- bgWhite
+
+
+## License
+
+MIT © [Sindre Sorhus](http://sindresorhus.com)

+ 32 - 0
Build/node_modules/jake/node_modules/chalk/node_modules/has-color/index.js

@@ -0,0 +1,32 @@
+'use strict';
+module.exports = (function () {
+	if (process.argv.indexOf('--no-color') !== -1) {
+		return false;
+	}
+
+	if (process.argv.indexOf('--color') !== -1) {
+		return true;
+	}
+
+	if (process.stdout && !process.stdout.isTTY) {
+		return false;
+	}
+
+	if (process.platform === 'win32') {
+		return true;
+	}
+
+	if ('COLORTERM' in process.env) {
+		return true;
+	}
+
+	if (process.env.TERM === 'dumb') {
+		return false;
+	}
+
+	if (/^screen|^xterm|^vt100|color|ansi|cygwin|linux/i.test(process.env.TERM)) {
+		return true;
+	}
+
+	return false;
+})();

+ 71 - 0
Build/node_modules/jake/node_modules/chalk/node_modules/has-color/package.json

@@ -0,0 +1,71 @@
+{
+  "name": "has-color",
+  "version": "0.1.7",
+  "description": "Detect whether a terminal supports color",
+  "license": "MIT",
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/sindresorhus/has-color.git"
+  },
+  "author": {
+    "name": "Sindre Sorhus",
+    "email": "[email protected]",
+    "url": "http://sindresorhus.com"
+  },
+  "engines": {
+    "node": ">=0.10.0"
+  },
+  "scripts": {
+    "test": "mocha"
+  },
+  "files": [
+    "index.js"
+  ],
+  "keywords": [
+    "color",
+    "colour",
+    "colors",
+    "terminal",
+    "console",
+    "cli",
+    "ansi",
+    "styles",
+    "tty",
+    "rgb",
+    "256",
+    "shell",
+    "xterm",
+    "command-line",
+    "support",
+    "capability",
+    "detect"
+  ],
+  "devDependencies": {
+    "mocha": "*"
+  },
+  "bugs": {
+    "url": "https://github.com/sindresorhus/has-color/issues"
+  },
+  "homepage": "https://github.com/sindresorhus/has-color",
+  "_id": "[email protected]",
+  "dist": {
+    "shasum": "67144a5260c34fc3cca677d041daf52fe7b78b2f",
+    "tarball": "http://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz"
+  },
+  "_from": "has-color@>=0.1.0 <0.2.0",
+  "_npmVersion": "1.4.6",
+  "_npmUser": {
+    "name": "sindresorhus",
+    "email": "[email protected]"
+  },
+  "maintainers": [
+    {
+      "name": "sindresorhus",
+      "email": "[email protected]"
+    }
+  ],
+  "directories": {},
+  "_shasum": "67144a5260c34fc3cca677d041daf52fe7b78b2f",
+  "_resolved": "https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz",
+  "readme": "ERROR: No README data found!"
+}

+ 30 - 0
Build/node_modules/jake/node_modules/chalk/node_modules/has-color/readme.md

@@ -0,0 +1,30 @@
+# has-color [![Build Status](https://travis-ci.org/sindresorhus/has-color.svg?branch=master)](https://travis-ci.org/sindresorhus/has-color)
+
+> Detect whether a terminal supports color.
+
+Used in the terminal color module [chalk](https://github.com/sindresorhus/chalk).
+
+
+## Install
+
+```bash
+$ npm install --save has-color
+```
+
+
+## Usage
+
+```js
+var hasColor = require('has-color');
+
+if (hasColor) {
+	console.log('Terminal supports color.');
+}
+```
+
+It obeys the `--color` and `--no-color` CLI flags.
+
+
+## License
+
+[MIT](http://opensource.org/licenses/MIT) © [Sindre Sorhus](http://sindresorhus.com)

+ 27 - 0
Build/node_modules/jake/node_modules/chalk/node_modules/strip-ansi/cli.js

@@ -0,0 +1,27 @@
+#!/usr/bin/env node
+'use strict';
+var fs = require('fs');
+var strip = require('./index');
+var input = process.argv[2];
+
+if (process.argv.indexOf('-h') !== -1 || process.argv.indexOf('--help') !== -1) {
+	console.log('strip-ansi <input file> > <output file>');
+	console.log('or');
+	console.log('cat <input file> | strip-ansi > <output file>');
+	return;
+}
+
+if (process.argv.indexOf('-v') !== -1 || process.argv.indexOf('--version') !== -1) {
+	console.log(require('./package').version);
+	return;
+}
+
+if (input) {
+	process.stdout.write(strip(fs.readFileSync(input, 'utf8')));
+	return;
+}
+
+process.stdin.setEncoding('utf8');
+process.stdin.on('data', function (data) {
+	process.stdout.write(strip(data));
+});

+ 4 - 0
Build/node_modules/jake/node_modules/chalk/node_modules/strip-ansi/index.js

@@ -0,0 +1,4 @@
+'use strict';
+module.exports = function (str) {
+	return typeof str === 'string' ? str.replace(/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]/g, '') : str;
+};

+ 81 - 0
Build/node_modules/jake/node_modules/chalk/node_modules/strip-ansi/package.json

@@ -0,0 +1,81 @@
+{
+  "name": "strip-ansi",
+  "version": "0.1.1",
+  "description": "Strip ANSI escape codes (used for colorizing strings in the terminal)",
+  "license": "MIT",
+  "bin": {
+    "strip-ansi": "cli.js"
+  },
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/sindresorhus/strip-ansi.git"
+  },
+  "author": {
+    "name": "Sindre Sorhus",
+    "email": "[email protected]",
+    "url": "http://sindresorhus.com"
+  },
+  "engines": {
+    "node": ">=0.8.0"
+  },
+  "scripts": {
+    "test": "mocha"
+  },
+  "files": [
+    "index.js",
+    "cli.js"
+  ],
+  "keywords": [
+    "strip",
+    "trim",
+    "remove",
+    "ansi",
+    "styles",
+    "color",
+    "colour",
+    "colors",
+    "terminal",
+    "console",
+    "cli",
+    "string",
+    "tty",
+    "escape",
+    "formatting",
+    "rgb",
+    "256",
+    "shell",
+    "xterm",
+    "log",
+    "logging",
+    "command-line",
+    "text"
+  ],
+  "devDependencies": {
+    "mocha": "~1.x"
+  },
+  "bugs": {
+    "url": "https://github.com/sindresorhus/strip-ansi/issues"
+  },
+  "homepage": "https://github.com/sindresorhus/strip-ansi",
+  "_id": "[email protected]",
+  "dist": {
+    "shasum": "39e8a98d044d150660abe4a6808acf70bb7bc991",
+    "tarball": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz"
+  },
+  "_from": "strip-ansi@>=0.1.0 <0.2.0",
+  "_npmVersion": "1.3.15",
+  "_npmUser": {
+    "name": "sindresorhus",
+    "email": "[email protected]"
+  },
+  "maintainers": [
+    {
+      "name": "sindresorhus",
+      "email": "[email protected]"
+    }
+  ],
+  "directories": {},
+  "_shasum": "39e8a98d044d150660abe4a6808acf70bb7bc991",
+  "_resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz",
+  "readme": "ERROR: No README data found!"
+}

+ 46 - 0
Build/node_modules/jake/node_modules/chalk/node_modules/strip-ansi/readme.md

@@ -0,0 +1,46 @@
+# strip-ansi [![Build Status](https://secure.travis-ci.org/sindresorhus/strip-ansi.png?branch=master)](http://travis-ci.org/sindresorhus/strip-ansi)
+
+> Strip [ANSI escape codes](http://en.wikipedia.org/wiki/ANSI_escape_code#Colors_and_Styles) (used for colorizing strings in the terminal)
+
+Used in the terminal color module [chalk](https://github.com/sindresorhus/chalk).
+
+
+## Install
+
+Install locally with [npm](https://npmjs.org/package/strip-ansi):
+
+```
+npm install --save strip-ansi
+```
+
+Or globally if you want to use it as a CLI app:
+
+```
+npm install --global strip-ansi
+```
+
+You can then use it in your Terminal like:
+
+```
+strip-ansi file-with-color-codes
+```
+
+Or pipe something to it:
+
+```
+ls | strip-ansi
+```
+
+
+## Example
+
+```js
+var stripAnsi = require('strip-ansi');
+stripAnsi('\x1b[4mcake\x1b[0m');
+//=> cake
+```
+
+
+## License
+
+MIT © [Sindre Sorhus](http://sindresorhus.com)

+ 78 - 0
Build/node_modules/jake/node_modules/chalk/package.json

@@ -0,0 +1,78 @@
+{
+  "name": "chalk",
+  "version": "0.4.0",
+  "description": "Terminal string styling done right. Created because the `colors` module does some really horrible things.",
+  "license": "MIT",
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/sindresorhus/chalk.git"
+  },
+  "author": {
+    "name": "Sindre Sorhus",
+    "email": "[email protected]",
+    "url": "http://sindresorhus.com"
+  },
+  "engines": {
+    "node": ">=0.8.0"
+  },
+  "scripts": {
+    "test": "mocha"
+  },
+  "files": [
+    "index.js"
+  ],
+  "keywords": [
+    "color",
+    "colour",
+    "colors",
+    "terminal",
+    "console",
+    "cli",
+    "string",
+    "ansi",
+    "styles",
+    "tty",
+    "formatting",
+    "rgb",
+    "256",
+    "shell",
+    "xterm",
+    "log",
+    "logging",
+    "command-line",
+    "text"
+  ],
+  "dependencies": {
+    "has-color": "~0.1.0",
+    "ansi-styles": "~1.0.0",
+    "strip-ansi": "~0.1.0"
+  },
+  "devDependencies": {
+    "mocha": "~1.x"
+  },
+  "bugs": {
+    "url": "https://github.com/sindresorhus/chalk/issues"
+  },
+  "homepage": "https://github.com/sindresorhus/chalk",
+  "_id": "[email protected]",
+  "dist": {
+    "shasum": "5199a3ddcd0c1efe23bc08c1b027b06176e0c64f",
+    "tarball": "http://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz"
+  },
+  "_from": "chalk@>=0.4.0 <0.5.0",
+  "_npmVersion": "1.3.17",
+  "_npmUser": {
+    "name": "sindresorhus",
+    "email": "[email protected]"
+  },
+  "maintainers": [
+    {
+      "name": "sindresorhus",
+      "email": "[email protected]"
+    }
+  ],
+  "directories": {},
+  "_shasum": "5199a3ddcd0c1efe23bc08c1b027b06176e0c64f",
+  "_resolved": "https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz",
+  "readme": "ERROR: No README data found!"
+}

+ 158 - 0
Build/node_modules/jake/node_modules/chalk/readme.md

@@ -0,0 +1,158 @@
+# <img width="250" src="logo.png" alt="chalk">
+
+> Terminal string styling done right
+
+[![Build Status](https://secure.travis-ci.org/sindresorhus/chalk.png?branch=master)](http://travis-ci.org/sindresorhus/chalk)
+
+[colors.js](https://github.com/Marak/colors.js) is currently the most popular string styling module, but it has serious deficiencies like extending String.prototype which causes all kinds of [problems](https://github.com/yeoman/yo/issues/68). Although there are other ones, they either do too much or not enough.
+
+**Chalk is a clean and focused alternative.**
+
+![screenshot](screenshot.png)
+
+
+## Why
+
+- **Doesn't extend String.prototype**
+- Expressive API
+- Clean and focused
+- Auto-detects color support
+- Actively maintained
+- [Used by 150+ modules](https://npmjs.org/browse/depended/chalk)
+
+
+## Install
+
+Install with [npm](https://npmjs.org/package/chalk): `npm install --save chalk`
+
+
+## Example
+
+Chalk comes with an easy to use composable API where you just chain and nest the styles you want.
+
+```js
+var chalk = require('chalk');
+
+// style a string
+console.log(  chalk.blue('Hello world!')  );
+
+// combine styled and normal strings
+console.log(  chalk.blue('Hello'), 'World' + chalk.red('!')  );
+
+// compose multiple styles using the chainable API
+console.log(  chalk.blue.bgRed.bold('Hello world!')  );
+
+// nest styles
+console.log(  chalk.red('Hello', chalk.underline.bgBlue('world') + '!')  );
+
+// pass in multiple arguments
+console.log(  chalk.blue('Hello', 'World!', 'Foo', 'bar', 'biz', 'baz')  );
+```
+
+You can easily define your own themes.
+
+```js
+var chalk = require('chalk');
+var error = chalk.bold.red;
+console.log(error('Error!'));
+```
+
+
+## API
+
+### chalk.`<style>[.<style>...](string, [string...])`
+
+Example: `chalk.red.bold.underline('Hello', 'world');`
+
+Chain [styles](#styles) and call the last one as a method with a string argument. Order doesn't matter.
+
+Multiple arguments will be separated by space.
+
+### chalk.enabled
+
+Color support is automatically detected, but you can override it.
+
+### chalk.supportsColor
+
+Detect whether the terminal [supports color](https://github.com/sindresorhus/has-color).
+
+Can be overridden by the user with the flags `--color` and `--no-color`.
+
+Used internally and handled for you, but exposed for convenience.
+
+### chalk.styles
+
+Exposes the styles as [ANSI escape codes](https://github.com/sindresorhus/ansi-styles).
+
+Generally not useful, but you might need just the `.open` or `.close` escape code if you're mixing externally styled strings with yours.
+
+```js
+var chalk = require('chalk');
+
+console.log(chalk.styles.red);
+//=> {open: '\x1b[31m', close: '\x1b[39m'}
+
+console.log(chalk.styles.red.open + 'Hello' + chalk.styles.red.close);
+```
+
+### chalk.stripColor(string)
+
+[Strip color](https://github.com/sindresorhus/strip-ansi) from a string.
+
+Can be useful in combination with `.supportsColor` to strip color on externally styled text when it's not supported.
+
+Example:
+
+```js
+var chalk = require('chalk');
+var styledString = fromExternal();
+
+if (!chalk.supportsColor) {
+	chalk.stripColor(styledString);
+}
+```
+
+
+## Styles
+
+### General
+
+- reset
+- bold
+- italic
+- underline
+- inverse
+- strikethrough
+
+### Text colors
+
+- black
+- red
+- green
+- yellow
+- blue
+- magenta
+- cyan
+- white
+- gray
+
+### Background colors
+
+- bgBlack
+- bgRed
+- bgGreen
+- bgYellow
+- bgBlue
+- bgMagenta
+- bgCyan
+- bgWhite
+
+
+## License
+
+MIT © [Sindre Sorhus](http://sindresorhus.com)
+
+
+-
+
+[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/sindresorhus/chalk/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

+ 14 - 0
Build/node_modules/jake/node_modules/filelist/Jakefile

@@ -0,0 +1,14 @@
+testTask('FileList', function () {
+  this.testFiles.include('test/*.js');
+});
+
+publishTask('FileList', function () {
+  this.packageFiles.include([
+    'Jakefile'
+  , 'README.md'
+  , 'package.json'
+  , 'index.js'
+    ]);
+});
+
+

+ 84 - 0
Build/node_modules/jake/node_modules/filelist/README.md

@@ -0,0 +1,84 @@
+## FileList
+
+A FileList is a lazy-evaluated list of files. When given a list
+of glob patterns for possible files to be included in the file
+list, instead of searching the file structures to find the files,
+a FileList holds the pattern for latter use.
+
+This allows you to define a FileList to match any number of
+files, but only search out the actual files when then FileList
+itself is actually used. The key is that the first time an
+element of the FileList/Array is requested, the pending patterns
+are resolved into a real list of file names.
+
+### Usage
+
+Add files to the list with the `include` method. You can add glob
+patterns, individual files, or RegExp objects. When the Array
+methods are invoked on the FileList, these items are resolved to
+an actual list of files.
+
+```javascript
+var fl = new FileList();
+fl.include('test/*.js');
+fl.exclude('test/helpers.js');
+```
+
+Use the `exclude` method to override inclusions. You can use this
+when your inclusions are too broad.
+
+### Array methods
+
+FileList has lazy-evaluated versions of most of the array
+methods, including the following:
+
+* join
+* pop
+* push
+* concat
+* reverse
+* shift
+* unshift
+* slice
+* splice
+* sort
+* filter
+* forEach
+* some
+* every
+* map
+* indexOf
+* lastIndexOf
+* reduce
+* reduceRight
+
+When you call one of these methods, the items in the FileList
+will be resolved to the full list of files, and the method will
+be invoked on that result.
+
+### Special `length` method
+
+`length`: FileList includes a length *method* (instead of a
+property) which returns the number of actual files in the list
+once it's been resolved.
+
+### FileList-specific methods
+
+`include`: Add a filename/glob/regex to the list
+
+`exclude`: Override inclusions by excluding a filename/glob/regex
+
+`resolve`: Resolve the items in the FileList to the full list of
+files. This method is invoked automatically when one of the array
+methods is called.
+
+`toArray`: Immediately resolves the list of items, and returns an
+actual array of filepaths.
+
+`clearInclusions`: Clears any pending items -- must be used
+before resolving the list.
+
+`clearExclusions`: Clears the list of exclusions rules.
+
+
+

+ 319 - 0
Build/node_modules/jake/node_modules/filelist/index.js

@@ -0,0 +1,319 @@
+/*
+ * Jake JavaScript build tool
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+var fs = require('fs')
+, path = require('path')
+, minimatch = require('minimatch')
+, utils = require('utilities')
+, globSync;
+
+globSync = function (pat) {
+  var dirname = utils.file.basedir(pat)
+    , files
+    , matches;
+
+  try {
+    files = utils.file.readdirR(dirname).map(function(file){
+      return file.replace(/\\/g, '/');
+    });
+  }
+  // Bail if path doesn't exist -- assume no files
+  catch(e) {
+    console.error(e.message);
+  }
+
+  if (files) {
+    pat = path.normalize(pat);
+    // Hack, Minimatch doesn't support backslashes in the pattern
+    // https://github.com/isaacs/minimatch/issues/7
+    pat = pat.replace(/\\/g, '/');
+    matches = minimatch.match(files, pat, {});
+  }
+  return matches || [];
+};
+
+// Constants
+// ---------------
+// List of all the builtin Array methods we want to override
+var ARRAY_METHODS = Object.getOwnPropertyNames(Array.prototype)
+// Array methods that return a copy instead of affecting the original
+  , SPECIAL_RETURN = {
+      'concat': true
+    , 'slice': true
+    , 'filter': true
+    , 'map': true
+    }
+// Default file-patterns we want to ignore
+  , DEFAULT_IGNORE_PATTERNS = [
+      /(^|[\/\\])CVS([\/\\]|$)/
+    , /(^|[\/\\])\.svn([\/\\]|$)/
+    , /(^|[\/\\])\.git([\/\\]|$)/
+    , /\.bak$/
+    , /~$/
+    ]
+// Ignore core files
+  , DEFAULT_IGNORE_FUNCS = [
+      function (name) {
+        var isDir = false
+          , stats;
+        try {
+          stats = fs.statSync(name);
+          isDir = stats.isDirectory();
+        }
+        catch(e) {}
+        return (/(^|[\/\\])core$/).test(name) && !isDir;
+      }
+    ];
+
+var FileList = function () {
+  var self = this
+    , wrap;
+
+  // List of glob-patterns or specific filenames
+  this.pendingAdd = [];
+  // Switched to false after lazy-eval of files
+  this.pending = true;
+  // Used to calculate exclusions from the list of files
+  this.excludes = {
+    pats: DEFAULT_IGNORE_PATTERNS.slice()
+  , funcs: DEFAULT_IGNORE_FUNCS.slice()
+  , regex: null
+  };
+  this.items = [];
+
+  // Wrap the array methods with the delegates
+  wrap = function (prop) {
+    var arr;
+    self[prop] = function () {
+      if (self.pending) {
+        self.resolve();
+      }
+      if (typeof self.items[prop] == 'function') {
+        // Special method that return a copy
+        if (SPECIAL_RETURN[prop]) {
+          arr = self.items[prop].apply(self.items, arguments);
+          return FileList.clone(self, arr);
+        }
+        else {
+          return self.items[prop].apply(self.items, arguments);
+        }
+      }
+      else {
+        return self.items[prop];
+      }
+    };
+  };
+  for (var i = 0, ii = ARRAY_METHODS.length; i < ii; i++) {
+    wrap(ARRAY_METHODS[i]);
+  }
+
+  // Include whatever files got passed to the constructor
+  this.include.apply(this, arguments);
+
+  // Fix constructor linkage
+  this.constructor = FileList;
+};
+
+FileList.prototype = new (function () {
+  var globPattern = /[*?\[\{]/;
+
+  var _addMatching = function (pat) {
+        var matches = globSync(pat);
+        this.items = this.items.concat(matches);
+      }
+
+    , _resolveAdd = function (name) {
+        if (globPattern.test(name)) {
+          _addMatching.call(this, name);
+        }
+        else {
+          this.push(name);
+        }
+      }
+
+    , _calculateExcludeRe = function () {
+        var pats = this.excludes.pats
+          , pat
+          , excl = []
+          , matches = [];
+
+        for (var i = 0, ii = pats.length; i < ii; i++) {
+          pat = pats[i];
+          if (typeof pat == 'string') {
+            // Glob, look up files
+            if (/[*?]/.test(pat)) {
+              matches = globSync(pat);
+              matches = matches.map(function (m) {
+                return utils.string.escapeRegExpChars(m);
+              });
+              excl = excl.concat(matches);
+            }
+            // String for regex
+            else {
+              excl.push(utils.string.escapeRegExpChars(pat));
+            }
+          }
+          // Regex, grab the string-representation
+          else if (pat instanceof RegExp) {
+            excl.push(pat.toString().replace(/^\/|\/$/g, ''));
+          }
+        }
+        if (excl.length) {
+          this.excludes.regex = new RegExp('(' + excl.join(')|(') + ')');
+        }
+        else {
+          this.excludes.regex = /^$/;
+        }
+      }
+
+    , _resolveExclude = function () {
+        var self = this;
+        _calculateExcludeRe.call(this);
+        // No `reject` method, so use reverse-filter
+        this.items = this.items.filter(function (name) {
+          return !self.shouldExclude(name);
+        });
+      };
+
+  /**
+   * Includes file-patterns in the FileList. Should be called with one or more
+   * pattern for finding file to include in the list. Arguments should be strings
+   * for either a glob-pattern or a specific file-name, or an array of them
+   */
+  this.include = function (items) {
+    if (items) {
+      this.pendingAdd = this.pendingAdd.concat(items).filter(function (item) {
+        return !!item;
+      });
+    }
+    return this;
+  };
+
+  /**
+   * Indicates whether a particular file would be filtered out by the current
+   * exclusion rules for this FileList.
+   * @param {String} name The filename to check
+   * @return {Boolean} Whether or not the file should be excluded
+   */
+  this.shouldExclude = function (name) {
+    if (!this.excludes.regex) {
+      _calculateExcludeRe.call(this);
+    }
+    var excl = this.excludes;
+    return excl.regex.test(name) || excl.funcs.some(function (f) {
+      return !!f(name);
+    });
+  };
+
+  /**
+   * Excludes file-patterns from the FileList. Should be called with one or more
+   * pattern for finding file to include in the list. Arguments can be:
+   * 1. Strings for either a glob-pattern or a specific file-name
+   * 2. Regular expression literals
+   * 3. Functions to be run on the filename that return a true/false
+   */
+  this.exclude = function () {
+    var args = Array.isArray(arguments[0]) ? arguments[0] : arguments
+      , arg;
+    for (var i = 0, ii = args.length; i < ii; i++) {
+      arg = args[i];
+      if (typeof arg == 'function' && !(arg instanceof RegExp)) {
+        this.excludes.funcs.push(arg);
+      }
+      else {
+        this.excludes.pats.push(arg);
+      }
+    }
+    if (!this.pending) {
+      _resolveExclude.call(this);
+    }
+    return this;
+  };
+
+  /**
+   * Populates the FileList from the include/exclude rules with a list of
+   * actual files
+   */
+  this.resolve = function () {
+    var name
+      , uniqueFunc = function (p, c) {
+          if (p.indexOf(c) < 0) {
+            p.push(c);
+          }
+          return p;
+        };
+    if (this.pending) {
+      this.pending = false;
+      while ((name = this.pendingAdd.shift())) {
+        _resolveAdd.call(this, name);
+      }
+      // Reduce to a unique list
+      this.items = this.items.reduce(uniqueFunc, []);
+      // Remove exclusions
+      _resolveExclude.call(this);
+    }
+    return this;
+  };
+
+  /**
+   * Convert to a plain-jane array
+   */
+  this.toArray = function () {
+    // Call slice to ensure lazy-resolution before slicing items
+    var ret = this.slice().items.slice();
+    return ret;
+  };
+
+  /**
+   * Clear any pending items -- only useful before
+   * calling `resolve`
+   */
+  this.clearInclusions = function () {
+    this.pendingAdd = [];
+    return this;
+  };
+
+  /**
+   * Clear any current exclusion rules
+   */
+  this.clearExclusions = function () {
+    this.excludes = {
+      pats: []
+    , funcs: []
+    , regex: null
+    };
+    return this;
+  };
+
+})();
+
+// Static method, used to create copy returned by special
+// array methods
+FileList.clone = function (list, items) {
+  var clone = new FileList();
+  if (items) {
+    clone.items = items;
+  }
+  clone.pendingAdd = list.pendingAdd;
+  clone.pending = list.pending;
+  for (var p in list.excludes) {
+    clone.excludes[p] = list.excludes[p];
+  }
+  return clone;
+};
+
+exports.FileList = FileList;

+ 1 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/.npmignore

@@ -0,0 +1 @@
+node_modules

+ 23 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/LICENSE

@@ -0,0 +1,23 @@
+Copyright 2009, 2010, 2011 Isaac Z. Schlueter.
+All rights reserved.
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.

+ 218 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/README.md

@@ -0,0 +1,218 @@
+# minimatch
+
+A minimal matching utility.
+
+[![Build Status](https://secure.travis-ci.org/isaacs/minimatch.png)](http://travis-ci.org/isaacs/minimatch)
+
+
+This is the matching library used internally by npm.
+
+Eventually, it will replace the C binding in node-glob.
+
+It works by converting glob expressions into JavaScript `RegExp`
+objects.
+
+## Usage
+
+```javascript
+var minimatch = require("minimatch")
+
+minimatch("bar.foo", "*.foo") // true!
+minimatch("bar.foo", "*.bar") // false!
+minimatch("bar.foo", "*.+(bar|foo)", { debug: true }) // true, and noisy!
+```
+
+## Features
+
+Supports these glob features:
+
+* Brace Expansion
+* Extended glob matching
+* "Globstar" `**` matching
+
+See:
+
+* `man sh`
+* `man bash`
+* `man 3 fnmatch`
+* `man 5 gitignore`
+
+## Minimatch Class
+
+Create a minimatch object by instanting the `minimatch.Minimatch` class.
+
+```javascript
+var Minimatch = require("minimatch").Minimatch
+var mm = new Minimatch(pattern, options)
+```
+
+### Properties
+
+* `pattern` The original pattern the minimatch object represents.
+* `options` The options supplied to the constructor.
+* `set` A 2-dimensional array of regexp or string expressions.
+  Each row in the
+  array corresponds to a brace-expanded pattern.  Each item in the row
+  corresponds to a single path-part.  For example, the pattern
+  `{a,b/c}/d` would expand to a set of patterns like:
+
+        [ [ a, d ]
+        , [ b, c, d ] ]
+
+    If a portion of the pattern doesn't have any "magic" in it
+    (that is, it's something like `"foo"` rather than `fo*o?`), then it
+    will be left as a string rather than converted to a regular
+    expression.
+
+* `regexp` Created by the `makeRe` method.  A single regular expression
+  expressing the entire pattern.  This is useful in cases where you wish
+  to use the pattern somewhat like `fnmatch(3)` with `FNM_PATH` enabled.
+* `negate` True if the pattern is negated.
+* `comment` True if the pattern is a comment.
+* `empty` True if the pattern is `""`.
+
+### Methods
+
+* `makeRe` Generate the `regexp` member if necessary, and return it.
+  Will return `false` if the pattern is invalid.
+* `match(fname)` Return true if the filename matches the pattern, or
+  false otherwise.
+* `matchOne(fileArray, patternArray, partial)` Take a `/`-split
+  filename, and match it against a single row in the `regExpSet`.  This
+  method is mainly for internal use, but is exposed so that it can be
+  used by a glob-walker that needs to avoid excessive filesystem calls.
+
+All other methods are internal, and will be called as necessary.
+
+## Functions
+
+The top-level exported function has a `cache` property, which is an LRU
+cache set to store 100 items.  So, calling these methods repeatedly
+with the same pattern and options will use the same Minimatch object,
+saving the cost of parsing it multiple times.
+
+### minimatch(path, pattern, options)
+
+Main export.  Tests a path against the pattern using the options.
+
+```javascript
+var isJS = minimatch(file, "*.js", { matchBase: true })
+```
+
+### minimatch.filter(pattern, options)
+
+Returns a function that tests its
+supplied argument, suitable for use with `Array.filter`.  Example:
+
+```javascript
+var javascripts = fileList.filter(minimatch.filter("*.js", {matchBase: true}))
+```
+
+### minimatch.match(list, pattern, options)
+
+Match against the list of
+files, in the style of fnmatch or glob.  If nothing is matched, and
+options.nonull is set, then return a list containing the pattern itself.
+
+```javascript
+var javascripts = minimatch.match(fileList, "*.js", {matchBase: true}))
+```
+
+### minimatch.makeRe(pattern, options)
+
+Make a regular expression object from the pattern.
+
+## Options
+
+All options are `false` by default.
+
+### debug
+
+Dump a ton of stuff to stderr.
+
+### nobrace
+
+Do not expand `{a,b}` and `{1..3}` brace sets.
+
+### noglobstar
+
+Disable `**` matching against multiple folder names.
+
+### dot
+
+Allow patterns to match filenames starting with a period, even if
+the pattern does not explicitly have a period in that spot.
+
+Note that by default, `a/**/b` will **not** match `a/.d/b`, unless `dot`
+is set.
+
+### noext
+
+Disable "extglob" style patterns like `+(a|b)`.
+
+### nocase
+
+Perform a case-insensitive match.
+
+### nonull
+
+When a match is not found by `minimatch.match`, return a list containing
+the pattern itself if this option is set.  When not set, an empty list
+is returned if there are no matches.
+
+### matchBase
+
+If set, then patterns without slashes will be matched
+against the basename of the path if it contains slashes.  For example,
+`a?b` would match the path `/xyz/123/acb`, but not `/xyz/acb/123`.
+
+### nocomment
+
+Suppress the behavior of treating `#` at the start of a pattern as a
+comment.
+
+### nonegate
+
+Suppress the behavior of treating a leading `!` character as negation.
+
+### flipNegate
+
+Returns from negate expressions the same as if they were not negated.
+(Ie, true on a hit, false on a miss.)
+
+
+## Comparisons to other fnmatch/glob implementations
+
+While strict compliance with the existing standards is a worthwhile
+goal, some discrepancies exist between minimatch and other
+implementations, and are intentional.
+
+If the pattern starts with a `!` character, then it is negated.  Set the
+`nonegate` flag to suppress this behavior, and treat leading `!`
+characters normally.  This is perhaps relevant if you wish to start the
+pattern with a negative extglob pattern like `!(a|B)`.  Multiple `!`
+characters at the start of a pattern will negate the pattern multiple
+times.
+
+If a pattern starts with `#`, then it is treated as a comment, and
+will not match anything.  Use `\#` to match a literal `#` at the
+start of a line, or set the `nocomment` flag to suppress this behavior.
+
+The double-star character `**` is supported by default, unless the
+`noglobstar` flag is set.  This is supported in the manner of bsdglob
+and bash 4.1, where `**` only has special significance if it is the only
+thing in a path part.  That is, `a/**/b` will match `a/x/y/b`, but
+`a/**b` will not.
+
+If an escaped pattern has no matches, and the `nonull` flag is set,
+then minimatch.match returns the pattern as-provided, rather than
+interpreting the character escapes.  For example,
+`minimatch.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than
+`"*a?"`.  This is akin to setting the `nullglob` option in bash, except
+that it does not resolve escaped pattern characters.
+
+If brace expansion is not disabled, then it is performed before any
+other interpretation of the glob pattern.  Thus, a pattern like
+`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded
+**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are
+checked for validity.  Since those two are valid, matching proceeds.

+ 1061 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/minimatch.js

@@ -0,0 +1,1061 @@
+;(function (require, exports, module, platform) {
+
+if (module) module.exports = minimatch
+else exports.minimatch = minimatch
+
+if (!require) {
+  require = function (id) {
+    switch (id) {
+      case "sigmund": return function sigmund (obj) {
+        return JSON.stringify(obj)
+      }
+      case "path": return { basename: function (f) {
+        f = f.split(/[\/\\]/)
+        var e = f.pop()
+        if (!e) e = f.pop()
+        return e
+      }}
+      case "lru-cache": return function LRUCache () {
+        // not quite an LRU, but still space-limited.
+        var cache = {}
+        var cnt = 0
+        this.set = function (k, v) {
+          cnt ++
+          if (cnt >= 100) cache = {}
+          cache[k] = v
+        }
+        this.get = function (k) { return cache[k] }
+      }
+    }
+  }
+}
+
+minimatch.Minimatch = Minimatch
+
+var LRU = require("lru-cache")
+  , cache = minimatch.cache = new LRU({max: 100})
+  , GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {}
+  , sigmund = require("sigmund")
+
+var path = require("path")
+  // any single thing other than /
+  // don't need to escape / when using new RegExp()
+  , qmark = "[^/]"
+
+  // * => any number of characters
+  , star = qmark + "*?"
+
+  // ** when dots are allowed.  Anything goes, except .. and .
+  // not (^ or / followed by one or two dots followed by $ or /),
+  // followed by anything, any number of times.
+  , twoStarDot = "(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?"
+
+  // not a ^ or / followed by a dot,
+  // followed by anything, any number of times.
+  , twoStarNoDot = "(?:(?!(?:\\\/|^)\\.).)*?"
+
+  // characters that need to be escaped in RegExp.
+  , reSpecials = charSet("().*{}+?[]^$\\!")
+
+// "abc" -> { a:true, b:true, c:true }
+function charSet (s) {
+  return s.split("").reduce(function (set, c) {
+    set[c] = true
+    return set
+  }, {})
+}
+
+// normalizes slashes.
+var slashSplit = /\/+/
+
+minimatch.filter = filter
+function filter (pattern, options) {
+  options = options || {}
+  return function (p, i, list) {
+    return minimatch(p, pattern, options)
+  }
+}
+
+function ext (a, b) {
+  a = a || {}
+  b = b || {}
+  var t = {}
+  Object.keys(b).forEach(function (k) {
+    t[k] = b[k]
+  })
+  Object.keys(a).forEach(function (k) {
+    t[k] = a[k]
+  })
+  return t
+}
+
+minimatch.defaults = function (def) {
+  if (!def || !Object.keys(def).length) return minimatch
+
+  var orig = minimatch
+
+  var m = function minimatch (p, pattern, options) {
+    return orig.minimatch(p, pattern, ext(def, options))
+  }
+
+  m.Minimatch = function Minimatch (pattern, options) {
+    return new orig.Minimatch(pattern, ext(def, options))
+  }
+
+  return m
+}
+
+Minimatch.defaults = function (def) {
+  if (!def || !Object.keys(def).length) return Minimatch
+  return minimatch.defaults(def).Minimatch
+}
+
+
+function minimatch (p, pattern, options) {
+  if (typeof pattern !== "string") {
+    throw new TypeError("glob pattern string required")
+  }
+
+  if (!options) options = {}
+
+  // shortcut: comments match nothing.
+  if (!options.nocomment && pattern.charAt(0) === "#") {
+    return false
+  }
+
+  // "" only matches ""
+  if (pattern.trim() === "") return p === ""
+
+  return new Minimatch(pattern, options).match(p)
+}
+
+function Minimatch (pattern, options) {
+  if (!(this instanceof Minimatch)) {
+    return new Minimatch(pattern, options, cache)
+  }
+
+  if (typeof pattern !== "string") {
+    throw new TypeError("glob pattern string required")
+  }
+
+  if (!options) options = {}
+  pattern = pattern.trim()
+
+  // windows: need to use /, not \
+  // On other platforms, \ is a valid (albeit bad) filename char.
+  if (platform === "win32") {
+    pattern = pattern.split("\\").join("/")
+  }
+
+  // lru storage.
+  // these things aren't particularly big, but walking down the string
+  // and turning it into a regexp can get pretty costly.
+  var cacheKey = pattern + "\n" + sigmund(options)
+  var cached = minimatch.cache.get(cacheKey)
+  if (cached) return cached
+  minimatch.cache.set(cacheKey, this)
+
+  this.options = options
+  this.set = []
+  this.pattern = pattern
+  this.regexp = null
+  this.negate = false
+  this.comment = false
+  this.empty = false
+
+  // make the set of regexps etc.
+  this.make()
+}
+
+Minimatch.prototype.debug = function() {}
+
+Minimatch.prototype.make = make
+function make () {
+  // don't do it more than once.
+  if (this._made) return
+
+  var pattern = this.pattern
+  var options = this.options
+
+  // empty patterns and comments match nothing.
+  if (!options.nocomment && pattern.charAt(0) === "#") {
+    this.comment = true
+    return
+  }
+  if (!pattern) {
+    this.empty = true
+    return
+  }
+
+  // step 1: figure out negation, etc.
+  this.parseNegate()
+
+  // step 2: expand braces
+  var set = this.globSet = this.braceExpand()
+
+  if (options.debug) this.debug = console.error
+
+  this.debug(this.pattern, set)
+
+  // step 3: now we have a set, so turn each one into a series of path-portion
+  // matching patterns.
+  // These will be regexps, except in the case of "**", which is
+  // set to the GLOBSTAR object for globstar behavior,
+  // and will not contain any / characters
+  set = this.globParts = set.map(function (s) {
+    return s.split(slashSplit)
+  })
+
+  this.debug(this.pattern, set)
+
+  // glob --> regexps
+  set = set.map(function (s, si, set) {
+    return s.map(this.parse, this)
+  }, this)
+
+  this.debug(this.pattern, set)
+
+  // filter out everything that didn't compile properly.
+  set = set.filter(function (s) {
+    return -1 === s.indexOf(false)
+  })
+
+  this.debug(this.pattern, set)
+
+  this.set = set
+}
+
+Minimatch.prototype.parseNegate = parseNegate
+function parseNegate () {
+  var pattern = this.pattern
+    , negate = false
+    , options = this.options
+    , negateOffset = 0
+
+  if (options.nonegate) return
+
+  for ( var i = 0, l = pattern.length
+      ; i < l && pattern.charAt(i) === "!"
+      ; i ++) {
+    negate = !negate
+    negateOffset ++
+  }
+
+  if (negateOffset) this.pattern = pattern.substr(negateOffset)
+  this.negate = negate
+}
+
+// Brace expansion:
+// a{b,c}d -> abd acd
+// a{b,}c -> abc ac
+// a{0..3}d -> a0d a1d a2d a3d
+// a{b,c{d,e}f}g -> abg acdfg acefg
+// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg
+//
+// Invalid sets are not expanded.
+// a{2..}b -> a{2..}b
+// a{b}c -> a{b}c
+minimatch.braceExpand = function (pattern, options) {
+  return new Minimatch(pattern, options).braceExpand()
+}
+
+Minimatch.prototype.braceExpand = braceExpand
+function braceExpand (pattern, options) {
+  options = options || this.options
+  pattern = typeof pattern === "undefined"
+    ? this.pattern : pattern
+
+  if (typeof pattern === "undefined") {
+    throw new Error("undefined pattern")
+  }
+
+  if (options.nobrace ||
+      !pattern.match(/\{.*\}/)) {
+    // shortcut. no need to expand.
+    return [pattern]
+  }
+
+  var escaping = false
+
+  // examples and comments refer to this crazy pattern:
+  // a{b,c{d,e},{f,g}h}x{y,z}
+  // expected:
+  // abxy
+  // abxz
+  // acdxy
+  // acdxz
+  // acexy
+  // acexz
+  // afhxy
+  // afhxz
+  // aghxy
+  // aghxz
+
+  // everything before the first \{ is just a prefix.
+  // So, we pluck that off, and work with the rest,
+  // and then prepend it to everything we find.
+  if (pattern.charAt(0) !== "{") {
+    this.debug(pattern)
+    var prefix = null
+    for (var i = 0, l = pattern.length; i < l; i ++) {
+      var c = pattern.charAt(i)
+      this.debug(i, c)
+      if (c === "\\") {
+        escaping = !escaping
+      } else if (c === "{" && !escaping) {
+        prefix = pattern.substr(0, i)
+        break
+      }
+    }
+
+    // actually no sets, all { were escaped.
+    if (prefix === null) {
+      this.debug("no sets")
+      return [pattern]
+    }
+
+   var tail = braceExpand.call(this, pattern.substr(i), options)
+    return tail.map(function (t) {
+      return prefix + t
+    })
+  }
+
+  // now we have something like:
+  // {b,c{d,e},{f,g}h}x{y,z}
+  // walk through the set, expanding each part, until
+  // the set ends.  then, we'll expand the suffix.
+  // If the set only has a single member, then'll put the {} back
+
+  // first, handle numeric sets, since they're easier
+  var numset = pattern.match(/^\{(-?[0-9]+)\.\.(-?[0-9]+)\}/)
+  if (numset) {
+    this.debug("numset", numset[1], numset[2])
+    var suf = braceExpand.call(this, pattern.substr(numset[0].length), options)
+      , start = +numset[1]
+      , end = +numset[2]
+      , inc = start > end ? -1 : 1
+      , set = []
+    for (var i = start; i != (end + inc); i += inc) {
+      // append all the suffixes
+      for (var ii = 0, ll = suf.length; ii < ll; ii ++) {
+        set.push(i + suf[ii])
+      }
+    }
+    return set
+  }
+
+  // ok, walk through the set
+  // We hope, somewhat optimistically, that there
+  // will be a } at the end.
+  // If the closing brace isn't found, then the pattern is
+  // interpreted as braceExpand("\\" + pattern) so that
+  // the leading \{ will be interpreted literally.
+  var i = 1 // skip the \{
+    , depth = 1
+    , set = []
+    , member = ""
+    , sawEnd = false
+    , escaping = false
+
+  function addMember () {
+    set.push(member)
+    member = ""
+  }
+
+  this.debug("Entering for")
+  FOR: for (i = 1, l = pattern.length; i < l; i ++) {
+    var c = pattern.charAt(i)
+    this.debug("", i, c)
+
+    if (escaping) {
+      escaping = false
+      member += "\\" + c
+    } else {
+      switch (c) {
+        case "\\":
+          escaping = true
+          continue
+
+        case "{":
+          depth ++
+          member += "{"
+          continue
+
+        case "}":
+          depth --
+          // if this closes the actual set, then we're done
+          if (depth === 0) {
+            addMember()
+            // pluck off the close-brace
+            i ++
+            break FOR
+          } else {
+            member += c
+            continue
+          }
+
+        case ",":
+          if (depth === 1) {
+            addMember()
+          } else {
+            member += c
+          }
+          continue
+
+        default:
+          member += c
+          continue
+      } // switch
+    } // else
+  } // for
+
+  // now we've either finished the set, and the suffix is
+  // pattern.substr(i), or we have *not* closed the set,
+  // and need to escape the leading brace
+  if (depth !== 0) {
+    this.debug("didn't close", pattern)
+    return braceExpand.call(this, "\\" + pattern, options)
+  }
+
+  // x{y,z} -> ["xy", "xz"]
+  this.debug("set", set)
+  this.debug("suffix", pattern.substr(i))
+  var suf = braceExpand.call(this, pattern.substr(i), options)
+  // ["b", "c{d,e}","{f,g}h"] ->
+  //   [["b"], ["cd", "ce"], ["fh", "gh"]]
+  var addBraces = set.length === 1
+  this.debug("set pre-expanded", set)
+  set = set.map(function (p) {
+    return braceExpand.call(this, p, options)
+  }, this)
+  this.debug("set expanded", set)
+
+
+  // [["b"], ["cd", "ce"], ["fh", "gh"]] ->
+  //   ["b", "cd", "ce", "fh", "gh"]
+  set = set.reduce(function (l, r) {
+    return l.concat(r)
+  })
+
+  if (addBraces) {
+    set = set.map(function (s) {
+      return "{" + s + "}"
+    })
+  }
+
+  // now attach the suffixes.
+  var ret = []
+  for (var i = 0, l = set.length; i < l; i ++) {
+    for (var ii = 0, ll = suf.length; ii < ll; ii ++) {
+      ret.push(set[i] + suf[ii])
+    }
+  }
+  return ret
+}
+
+// parse a component of the expanded set.
+// At this point, no pattern may contain "/" in it
+// so we're going to return a 2d array, where each entry is the full
+// pattern, split on '/', and then turned into a regular expression.
+// A regexp is made at the end which joins each array with an
+// escaped /, and another full one which joins each regexp with |.
+//
+// Following the lead of Bash 4.1, note that "**" only has special meaning
+// when it is the *only* thing in a path portion.  Otherwise, any series
+// of * is equivalent to a single *.  Globstar behavior is enabled by
+// default, and can be disabled by setting options.noglobstar.
+Minimatch.prototype.parse = parse
+var SUBPARSE = {}
+function parse (pattern, isSub) {
+  var options = this.options
+
+  // shortcuts
+  if (!options.noglobstar && pattern === "**") return GLOBSTAR
+  if (pattern === "") return ""
+
+  var re = ""
+    , hasMagic = !!options.nocase
+    , escaping = false
+    // ? => one single character
+    , patternListStack = []
+    , plType
+    , stateChar
+    , inClass = false
+    , reClassStart = -1
+    , classStart = -1
+    // . and .. never match anything that doesn't start with .,
+    // even when options.dot is set.
+    , patternStart = pattern.charAt(0) === "." ? "" // anything
+      // not (start or / followed by . or .. followed by / or end)
+      : options.dot ? "(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))"
+      : "(?!\\.)"
+    , self = this
+
+  function clearStateChar () {
+    if (stateChar) {
+      // we had some state-tracking character
+      // that wasn't consumed by this pass.
+      switch (stateChar) {
+        case "*":
+          re += star
+          hasMagic = true
+          break
+        case "?":
+          re += qmark
+          hasMagic = true
+          break
+        default:
+          re += "\\"+stateChar
+          break
+      }
+      self.debug('clearStateChar %j %j', stateChar, re)
+      stateChar = false
+    }
+  }
+
+  for ( var i = 0, len = pattern.length, c
+      ; (i < len) && (c = pattern.charAt(i))
+      ; i ++ ) {
+
+    this.debug("%s\t%s %s %j", pattern, i, re, c)
+
+    // skip over any that are escaped.
+    if (escaping && reSpecials[c]) {
+      re += "\\" + c
+      escaping = false
+      continue
+    }
+
+    SWITCH: switch (c) {
+      case "/":
+        // completely not allowed, even escaped.
+        // Should already be path-split by now.
+        return false
+
+      case "\\":
+        clearStateChar()
+        escaping = true
+        continue
+
+      // the various stateChar values
+      // for the "extglob" stuff.
+      case "?":
+      case "*":
+      case "+":
+      case "@":
+      case "!":
+        this.debug("%s\t%s %s %j <-- stateChar", pattern, i, re, c)
+
+        // all of those are literals inside a class, except that
+        // the glob [!a] means [^a] in regexp
+        if (inClass) {
+          this.debug('  in class')
+          if (c === "!" && i === classStart + 1) c = "^"
+          re += c
+          continue
+        }
+
+        // if we already have a stateChar, then it means
+        // that there was something like ** or +? in there.
+        // Handle the stateChar, then proceed with this one.
+        self.debug('call clearStateChar %j', stateChar)
+        clearStateChar()
+        stateChar = c
+        // if extglob is disabled, then +(asdf|foo) isn't a thing.
+        // just clear the statechar *now*, rather than even diving into
+        // the patternList stuff.
+        if (options.noext) clearStateChar()
+        continue
+
+      case "(":
+        if (inClass) {
+          re += "("
+          continue
+        }
+
+        if (!stateChar) {
+          re += "\\("
+          continue
+        }
+
+        plType = stateChar
+        patternListStack.push({ type: plType
+                              , start: i - 1
+                              , reStart: re.length })
+        // negation is (?:(?!js)[^/]*)
+        re += stateChar === "!" ? "(?:(?!" : "(?:"
+        this.debug('plType %j %j', stateChar, re)
+        stateChar = false
+        continue
+
+      case ")":
+        if (inClass || !patternListStack.length) {
+          re += "\\)"
+          continue
+        }
+
+        clearStateChar()
+        hasMagic = true
+        re += ")"
+        plType = patternListStack.pop().type
+        // negation is (?:(?!js)[^/]*)
+        // The others are (?:<pattern>)<type>
+        switch (plType) {
+          case "!":
+            re += "[^/]*?)"
+            break
+          case "?":
+          case "+":
+          case "*": re += plType
+          case "@": break // the default anyway
+        }
+        continue
+
+      case "|":
+        if (inClass || !patternListStack.length || escaping) {
+          re += "\\|"
+          escaping = false
+          continue
+        }
+
+        clearStateChar()
+        re += "|"
+        continue
+
+      // these are mostly the same in regexp and glob
+      case "[":
+        // swallow any state-tracking char before the [
+        clearStateChar()
+
+        if (inClass) {
+          re += "\\" + c
+          continue
+        }
+
+        inClass = true
+        classStart = i
+        reClassStart = re.length
+        re += c
+        continue
+
+      case "]":
+        //  a right bracket shall lose its special
+        //  meaning and represent itself in
+        //  a bracket expression if it occurs
+        //  first in the list.  -- POSIX.2 2.8.3.2
+        if (i === classStart + 1 || !inClass) {
+          re += "\\" + c
+          escaping = false
+          continue
+        }
+
+        // finish up the class.
+        hasMagic = true
+        inClass = false
+        re += c
+        continue
+
+      default:
+        // swallow any state char that wasn't consumed
+        clearStateChar()
+
+        if (escaping) {
+          // no need
+          escaping = false
+        } else if (reSpecials[c]
+                   && !(c === "^" && inClass)) {
+          re += "\\"
+        }
+
+        re += c
+
+    } // switch
+  } // for
+
+
+  // handle the case where we left a class open.
+  // "[abc" is valid, equivalent to "\[abc"
+  if (inClass) {
+    // split where the last [ was, and escape it
+    // this is a huge pita.  We now have to re-walk
+    // the contents of the would-be class to re-translate
+    // any characters that were passed through as-is
+    var cs = pattern.substr(classStart + 1)
+      , sp = this.parse(cs, SUBPARSE)
+    re = re.substr(0, reClassStart) + "\\[" + sp[0]
+    hasMagic = hasMagic || sp[1]
+  }
+
+  // handle the case where we had a +( thing at the *end*
+  // of the pattern.
+  // each pattern list stack adds 3 chars, and we need to go through
+  // and escape any | chars that were passed through as-is for the regexp.
+  // Go through and escape them, taking care not to double-escape any
+  // | chars that were already escaped.
+  var pl
+  while (pl = patternListStack.pop()) {
+    var tail = re.slice(pl.reStart + 3)
+    // maybe some even number of \, then maybe 1 \, followed by a |
+    tail = tail.replace(/((?:\\{2})*)(\\?)\|/g, function (_, $1, $2) {
+      if (!$2) {
+        // the | isn't already escaped, so escape it.
+        $2 = "\\"
+      }
+
+      // need to escape all those slashes *again*, without escaping the
+      // one that we need for escaping the | character.  As it works out,
+      // escaping an even number of slashes can be done by simply repeating
+      // it exactly after itself.  That's why this trick works.
+      //
+      // I am sorry that you have to see this.
+      return $1 + $1 + $2 + "|"
+    })
+
+    this.debug("tail=%j\n   %s", tail, tail)
+    var t = pl.type === "*" ? star
+          : pl.type === "?" ? qmark
+          : "\\" + pl.type
+
+    hasMagic = true
+    re = re.slice(0, pl.reStart)
+       + t + "\\("
+       + tail
+  }
+
+  // handle trailing things that only matter at the very end.
+  clearStateChar()
+  if (escaping) {
+    // trailing \\
+    re += "\\\\"
+  }
+
+  // only need to apply the nodot start if the re starts with
+  // something that could conceivably capture a dot
+  var addPatternStart = false
+  switch (re.charAt(0)) {
+    case ".":
+    case "[":
+    case "(": addPatternStart = true
+  }
+
+  // if the re is not "" at this point, then we need to make sure
+  // it doesn't match against an empty path part.
+  // Otherwise a/* will match a/, which it should not.
+  if (re !== "" && hasMagic) re = "(?=.)" + re
+
+  if (addPatternStart) re = patternStart + re
+
+  // parsing just a piece of a larger pattern.
+  if (isSub === SUBPARSE) {
+    return [ re, hasMagic ]
+  }
+
+  // skip the regexp for non-magical patterns
+  // unescape anything in it, though, so that it'll be
+  // an exact match against a file etc.
+  if (!hasMagic) {
+    return globUnescape(pattern)
+  }
+
+  var flags = options.nocase ? "i" : ""
+    , regExp = new RegExp("^" + re + "$", flags)
+
+  regExp._glob = pattern
+  regExp._src = re
+
+  return regExp
+}
+
+minimatch.makeRe = function (pattern, options) {
+  return new Minimatch(pattern, options || {}).makeRe()
+}
+
+Minimatch.prototype.makeRe = makeRe
+function makeRe () {
+  if (this.regexp || this.regexp === false) return this.regexp
+
+  // at this point, this.set is a 2d array of partial
+  // pattern strings, or "**".
+  //
+  // It's better to use .match().  This function shouldn't
+  // be used, really, but it's pretty convenient sometimes,
+  // when you just want to work with a regex.
+  var set = this.set
+
+  if (!set.length) return this.regexp = false
+  var options = this.options
+
+  var twoStar = options.noglobstar ? star
+      : options.dot ? twoStarDot
+      : twoStarNoDot
+    , flags = options.nocase ? "i" : ""
+
+  var re = set.map(function (pattern) {
+    return pattern.map(function (p) {
+      return (p === GLOBSTAR) ? twoStar
+           : (typeof p === "string") ? regExpEscape(p)
+           : p._src
+    }).join("\\\/")
+  }).join("|")
+
+  // must match entire pattern
+  // ending in a * or ** will make it less strict.
+  re = "^(?:" + re + ")$"
+
+  // can match anything, as long as it's not this.
+  if (this.negate) re = "^(?!" + re + ").*$"
+
+  try {
+    return this.regexp = new RegExp(re, flags)
+  } catch (ex) {
+    return this.regexp = false
+  }
+}
+
+minimatch.match = function (list, pattern, options) {
+  options = options || {}
+  var mm = new Minimatch(pattern, options)
+  list = list.filter(function (f) {
+    return mm.match(f)
+  })
+  if (mm.options.nonull && !list.length) {
+    list.push(pattern)
+  }
+  return list
+}
+
+Minimatch.prototype.match = match
+function match (f, partial) {
+  this.debug("match", f, this.pattern)
+  // short-circuit in the case of busted things.
+  // comments, etc.
+  if (this.comment) return false
+  if (this.empty) return f === ""
+
+  if (f === "/" && partial) return true
+
+  var options = this.options
+
+  // windows: need to use /, not \
+  // On other platforms, \ is a valid (albeit bad) filename char.
+  if (platform === "win32") {
+    f = f.split("\\").join("/")
+  }
+
+  // treat the test path as a set of pathparts.
+  f = f.split(slashSplit)
+  this.debug(this.pattern, "split", f)
+
+  // just ONE of the pattern sets in this.set needs to match
+  // in order for it to be valid.  If negating, then just one
+  // match means that we have failed.
+  // Either way, return on the first hit.
+
+  var set = this.set
+  this.debug(this.pattern, "set", set)
+
+  // Find the basename of the path by looking for the last non-empty segment
+  var filename;
+  for (var i = f.length - 1; i >= 0; i--) {
+    filename = f[i]
+    if (filename) break
+  }
+
+  for (var i = 0, l = set.length; i < l; i ++) {
+    var pattern = set[i], file = f
+    if (options.matchBase && pattern.length === 1) {
+      file = [filename]
+    }
+    var hit = this.matchOne(file, pattern, partial)
+    if (hit) {
+      if (options.flipNegate) return true
+      return !this.negate
+    }
+  }
+
+  // didn't get any hits.  this is success if it's a negative
+  // pattern, failure otherwise.
+  if (options.flipNegate) return false
+  return this.negate
+}
+
+// set partial to true to test if, for example,
+// "/a/b" matches the start of "/*/b/*/d"
+// Partial means, if you run out of file before you run
+// out of pattern, then that's fine, as long as all
+// the parts match.
+Minimatch.prototype.matchOne = function (file, pattern, partial) {
+  var options = this.options
+
+  this.debug("matchOne",
+              { "this": this
+              , file: file
+              , pattern: pattern })
+
+  this.debug("matchOne", file.length, pattern.length)
+
+  for ( var fi = 0
+          , pi = 0
+          , fl = file.length
+          , pl = pattern.length
+      ; (fi < fl) && (pi < pl)
+      ; fi ++, pi ++ ) {
+
+    this.debug("matchOne loop")
+    var p = pattern[pi]
+      , f = file[fi]
+
+    this.debug(pattern, p, f)
+
+    // should be impossible.
+    // some invalid regexp stuff in the set.
+    if (p === false) return false
+
+    if (p === GLOBSTAR) {
+      this.debug('GLOBSTAR', [pattern, p, f])
+
+      // "**"
+      // a/**/b/**/c would match the following:
+      // a/b/x/y/z/c
+      // a/x/y/z/b/c
+      // a/b/x/b/x/c
+      // a/b/c
+      // To do this, take the rest of the pattern after
+      // the **, and see if it would match the file remainder.
+      // If so, return success.
+      // If not, the ** "swallows" a segment, and try again.
+      // This is recursively awful.
+      //
+      // a/**/b/**/c matching a/b/x/y/z/c
+      // - a matches a
+      // - doublestar
+      //   - matchOne(b/x/y/z/c, b/**/c)
+      //     - b matches b
+      //     - doublestar
+      //       - matchOne(x/y/z/c, c) -> no
+      //       - matchOne(y/z/c, c) -> no
+      //       - matchOne(z/c, c) -> no
+      //       - matchOne(c, c) yes, hit
+      var fr = fi
+        , pr = pi + 1
+      if (pr === pl) {
+        this.debug('** at the end')
+        // a ** at the end will just swallow the rest.
+        // We have found a match.
+        // however, it will not swallow /.x, unless
+        // options.dot is set.
+        // . and .. are *never* matched by **, for explosively
+        // exponential reasons.
+        for ( ; fi < fl; fi ++) {
+          if (file[fi] === "." || file[fi] === ".." ||
+              (!options.dot && file[fi].charAt(0) === ".")) return false
+        }
+        return true
+      }
+
+      // ok, let's see if we can swallow whatever we can.
+      WHILE: while (fr < fl) {
+        var swallowee = file[fr]
+
+        this.debug('\nglobstar while',
+                    file, fr, pattern, pr, swallowee)
+
+        // XXX remove this slice.  Just pass the start index.
+        if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {
+          this.debug('globstar found match!', fr, fl, swallowee)
+          // found a match.
+          return true
+        } else {
+          // can't swallow "." or ".." ever.
+          // can only swallow ".foo" when explicitly asked.
+          if (swallowee === "." || swallowee === ".." ||
+              (!options.dot && swallowee.charAt(0) === ".")) {
+            this.debug("dot detected!", file, fr, pattern, pr)
+            break WHILE
+          }
+
+          // ** swallows a segment, and continue.
+          this.debug('globstar swallow a segment, and continue')
+          fr ++
+        }
+      }
+      // no match was found.
+      // However, in partial mode, we can't say this is necessarily over.
+      // If there's more *pattern* left, then
+      if (partial) {
+        // ran out of file
+        this.debug("\n>>> no match, partial?", file, fr, pattern, pr)
+        if (fr === fl) return true
+      }
+      return false
+    }
+
+    // something other than **
+    // non-magic patterns just have to match exactly
+    // patterns with magic have been turned into regexps.
+    var hit
+    if (typeof p === "string") {
+      if (options.nocase) {
+        hit = f.toLowerCase() === p.toLowerCase()
+      } else {
+        hit = f === p
+      }
+      this.debug("string match", p, f, hit)
+    } else {
+      hit = f.match(p)
+      this.debug("pattern match", p, f, hit)
+    }
+
+    if (!hit) return false
+  }
+
+  // Note: ending in / means that we'll get a final ""
+  // at the end of the pattern.  This can only match a
+  // corresponding "" at the end of the file.
+  // If the file ends in /, then it can only match a
+  // a pattern that ends in /, unless the pattern just
+  // doesn't have any more for it. But, a/b/ should *not*
+  // match "a/b/*", even though "" matches against the
+  // [^/]*? pattern, except in partial mode, where it might
+  // simply not be reached yet.
+  // However, a/b/ should still satisfy a/*
+
+  // now either we fell off the end of the pattern, or we're done.
+  if (fi === fl && pi === pl) {
+    // ran out of pattern and filename at the same time.
+    // an exact hit!
+    return true
+  } else if (fi === fl) {
+    // ran out of file, but still had pattern left.
+    // this is ok if we're doing the match as part of
+    // a glob fs traversal.
+    return partial
+  } else if (pi === pl) {
+    // ran out of pattern, still have file left.
+    // this is only acceptable if we're on the very last
+    // empty segment of a file with a trailing slash.
+    // a/* should match a/b/
+    var emptyFileEnd = (fi === fl - 1) && (file[fi] === "")
+    return emptyFileEnd
+  }
+
+  // should be unreachable.
+  throw new Error("wtf?")
+}
+
+
+// replace stuff like \* with *
+function globUnescape (s) {
+  return s.replace(/\\(.)/g, "$1")
+}
+
+
+function regExpEscape (s) {
+  return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&")
+}
+
+})( typeof require === "function" ? require : null,
+    this,
+    typeof module === "object" ? module : null,
+    typeof process === "object" ? process.platform : "win32"
+  )

+ 1 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/lru-cache/.npmignore

@@ -0,0 +1 @@
+/node_modules

+ 8 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/lru-cache/.travis.yml

@@ -0,0 +1,8 @@
+language: node_js
+node_js:
+  - '0.8'
+  - '0.10'
+  - '0.12'
+  - 'iojs'
+before_install:
+  - npm install -g npm@latest

+ 14 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/lru-cache/CONTRIBUTORS

@@ -0,0 +1,14 @@
+# Authors, sorted by whether or not they are me
+Isaac Z. Schlueter <[email protected]>
+Brian Cottingham <[email protected]>
+Carlos Brito Lage <[email protected]>
+Jesse Dailey <[email protected]>
+Kevin O'Hara <[email protected]>
+Marco Rogers <[email protected]>
+Mark Cavage <[email protected]>
+Marko Mikulicic <[email protected]>
+Nathan Rajlich <[email protected]>
+Satheesh Natesan <[email protected]>
+Trent Mick <[email protected]>
+ashleybrener <[email protected]>
+n4kz <[email protected]>

+ 15 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/lru-cache/LICENSE

@@ -0,0 +1,15 @@
+The ISC License
+
+Copyright (c) Isaac Z. Schlueter and Contributors
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

+ 109 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/lru-cache/README.md

@@ -0,0 +1,109 @@
+# lru cache
+
+A cache object that deletes the least-recently-used items.
+
+## Usage:
+
+```javascript
+var LRU = require("lru-cache")
+  , options = { max: 500
+              , length: function (n) { return n * 2 }
+              , dispose: function (key, n) { n.close() }
+              , maxAge: 1000 * 60 * 60 }
+  , cache = LRU(options)
+  , otherCache = LRU(50) // sets just the max size
+
+cache.set("key", "value")
+cache.get("key") // "value"
+
+cache.reset()    // empty the cache
+```
+
+If you put more stuff in it, then items will fall out.
+
+If you try to put an oversized thing in it, then it'll fall out right
+away.
+
+## Options
+
+* `max` The maximum size of the cache, checked by applying the length
+  function to all values in the cache.  Not setting this is kind of
+  silly, since that's the whole purpose of this lib, but it defaults
+  to `Infinity`.
+* `maxAge` Maximum age in ms.  Items are not pro-actively pruned out
+  as they age, but if you try to get an item that is too old, it'll
+  drop it and return undefined instead of giving it to you.
+* `length` Function that is used to calculate the length of stored
+  items.  If you're storing strings or buffers, then you probably want
+  to do something like `function(n){return n.length}`.  The default is
+  `function(n){return 1}`, which is fine if you want to store `n`
+  like-sized things.
+* `dispose` Function that is called on items when they are dropped
+  from the cache.  This can be handy if you want to close file
+  descriptors or do other cleanup tasks when items are no longer
+  accessible.  Called with `key, value`.  It's called *before*
+  actually removing the item from the internal cache, so if you want
+  to immediately put it back in, you'll have to do that in a
+  `nextTick` or `setTimeout` callback or it won't do anything.
+* `stale` By default, if you set a `maxAge`, it'll only actually pull
+  stale items out of the cache when you `get(key)`.  (That is, it's
+  not pre-emptively doing a `setTimeout` or anything.)  If you set
+  `stale:true`, it'll return the stale value before deleting it.  If
+  you don't set this, then it'll return `undefined` when you try to
+  get a stale entry, as if it had already been deleted.
+
+## API
+
+* `set(key, value, maxAge)`
+* `get(key) => value`
+
+    Both of these will update the "recently used"-ness of the key.
+    They do what you think. `max` is optional and overrides the
+    cache `max` option if provided.
+
+* `peek(key)`
+
+    Returns the key value (or `undefined` if not found) without
+    updating the "recently used"-ness of the key.
+
+    (If you find yourself using this a lot, you *might* be using the
+    wrong sort of data structure, but there are some use cases where
+    it's handy.)
+
+* `del(key)`
+
+    Deletes a key out of the cache.
+
+* `reset()`
+
+    Clear the cache entirely, throwing away all values.
+
+* `has(key)`
+
+    Check if a key is in the cache, without updating the recent-ness
+    or deleting it for being stale.
+
+* `forEach(function(value,key,cache), [thisp])`
+
+    Just like `Array.prototype.forEach`.  Iterates over all the keys
+    in the cache, in order of recent-ness.  (Ie, more recently used
+    items are iterated over first.)
+
+* `keys()`
+
+    Return an array of the keys in the cache.
+
+* `values()`
+
+    Return an array of the values in the cache.
+
+* `length()`
+
+    Return total length of objects in cache taking into account
+    `length` options function.
+
+* `itemCount()`
+
+    Return total quantity of objects currently in cache. Note, that
+    `stale` (see options) items are returned as part of this item
+    count.

+ 274 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/lru-cache/lib/lru-cache.js

@@ -0,0 +1,274 @@
+;(function () { // closure for web browsers
+
+if (typeof module === 'object' && module.exports) {
+  module.exports = LRUCache
+} else {
+  // just set the global for non-node platforms.
+  this.LRUCache = LRUCache
+}
+
+function hOP (obj, key) {
+  return Object.prototype.hasOwnProperty.call(obj, key)
+}
+
+function naiveLength () { return 1 }
+
+function LRUCache (options) {
+  if (!(this instanceof LRUCache))
+    return new LRUCache(options)
+
+  if (typeof options === 'number')
+    options = { max: options }
+
+  if (!options)
+    options = {}
+
+  this._max = options.max
+  // Kind of weird to have a default max of Infinity, but oh well.
+  if (!this._max || !(typeof this._max === "number") || this._max <= 0 )
+    this._max = Infinity
+
+  this._lengthCalculator = options.length || naiveLength
+  if (typeof this._lengthCalculator !== "function")
+    this._lengthCalculator = naiveLength
+
+  this._allowStale = options.stale || false
+  this._maxAge = options.maxAge || null
+  this._dispose = options.dispose
+  this.reset()
+}
+
+// resize the cache when the max changes.
+Object.defineProperty(LRUCache.prototype, "max",
+  { set : function (mL) {
+      if (!mL || !(typeof mL === "number") || mL <= 0 ) mL = Infinity
+      this._max = mL
+      if (this._length > this._max) trim(this)
+    }
+  , get : function () { return this._max }
+  , enumerable : true
+  })
+
+// resize the cache when the lengthCalculator changes.
+Object.defineProperty(LRUCache.prototype, "lengthCalculator",
+  { set : function (lC) {
+      if (typeof lC !== "function") {
+        this._lengthCalculator = naiveLength
+        this._length = this._itemCount
+        for (var key in this._cache) {
+          this._cache[key].length = 1
+        }
+      } else {
+        this._lengthCalculator = lC
+        this._length = 0
+        for (var key in this._cache) {
+          this._cache[key].length = this._lengthCalculator(this._cache[key].value)
+          this._length += this._cache[key].length
+        }
+      }
+
+      if (this._length > this._max) trim(this)
+    }
+  , get : function () { return this._lengthCalculator }
+  , enumerable : true
+  })
+
+Object.defineProperty(LRUCache.prototype, "length",
+  { get : function () { return this._length }
+  , enumerable : true
+  })
+
+
+Object.defineProperty(LRUCache.prototype, "itemCount",
+  { get : function () { return this._itemCount }
+  , enumerable : true
+  })
+
+LRUCache.prototype.forEach = function (fn, thisp) {
+  thisp = thisp || this
+  var i = 0
+  var itemCount = this._itemCount
+
+  for (var k = this._mru - 1; k >= 0 && i < itemCount; k--) if (this._lruList[k]) {
+    i++
+    var hit = this._lruList[k]
+    if (isStale(this, hit)) {
+      del(this, hit)
+      if (!this._allowStale) hit = undefined
+    }
+    if (hit) {
+      fn.call(thisp, hit.value, hit.key, this)
+    }
+  }
+}
+
+LRUCache.prototype.keys = function () {
+  var keys = new Array(this._itemCount)
+  var i = 0
+  for (var k = this._mru - 1; k >= 0 && i < this._itemCount; k--) if (this._lruList[k]) {
+    var hit = this._lruList[k]
+    keys[i++] = hit.key
+  }
+  return keys
+}
+
+LRUCache.prototype.values = function () {
+  var values = new Array(this._itemCount)
+  var i = 0
+  for (var k = this._mru - 1; k >= 0 && i < this._itemCount; k--) if (this._lruList[k]) {
+    var hit = this._lruList[k]
+    values[i++] = hit.value
+  }
+  return values
+}
+
+LRUCache.prototype.reset = function () {
+  if (this._dispose && this._cache) {
+    for (var k in this._cache) {
+      this._dispose(k, this._cache[k].value)
+    }
+  }
+
+  this._cache = Object.create(null) // hash of items by key
+  this._lruList = Object.create(null) // list of items in order of use recency
+  this._mru = 0 // most recently used
+  this._lru = 0 // least recently used
+  this._length = 0 // number of items in the list
+  this._itemCount = 0
+}
+
+// Provided for debugging/dev purposes only. No promises whatsoever that
+// this API stays stable.
+LRUCache.prototype.dump = function () {
+  return this._cache
+}
+
+LRUCache.prototype.dumpLru = function () {
+  return this._lruList
+}
+
+LRUCache.prototype.set = function (key, value, maxAge) {
+  maxAge = maxAge || this._maxAge
+  var now = maxAge ? Date.now() : 0
+
+  if (hOP(this._cache, key)) {
+    // dispose of the old one before overwriting
+    if (this._dispose)
+      this._dispose(key, this._cache[key].value)
+
+    this._cache[key].now = now
+    this._cache[key].maxAge = maxAge
+    this._cache[key].value = value
+    this.get(key)
+    return true
+  }
+
+  var len = this._lengthCalculator(value)
+  var hit = new Entry(key, value, this._mru++, len, now, maxAge)
+
+  // oversized objects fall out of cache automatically.
+  if (hit.length > this._max) {
+    if (this._dispose) this._dispose(key, value)
+    return false
+  }
+
+  this._length += hit.length
+  this._lruList[hit.lu] = this._cache[key] = hit
+  this._itemCount ++
+
+  if (this._length > this._max)
+    trim(this)
+
+  return true
+}
+
+LRUCache.prototype.has = function (key) {
+  if (!hOP(this._cache, key)) return false
+  var hit = this._cache[key]
+  if (isStale(this, hit)) {
+    return false
+  }
+  return true
+}
+
+LRUCache.prototype.get = function (key) {
+  return get(this, key, true)
+}
+
+LRUCache.prototype.peek = function (key) {
+  return get(this, key, false)
+}
+
+LRUCache.prototype.pop = function () {
+  var hit = this._lruList[this._lru]
+  del(this, hit)
+  return hit || null
+}
+
+LRUCache.prototype.del = function (key) {
+  del(this, this._cache[key])
+}
+
+function get (self, key, doUse) {
+  var hit = self._cache[key]
+  if (hit) {
+    if (isStale(self, hit)) {
+      del(self, hit)
+      if (!self._allowStale) hit = undefined
+    } else {
+      if (doUse) use(self, hit)
+    }
+    if (hit) hit = hit.value
+  }
+  return hit
+}
+
+function isStale(self, hit) {
+  if (!hit || (!hit.maxAge && !self._maxAge)) return false
+  var stale = false;
+  var diff = Date.now() - hit.now
+  if (hit.maxAge) {
+    stale = diff > hit.maxAge
+  } else {
+    stale = self._maxAge && (diff > self._maxAge)
+  }
+  return stale;
+}
+
+function use (self, hit) {
+  shiftLU(self, hit)
+  hit.lu = self._mru ++
+  self._lruList[hit.lu] = hit
+}
+
+function trim (self) {
+  while (self._lru < self._mru && self._length > self._max)
+    del(self, self._lruList[self._lru])
+}
+
+function shiftLU (self, hit) {
+  delete self._lruList[ hit.lu ]
+  while (self._lru < self._mru && !self._lruList[self._lru]) self._lru ++
+}
+
+function del (self, hit) {
+  if (hit) {
+    if (self._dispose) self._dispose(hit.key, hit.value)
+    self._length -= hit.length
+    self._itemCount --
+    delete self._cache[ hit.key ]
+    shiftLU(self, hit)
+  }
+}
+
+// classy, since V8 prefers predictable objects.
+function Entry (key, value, lu, length, now, maxAge) {
+  this.key = key
+  this.value = value
+  this.lu = lu
+  this.length = length
+  this.now = now
+  if (maxAge) this.maxAge = maxAge
+}
+
+})()

+ 58 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/lru-cache/package.json

@@ -0,0 +1,58 @@
+{
+  "name": "lru-cache",
+  "description": "A cache object that deletes the least-recently-used items.",
+  "version": "2.6.5",
+  "author": {
+    "name": "Isaac Z. Schlueter",
+    "email": "[email protected]"
+  },
+  "keywords": [
+    "mru",
+    "lru",
+    "cache"
+  ],
+  "scripts": {
+    "test": "tap test --gc"
+  },
+  "main": "lib/lru-cache.js",
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/isaacs/node-lru-cache.git"
+  },
+  "devDependencies": {
+    "tap": "^1.2.0",
+    "weak": ""
+  },
+  "license": "ISC",
+  "gitHead": "7062a0c891bfb80a294be9217e4de0f882e75776",
+  "bugs": {
+    "url": "https://github.com/isaacs/node-lru-cache/issues"
+  },
+  "homepage": "https://github.com/isaacs/node-lru-cache#readme",
+  "_id": "[email protected]",
+  "_shasum": "e56d6354148ede8d7707b58d143220fd08df0fd5",
+  "_from": "lru-cache@>=2.0.0 <3.0.0",
+  "_npmVersion": "3.0.0",
+  "_nodeVersion": "2.2.1",
+  "_npmUser": {
+    "name": "isaacs",
+    "email": "[email protected]"
+  },
+  "dist": {
+    "shasum": "e56d6354148ede8d7707b58d143220fd08df0fd5",
+    "tarball": "http://registry.npmjs.org/lru-cache/-/lru-cache-2.6.5.tgz"
+  },
+  "maintainers": [
+    {
+      "name": "isaacs",
+      "email": "[email protected]"
+    },
+    {
+      "name": "othiym23",
+      "email": "[email protected]"
+    }
+  ],
+  "directories": {},
+  "_resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.6.5.tgz",
+  "readme": "ERROR: No README data found!"
+}

+ 395 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/lru-cache/test/basic.js

@@ -0,0 +1,395 @@
+var test = require("tap").test
+  , LRU = require("../")
+
+test("basic", function (t) {
+  var cache = new LRU({max: 10})
+  cache.set("key", "value")
+  t.equal(cache.get("key"), "value")
+  t.equal(cache.get("nada"), undefined)
+  t.equal(cache.length, 1)
+  t.equal(cache.max, 10)
+  t.end()
+})
+
+test("least recently set", function (t) {
+  var cache = new LRU(2)
+  cache.set("a", "A")
+  cache.set("b", "B")
+  cache.set("c", "C")
+  t.equal(cache.get("c"), "C")
+  t.equal(cache.get("b"), "B")
+  t.equal(cache.get("a"), undefined)
+  t.end()
+})
+
+test("lru recently gotten", function (t) {
+  var cache = new LRU(2)
+  cache.set("a", "A")
+  cache.set("b", "B")
+  cache.get("a")
+  cache.set("c", "C")
+  t.equal(cache.get("c"), "C")
+  t.equal(cache.get("b"), undefined)
+  t.equal(cache.get("a"), "A")
+  t.end()
+})
+
+test("del", function (t) {
+  var cache = new LRU(2)
+  cache.set("a", "A")
+  cache.del("a")
+  t.equal(cache.get("a"), undefined)
+  t.end()
+})
+
+test("max", function (t) {
+  var cache = new LRU(3)
+
+  // test changing the max, verify that the LRU items get dropped.
+  cache.max = 100
+  for (var i = 0; i < 100; i ++) cache.set(i, i)
+  t.equal(cache.length, 100)
+  for (var i = 0; i < 100; i ++) {
+    t.equal(cache.get(i), i)
+  }
+  cache.max = 3
+  t.equal(cache.length, 3)
+  for (var i = 0; i < 97; i ++) {
+    t.equal(cache.get(i), undefined)
+  }
+  for (var i = 98; i < 100; i ++) {
+    t.equal(cache.get(i), i)
+  }
+
+  // now remove the max restriction, and try again.
+  cache.max = "hello"
+  for (var i = 0; i < 100; i ++) cache.set(i, i)
+  t.equal(cache.length, 100)
+  for (var i = 0; i < 100; i ++) {
+    t.equal(cache.get(i), i)
+  }
+  // should trigger an immediate resize
+  cache.max = 3
+  t.equal(cache.length, 3)
+  for (var i = 0; i < 97; i ++) {
+    t.equal(cache.get(i), undefined)
+  }
+  for (var i = 98; i < 100; i ++) {
+    t.equal(cache.get(i), i)
+  }
+  t.end()
+})
+
+test("reset", function (t) {
+  var cache = new LRU(10)
+  cache.set("a", "A")
+  cache.set("b", "B")
+  cache.reset()
+  t.equal(cache.length, 0)
+  t.equal(cache.max, 10)
+  t.equal(cache.get("a"), undefined)
+  t.equal(cache.get("b"), undefined)
+  t.end()
+})
+
+
+// Note: `<cache>.dump()` is a debugging tool only. No guarantees are made
+// about the format/layout of the response.
+test("dump", function (t) {
+  var cache = new LRU(10)
+  var d = cache.dump();
+  t.equal(Object.keys(d).length, 0, "nothing in dump for empty cache")
+  cache.set("a", "A")
+  var d = cache.dump()  // { a: { key: "a", value: "A", lu: 0 } }
+  t.ok(d.a)
+  t.equal(d.a.key, "a")
+  t.equal(d.a.value, "A")
+  t.equal(d.a.lu, 0)
+
+  cache.set("b", "B")
+  cache.get("b")
+  d = cache.dump()
+  t.ok(d.b)
+  t.equal(d.b.key, "b")
+  t.equal(d.b.value, "B")
+  t.equal(d.b.lu, 2)
+
+  t.end()
+})
+
+
+test("basic with weighed length", function (t) {
+  var cache = new LRU({
+    max: 100,
+    length: function (item) { return item.size }
+  })
+  cache.set("key", {val: "value", size: 50})
+  t.equal(cache.get("key").val, "value")
+  t.equal(cache.get("nada"), undefined)
+  t.equal(cache.lengthCalculator(cache.get("key")), 50)
+  t.equal(cache.length, 50)
+  t.equal(cache.max, 100)
+  t.end()
+})
+
+
+test("weighed length item too large", function (t) {
+  var cache = new LRU({
+    max: 10,
+    length: function (item) { return item.size }
+  })
+  t.equal(cache.max, 10)
+
+  // should fall out immediately
+  cache.set("key", {val: "value", size: 50})
+
+  t.equal(cache.length, 0)
+  t.equal(cache.get("key"), undefined)
+  t.end()
+})
+
+test("least recently set with weighed length", function (t) {
+  var cache = new LRU({
+    max:8,
+    length: function (item) { return item.length }
+  })
+  cache.set("a", "A")
+  cache.set("b", "BB")
+  cache.set("c", "CCC")
+  cache.set("d", "DDDD")
+  t.equal(cache.get("d"), "DDDD")
+  t.equal(cache.get("c"), "CCC")
+  t.equal(cache.get("b"), undefined)
+  t.equal(cache.get("a"), undefined)
+  t.end()
+})
+
+test("lru recently gotten with weighed length", function (t) {
+  var cache = new LRU({
+    max: 8,
+    length: function (item) { return item.length }
+  })
+  cache.set("a", "A")
+  cache.set("b", "BB")
+  cache.set("c", "CCC")
+  cache.get("a")
+  cache.get("b")
+  cache.set("d", "DDDD")
+  t.equal(cache.get("c"), undefined)
+  t.equal(cache.get("d"), "DDDD")
+  t.equal(cache.get("b"), "BB")
+  t.equal(cache.get("a"), "A")
+  t.end()
+})
+
+test("set returns proper booleans", function(t) {
+  var cache = new LRU({
+    max: 5,
+    length: function (item) { return item.length }
+  })
+
+  t.equal(cache.set("a", "A"), true)
+
+  // should return false for max exceeded
+  t.equal(cache.set("b", "donuts"), false)
+
+  t.equal(cache.set("b", "B"), true)
+  t.equal(cache.set("c", "CCCC"), true)
+  t.end()
+})
+
+test("drop the old items", function(t) {
+  var cache = new LRU({
+    max: 5,
+    maxAge: 50
+  })
+
+  cache.set("a", "A")
+
+  setTimeout(function () {
+    cache.set("b", "b")
+    t.equal(cache.get("a"), "A")
+  }, 25)
+
+  setTimeout(function () {
+    cache.set("c", "C")
+    // timed out
+    t.notOk(cache.get("a"))
+  }, 60 + 25)
+
+  setTimeout(function () {
+    t.notOk(cache.get("b"))
+    t.equal(cache.get("c"), "C")
+  }, 90)
+
+  setTimeout(function () {
+    t.notOk(cache.get("c"))
+    t.end()
+  }, 155)
+})
+
+test("individual item can have it's own maxAge", function(t) {
+  var cache = new LRU({
+    max: 5,
+    maxAge: 50
+  })
+
+  cache.set("a", "A", 20)
+  setTimeout(function () {
+    t.notOk(cache.get("a"))
+    t.end()
+  }, 25)
+})
+
+test("individual item can have it's own maxAge > cache's", function(t) {
+  var cache = new LRU({
+    max: 5,
+    maxAge: 20
+  })
+
+  cache.set("a", "A", 50)
+  setTimeout(function () {
+    t.equal(cache.get("a"), "A")
+    t.end()
+  }, 25)
+})
+
+test("disposal function", function(t) {
+  var disposed = false
+  var cache = new LRU({
+    max: 1,
+    dispose: function (k, n) {
+      disposed = n
+    }
+  })
+
+  cache.set(1, 1)
+  cache.set(2, 2)
+  t.equal(disposed, 1)
+  cache.set(3, 3)
+  t.equal(disposed, 2)
+  cache.reset()
+  t.equal(disposed, 3)
+  t.end()
+})
+
+test("disposal function on too big of item", function(t) {
+  var disposed = false
+  var cache = new LRU({
+    max: 1,
+    length: function (k) {
+      return k.length
+    },
+    dispose: function (k, n) {
+      disposed = n
+    }
+  })
+  var obj = [ 1, 2 ]
+
+  t.equal(disposed, false)
+  cache.set("obj", obj)
+  t.equal(disposed, obj)
+  t.end()
+})
+
+test("has()", function(t) {
+  var cache = new LRU({
+    max: 1,
+    maxAge: 10
+  })
+
+  cache.set('foo', 'bar')
+  t.equal(cache.has('foo'), true)
+  cache.set('blu', 'baz')
+  t.equal(cache.has('foo'), false)
+  t.equal(cache.has('blu'), true)
+  setTimeout(function() {
+    t.equal(cache.has('blu'), false)
+    t.end()
+  }, 15)
+})
+
+test("stale", function(t) {
+  var cache = new LRU({
+    maxAge: 10,
+    stale: true
+  })
+
+  cache.set('foo', 'bar')
+  t.equal(cache.get('foo'), 'bar')
+  t.equal(cache.has('foo'), true)
+  setTimeout(function() {
+    t.equal(cache.has('foo'), false)
+    t.equal(cache.get('foo'), 'bar')
+    t.equal(cache.get('foo'), undefined)
+    t.end()
+  }, 15)
+})
+
+test("lru update via set", function(t) {
+  var cache = LRU({ max: 2 });
+
+  cache.set('foo', 1);
+  cache.set('bar', 2);
+  cache.del('bar');
+  cache.set('baz', 3);
+  cache.set('qux', 4);
+
+  t.equal(cache.get('foo'), undefined)
+  t.equal(cache.get('bar'), undefined)
+  t.equal(cache.get('baz'), 3)
+  t.equal(cache.get('qux'), 4)
+  t.end()
+})
+
+test("least recently set w/ peek", function (t) {
+  var cache = new LRU(2)
+  cache.set("a", "A")
+  cache.set("b", "B")
+  t.equal(cache.peek("a"), "A")
+  cache.set("c", "C")
+  t.equal(cache.get("c"), "C")
+  t.equal(cache.get("b"), "B")
+  t.equal(cache.get("a"), undefined)
+  t.end()
+})
+
+test("pop the least used item", function (t) {
+  var cache = new LRU(3)
+  , last
+
+  cache.set("a", "A")
+  cache.set("b", "B")
+  cache.set("c", "C")
+
+  t.equal(cache.length, 3)
+  t.equal(cache.max, 3)
+
+  // Ensure we pop a, c, b
+  cache.get("b", "B")
+
+  last = cache.pop()
+  t.equal(last.key, "a")
+  t.equal(last.value, "A")
+  t.equal(cache.length, 2)
+  t.equal(cache.max, 3)
+
+  last = cache.pop()
+  t.equal(last.key, "c")
+  t.equal(last.value, "C")
+  t.equal(cache.length, 1)
+  t.equal(cache.max, 3)
+
+  last = cache.pop()
+  t.equal(last.key, "b")
+  t.equal(last.value, "B")
+  t.equal(cache.length, 0)
+  t.equal(cache.max, 3)
+
+  last = cache.pop()
+  t.equal(last, null)
+  t.equal(cache.length, 0)
+  t.equal(cache.max, 3)
+
+  t.end()
+})

+ 120 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/lru-cache/test/foreach.js

@@ -0,0 +1,120 @@
+var test = require('tap').test
+var LRU = require('../')
+
+test('forEach', function (t) {
+  var l = new LRU(5)
+  for (var i = 0; i < 10; i ++) {
+    l.set(i.toString(), i.toString(2))
+  }
+
+  var i = 9
+  l.forEach(function (val, key, cache) {
+    t.equal(cache, l)
+    t.equal(key, i.toString())
+    t.equal(val, i.toString(2))
+    i -= 1
+  })
+
+  // get in order of most recently used
+  l.get(6)
+  l.get(8)
+
+  var order = [ 8, 6, 9, 7, 5 ]
+  var i = 0
+
+  l.forEach(function (val, key, cache) {
+    var j = order[i ++]
+    t.equal(cache, l)
+    t.equal(key, j.toString())
+    t.equal(val, j.toString(2))
+  })
+  t.equal(i, order.length);
+
+  t.end()
+})
+
+test('keys() and values()', function (t) {
+  var l = new LRU(5)
+  for (var i = 0; i < 10; i ++) {
+    l.set(i.toString(), i.toString(2))
+  }
+
+  t.similar(l.keys(), ['9', '8', '7', '6', '5'])
+  t.similar(l.values(), ['1001', '1000', '111', '110', '101'])
+
+  // get in order of most recently used
+  l.get(6)
+  l.get(8)
+
+  t.similar(l.keys(), ['8', '6', '9', '7', '5'])
+  t.similar(l.values(), ['1000', '110', '1001', '111', '101'])
+
+  t.end()
+})
+
+test('all entries are iterated over', function(t) {
+  var l = new LRU(5)
+  for (var i = 0; i < 10; i ++) {
+    l.set(i.toString(), i.toString(2))
+  }
+
+  var i = 0
+  l.forEach(function (val, key, cache) {
+    if (i > 0) {
+      cache.del(key)
+    }
+    i += 1
+  })
+
+  t.equal(i, 5)
+  t.equal(l.keys().length, 1)
+
+  t.end()
+})
+
+test('all stale entries are removed', function(t) {
+  var l = new LRU({ max: 5, maxAge: -5, stale: true })
+  for (var i = 0; i < 10; i ++) {
+    l.set(i.toString(), i.toString(2))
+  }
+
+  var i = 0
+  l.forEach(function () {
+    i += 1
+  })
+
+  t.equal(i, 5)
+  t.equal(l.keys().length, 0)
+
+  t.end()
+})
+
+test('expires', function (t) {
+  var l = new LRU({
+    max: 10,
+    maxAge: 50
+  })
+  for (var i = 0; i < 10; i++) {
+    l.set(i.toString(), i.toString(2), ((i % 2) ? 25 : undefined))
+  }
+
+  var i = 0
+  var order = [ 8, 6, 4, 2, 0 ]
+  setTimeout(function () {
+    l.forEach(function (val, key, cache) {
+      var j = order[i++]
+      t.equal(cache, l)
+      t.equal(key, j.toString())
+      t.equal(val, j.toString(2))
+    })
+    t.equal(i, order.length);
+
+    setTimeout(function () {
+      var count = 0;
+      l.forEach(function (val, key, cache) { count++; })
+      t.equal(0, count);
+      t.end()
+    }, 25)
+
+  }, 26)
+})

+ 51 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/lru-cache/test/memory-leak.js

@@ -0,0 +1,51 @@
+#!/usr/bin/env node --expose_gc
+
+
+var weak = require('weak');
+var test = require('tap').test
+var LRU = require('../')
+var l = new LRU({ max: 10 })
+var refs = 0
+function X() {
+  refs ++
+  weak(this, deref)
+}
+
+function deref() {
+  refs --
+}
+
+test('no leaks', function (t) {
+  // fill up the cache
+  for (var i = 0; i < 100; i++) {
+    l.set(i, new X);
+    // throw some gets in there, too.
+    if (i % 2 === 0)
+      l.get(i / 2)
+  }
+
+  gc()
+
+  var start = process.memoryUsage()
+
+  // capture the memory
+  var startRefs = refs
+
+  // do it again, but more
+  for (var i = 0; i < 10000; i++) {
+    l.set(i, new X);
+    // throw some gets in there, too.
+    if (i % 2 === 0)
+      l.get(i / 2)
+  }
+
+  gc()
+
+  var end = process.memoryUsage()
+  t.equal(refs, startRefs, 'no leaky refs')
+
+  console.error('start: %j\n' +
+                'end:   %j', start, end);
+  t.pass();
+  t.end();
+})

+ 15 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/sigmund/LICENSE

@@ -0,0 +1,15 @@
+The ISC License
+
+Copyright (c) Isaac Z. Schlueter and Contributors
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

+ 53 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/sigmund/README.md

@@ -0,0 +1,53 @@
+# sigmund
+
+Quick and dirty signatures for Objects.
+
+This is like a much faster `deepEquals` comparison, which returns a
+string key suitable for caches and the like.
+
+## Usage
+
+```javascript
+function doSomething (someObj) {
+  var key = sigmund(someObj, maxDepth) // max depth defaults to 10
+  var cached = cache.get(key)
+  if (cached) return cached
+
+  var result = expensiveCalculation(someObj)
+  cache.set(key, result)
+  return result
+}
+```
+
+The resulting key will be as unique and reproducible as calling
+`JSON.stringify` or `util.inspect` on the object, but is much faster.
+In order to achieve this speed, some differences are glossed over.
+For example, the object `{0:'foo'}` will be treated identically to the
+array `['foo']`.
+
+Also, just as there is no way to summon the soul from the scribblings
+of a cocaine-addled psychoanalyst, there is no way to revive the object
+from the signature string that sigmund gives you.  In fact, it's
+barely even readable.
+
+As with `util.inspect` and `JSON.stringify`, larger objects will
+produce larger signature strings.
+
+Because sigmund is a bit less strict than the more thorough
+alternatives, the strings will be shorter, and also there is a
+slightly higher chance for collisions.  For example, these objects
+have the same signature:
+
+    var obj1 = {a:'b',c:/def/,g:['h','i',{j:'',k:'l'}]}
+    var obj2 = {a:'b',c:'/def/',g:['h','i','{jkl']}
+
+Like a good Freudian, sigmund is most effective when you already have
+some understanding of what you're looking for.  It can help you help
+yourself, but you must be willing to do some work as well.
+
+Cycles are handled, and cyclical objects are silently omitted (though
+the key is included in the signature output.)
+
+The second argument is the maximum depth, which defaults to 10,
+because that is the maximum object traversal depth covered by most
+insurance carriers.

+ 283 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/sigmund/bench.js

@@ -0,0 +1,283 @@
+// different ways to id objects
+// use a req/res pair, since it's crazy deep and cyclical
+
+// sparseFE10 and sigmund are usually pretty close, which is to be expected,
+// since they are essentially the same algorithm, except that sigmund handles
+// regular expression objects properly.
+
+
+var http = require('http')
+var util = require('util')
+var sigmund = require('./sigmund.js')
+var sreq, sres, creq, cres, test
+
+http.createServer(function (q, s) {
+  sreq = q
+  sres = s
+  sres.end('ok')
+  this.close(function () { setTimeout(function () {
+    start()
+  }, 200) })
+}).listen(1337, function () {
+  creq = http.get({ port: 1337 })
+  creq.on('response', function (s) { cres = s })
+})
+
+function start () {
+  test = [sreq, sres, creq, cres]
+  // test = sreq
+  // sreq.sres = sres
+  // sreq.creq = creq
+  // sreq.cres = cres
+
+  for (var i in exports.compare) {
+    console.log(i)
+    var hash = exports.compare[i]()
+    console.log(hash)
+    console.log(hash.length)
+    console.log('')
+  }
+
+  require('bench').runMain()
+}
+
+function customWs (obj, md, d) {
+  d = d || 0
+  var to = typeof obj
+  if (to === 'undefined' || to === 'function' || to === null) return ''
+  if (d > md || !obj || to !== 'object') return ('' + obj).replace(/[\n ]+/g, '')
+
+  if (Array.isArray(obj)) {
+    return obj.map(function (i, _, __) {
+      return customWs(i, md, d + 1)
+    }).reduce(function (a, b) { return a + b }, '')
+  }
+
+  var keys = Object.keys(obj)
+  return keys.map(function (k, _, __) {
+    return k + ':' + customWs(obj[k], md, d + 1)
+  }).reduce(function (a, b) { return a + b }, '')
+}
+
+function custom (obj, md, d) {
+  d = d || 0
+  var to = typeof obj
+  if (to === 'undefined' || to === 'function' || to === null) return ''
+  if (d > md || !obj || to !== 'object') return '' + obj
+
+  if (Array.isArray(obj)) {
+    return obj.map(function (i, _, __) {
+      return custom(i, md, d + 1)
+    }).reduce(function (a, b) { return a + b }, '')
+  }
+
+  var keys = Object.keys(obj)
+  return keys.map(function (k, _, __) {
+    return k + ':' + custom(obj[k], md, d + 1)
+  }).reduce(function (a, b) { return a + b }, '')
+}
+
+function sparseFE2 (obj, maxDepth) {
+  var seen = []
+  var soFar = ''
+  function ch (v, depth) {
+    if (depth > maxDepth) return
+    if (typeof v === 'function' || typeof v === 'undefined') return
+    if (typeof v !== 'object' || !v) {
+      soFar += v
+      return
+    }
+    if (seen.indexOf(v) !== -1 || depth === maxDepth) return
+    seen.push(v)
+    soFar += '{'
+    Object.keys(v).forEach(function (k, _, __) {
+      // pseudo-private values.  skip those.
+      if (k.charAt(0) === '_') return
+      var to = typeof v[k]
+      if (to === 'function' || to === 'undefined') return
+      soFar += k + ':'
+      ch(v[k], depth + 1)
+    })
+    soFar += '}'
+  }
+  ch(obj, 0)
+  return soFar
+}
+
+function sparseFE (obj, maxDepth) {
+  var seen = []
+  var soFar = ''
+  function ch (v, depth) {
+    if (depth > maxDepth) return
+    if (typeof v === 'function' || typeof v === 'undefined') return
+    if (typeof v !== 'object' || !v) {
+      soFar += v
+      return
+    }
+    if (seen.indexOf(v) !== -1 || depth === maxDepth) return
+    seen.push(v)
+    soFar += '{'
+    Object.keys(v).forEach(function (k, _, __) {
+      // pseudo-private values.  skip those.
+      if (k.charAt(0) === '_') return
+      var to = typeof v[k]
+      if (to === 'function' || to === 'undefined') return
+      soFar += k
+      ch(v[k], depth + 1)
+    })
+  }
+  ch(obj, 0)
+  return soFar
+}
+
+function sparse (obj, maxDepth) {
+  var seen = []
+  var soFar = ''
+  function ch (v, depth) {
+    if (depth > maxDepth) return
+    if (typeof v === 'function' || typeof v === 'undefined') return
+    if (typeof v !== 'object' || !v) {
+      soFar += v
+      return
+    }
+    if (seen.indexOf(v) !== -1 || depth === maxDepth) return
+    seen.push(v)
+    soFar += '{'
+    for (var k in v) {
+      // pseudo-private values.  skip those.
+      if (k.charAt(0) === '_') continue
+      var to = typeof v[k]
+      if (to === 'function' || to === 'undefined') continue
+      soFar += k
+      ch(v[k], depth + 1)
+    }
+  }
+  ch(obj, 0)
+  return soFar
+}
+
+function noCommas (obj, maxDepth) {
+  var seen = []
+  var soFar = ''
+  function ch (v, depth) {
+    if (depth > maxDepth) return
+    if (typeof v === 'function' || typeof v === 'undefined') return
+    if (typeof v !== 'object' || !v) {
+      soFar += v
+      return
+    }
+    if (seen.indexOf(v) !== -1 || depth === maxDepth) return
+    seen.push(v)
+    soFar += '{'
+    for (var k in v) {
+      // pseudo-private values.  skip those.
+      if (k.charAt(0) === '_') continue
+      var to = typeof v[k]
+      if (to === 'function' || to === 'undefined') continue
+      soFar += k + ':'
+      ch(v[k], depth + 1)
+    }
+    soFar += '}'
+  }
+  ch(obj, 0)
+  return soFar
+}
+
+
+function flatten (obj, maxDepth) {
+  var seen = []
+  var soFar = ''
+  function ch (v, depth) {
+    if (depth > maxDepth) return
+    if (typeof v === 'function' || typeof v === 'undefined') return
+    if (typeof v !== 'object' || !v) {
+      soFar += v
+      return
+    }
+    if (seen.indexOf(v) !== -1 || depth === maxDepth) return
+    seen.push(v)
+    soFar += '{'
+    for (var k in v) {
+      // pseudo-private values.  skip those.
+      if (k.charAt(0) === '_') continue
+      var to = typeof v[k]
+      if (to === 'function' || to === 'undefined') continue
+      soFar += k + ':'
+      ch(v[k], depth + 1)
+      soFar += ','
+    }
+    soFar += '}'
+  }
+  ch(obj, 0)
+  return soFar
+}
+
+exports.compare =
+{
+  // 'custom 2': function () {
+  //   return custom(test, 2, 0)
+  // },
+  // 'customWs 2': function () {
+  //   return customWs(test, 2, 0)
+  // },
+  'JSON.stringify (guarded)': function () {
+    var seen = []
+    return JSON.stringify(test, function (k, v) {
+      if (typeof v !== 'object' || !v) return v
+      if (seen.indexOf(v) !== -1) return undefined
+      seen.push(v)
+      return v
+    })
+  },
+
+  'flatten 10': function () {
+    return flatten(test, 10)
+  },
+
+  // 'flattenFE 10': function () {
+  //   return flattenFE(test, 10)
+  // },
+
+  'noCommas 10': function () {
+    return noCommas(test, 10)
+  },
+
+  'sparse 10': function () {
+    return sparse(test, 10)
+  },
+
+  'sparseFE 10': function () {
+    return sparseFE(test, 10)
+  },
+
+  'sparseFE2 10': function () {
+    return sparseFE2(test, 10)
+  },
+
+  sigmund: function() {
+    return sigmund(test, 10)
+  },
+
+
+  // 'util.inspect 1': function () {
+  //   return util.inspect(test, false, 1, false)
+  // },
+  // 'util.inspect undefined': function () {
+  //   util.inspect(test)
+  // },
+  // 'util.inspect 2': function () {
+  //   util.inspect(test, false, 2, false)
+  // },
+  // 'util.inspect 3': function () {
+  //   util.inspect(test, false, 3, false)
+  // },
+  // 'util.inspect 4': function () {
+  //   util.inspect(test, false, 4, false)
+  // },
+  // 'util.inspect Infinity': function () {
+  //   util.inspect(test, false, Infinity, false)
+  // }
+}
+
+/** results
+**/

+ 60 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/sigmund/package.json

@@ -0,0 +1,60 @@
+{
+  "name": "sigmund",
+  "version": "1.0.1",
+  "description": "Quick and dirty signatures for Objects.",
+  "main": "sigmund.js",
+  "directories": {
+    "test": "test"
+  },
+  "dependencies": {},
+  "devDependencies": {
+    "tap": "~0.3.0"
+  },
+  "scripts": {
+    "test": "tap test/*.js",
+    "bench": "node bench.js"
+  },
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/isaacs/sigmund.git"
+  },
+  "keywords": [
+    "object",
+    "signature",
+    "key",
+    "data",
+    "psychoanalysis"
+  ],
+  "author": {
+    "name": "Isaac Z. Schlueter",
+    "email": "[email protected]",
+    "url": "http://blog.izs.me/"
+  },
+  "license": "ISC",
+  "gitHead": "527f97aa5bb253d927348698c0cd3bb267d098c6",
+  "bugs": {
+    "url": "https://github.com/isaacs/sigmund/issues"
+  },
+  "homepage": "https://github.com/isaacs/sigmund#readme",
+  "_id": "[email protected]",
+  "_shasum": "3ff21f198cad2175f9f3b781853fd94d0d19b590",
+  "_from": "sigmund@>=1.0.0 <1.1.0",
+  "_npmVersion": "2.10.0",
+  "_nodeVersion": "2.0.1",
+  "_npmUser": {
+    "name": "isaacs",
+    "email": "[email protected]"
+  },
+  "dist": {
+    "shasum": "3ff21f198cad2175f9f3b781853fd94d0d19b590",
+    "tarball": "http://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz"
+  },
+  "maintainers": [
+    {
+      "name": "isaacs",
+      "email": "[email protected]"
+    }
+  ],
+  "_resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz",
+  "readme": "ERROR: No README data found!"
+}

+ 39 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/sigmund/sigmund.js

@@ -0,0 +1,39 @@
+module.exports = sigmund
+function sigmund (subject, maxSessions) {
+    maxSessions = maxSessions || 10;
+    var notes = [];
+    var analysis = '';
+    var RE = RegExp;
+
+    function psychoAnalyze (subject, session) {
+        if (session > maxSessions) return;
+
+        if (typeof subject === 'function' ||
+            typeof subject === 'undefined') {
+            return;
+        }
+
+        if (typeof subject !== 'object' || !subject ||
+            (subject instanceof RE)) {
+            analysis += subject;
+            return;
+        }
+
+        if (notes.indexOf(subject) !== -1 || session === maxSessions) return;
+
+        notes.push(subject);
+        analysis += '{';
+        Object.keys(subject).forEach(function (issue, _, __) {
+            // pseudo-private values.  skip those.
+            if (issue.charAt(0) === '_') return;
+            var to = typeof subject[issue];
+            if (to === 'function' || to === 'undefined') return;
+            analysis += issue;
+            psychoAnalyze(subject[issue], session + 1);
+        });
+    }
+    psychoAnalyze(subject, 0);
+    return analysis;
+}
+
+// vim: set softtabstop=4 shiftwidth=4:

+ 24 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/sigmund/test/basic.js

@@ -0,0 +1,24 @@
+var test = require('tap').test
+var sigmund = require('../sigmund.js')
+
+
+// occasionally there are duplicates
+// that's an acceptable edge-case.  JSON.stringify and util.inspect
+// have some collision potential as well, though less, and collision
+// detection is expensive.
+var hash = '{abc/def/g{0h1i2{jkl'
+var obj1 = {a:'b',c:/def/,g:['h','i',{j:'',k:'l'}]}
+var obj2 = {a:'b',c:'/def/',g:['h','i','{jkl']}
+
+var obj3 = JSON.parse(JSON.stringify(obj1))
+obj3.c = /def/
+obj3.g[2].cycle = obj3
+var cycleHash = '{abc/def/g{0h1i2{jklcycle'
+
+test('basic', function (t) {
+    t.equal(sigmund(obj1), hash)
+    t.equal(sigmund(obj2), hash)
+    t.equal(sigmund(obj3), cycleHash)
+    t.end()
+})
+

File diff suppressed because it is too large
+ 31 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/package.json


+ 399 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/test/basic.js

@@ -0,0 +1,399 @@
+// http://www.bashcookbook.com/bashinfo/source/bash-1.14.7/tests/glob-test
+//
+// TODO: Some of these tests do very bad things with backslashes, and will
+// most likely fail badly on windows.  They should probably be skipped.
+
+var tap = require("tap")
+  , globalBefore = Object.keys(global)
+  , mm = require("../")
+  , files = [ "a", "b", "c", "d", "abc"
+            , "abd", "abe", "bb", "bcd"
+            , "ca", "cb", "dd", "de"
+            , "bdir/", "bdir/cfile"]
+  , next = files.concat([ "a-b", "aXb"
+                        , ".x", ".y" ])
+
+
+var patterns =
+  [ "http://www.bashcookbook.com/bashinfo/source/bash-1.14.7/tests/glob-test"
+  , ["a*", ["a", "abc", "abd", "abe"]]
+  , ["X*", ["X*"], {nonull: true}]
+
+  // allow null glob expansion
+  , ["X*", []]
+
+  // isaacs: Slightly different than bash/sh/ksh
+  // \\* is not un-escaped to literal "*" in a failed match,
+  // but it does make it get treated as a literal star
+  , ["\\*", ["\\*"], {nonull: true}]
+  , ["\\**", ["\\**"], {nonull: true}]
+  , ["\\*\\*", ["\\*\\*"], {nonull: true}]
+
+  , ["b*/", ["bdir/"]]
+  , ["c*", ["c", "ca", "cb"]]
+  , ["**", files]
+
+  , ["\\.\\./*/", ["\\.\\./*/"], {nonull: true}]
+  , ["s/\\..*//", ["s/\\..*//"], {nonull: true}]
+
+  , "legendary larry crashes bashes"
+  , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"
+    , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"], {nonull: true}]
+  , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"
+    , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"], {nonull: true}]
+
+  , "character classes"
+  , ["[a-c]b*", ["abc", "abd", "abe", "bb", "cb"]]
+  , ["[a-y]*[^c]", ["abd", "abe", "bb", "bcd",
+     "bdir/", "ca", "cb", "dd", "de"]]
+  , ["a*[^c]", ["abd", "abe"]]
+  , function () { files.push("a-b", "aXb") }
+  , ["a[X-]b", ["a-b", "aXb"]]
+  , function () { files.push(".x", ".y") }
+  , ["[^a-c]*", ["d", "dd", "de"]]
+  , function () { files.push("a*b/", "a*b/ooo") }
+  , ["a\\*b/*", ["a*b/ooo"]]
+  , ["a\\*?/*", ["a*b/ooo"]]
+  , ["*\\\\!*", [], {null: true}, ["echo !7"]]
+  , ["*\\!*", ["echo !7"], null, ["echo !7"]]
+  , ["*.\\*", ["r.*"], null, ["r.*"]]
+  , ["a[b]c", ["abc"]]
+  , ["a[\\b]c", ["abc"]]
+  , ["a?c", ["abc"]]
+  , ["a\\*c", [], {null: true}, ["abc"]]
+  , ["", [""], { null: true }, [""]]
+
+  , "http://www.opensource.apple.com/source/bash/bash-23/" +
+    "bash/tests/glob-test"
+  , function () { files.push("man/", "man/man1/", "man/man1/bash.1") }
+  , ["*/man*/bash.*", ["man/man1/bash.1"]]
+  , ["man/man1/bash.1", ["man/man1/bash.1"]]
+  , ["a***c", ["abc"], null, ["abc"]]
+  , ["a*****?c", ["abc"], null, ["abc"]]
+  , ["?*****??", ["abc"], null, ["abc"]]
+  , ["*****??", ["abc"], null, ["abc"]]
+  , ["?*****?c", ["abc"], null, ["abc"]]
+  , ["?***?****c", ["abc"], null, ["abc"]]
+  , ["?***?****?", ["abc"], null, ["abc"]]
+  , ["?***?****", ["abc"], null, ["abc"]]
+  , ["*******c", ["abc"], null, ["abc"]]
+  , ["*******?", ["abc"], null, ["abc"]]
+  , ["a*cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
+  , ["a**?**cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
+  , ["a**?**cd**?**??k***", ["abcdecdhjk"], null, ["abcdecdhjk"]]
+  , ["a**?**cd**?**??***k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
+  , ["a**?**cd**?**??***k**", ["abcdecdhjk"], null, ["abcdecdhjk"]]
+  , ["a****c**?**??*****", ["abcdecdhjk"], null, ["abcdecdhjk"]]
+  , ["[-abc]", ["-"], null, ["-"]]
+  , ["[abc-]", ["-"], null, ["-"]]
+  , ["\\", ["\\"], null, ["\\"]]
+  , ["[\\\\]", ["\\"], null, ["\\"]]
+  , ["[[]", ["["], null, ["["]]
+  , ["[", ["["], null, ["["]]
+  , ["[*", ["[abc"], null, ["[abc"]]
+  , "a right bracket shall lose its special meaning and\n" +
+    "represent itself in a bracket expression if it occurs\n" +
+    "first in the list.  -- POSIX.2 2.8.3.2"
+  , ["[]]", ["]"], null, ["]"]]
+  , ["[]-]", ["]"], null, ["]"]]
+  , ["[a-\z]", ["p"], null, ["p"]]
+  , ["??**********?****?", [], { null: true }, ["abc"]]
+  , ["??**********?****c", [], { null: true }, ["abc"]]
+  , ["?************c****?****", [], { null: true }, ["abc"]]
+  , ["*c*?**", [], { null: true }, ["abc"]]
+  , ["a*****c*?**", [], { null: true }, ["abc"]]
+  , ["a********???*******", [], { null: true }, ["abc"]]
+  , ["[]", [], { null: true }, ["a"]]
+  , ["[abc", [], { null: true }, ["["]]
+
+  , "nocase tests"
+  , ["XYZ", ["xYz"], { nocase: true, null: true }
+    , ["xYz", "ABC", "IjK"]]
+  , ["ab*", ["ABC"], { nocase: true, null: true }
+    , ["xYz", "ABC", "IjK"]]
+  , ["[ia]?[ck]", ["ABC", "IjK"], { nocase: true, null: true }
+    , ["xYz", "ABC", "IjK"]]
+
+  // [ pattern, [matches], MM opts, files, TAP opts]
+  , "onestar/twostar"
+  , ["{/*,*}", [], {null: true}, ["/asdf/asdf/asdf"]]
+  , ["{/?,*}", ["/a", "bb"], {null: true}
+    , ["/a", "/b/b", "/a/b/c", "bb"]]
+
+  , "dots should not match unless requested"
+  , ["**", ["a/b"], {}, ["a/b", "a/.d", ".a/.d"]]
+
+  // .. and . can only match patterns starting with .,
+  // even when options.dot is set.
+  , function () {
+      files = ["a/./b", "a/../b", "a/c/b", "a/.d/b"]
+    }
+  , ["a/*/b", ["a/c/b", "a/.d/b"], {dot: true}]
+  , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: true}]
+  , ["a/*/b", ["a/c/b"], {dot:false}]
+  , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: false}]
+
+
+  // this also tests that changing the options needs
+  // to change the cache key, even if the pattern is
+  // the same!
+  , ["**", ["a/b","a/.d",".a/.d"], { dot: true }
+    , [ ".a/.d", "a/.d", "a/b"]]
+
+  , "paren sets cannot contain slashes"
+  , ["*(a/b)", ["*(a/b)"], {nonull: true}, ["a/b"]]
+
+  // brace sets trump all else.
+  //
+  // invalid glob pattern.  fails on bash4 and bsdglob.
+  // however, in this implementation, it's easier just
+  // to do the intuitive thing, and let brace-expansion
+  // actually come before parsing any extglob patterns,
+  // like the documentation seems to say.
+  //
+  // XXX: if anyone complains about this, either fix it
+  // or tell them to grow up and stop complaining.
+  //
+  // bash/bsdglob says this:
+  // , ["*(a|{b),c)}", ["*(a|{b),c)}"], {}, ["a", "ab", "ac", "ad"]]
+  // but we do this instead:
+  , ["*(a|{b),c)}", ["a", "ab", "ac"], {}, ["a", "ab", "ac", "ad"]]
+
+  // test partial parsing in the presence of comment/negation chars
+  , ["[!a*", ["[!ab"], {}, ["[!ab", "[ab"]]
+  , ["[#a*", ["[#ab"], {}, ["[#ab", "[ab"]]
+
+  // like: {a,b|c\\,d\\\|e} except it's unclosed, so it has to be escaped.
+  , ["+(a|*\\|c\\\\|d\\\\\\|e\\\\\\\\|f\\\\\\\\\\|g"
+    , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g"]
+    , {}
+    , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g", "a", "b\\c"]]
+
+
+  // crazy nested {,,} and *(||) tests.
+  , function () {
+      files = [ "a", "b", "c", "d"
+              , "ab", "ac", "ad"
+              , "bc", "cb"
+              , "bc,d", "c,db", "c,d"
+              , "d)", "(b|c", "*(b|c"
+              , "b|c", "b|cc", "cb|c"
+              , "x(a|b|c)", "x(a|c)"
+              , "(a|b|c)", "(a|c)"]
+    }
+  , ["*(a|{b,c})", ["a", "b", "c", "ab", "ac"]]
+  , ["{a,*(b|c,d)}", ["a","(b|c", "*(b|c", "d)"]]
+  // a
+  // *(b|c)
+  // *(b|d)
+  , ["{a,*(b|{c,d})}", ["a","b", "bc", "cb", "c", "d"]]
+  , ["*(a|{b|c,c})", ["a", "b", "c", "ab", "ac", "bc", "cb"]]
+
+
+  // test various flag settings.
+  , [ "*(a|{b|c,c})", ["x(a|b|c)", "x(a|c)", "(a|b|c)", "(a|c)"]
+    , { noext: true } ]
+  , ["a?b", ["x/y/acb", "acb/"], {matchBase: true}
+    , ["x/y/acb", "acb/", "acb/d/e", "x/y/acb/d"] ]
+  , ["#*", ["#a", "#b"], {nocomment: true}, ["#a", "#b", "c#d"]]
+
+
+  // begin channelling Boole and deMorgan...
+  , "negation tests"
+  , function () {
+      files = ["d", "e", "!ab", "!abc", "a!b", "\\!a"]
+    }
+
+  // anything that is NOT a* matches.
+  , ["!a*", ["\\!a", "d", "e", "!ab", "!abc"]]
+
+  // anything that IS !a* matches.
+  , ["!a*", ["!ab", "!abc"], {nonegate: true}]
+
+  // anything that IS a* matches
+  , ["!!a*", ["a!b"]]
+
+  // anything that is NOT !a* matches
+  , ["!\\!a*", ["a!b", "d", "e", "\\!a"]]
+
+  // negation nestled within a pattern
+  , function () {
+      files = [ "foo.js"
+              , "foo.bar"
+              // can't match this one without negative lookbehind.
+              , "foo.js.js"
+              , "blar.js"
+              , "foo."
+              , "boo.js.boo" ]
+    }
+  , ["*.!(js)", ["foo.bar", "foo.", "boo.js.boo"] ]
+
+  // https://github.com/isaacs/minimatch/issues/5
+  , function () {
+      files = [ 'a/b/.x/c'
+              , 'a/b/.x/c/d'
+              , 'a/b/.x/c/d/e'
+              , 'a/b/.x'
+              , 'a/b/.x/'
+              , 'a/.x/b'
+              , '.x'
+              , '.x/'
+              , '.x/a'
+              , '.x/a/b'
+              , 'a/.x/b/.x/c'
+              , '.x/.x' ]
+  }
+  , ["**/.x/**", [ '.x/'
+                 , '.x/a'
+                 , '.x/a/b'
+                 , 'a/.x/b'
+                 , 'a/b/.x/'
+                 , 'a/b/.x/c'
+                 , 'a/b/.x/c/d'
+                 , 'a/b/.x/c/d/e' ] ]
+
+  ]
+
+var regexps =
+  [ '/^(?:(?=.)a[^/]*?)$/',
+    '/^(?:(?=.)X[^/]*?)$/',
+    '/^(?:(?=.)X[^/]*?)$/',
+    '/^(?:\\*)$/',
+    '/^(?:(?=.)\\*[^/]*?)$/',
+    '/^(?:\\*\\*)$/',
+    '/^(?:(?=.)b[^/]*?\\/)$/',
+    '/^(?:(?=.)c[^/]*?)$/',
+    '/^(?:(?:(?!(?:\\/|^)\\.).)*?)$/',
+    '/^(?:\\.\\.\\/(?!\\.)(?=.)[^/]*?\\/)$/',
+    '/^(?:s\\/(?=.)\\.\\.[^/]*?\\/)$/',
+    '/^(?:\\/\\^root:\\/\\{s\\/(?=.)\\^[^:][^/]*?:[^:][^/]*?:\\([^:]\\)[^/]*?\\.[^/]*?\\$\\/1\\/)$/',
+    '/^(?:\\/\\^root:\\/\\{s\\/(?=.)\\^[^:][^/]*?:[^:][^/]*?:\\([^:]\\)[^/]*?\\.[^/]*?\\$\\/\u0001\\/)$/',
+    '/^(?:(?!\\.)(?=.)[a-c]b[^/]*?)$/',
+    '/^(?:(?!\\.)(?=.)[a-y][^/]*?[^c])$/',
+    '/^(?:(?=.)a[^/]*?[^c])$/',
+    '/^(?:(?=.)a[X-]b)$/',
+    '/^(?:(?!\\.)(?=.)[^a-c][^/]*?)$/',
+    '/^(?:a\\*b\\/(?!\\.)(?=.)[^/]*?)$/',
+    '/^(?:(?=.)a\\*[^/]\\/(?!\\.)(?=.)[^/]*?)$/',
+    '/^(?:(?!\\.)(?=.)[^/]*?\\\\\\![^/]*?)$/',
+    '/^(?:(?!\\.)(?=.)[^/]*?\\![^/]*?)$/',
+    '/^(?:(?!\\.)(?=.)[^/]*?\\.\\*)$/',
+    '/^(?:(?=.)a[b]c)$/',
+    '/^(?:(?=.)a[b]c)$/',
+    '/^(?:(?=.)a[^/]c)$/',
+    '/^(?:a\\*c)$/',
+    'false',
+    '/^(?:(?!\\.)(?=.)[^/]*?\\/(?=.)man[^/]*?\\/(?=.)bash\\.[^/]*?)$/',
+    '/^(?:man\\/man1\\/bash\\.1)$/',
+    '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?c)$/',
+    '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]c)$/',
+    '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/])$/',
+    '/^(?:(?!\\.)(?=.)[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/])$/',
+    '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]c)$/',
+    '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?c)$/',
+    '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/])$/',
+    '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?)$/',
+    '/^(?:(?!\\.)(?=.)[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?c)$/',
+    '/^(?:(?!\\.)(?=.)[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/])$/',
+    '/^(?:(?=.)a[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/]k)$/',
+    '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/]k)$/',
+    '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/]k[^/]*?[^/]*?[^/]*?)$/',
+    '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/][^/]*?[^/]*?[^/]*?k)$/',
+    '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/][^/]*?[^/]*?[^/]*?k[^/]*?[^/]*?)$/',
+    '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?c[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?)$/',
+    '/^(?:(?!\\.)(?=.)[-abc])$/',
+    '/^(?:(?!\\.)(?=.)[abc-])$/',
+    '/^(?:\\\\)$/',
+    '/^(?:(?!\\.)(?=.)[\\\\])$/',
+    '/^(?:(?!\\.)(?=.)[\\[])$/',
+    '/^(?:\\[)$/',
+    '/^(?:(?=.)\\[(?!\\.)(?=.)[^/]*?)$/',
+    '/^(?:(?!\\.)(?=.)[\\]])$/',
+    '/^(?:(?!\\.)(?=.)[\\]-])$/',
+    '/^(?:(?!\\.)(?=.)[a-z])$/',
+    '/^(?:(?!\\.)(?=.)[^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/])$/',
+    '/^(?:(?!\\.)(?=.)[^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?c)$/',
+    '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?c[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?)$/',
+    '/^(?:(?!\\.)(?=.)[^/]*?c[^/]*?[^/][^/]*?[^/]*?)$/',
+    '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?c[^/]*?[^/][^/]*?[^/]*?)$/',
+    '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?)$/',
+    '/^(?:\\[\\])$/',
+    '/^(?:\\[abc)$/',
+    '/^(?:(?=.)XYZ)$/i',
+    '/^(?:(?=.)ab[^/]*?)$/i',
+    '/^(?:(?!\\.)(?=.)[ia][^/][ck])$/i',
+    '/^(?:\\/(?!\\.)(?=.)[^/]*?|(?!\\.)(?=.)[^/]*?)$/',
+    '/^(?:\\/(?!\\.)(?=.)[^/]|(?!\\.)(?=.)[^/]*?)$/',
+    '/^(?:(?:(?!(?:\\/|^)\\.).)*?)$/',
+    '/^(?:a\\/(?!(?:^|\\/)\\.{1,2}(?:$|\\/))(?=.)[^/]*?\\/b)$/',
+    '/^(?:a\\/(?=.)\\.[^/]*?\\/b)$/',
+    '/^(?:a\\/(?!\\.)(?=.)[^/]*?\\/b)$/',
+    '/^(?:a\\/(?=.)\\.[^/]*?\\/b)$/',
+    '/^(?:(?:(?!(?:\\/|^)(?:\\.{1,2})($|\\/)).)*?)$/',
+    '/^(?:(?!\\.)(?=.)[^/]*?\\(a\\/b\\))$/',
+    '/^(?:(?!\\.)(?=.)(?:a|b)*|(?!\\.)(?=.)(?:a|c)*)$/',
+    '/^(?:(?=.)\\[(?=.)\\!a[^/]*?)$/',
+    '/^(?:(?=.)\\[(?=.)#a[^/]*?)$/',
+    '/^(?:(?=.)\\+\\(a\\|[^/]*?\\|c\\\\\\\\\\|d\\\\\\\\\\|e\\\\\\\\\\\\\\\\\\|f\\\\\\\\\\\\\\\\\\|g)$/',
+    '/^(?:(?!\\.)(?=.)(?:a|b)*|(?!\\.)(?=.)(?:a|c)*)$/',
+    '/^(?:a|(?!\\.)(?=.)[^/]*?\\(b\\|c|d\\))$/',
+    '/^(?:a|(?!\\.)(?=.)(?:b|c)*|(?!\\.)(?=.)(?:b|d)*)$/',
+    '/^(?:(?!\\.)(?=.)(?:a|b|c)*|(?!\\.)(?=.)(?:a|c)*)$/',
+    '/^(?:(?!\\.)(?=.)[^/]*?\\(a\\|b\\|c\\)|(?!\\.)(?=.)[^/]*?\\(a\\|c\\))$/',
+    '/^(?:(?=.)a[^/]b)$/',
+    '/^(?:(?=.)#[^/]*?)$/',
+    '/^(?!^(?:(?=.)a[^/]*?)$).*$/',
+    '/^(?:(?=.)\\!a[^/]*?)$/',
+    '/^(?:(?=.)a[^/]*?)$/',
+    '/^(?!^(?:(?=.)\\!a[^/]*?)$).*$/',
+    '/^(?:(?!\\.)(?=.)[^/]*?\\.(?:(?!js)[^/]*?))$/',
+    '/^(?:(?:(?!(?:\\/|^)\\.).)*?\\/\\.x\\/(?:(?!(?:\\/|^)\\.).)*?)$/' ]
+var re = 0;
+
+tap.test("basic tests", function (t) {
+  var start = Date.now()
+
+  // [ pattern, [matches], MM opts, files, TAP opts]
+  patterns.forEach(function (c) {
+    if (typeof c === "function") return c()
+    if (typeof c === "string") return t.comment(c)
+
+    var pattern = c[0]
+      , expect = c[1].sort(alpha)
+      , options = c[2] || {}
+      , f = c[3] || files
+      , tapOpts = c[4] || {}
+
+    // options.debug = true
+    var m = new mm.Minimatch(pattern, options)
+    var r = m.makeRe()
+    var expectRe = regexps[re++]
+    tapOpts.re = String(r) || JSON.stringify(r)
+    tapOpts.files = JSON.stringify(f)
+    tapOpts.pattern = pattern
+    tapOpts.set = m.set
+    tapOpts.negated = m.negate
+
+    var actual = mm.match(f, pattern, options)
+    actual.sort(alpha)
+
+    t.equivalent( actual, expect
+                , JSON.stringify(pattern) + " " + JSON.stringify(expect)
+                , tapOpts )
+
+    t.equal(tapOpts.re, expectRe, tapOpts)
+  })
+
+  t.comment("time=" + (Date.now() - start) + "ms")
+  t.end()
+})
+
+tap.test("global leak test", function (t) {
+  var globalAfter = Object.keys(global)
+  t.equivalent(globalAfter, globalBefore, "no new globals, please")
+  t.end()
+})
+
+function alpha (a, b) {
+  return a > b ? 1 : -1
+}

+ 33 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/test/brace-expand.js

@@ -0,0 +1,33 @@
+var tap = require("tap")
+  , minimatch = require("../")
+
+tap.test("brace expansion", function (t) {
+  // [ pattern, [expanded] ]
+  ; [ [ "a{b,c{d,e},{f,g}h}x{y,z}"
+      , [ "abxy"
+        , "abxz"
+        , "acdxy"
+        , "acdxz"
+        , "acexy"
+        , "acexz"
+        , "afhxy"
+        , "afhxz"
+        , "aghxy"
+        , "aghxz" ] ]
+    , [ "a{1..5}b"
+      , [ "a1b"
+        , "a2b"
+        , "a3b"
+        , "a4b"
+        , "a5b" ] ]
+    , [ "a{b}c", ["a{b}c"] ]
+  ].forEach(function (tc) {
+    var p = tc[0]
+      , expect = tc[1]
+    t.equivalent(minimatch.braceExpand(p), expect, p)
+  })
+  console.error("ending")
+  t.end()
+})
+
+

+ 14 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/test/caching.js

@@ -0,0 +1,14 @@
+var Minimatch = require("../minimatch.js").Minimatch
+var tap = require("tap")
+tap.test("cache test", function (t) {
+  var mm1 = new Minimatch("a?b")
+  var mm2 = new Minimatch("a?b")
+  t.equal(mm1, mm2, "should get the same object")
+  // the lru should drop it after 100 entries
+  for (var i = 0; i < 100; i ++) {
+    new Minimatch("a"+i)
+  }
+  mm2 = new Minimatch("a?b")
+  t.notEqual(mm1, mm2, "cache should have dropped")
+  t.end()
+})

+ 274 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/test/defaults.js

@@ -0,0 +1,274 @@
+// http://www.bashcookbook.com/bashinfo/source/bash-1.14.7/tests/glob-test
+//
+// TODO: Some of these tests do very bad things with backslashes, and will
+// most likely fail badly on windows.  They should probably be skipped.
+
+var tap = require("tap")
+  , globalBefore = Object.keys(global)
+  , mm = require("../")
+  , files = [ "a", "b", "c", "d", "abc"
+            , "abd", "abe", "bb", "bcd"
+            , "ca", "cb", "dd", "de"
+            , "bdir/", "bdir/cfile"]
+  , next = files.concat([ "a-b", "aXb"
+                        , ".x", ".y" ])
+
+tap.test("basic tests", function (t) {
+  var start = Date.now()
+
+  // [ pattern, [matches], MM opts, files, TAP opts]
+  ; [ "http://www.bashcookbook.com/bashinfo" +
+      "/source/bash-1.14.7/tests/glob-test"
+    , ["a*", ["a", "abc", "abd", "abe"]]
+    , ["X*", ["X*"], {nonull: true}]
+
+    // allow null glob expansion
+    , ["X*", []]
+
+    // isaacs: Slightly different than bash/sh/ksh
+    // \\* is not un-escaped to literal "*" in a failed match,
+    // but it does make it get treated as a literal star
+    , ["\\*", ["\\*"], {nonull: true}]
+    , ["\\**", ["\\**"], {nonull: true}]
+    , ["\\*\\*", ["\\*\\*"], {nonull: true}]
+
+    , ["b*/", ["bdir/"]]
+    , ["c*", ["c", "ca", "cb"]]
+    , ["**", files]
+
+    , ["\\.\\./*/", ["\\.\\./*/"], {nonull: true}]
+    , ["s/\\..*//", ["s/\\..*//"], {nonull: true}]
+
+    , "legendary larry crashes bashes"
+    , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"
+      , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"], {nonull: true}]
+    , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"
+      , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"], {nonull: true}]
+
+    , "character classes"
+    , ["[a-c]b*", ["abc", "abd", "abe", "bb", "cb"]]
+    , ["[a-y]*[^c]", ["abd", "abe", "bb", "bcd",
+       "bdir/", "ca", "cb", "dd", "de"]]
+    , ["a*[^c]", ["abd", "abe"]]
+    , function () { files.push("a-b", "aXb") }
+    , ["a[X-]b", ["a-b", "aXb"]]
+    , function () { files.push(".x", ".y") }
+    , ["[^a-c]*", ["d", "dd", "de"]]
+    , function () { files.push("a*b/", "a*b/ooo") }
+    , ["a\\*b/*", ["a*b/ooo"]]
+    , ["a\\*?/*", ["a*b/ooo"]]
+    , ["*\\\\!*", [], {null: true}, ["echo !7"]]
+    , ["*\\!*", ["echo !7"], null, ["echo !7"]]
+    , ["*.\\*", ["r.*"], null, ["r.*"]]
+    , ["a[b]c", ["abc"]]
+    , ["a[\\b]c", ["abc"]]
+    , ["a?c", ["abc"]]
+    , ["a\\*c", [], {null: true}, ["abc"]]
+    , ["", [""], { null: true }, [""]]
+
+    , "http://www.opensource.apple.com/source/bash/bash-23/" +
+      "bash/tests/glob-test"
+    , function () { files.push("man/", "man/man1/", "man/man1/bash.1") }
+    , ["*/man*/bash.*", ["man/man1/bash.1"]]
+    , ["man/man1/bash.1", ["man/man1/bash.1"]]
+    , ["a***c", ["abc"], null, ["abc"]]
+    , ["a*****?c", ["abc"], null, ["abc"]]
+    , ["?*****??", ["abc"], null, ["abc"]]
+    , ["*****??", ["abc"], null, ["abc"]]
+    , ["?*****?c", ["abc"], null, ["abc"]]
+    , ["?***?****c", ["abc"], null, ["abc"]]
+    , ["?***?****?", ["abc"], null, ["abc"]]
+    , ["?***?****", ["abc"], null, ["abc"]]
+    , ["*******c", ["abc"], null, ["abc"]]
+    , ["*******?", ["abc"], null, ["abc"]]
+    , ["a*cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
+    , ["a**?**cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
+    , ["a**?**cd**?**??k***", ["abcdecdhjk"], null, ["abcdecdhjk"]]
+    , ["a**?**cd**?**??***k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
+    , ["a**?**cd**?**??***k**", ["abcdecdhjk"], null, ["abcdecdhjk"]]
+    , ["a****c**?**??*****", ["abcdecdhjk"], null, ["abcdecdhjk"]]
+    , ["[-abc]", ["-"], null, ["-"]]
+    , ["[abc-]", ["-"], null, ["-"]]
+    , ["\\", ["\\"], null, ["\\"]]
+    , ["[\\\\]", ["\\"], null, ["\\"]]
+    , ["[[]", ["["], null, ["["]]
+    , ["[", ["["], null, ["["]]
+    , ["[*", ["[abc"], null, ["[abc"]]
+    , "a right bracket shall lose its special meaning and\n" +
+      "represent itself in a bracket expression if it occurs\n" +
+      "first in the list.  -- POSIX.2 2.8.3.2"
+    , ["[]]", ["]"], null, ["]"]]
+    , ["[]-]", ["]"], null, ["]"]]
+    , ["[a-\z]", ["p"], null, ["p"]]
+    , ["??**********?****?", [], { null: true }, ["abc"]]
+    , ["??**********?****c", [], { null: true }, ["abc"]]
+    , ["?************c****?****", [], { null: true }, ["abc"]]
+    , ["*c*?**", [], { null: true }, ["abc"]]
+    , ["a*****c*?**", [], { null: true }, ["abc"]]
+    , ["a********???*******", [], { null: true }, ["abc"]]
+    , ["[]", [], { null: true }, ["a"]]
+    , ["[abc", [], { null: true }, ["["]]
+
+    , "nocase tests"
+    , ["XYZ", ["xYz"], { nocase: true, null: true }
+      , ["xYz", "ABC", "IjK"]]
+    , ["ab*", ["ABC"], { nocase: true, null: true }
+      , ["xYz", "ABC", "IjK"]]
+    , ["[ia]?[ck]", ["ABC", "IjK"], { nocase: true, null: true }
+      , ["xYz", "ABC", "IjK"]]
+
+    // [ pattern, [matches], MM opts, files, TAP opts]
+    , "onestar/twostar"
+    , ["{/*,*}", [], {null: true}, ["/asdf/asdf/asdf"]]
+    , ["{/?,*}", ["/a", "bb"], {null: true}
+      , ["/a", "/b/b", "/a/b/c", "bb"]]
+
+    , "dots should not match unless requested"
+    , ["**", ["a/b"], {}, ["a/b", "a/.d", ".a/.d"]]
+
+    // .. and . can only match patterns starting with .,
+    // even when options.dot is set.
+    , function () {
+        files = ["a/./b", "a/../b", "a/c/b", "a/.d/b"]
+      }
+    , ["a/*/b", ["a/c/b", "a/.d/b"], {dot: true}]
+    , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: true}]
+    , ["a/*/b", ["a/c/b"], {dot:false}]
+    , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: false}]
+
+
+    // this also tests that changing the options needs
+    // to change the cache key, even if the pattern is
+    // the same!
+    , ["**", ["a/b","a/.d",".a/.d"], { dot: true }
+      , [ ".a/.d", "a/.d", "a/b"]]
+
+    , "paren sets cannot contain slashes"
+    , ["*(a/b)", ["*(a/b)"], {nonull: true}, ["a/b"]]
+
+    // brace sets trump all else.
+    //
+    // invalid glob pattern.  fails on bash4 and bsdglob.
+    // however, in this implementation, it's easier just
+    // to do the intuitive thing, and let brace-expansion
+    // actually come before parsing any extglob patterns,
+    // like the documentation seems to say.
+    //
+    // XXX: if anyone complains about this, either fix it
+    // or tell them to grow up and stop complaining.
+    //
+    // bash/bsdglob says this:
+    // , ["*(a|{b),c)}", ["*(a|{b),c)}"], {}, ["a", "ab", "ac", "ad"]]
+    // but we do this instead:
+    , ["*(a|{b),c)}", ["a", "ab", "ac"], {}, ["a", "ab", "ac", "ad"]]
+
+    // test partial parsing in the presence of comment/negation chars
+    , ["[!a*", ["[!ab"], {}, ["[!ab", "[ab"]]
+    , ["[#a*", ["[#ab"], {}, ["[#ab", "[ab"]]
+
+    // like: {a,b|c\\,d\\\|e} except it's unclosed, so it has to be escaped.
+    , ["+(a|*\\|c\\\\|d\\\\\\|e\\\\\\\\|f\\\\\\\\\\|g"
+      , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g"]
+      , {}
+      , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g", "a", "b\\c"]]
+
+
+    // crazy nested {,,} and *(||) tests.
+    , function () {
+        files = [ "a", "b", "c", "d"
+                , "ab", "ac", "ad"
+                , "bc", "cb"
+                , "bc,d", "c,db", "c,d"
+                , "d)", "(b|c", "*(b|c"
+                , "b|c", "b|cc", "cb|c"
+                , "x(a|b|c)", "x(a|c)"
+                , "(a|b|c)", "(a|c)"]
+      }
+    , ["*(a|{b,c})", ["a", "b", "c", "ab", "ac"]]
+    , ["{a,*(b|c,d)}", ["a","(b|c", "*(b|c", "d)"]]
+    // a
+    // *(b|c)
+    // *(b|d)
+    , ["{a,*(b|{c,d})}", ["a","b", "bc", "cb", "c", "d"]]
+    , ["*(a|{b|c,c})", ["a", "b", "c", "ab", "ac", "bc", "cb"]]
+
+
+    // test various flag settings.
+    , [ "*(a|{b|c,c})", ["x(a|b|c)", "x(a|c)", "(a|b|c)", "(a|c)"]
+      , { noext: true } ]
+    , ["a?b", ["x/y/acb", "acb/"], {matchBase: true}
+      , ["x/y/acb", "acb/", "acb/d/e", "x/y/acb/d"] ]
+    , ["#*", ["#a", "#b"], {nocomment: true}, ["#a", "#b", "c#d"]]
+
+
+    // begin channelling Boole and deMorgan...
+    , "negation tests"
+    , function () {
+        files = ["d", "e", "!ab", "!abc", "a!b", "\\!a"]
+      }
+
+    // anything that is NOT a* matches.
+    , ["!a*", ["\\!a", "d", "e", "!ab", "!abc"]]
+
+    // anything that IS !a* matches.
+    , ["!a*", ["!ab", "!abc"], {nonegate: true}]
+
+    // anything that IS a* matches
+    , ["!!a*", ["a!b"]]
+
+    // anything that is NOT !a* matches
+    , ["!\\!a*", ["a!b", "d", "e", "\\!a"]]
+
+    // negation nestled within a pattern
+    , function () {
+        files = [ "foo.js"
+                , "foo.bar"
+                // can't match this one without negative lookbehind.
+                , "foo.js.js"
+                , "blar.js"
+                , "foo."
+                , "boo.js.boo" ]
+      }
+    , ["*.!(js)", ["foo.bar", "foo.", "boo.js.boo"] ]
+
+    ].forEach(function (c) {
+      if (typeof c === "function") return c()
+      if (typeof c === "string") return t.comment(c)
+
+      var pattern = c[0]
+        , expect = c[1].sort(alpha)
+        , options = c[2]
+        , f = c[3] || files
+        , tapOpts = c[4] || {}
+
+      // options.debug = true
+      var Class = mm.defaults(options).Minimatch
+      var m = new Class(pattern, {})
+      var r = m.makeRe()
+      tapOpts.re = String(r) || JSON.stringify(r)
+      tapOpts.files = JSON.stringify(f)
+      tapOpts.pattern = pattern
+      tapOpts.set = m.set
+      tapOpts.negated = m.negate
+
+      var actual = mm.match(f, pattern, options)
+      actual.sort(alpha)
+
+      t.equivalent( actual, expect
+                  , JSON.stringify(pattern) + " " + JSON.stringify(expect)
+                  , tapOpts )
+    })
+
+  t.comment("time=" + (Date.now() - start) + "ms")
+  t.end()
+})
+
+tap.test("global leak test", function (t) {
+  var globalAfter = Object.keys(global)
+  t.equivalent(globalAfter, globalBefore, "no new globals, please")
+  t.end()
+})
+
+function alpha (a, b) {
+  return a > b ? 1 : -1
+}

+ 8 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/test/extglob-ending-with-state-char.js

@@ -0,0 +1,8 @@
+var test = require('tap').test
+var minimatch = require('../')
+
+test('extglob ending with statechar', function(t) {
+  t.notOk(minimatch('ax', 'a?(b*)'))
+  t.ok(minimatch('ax', '?(a*|b)'))
+  t.end()
+})

+ 42 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/Jakefile

@@ -0,0 +1,42 @@
+
+var t = new jake.TestTask('Utilities', function () {
+  this.testFiles.include('test/*.js');
+  
+  // Can't reliably test ports on travis
+  if(process.env.CI) {
+    this.testFiles.exclude('test/network.js');
+  }
+});
+
+namespace('doc', function () {
+  task('generate', ['doc:clobber'], function () {
+    var cmd = '../node-jsdoc-toolkit/app/run.js -n -r=100 ' +
+        '-t=../node-jsdoc-toolkit/templates/codeview -d=./doc/ ./lib';
+    console.log('Generating docs ...');
+    jake.exec([cmd], function () {
+      console.log('Done.');
+      complete();
+    });
+  }, {async: true});
+
+  task('clobber', function () {
+    var cmd = 'rm -fr ./doc/**';
+    jake.exec([cmd], function () {
+      console.log('Clobbered old docs.');
+      complete();
+    });
+  }, {async: true});
+
+});
+
+desc('Generate docs for Utilities');
+task('doc', ['doc:generate']);
+
+var p = new jake.NpmPublishTask('utilities', [
+  'Jakefile'
+, 'README.md'
+, 'package.json'
+, 'lib/**'
+, 'test/**'
+]);
+

+ 6 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/README.md

@@ -0,0 +1,6 @@
+utilities
+=========
+
+[![Build Status](https://travis-ci.org/mde/utilities.png?branch=master)](https://travis-ci.org/mde/utilities)
+
+A classic collection of JavaScript utilities

+ 94 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/array.js

@@ -0,0 +1,94 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+/**
+  @name array
+  @namespace array
+*/
+
+var array = new (function () {
+
+  /**
+    @name array#humanize
+    @public
+    @function
+    @return {String} A string containing the array elements in a readable format
+    @description Creates a string containing the array elements in a readable format
+    @param {Array} array The array to humanize
+  */
+  this.humanize = function (a) {
+    var array = a.slice();
+    // If array only has one item then just return it
+    if (array.length <= 1) {
+      return String(array);
+    }
+
+    var last = array.pop()
+      , items = array.join(', ');
+
+    return items + ' and ' + last;
+  };
+
+  /**
+    @name array#included
+    @public
+    @function
+    @return {Array/Boolean} If `item` is included the `array` is
+      returned otherwise false
+    @description Checks if an `item` is included in an `array`
+    @param {Any} item The item to look for
+    @param {Array} array The array to check
+  */
+  this.included = function (item, array) {
+    var result = array.indexOf(item);
+
+    if (result === -1) {
+      return false;
+    } else {
+      return array;
+    }
+  };
+
+  /**
+    @name array#include
+    @public
+    @function
+    @return {Boolean} Return true if the item is included in the array
+    @description Checks if an `item` is included in an `array`
+    @param {Array} array The array to check
+    @param {Any} item The item to look for
+  */
+  this.include = function (array, item) {
+    var res = -1;
+    if (typeof array.indexOf == 'function') {
+      res = array.indexOf(item);
+    }
+    else {
+      for (var i = 0, ii = array.length; i < ii; i++) {
+        if (array[i] == item) {
+          res = i;
+          break;
+        }
+      }
+    }
+    return res > -1;
+  };
+
+})();
+
+module.exports = array;

+ 298 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/async.js

@@ -0,0 +1,298 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+var async = {};
+
+/*
+AsyncChain -- performs a list of asynchronous calls in a desired order.
+Optional "last" method can be set to run after all the items in the
+chain have completed.
+
+  // Example usage
+  var asyncChain = new async.AsyncChain([
+    {
+      func: app.trainToBangkok,
+      args: [geddy, neil, alex],
+      callback: null, // No callback for this action
+    },
+    {
+      func: fs.readdir,
+      args: [geddy.config.dirname + '/thailand/express'],
+      callback: function (err, result) {
+        if (err) {
+          // Bail out completely
+          arguments.callee.chain.abort();
+        }
+        else if (result.theBest) {
+          // Don't run the next item in the chain; go directly
+          // to the 'last' method.
+          arguments.callee.chain.shortCircuit();
+        }
+        else {
+          // Otherwise do some other stuff and
+          // then go to the next link
+        }
+      }
+    },
+    {
+      func: child_process.exec,
+      args: ['ls ./'],
+      callback: this.hitTheStops
+    }
+  ]);
+
+  // Function to exec after all the links in the chain finish
+  asyncChain.last = function () { // Do some final stuff };
+
+  // Start the async-chain
+  asyncChain.run();
+
+*/
+async.execNonBlocking = function (func) {
+  if (typeof process != 'undefined' && typeof process.nextTick == 'function') {
+    process.nextTick(func);
+  }
+  else {
+    setTimeout(func, 0);
+  }
+};
+
+async.AsyncBase = new (function () {
+
+  this.init = function (chain) {
+    var item;
+    this.chain = [];
+    this.currentItem = null;
+    this.shortCircuited = false;
+    this.shortCircuitedArgs = undefined;
+    this.aborted = false;
+
+    for (var i = 0; i < chain.length; i++) {
+      item = chain[i];
+      this.addItem(item);
+    }
+  };
+
+  this.addItem = function(item) {
+    this.chain.push(new async.AsyncCall(
+      item.func, item.args || [], item.callback, item.context));
+  };
+
+  // alias
+  this.push = this.addItem;
+
+  this.runItem = function (item) {
+    // Reference to the current item in the chain -- used
+    // to look up the callback to execute with execCallback
+    this.currentItem = item;
+    // Scopage
+    var _this = this;
+    // Pass the arguments passed to the current async call
+    // to the callback executor, execute it in the correct scope
+    var executor = function () {
+      _this.execCallback.apply(_this, arguments);
+    };
+    // Append the callback executor to the end of the arguments
+    // Node helpfully always has the callback func last
+    var args = item.args.concat(executor);
+    var func = item.func;
+    // Run the async call
+    func.apply(item.context, args);
+  };
+
+  this.next = function () {
+    if (this.chain.length) {
+      this.runItem(this.chain.shift());
+    }
+    else {
+      this.last();
+    }
+  };
+
+  this.execCallback = function () {
+    // Look up the callback, if any, specified for this async call
+    var callback = this.currentItem.callback;
+    // If there's a callback, do it
+    if (callback && typeof callback == 'function') {
+      // Allow access to the chain from inside the callback by setting
+      // callback.chain = this, and then using arguments.callee.chain
+      callback.chain = this;
+      callback.apply(this.currentItem.context, arguments);
+    }
+
+    this.currentItem.finished = true;
+
+    // If one of the async callbacks called chain.shortCircuit,
+    // skip to the 'last' function for the chain
+    if (this.shortCircuited) {
+      this.last.apply(null, this.shortCircuitedArgs);
+    }
+    // If one of the async callbacks called chain.abort,
+    // bail completely out
+    else if (this.aborted) {
+      return;
+    }
+    // Otherwise run the next item, if any, in the chain
+    // Let's try not to block if we don't have to
+    else {
+      // Scopage
+      var _this = this;
+      async.execNonBlocking(function () { _this.next.call(_this); });
+    }
+  }
+
+  // Short-circuit the chain, jump straight to the 'last' function
+  this.shortCircuit = function () {
+    this.shortCircuitedArgs = arguments;
+    this.shortCircuited = true;
+  }
+
+  // Stop execution of the chain, bail completely out
+  this.abort = function () {
+    this.aborted = true;
+  }
+
+  // Kick off the chain by grabbing the first item and running it
+  this.run = this.next;
+
+  // Function to run when the chain is done -- default is a no-op
+  this.last = function () {};
+
+})();
+
+async.AsyncChain = function (chain) {
+  this.init(chain);
+};
+
+async.AsyncChain.prototype = async.AsyncBase;
+
+async.AsyncGroup = function (group) {
+  var item;
+  var callback;
+  var args;
+
+  this.group = [];
+  this.outstandingCount = 0;
+
+  for (var i = 0; i < group.length; i++) {
+    item = group[i];
+    this.group.push(new async.AsyncCall(
+        item.func, item.args, item.callback, item.context));
+    this.outstandingCount++;
+  }
+
+};
+
+/*
+Simpler way to group async calls -- doesn't ensure completion order,
+but still has a "last" method called when the entire group of calls
+have completed.
+*/
+async.AsyncGroup.prototype = new function () {
+  this.run = function () {
+    var _this = this
+      , group = this.group
+      , item
+      , createItem = function (item, args) {
+          return function () {
+            item.func.apply(item.context, args);
+          };
+        }
+      , createCallback = function (item) {
+          return function () {
+            if (item.callback) {
+              item.callback.apply(null, arguments);
+            }
+            _this.finish.call(_this);
+          }
+        };
+
+    for (var i = 0; i < group.length; i++) {
+      item = group[i];
+      callback = createCallback(item);
+      args = item.args.concat(callback);
+      // Run the async call
+      async.execNonBlocking(createItem(item, args));
+    }
+  };
+
+  this.finish = function () {
+    this.outstandingCount--;
+    if (!this.outstandingCount) {
+      this.last();
+    };
+  };
+
+  this.last = function () {};
+
+};
+
+var _createSimpleAsyncCall = function (func, context) {
+  return {
+    func: func
+  , args: []
+  , callback: function () {}
+  , context: context
+  };
+};
+
+async.SimpleAsyncChain = function (funcs, context) {
+  chain = [];
+  for (var i = 0, ii = funcs.length; i < ii; i++) {
+    chain.push(_createSimpleAsyncCall(funcs[i], context));
+  }
+  this.init(chain);
+};
+
+async.SimpleAsyncChain.prototype = async.AsyncBase;
+
+async.AsyncCall = function (func, args, callback, context) {
+  this.func = func;
+  this.args = args;
+  this.callback = callback || null;
+  this.context = context || null;
+};
+
+async.Initializer = function (steps, callback) {
+  var self = this;
+  this.steps = {};
+  this.callback = callback;
+  // Create an object-literal of the steps to tick off
+  steps.forEach(function (step) {
+    self.steps[step] = false;
+  });
+};
+
+async.Initializer.prototype = new (function () {
+  this.complete = function (step) {
+    var steps = this.steps;
+    // Tick this step off
+    steps[step] = true;
+    // Iterate the steps -- if any are not done, bail out
+    for (var p in steps) {
+      if (!steps[p]) {
+        return false;
+      }
+    }
+    // If all steps are done, run the callback
+    this.callback();
+  };
+})();
+
+module.exports = async;
+

+ 128 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/core.js

@@ -0,0 +1,128 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+var core = new (function () {
+
+  var _mix = function (targ, src, merge, includeProto) {
+    for (var p in src) {
+      // Don't copy stuff from the prototype
+      if (src.hasOwnProperty(p) || includeProto) {
+        if (merge &&
+            // Assumes the source property is an Object you can
+            // actually recurse down into
+            (typeof src[p] == 'object') &&
+            (src[p] !== null) &&
+            !(src[p] instanceof Array)) {
+          // Create the source property if it doesn't exist
+          // Double-equal to undefined includes both null and undefined
+          if (targ[p] == undefined) {
+            targ[p] = {};
+          }
+          _mix(targ[p], src[p], merge, includeProto); // Recurse
+        }
+        // If it's not a merge-copy, just set and forget
+        else {
+          targ[p] = src[p];
+        }
+      }
+    }
+  };
+
+  /*
+   * Mix in the properties on an object to another object
+   * yam.mixin(target, source, [source,] [source, etc.] [merge-flag]);
+   * 'merge' recurses, to merge object sub-properties together instead
+   * of just overwriting with the source object.
+   */
+  this.mixin = function () {
+    var args = Array.prototype.slice.apply(arguments),
+        merge = false,
+        targ, sources;
+    if (args.length > 2) {
+      if (typeof args[args.length - 1] == 'boolean') {
+        merge = args.pop();
+      }
+    }
+    targ = args.shift();
+    sources = args;
+    for (var i = 0, ii = sources.length; i < ii; i++) {
+      _mix(targ, sources[i], merge);
+    }
+    return targ;
+  };
+
+  this.enhance = function () {
+    var args = Array.prototype.slice.apply(arguments),
+        merge = false,
+        targ, sources;
+    if (args.length > 2) {
+      if (typeof args[args.length - 1] == 'boolean') {
+        merge = args.pop();
+      }
+    }
+    targ = args.shift();
+    sources = args;
+    for (var i = 0, ii = sources.length; i < ii; i++) {
+      _mix(targ, sources[i], merge, true);
+    }
+    return targ;
+  };
+
+  // Idea to add invalid number & Date from Michael J. Ryan,
+  // http://frugalcoder.us/post/2010/02/15/js-is-empty.aspx
+  this.isEmpty = function (val) {
+    // Empty string, null or undefined (these two are double-equal)
+    if (val === '' || val == undefined) {
+      return true;
+    }
+    // Invalid numerics
+    if (typeof val == 'number' && isNaN(val)) {
+      return true;
+    }
+    // Invalid Dates
+    if (val instanceof Date && isNaN(val.getTime())) {
+      return true;
+    }
+    return false;
+  };
+
+  /*
+  binds a function to an object
+   */
+  this.bind = function () {
+    var args = Array.prototype.slice.call(arguments)
+      , ctxt = args.shift()
+      , fn = args.shift();
+
+    if (typeof fn === 'function') {
+      if (typeof Function.bind === 'function') {
+        return fn.bind.apply(ctxt, args);
+      }
+      else {
+        return fn.apply(ctxt, args);
+      }
+    }
+    // in IE, native methods are not functions so they cannot be bound,
+    // and don't need to be
+    else {
+      return fn;
+    }
+  }
+})();
+
+module.exports = core;

+ 928 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/date.js

@@ -0,0 +1,928 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+var string = require('./string')
+  , date
+  , log = require('./log');
+
+/**
+  @name date
+  @namespace date
+*/
+
+date = new (function () {
+  var _this = this
+    , _date = new Date();
+
+  var _US_DATE_PAT = /^(\d{1,2})(?:\-|\/|\.)(\d{1,2})(?:\-|\/|\.)(\d{4})/;
+  var _DATETIME_PAT = /^(\d{4})(?:\-|\/|\.)(\d{1,2})(?:\-|\/|\.)(\d{1,2})(?:T| )?(\d{2})?(?::)?(\d{2})?(?::)?(\d{2})?(?:\.)?(\d+)?(?: *)?(Z|[+-]\d{4}|[+-]\d{2}:\d{2}|[+-]\d{2})?/;
+  // TODO Add am/pm parsing instead of dumb, 24-hour clock.
+  var _TIME_PAT = /^(\d{1,2})?(?::)?(\d{2})?(?::)?(\d{2})?(?:\.)?(\d+)?$/;
+
+  var _dateMethods = [
+      'FullYear'
+    , 'Month'
+    , 'Date'
+    , 'Hours'
+    , 'Minutes'
+    , 'Seconds'
+    , 'Milliseconds'
+  ];
+
+  var _isArray = function (obj) {
+    return obj &&
+      typeof obj === 'object' &&
+      typeof obj.length === 'number' &&
+      typeof obj.splice === 'function' &&
+      !(obj.propertyIsEnumerable('length'));
+  };
+
+  this.weekdayLong = ['Sunday', 'Monday', 'Tuesday',
+    'Wednesday', 'Thursday', 'Friday', 'Saturday'];
+  this.weekdayShort = ['Sun', 'Mon', 'Tue', 'Wed',
+    'Thu', 'Fri', 'Sat'];
+  this.monthLong = ['January', 'February', 'March',
+    'April', 'May', 'June', 'July', 'August', 'September',
+    'October', 'November', 'December'];
+  this.monthShort = ['Jan', 'Feb', 'Mar', 'Apr',
+    'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
+  this.meridiem = {
+    'AM': 'AM',
+    'PM': 'PM'
+  }
+  // compat
+  this.meridian = this.meridiem
+
+  /**
+    @name date#supportedFormats
+    @public
+    @object
+    @description List of supported strftime formats
+  */
+  this.supportedFormats = {
+    // abbreviated weekday name according to the current locale
+    'a': function (dt) { return _this.weekdayShort[dt.getDay()]; },
+    // full weekday name according to the current locale
+    'A': function (dt) { return _this.weekdayLong[dt.getDay()]; },
+    //  abbreviated month name according to the current locale
+    'b': function (dt) { return _this.monthShort[dt.getMonth()]; },
+    'h': function (dt) { return _this.strftime(dt, '%b'); },
+    // full month name according to the current locale
+    'B': function (dt) { return _this.monthLong[dt.getMonth()]; },
+    // preferred date and time representation for the current locale
+    'c': function (dt) { return _this.strftime(dt, '%a %b %d %T %Y'); },
+    // century number (the year divided by 100 and truncated
+    // to an integer, range 00 to 99)
+    'C': function (dt) { return _this.calcCentury(dt.getFullYear());; },
+    // day of the month as a decimal number (range 01 to 31)
+    'd': function (dt) { return string.lpad(dt.getDate(), '0', 2); },
+    // same as %m/%d/%y
+    'D': function (dt) { return _this.strftime(dt, '%m/%d/%y') },
+    // day of the month as a decimal number, a single digit is
+    // preceded by a space (range ' 1' to '31')
+    'e': function (dt) { return string.lpad(dt.getDate(), ' ', 2); },
+    // month as a decimal number, a single digit is
+    // preceded by a space (range ' 1' to '12')
+    'f': function () { return _this.strftimeNotImplemented('f'); },
+    // same as %Y-%m-%d
+    'F': function (dt) { return _this.strftime(dt, '%Y-%m-%d');  },
+    // like %G, but without the century.
+    'g': function () { return _this.strftimeNotImplemented('g'); },
+    // The 4-digit year corresponding to the ISO week number
+    // (see %V).  This has the same format and value as %Y,
+    // except that if the ISO week number belongs to the
+    // previous or next year, that year is used instead.
+    'G': function () { return _this.strftimeNotImplemented('G'); },
+    // hour as a decimal number using a 24-hour clock (range
+    // 00 to 23)
+    'H': function (dt) { return string.lpad(dt.getHours(), '0', 2); },
+    // hour as a decimal number using a 12-hour clock (range
+    // 01 to 12)
+    'I': function (dt) { return string.lpad(
+      _this.hrMil2Std(dt.getHours()), '0', 2); },
+    // day of the year as a decimal number (range 001 to 366)
+    'j': function (dt) { return string.lpad(
+      _this.calcDays(dt), '0', 3); },
+    // Hour as a decimal number using a 24-hour clock (range
+    // 0 to 23 (space-padded))
+    'k': function (dt) { return string.lpad(dt.getHours(), ' ', 2); },
+    // Hour as a decimal number using a 12-hour clock (range
+    // 1 to 12 (space-padded))
+    'l': function (dt) { return string.lpad(
+      _this.hrMil2Std(dt.getHours()), ' ', 2); },
+    // month as a decimal number (range 01 to 12)
+    'm': function (dt) { return string.lpad((dt.getMonth()+1), '0', 2); },
+    // minute as a decimal number
+    'M': function (dt) { return string.lpad(dt.getMinutes(), '0', 2); },
+    // Linebreak
+    'n': function () { return '\n'; },
+    // either `am' or `pm' according to the given time value,
+    // or the corresponding strings for the current locale
+    'p': function (dt) { return _this.getMeridian(dt.getHours()); },
+    // time in a.m. and p.m. notation
+    'r': function (dt) { return _this.strftime(dt, '%I:%M:%S %p'); },
+    // time in 24 hour notation
+    'R': function (dt) { return _this.strftime(dt, '%H:%M'); },
+    // second as a decimal number
+    'S': function (dt) { return string.lpad(dt.getSeconds(), '0', 2); },
+    // Tab char
+    't': function () { return '\t'; },
+    // current time, equal to %H:%M:%S
+    'T': function (dt) { return _this.strftime(dt, '%H:%M:%S'); },
+    // weekday as a decimal number [1,7], with 1 representing
+    // Monday
+    'u': function (dt) { return _this.convertOneBase(dt.getDay()); },
+    // week number of the current year as a decimal number,
+    // starting with the first Sunday as the first day of the
+    // first week
+    'U': function () { return _this.strftimeNotImplemented('U'); },
+    // week number of the year (Monday as the first day of the
+    // week) as a decimal number [01,53]. If the week containing
+    // 1 January has four or more days in the new year, then it
+    // is considered week 1. Otherwise, it is the last week of
+    // the previous year, and the next week is week 1.
+    'V': function () { return _this.strftimeNotImplemented('V'); },
+    // week number of the current year as a decimal number,
+    // starting with the first Monday as the first day of the
+    // first week
+    'W': function () { return _this.strftimeNotImplemented('W'); },
+    // day of the week as a decimal, Sunday being 0
+    'w': function (dt) { return dt.getDay(); },
+    // preferred date representation for the current locale
+    // without the time
+    'x': function (dt) { return _this.strftime(dt, '%D'); },
+    // preferred time representation for the current locale
+    // without the date
+    'X': function (dt) { return _this.strftime(dt, '%T'); },
+    // year as a decimal number without a century (range 00 to
+    // 99)
+    'y': function (dt) { return _this.getTwoDigitYear(dt.getFullYear()); },
+    // year as a decimal number including the century
+    'Y': function (dt) { return string.lpad(dt.getFullYear(), '0', 4); },
+    // time zone or name or abbreviation
+    'z': function () { return _this.strftimeNotImplemented('z'); },
+    'Z': function () { return _this.strftimeNotImplemented('Z'); },
+    // Literal percent char
+    '%': function (dt) { return '%'; }
+  };
+
+  /**
+    @name date#getSupportedFormats
+    @public
+    @function
+    @description return the list of formats in a string
+    @return {String} The list of supported formats
+  */
+  this.getSupportedFormats = function () {
+    var str = '';
+    for (var i in this.supportedFormats) { str += i; }
+    return str;
+  }
+
+  this.supportedFormatsPat = new RegExp('%[' +
+      this.getSupportedFormats() + ']{1}', 'g');
+
+  /**
+    @name date#strftime
+    @public
+    @function
+    @return {String} The `dt` formated with the given `format`
+    @description Formats the given date with the strftime formated
+    @param {Date} dt the date object to format
+    @param {String} format the format to convert the date to
+  */
+  this.strftime = function (dt, format) {
+    if (!dt) { return '' }
+
+    var d = dt;
+    var pats = [];
+    var dts = [];
+    var str = format;
+
+    // Allow either Date obj or UTC stamp
+    d = typeof dt == 'number' ? new Date(dt) : dt;
+
+    // Grab all instances of expected formats into array
+    while (pats = this.supportedFormatsPat.exec(format)) {
+      dts.push(pats[0]);
+    }
+
+    // Process any hits
+    for (var i = 0; i < dts.length; i++) {
+      key = dts[i].replace(/%/, '');
+      str = str.replace('%' + key,
+        this.supportedFormats[key](d));
+    }
+    return str;
+
+  };
+
+  this.strftimeNotImplemented = function (s) {
+    throw('this.strftime format "' + s + '" not implemented.');
+  };
+
+  /**
+    @name date#calcCentury
+    @public
+    @function
+    @return {String} The century for the given date
+    @description Find the century for the given `year`
+    @param {Number} year The year to find the century for
+  */
+  this.calcCentury = function (year) {
+    if(!year) {
+      year = _date.getFullYear();
+    }
+
+    var ret = parseInt((year / 100) + 1);
+    year = year.toString();
+
+    // If year ends in 00 subtract one, because it's still the century before the one
+    // it divides to
+    if (year.substring(year.length - 2) === '00') {
+      ret--;
+    }
+
+    return ret.toString();
+  };
+
+  /**
+    @name date#calcDays
+    @public
+    @function
+    @return {Number} The number of days so far for the given date
+    @description Calculate the day number in the year a particular date is on
+    @param {Date} dt The date to use
+  */
+  this.calcDays = function (dt) {
+    var first = new Date(dt.getFullYear(), 0, 1);
+    var diff = 0;
+    var ret = 0;
+    first = first.getTime();
+    diff = (dt.getTime() - first);
+    ret = parseInt(((((diff/1000)/60)/60)/24))+1;
+    return ret;
+  };
+
+  /**
+   * Adjust from 0-6 base week to 1-7 base week
+   * @param d integer for day of week
+   * @return Integer day number for 1-7 base week
+   */
+  this.convertOneBase = function (d) {
+    return d == 0 ? 7 : d;
+  };
+
+  this.getTwoDigitYear = function (yr) {
+    // Add a millenium to take care of years before the year 1000,
+    // (e.g, the year 7) since we're only taking the last two digits
+    // If we overshoot, it doesn't matter
+    var millenYear = yr + 1000;
+    var str = millenYear.toString();
+    str = str.substr(2); // Get the last two digits
+    return str
+  };
+
+  /**
+    @name date#getMeridiem
+    @public
+    @function
+    @return {String} Return 'AM' or 'PM' based on hour in 24-hour format
+    @description Return 'AM' or 'PM' based on hour in 24-hour format
+    @param {Number} h The hour to check
+  */
+  this.getMeridiem = function (h) {
+    return h > 11 ? this.meridiem.PM :
+      this.meridiem.AM;
+  };
+  // Compat
+  this.getMeridian = this.getMeridiem;
+
+  /**
+    @name date#hrMil2Std
+    @public
+    @function
+    @return {String} Return a 12 hour version of the given time
+    @description Convert a 24-hour formatted hour to 12-hour format
+    @param {String} hour The hour to convert
+  */
+  this.hrMil2Std = function (hour) {
+    var h = typeof hour == 'number' ? hour : parseInt(hour);
+    var str = h > 12 ? h - 12 : h;
+    str = str == 0 ? 12 : str;
+    return str;
+  };
+
+  /**
+    @name date#hrStd2Mil
+    @public
+    @function
+    @return {String} Return a 24 hour version of the given time
+    @description Convert a 12-hour formatted hour with meridian flag to 24-hour format
+    @param {String} hour The hour to convert
+    @param {Boolean} pm hour is PM then this should be true
+  */
+  this.hrStd2Mil = function  (hour, pm) {
+    var h = typeof hour == 'number' ? hour : parseInt(hour);
+    var str = '';
+    // PM
+    if (pm) {
+      str = h < 12 ? (h+12) : h;
+    }
+    // AM
+    else {
+      str = h == 12 ? 0 : h;
+    }
+    return str;
+  };
+
+  // Constants for use in this.add
+  var dateParts = {
+    YEAR: 'year'
+    , MONTH: 'month'
+    , DAY: 'day'
+    , HOUR: 'hour'
+    , MINUTE: 'minute'
+    , SECOND: 'second'
+    , MILLISECOND: 'millisecond'
+    , QUARTER: 'quarter'
+    , WEEK: 'week'
+    , WEEKDAY: 'weekday'
+  };
+  // Create a map for singular/plural lookup, e.g., day/days
+  var datePartsMap = {};
+  for (var p in dateParts) {
+    datePartsMap[dateParts[p]] = dateParts[p];
+    datePartsMap[dateParts[p] + 's'] = dateParts[p];
+  }
+  this.dateParts = dateParts;
+
+  /**
+    @name date#add
+    @public
+    @function
+    @return {Date} Incremented date
+    @description Add to a Date in intervals of different size, from
+                 milliseconds to years
+    @param {Date} dt Date (or timestamp Number), date to increment
+    @param {String} interv a constant representing the interval,
+    e.g. YEAR, MONTH, DAY.  See this.dateParts
+    @param {Number} incr how much to add to the date
+  */
+  this.add = function (dt, interv, incr) {
+    if (typeof dt == 'number') { dt = new Date(dt); }
+    function fixOvershoot() {
+      if (sum.getDate() < dt.getDate()) {
+        sum.setDate(0);
+      }
+    }
+    var key = datePartsMap[interv];
+    var sum = new Date(dt);
+    switch (key) {
+      case dateParts.YEAR:
+        sum.setFullYear(dt.getFullYear()+incr);
+        // Keep increment/decrement from 2/29 out of March
+        fixOvershoot();
+        break;
+      case dateParts.QUARTER:
+        // Naive quarter is just three months
+        incr*=3;
+        // fallthrough...
+      case dateParts.MONTH:
+        sum.setMonth(dt.getMonth()+incr);
+        // Reset to last day of month if you overshoot
+        fixOvershoot();
+        break;
+      case dateParts.WEEK:
+        incr*=7;
+        // fallthrough...
+      case dateParts.DAY:
+        sum.setDate(dt.getDate() + incr);
+        break;
+      case dateParts.WEEKDAY:
+        //FIXME: assumes Saturday/Sunday weekend, but even this is not fixed.
+        // There are CLDR entries to localize this.
+        var dat = dt.getDate();
+        var weeks = 0;
+        var days = 0;
+        var strt = 0;
+        var trgt = 0;
+        var adj = 0;
+        // Divide the increment time span into weekspans plus leftover days
+        // e.g., 8 days is one 5-day weekspan / and two leftover days
+        // Can't have zero leftover days, so numbers divisible by 5 get
+        // a days value of 5, and the remaining days make up the number of weeks
+        var mod = incr % 5;
+        if (mod == 0) {
+          days = (incr > 0) ? 5 : -5;
+          weeks = (incr > 0) ? ((incr-5)/5) : ((incr+5)/5);
+        }
+        else {
+          days = mod;
+          weeks = parseInt(incr/5);
+        }
+        // Get weekday value for orig date param
+        strt = dt.getDay();
+        // Orig date is Sat / positive incrementer
+        // Jump over Sun
+        if (strt == 6 && incr > 0) {
+          adj = 1;
+        }
+        // Orig date is Sun / negative incrementer
+        // Jump back over Sat
+        else if (strt == 0 && incr < 0) {
+          adj = -1;
+        }
+        // Get weekday val for the new date
+        trgt = strt + days;
+        // New date is on Sat or Sun
+        if (trgt == 0 || trgt == 6) {
+          adj = (incr > 0) ? 2 : -2;
+        }
+        // Increment by number of weeks plus leftover days plus
+        // weekend adjustments
+        sum.setDate(dat + (7*weeks) + days + adj);
+        break;
+      case dateParts.HOUR:
+        sum.setHours(sum.getHours()+incr);
+        break;
+      case dateParts.MINUTE:
+        sum.setMinutes(sum.getMinutes()+incr);
+        break;
+      case dateParts.SECOND:
+        sum.setSeconds(sum.getSeconds()+incr);
+        break;
+      case dateParts.MILLISECOND:
+        sum.setMilliseconds(sum.getMilliseconds()+incr);
+        break;
+      default:
+        // Do nothing
+        break;
+    }
+    return sum; // Date
+  };
+
+  /**
+    @name date#diff
+    @public
+    @function
+    @return {Number} number of (interv) units apart that
+    the two dates are
+    @description Get the difference in a specific unit of time (e.g., number
+                 of months, weeks, days, etc.) between two dates.
+    @param {Date} date1 First date to check
+    @param {Date} date2 Date to compate `date1` with
+    @param {String} interv a constant representing the interval,
+    e.g. YEAR, MONTH, DAY.  See this.dateParts
+  */
+  this.diff = function (date1, date2, interv) {
+    //  date1
+    //    Date object or Number equivalent
+    //
+    //  date2
+    //    Date object or Number equivalent
+    //
+    //  interval
+    //    A constant representing the interval, e.g. YEAR, MONTH, DAY.  See this.dateParts.
+
+    // Accept timestamp input
+    if (typeof date1 == 'number') { date1 = new Date(date1); }
+    if (typeof date2 == 'number') { date2 = new Date(date2); }
+    var yeaDiff = date2.getFullYear() - date1.getFullYear();
+    var monDiff = (date2.getMonth() - date1.getMonth()) + (yeaDiff * 12);
+    var msDiff = date2.getTime() - date1.getTime(); // Millisecs
+    var secDiff = msDiff/1000;
+    var minDiff = secDiff/60;
+    var houDiff = minDiff/60;
+    var dayDiff = houDiff/24;
+    var weeDiff = dayDiff/7;
+    var delta = 0; // Integer return value
+
+    var key = datePartsMap[interv];
+    switch (key) {
+      case dateParts.YEAR:
+        delta = yeaDiff;
+        break;
+      case dateParts.QUARTER:
+        var m1 = date1.getMonth();
+        var m2 = date2.getMonth();
+        // Figure out which quarter the months are in
+        var q1 = Math.floor(m1/3) + 1;
+        var q2 = Math.floor(m2/3) + 1;
+        // Add quarters for any year difference between the dates
+        q2 += (yeaDiff * 4);
+        delta = q2 - q1;
+        break;
+      case dateParts.MONTH:
+        delta = monDiff;
+        break;
+      case dateParts.WEEK:
+        // Truncate instead of rounding
+        // Don't use Math.floor -- value may be negative
+        delta = parseInt(weeDiff);
+        break;
+      case dateParts.DAY:
+        delta = dayDiff;
+        break;
+      case dateParts.WEEKDAY:
+        var days = Math.round(dayDiff);
+        var weeks = parseInt(days/7);
+        var mod = days % 7;
+
+        // Even number of weeks
+        if (mod == 0) {
+          days = weeks*5;
+        }
+        else {
+          // Weeks plus spare change (< 7 days)
+          var adj = 0;
+          var aDay = date1.getDay();
+          var bDay = date2.getDay();
+
+          weeks = parseInt(days/7);
+          mod = days % 7;
+          // Mark the date advanced by the number of
+          // round weeks (may be zero)
+          var dtMark = new Date(date1);
+          dtMark.setDate(dtMark.getDate()+(weeks*7));
+          var dayMark = dtMark.getDay();
+
+          // Spare change days -- 6 or less
+          if (dayDiff > 0) {
+            switch (true) {
+              // Range starts on Sat
+              case aDay == 6:
+                adj = -1;
+                break;
+              // Range starts on Sun
+              case aDay == 0:
+                adj = 0;
+                break;
+              // Range ends on Sat
+              case bDay == 6:
+                adj = -1;
+                break;
+              // Range ends on Sun
+              case bDay == 0:
+                adj = -2;
+                break;
+              // Range contains weekend
+              case (dayMark + mod) > 5:
+                adj = -2;
+                break;
+              default:
+                // Do nothing
+                break;
+            }
+          }
+          else if (dayDiff < 0) {
+            switch (true) {
+              // Range starts on Sat
+              case aDay == 6:
+                adj = 0;
+                break;
+              // Range starts on Sun
+              case aDay == 0:
+                adj = 1;
+                break;
+              // Range ends on Sat
+              case bDay == 6:
+                adj = 2;
+                break;
+              // Range ends on Sun
+              case bDay == 0:
+                adj = 1;
+                break;
+              // Range contains weekend
+              case (dayMark + mod) < 0:
+                adj = 2;
+                break;
+              default:
+                // Do nothing
+                break;
+            }
+          }
+          days += adj;
+          days -= (weeks*2);
+        }
+        delta = days;
+
+        break;
+      case dateParts.HOUR:
+        delta = houDiff;
+        break;
+      case dateParts.MINUTE:
+        delta = minDiff;
+        break;
+      case dateParts.SECOND:
+        delta = secDiff;
+        break;
+      case dateParts.MILLISECOND:
+        delta = msDiff;
+        break;
+      default:
+        // Do nothing
+        break;
+    }
+    // Round for fractional values and DST leaps
+    return Math.round(delta); // Number (integer)
+  };
+
+  /**
+    @name date#parse
+    @public
+    @function
+    @return {Date} a JavaScript Date object
+    @description Convert various sorts of strings to JavaScript
+                 Date objects
+    @param {String} val The string to convert to a Date
+  */
+  this.parse = function (val) {
+    var dt
+      , matches
+      , reordered
+      , off
+      , posOff
+      , offHours
+      , offMinutes
+      , offSeconds
+      , curr
+      , stamp
+      , utc;
+
+    // Yay, we have a date, use it as-is
+    if (val instanceof Date || typeof val.getFullYear == 'function') {
+      dt = val;
+    }
+
+    // Timestamp?
+    else if (typeof val == 'number') {
+      dt = new Date(val);
+    }
+
+    // String or Array
+    else {
+      // Value preparsed, looks like [yyyy, mo, dd, hh, mi, ss, ms, (offset?)]
+      if (_isArray(val)) {
+        matches = val;
+        matches.unshift(null);
+        matches[8] = null;
+      }
+
+      // Oh, crap, it's a string -- parse this bitch
+      else if (typeof val == 'string') {
+        matches = val.match(_DATETIME_PAT);
+
+        // Stupid US-only format?
+        if (!matches) {
+          matches = val.match(_US_DATE_PAT);
+          if (matches) {
+            reordered = [matches[0], matches[3], matches[1], matches[2]];
+            // Pad the results to the same length as ISO8601
+            reordered[8] = null;
+            matches = reordered;
+          }
+        }
+
+        // Time-stored-in-Date hack?
+        if (!matches) {
+          matches = val.match(_TIME_PAT);
+          if (matches) {
+            reordered = [matches[0], 0, 1, 0, matches[1],
+                matches[2], matches[3], matches[4], null];
+            matches = reordered;
+          }
+        }
+
+      }
+
+      // Sweet, the regex actually parsed it into something useful
+      if (matches) {
+        matches.shift(); // First match is entire match, DO NOT WANT
+
+        off = matches.pop();
+        // If there's an offset (or the 'Z' non-offset offset), use UTC
+        // methods to set everything
+        if (off) {
+          if (off == 'Z') {
+            utc = true;
+            offSeconds = 0;
+          }
+          else {
+            utc = false;
+            // Convert from extended to basic if necessary
+            off = off.replace(/:/g, '');
+            // '+0000' will still be zero
+            if (parseInt(off, 10) === 0) {
+              utc = true;
+            }
+            else {
+              posOff = off.indexOf('+') === 0;
+              // Strip plus or minus
+              off = off.substr(1);
+
+              offHours = parseInt(off.substr(0, 2), 10);
+
+              offMinutes = off.substr(2, 2);
+              if (offMinutes) {
+                offMinutes = parseInt(offMinutes, 10);
+              }
+              else {
+                offMinutes = 0;
+              }
+
+              offSeconds = off.substr(4, 2);
+              if (offSeconds) {
+                offSeconds = parseInt(offSeconds, 10);
+              }
+              else {
+                offSeconds = 0;
+              }
+
+              offSeconds += (offMinutes * 60)
+              offSeconds += (offHours * 60 * 60);
+              if (!posOff) {
+                offSeconds = 0 - offSeconds;
+              }
+            }
+          }
+        }
+
+        dt = new Date(0);
+
+        // Stupid zero-based months
+        matches[1] = parseInt(matches[1], 10) - 1;
+
+        // Specific offset, iterate the array and set each date property
+        // using UTC setters, then adjust time using offset
+        if (off) {
+          for (var i = matches.length - 1; i > -1; i--) {
+            curr = parseInt(matches[i], 10) || 0;
+            dt['setUTC' + _dateMethods[i]](curr);
+          }
+          // Add any offset
+          dt.setSeconds(dt.getSeconds() - offSeconds);
+        }
+        // Otherwise we know nothing about the offset, just iterate the
+        // array and set each date property using regular setters
+        else {
+          for (var i = matches.length - 1; i > -1; i--) {
+            curr = parseInt(matches[i], 10) || 0;
+            dt['set' + _dateMethods[i]](curr);
+          }
+        }
+      }
+
+      // Shit, last-ditch effort using Date.parse
+      else {
+        stamp = Date.parse(val);
+        // Failures to parse yield NaN
+        if (!isNaN(stamp)) {
+          dt = new Date(stamp);
+        }
+      }
+
+    }
+
+    return dt || null;
+  };
+
+  /**
+    @name date#relativeTime
+    @public
+    @function
+    @return {String} A string describing the amount of time ago
+    the passed-in Date is
+    @description Convert a Date to an English sentence representing
+    how long ago the Date was
+    @param {Date} dt The Date to to convert to a relative time string
+    @param {Object} [opts]
+      @param {Boolean} [opts.abbreviated=false] Use short strings
+      (e.g., '<1m') for the relative-time string
+  */
+  this.relativeTime = function (dt, options) {
+    var opts = options || {}
+      , now = opts.now || new Date()
+      , abbr = opts.abbreviated || false
+      , format = opts.format || '%F %T'
+    // Diff in seconds
+      , diff = (now.getTime() - dt.getTime()) / 1000
+      , ret
+      , num
+      , hour = 60*60
+      , day = 24*hour
+      , week = 7*day
+      , month = 30*day;
+    switch (true) {
+      case diff < 60:
+        ret = abbr ? '<1m' : 'less than a minute ago';
+        break;
+      case diff < 120:
+        ret = abbr ? '1m' : 'about a minute ago';
+        break;
+      case diff < (45*60):
+        num = parseInt((diff / 60), 10);
+        ret = abbr ? num + 'm' : num + ' minutes ago';
+        break;
+      case diff < (2*hour):
+        ret = abbr ? '1h' : 'about an hour ago';
+        break;
+      case diff < (1*day):
+        num = parseInt((diff / hour), 10);
+        ret = abbr ? num + 'h' : 'about ' + num + ' hours ago';
+        break;
+      case diff < (2*day):
+        ret = abbr ? '1d' : 'one day ago';
+        break;
+      case diff < (7*day):
+        num = parseInt((diff / day), 10);
+        ret = abbr ? num + 'd' : 'about ' + num + ' days ago';
+        break;
+      case diff < (11*day):
+        ret = abbr ? '1w': 'one week ago';
+        break;
+      case diff < (1*month):
+        num = Math.round(diff / week);
+        ret = abbr ? num + 'w' : 'about ' + num + ' weeks ago';
+        break;
+      default:
+        ret = date.strftime(dt, format);
+        break;
+    }
+    return ret;
+  };
+
+  /**
+    @name date#toISO8601
+    @public
+    @function
+    @return {String} A string describing the amount of time ago
+    @description Convert a Date to an ISO8601-formatted string
+    @param {Date} dt The Date to to convert to an ISO8601 string
+  */
+  var _pad = function (n) {
+    return n < 10 ? '0' + n : n;
+  };
+  this.toISO8601 = function (dt, options) {
+    var opts = options || {}
+      , off = dt.getTimezoneOffset()
+      , offHours
+      , offMinutes
+      , str = this.strftime(dt, '%F') + 'T'
+          + this.strftime(dt, '%T') + '.'
+          + string.lpad(dt.getMilliseconds(), '0', 3);
+
+    if (opts.tz) {
+      // Pos and neg numbers are both truthy; only
+      // zero is falsy
+      if (off && !opts.utc) {
+        str += off > 0 ? '-' : '+';
+        offHours = parseInt(off / 60, 10);
+        str += string.lpad(offHours, '0', 2);
+        offMinutes = off % 60;
+        if (offMinutes) {
+          str += string.lpad(offMinutes, '0', 2);
+        }
+      }
+      else {
+        str += 'Z';
+      }
+    }
+
+    return str;
+  };
+
+  // Alias
+  this.toIso8601 = this.toISO8601;
+
+  this.toUTC = function (dt) {
+    return new Date(
+        dt.getUTCFullYear()
+      , dt.getUTCMonth()
+      , dt.getUTCDate()
+      , dt.getUTCHours()
+      , dt.getUTCMinutes()
+      , dt.getUTCSeconds()
+      , dt.getUTCMilliseconds());
+  };
+
+})();
+
+module.exports = date;
+
+

+ 109 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/event_buffer.js

@@ -0,0 +1,109 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+/*
+This is a very simple buffer for a predetermined set of events. It is unbounded.
+It forwards all arguments to any outlet emitter attached with sync().
+
+Example:
+    var source = new Stream()
+      , dest = new EventEmitter()
+      , buff = new EventBuffer(source)
+      , data = '';
+    dest.on('data', function (d) { data += d; });
+    source.writeable = true;
+    source.readable = true;
+    source.emit('data', 'abcdef');
+    source.emit('data', '123456');
+    buff.sync(dest);
+*/
+
+/**
+  @name EventBuffer
+  @namespace EventBuffer
+  @constructor
+*/
+
+var EventBuffer = function (src, events) {
+  // By default, we service the default stream events
+  var self = this
+    , streamEvents = ['data', 'end', 'error', 'close', 'fd', 'drain', 'pipe'];
+  this.events = events || streamEvents;
+  this.emitter = src;
+  this.eventBuffer = [];
+  this.outlet = null;
+  this.events.forEach(function (name) {
+    self.emitter.addListener(name, function () {
+      self.proxyEmit(name, arguments);
+    });
+  });
+};
+
+EventBuffer.prototype = new (function () {
+  /**
+    @name EventBuffer#proxyEmit
+    @public
+    @function
+    @description Emit an event by name and arguments or add it to the buffer if
+                 no outlet is set
+    @param {String} name The name to use for the event
+    @param {Array} args An array of arguments to emit
+  */
+  this.proxyEmit = function (name, args) {
+    if (this.outlet) {
+      this.emit(name, args);
+    }
+    else {
+      this.eventBuffer.push({name: name, args: args});
+    }
+  };
+
+  /**
+    @name EventBuffer#emit
+    @public
+    @function
+    @description Emit an event by name and arguments
+    @param {String} name The name to use for the event
+    @param {Array} args An array of arguments to emit
+  */
+  this.emit = function (name, args) {
+    // Prepend name to args
+    var outlet = this.outlet;
+    Array.prototype.splice.call(args, 0, 0, name);
+    outlet.emit.apply(outlet, args);
+  };
+
+  /**
+    @name EventBuffer#sync
+    @public
+    @function
+    @description Flush the buffer and continue piping new events to the outlet
+    @param {Object} outlet The emitter to send events to
+  */
+  this.sync = function (outlet) {
+    var buffer = this.eventBuffer
+      , bufferItem;
+    this.outlet = outlet;
+    while ((bufferItem = buffer.shift())) {
+      this.emit(bufferItem.name, bufferItem.args);
+    }
+  };
+})();
+EventBuffer.prototype.constructor = EventBuffer;
+
+module.exports.EventBuffer = EventBuffer;

+ 557 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/file.js

@@ -0,0 +1,557 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+var fs = require('fs')
+  , path = require('path')
+  , DEFAULT_INCLUDE_PAT = /\.(js|coffee|css|less|scss)$/
+  , DEFAULT_EXCLUDE_PAT = /\.git|node_modules/
+  , logger;
+
+var logger = new (function () {
+  var out;
+  try {
+    out = require('./log');
+  }
+  catch (e) {
+    out = console;
+  }
+
+  this.log = function (o) {
+    out.log(o);
+  };
+})();
+
+/**
+  @name file
+  @namespace file
+*/
+
+var fileUtils = new (function () {
+  var _copyFile
+    , _copyDir
+    , _readDir
+    , _rmDir
+    , _watch;
+
+
+  // Recursively copy files and directories
+  _copyFile = function (fromPath, toPath, opts) {
+    var from = path.normalize(fromPath)
+      , to = path.normalize(toPath)
+      , options = opts || {}
+      , fromStat
+      , toStat
+      , destExists
+      , destDoesNotExistErr
+      , content
+      , filename
+      , dirContents
+      , targetDir;
+
+    fromStat = fs.statSync(from);
+
+    try {
+      //console.dir(to + ' destExists');
+      toStat = fs.statSync(to);
+      destExists = true;
+    }
+    catch(e) {
+      //console.dir(to + ' does not exist');
+      destDoesNotExistErr = e;
+      destExists = false;
+    }
+    // Destination dir or file exists, copy into (directory)
+    // or overwrite (file)
+    if (destExists) {
+
+      // If there's a rename-via-copy file/dir name passed, use it.
+      // Otherwise use the actual file/dir name
+      filename = options.rename || path.basename(from);
+
+      // Copying a directory
+      if (fromStat.isDirectory()) {
+        dirContents = fs.readdirSync(from);
+        targetDir = path.join(to, filename);
+        // We don't care if the target dir already exists
+        try {
+          fs.mkdirSync(targetDir, options.mode || 0755);
+        }
+        catch(e) {
+          if (e.code != 'EEXIST') {
+            throw e;
+          }
+        }
+        for (var i = 0, ii = dirContents.length; i < ii; i++) {
+          //console.log(dirContents[i]);
+          _copyFile(path.join(from, dirContents[i]), targetDir);
+        }
+      }
+      // Copying a file
+      else {
+        content = fs.readFileSync(from);
+        // Copy into dir
+        if (toStat.isDirectory()) {
+          //console.log('copy into dir ' + to);
+          fs.writeFileSync(path.join(to, filename), content);
+        }
+        // Overwrite file
+        else {
+          //console.log('overwriting ' + to);
+          fs.writeFileSync(to, content);
+        }
+      }
+    }
+    // Dest doesn't exist, can't create it
+    else {
+      throw destDoesNotExistErr;
+    }
+  };
+
+  _copyDir = function (from, to, opts) {
+    var createDir = opts.createDir;
+  };
+
+  // Return the contents of a given directory
+  _readDir = function (dirPath) {
+    var dir = path.normalize(dirPath)
+      , paths = []
+      , ret = [dir]
+      , msg;
+
+    try {
+      paths = fs.readdirSync(dir);
+    }
+    catch (e) {
+      msg = 'Could not read path ' + dir + '\n';
+      if (e.stack) {
+        msg += e.stack;
+      }
+      throw new Error(msg);
+    }
+
+    paths.forEach(function (p) {
+      var curr = path.join(dir, p);
+      var stat = fs.statSync(curr);
+      if (stat.isDirectory()) {
+        ret = ret.concat(_readDir(curr));
+      }
+      else {
+        ret.push(curr);
+      }
+    });
+
+    return ret;
+  };
+
+  // Remove the given directory
+  _rmDir = function (dirPath) {
+    var dir = path.normalize(dirPath)
+      , paths = [];
+    paths = fs.readdirSync(dir);
+    paths.forEach(function (p) {
+      var curr = path.join(dir, p);
+      var stat = fs.statSync(curr);
+      if (stat.isDirectory()) {
+        _rmDir(curr);
+      }
+      else {
+        try {
+          fs.unlinkSync(curr);
+        } catch(e) {
+          if (e.code === 'EPERM') {
+            fs.chmodSync(curr, '0666');
+            fs.unlinkSync(curr);
+          } else {
+            throw e;
+          }
+        }
+      }
+    });
+    fs.rmdirSync(dir);
+  };
+
+  // Recursively watch files with a callback
+  _watch = function () {
+    var args = Array.prototype.slice.call(arguments)
+      , filePath
+      , opts
+      , callback
+      , inclPat
+      , exclPat
+      , createWatcher;
+
+    filePath = args.shift();
+    callback = args.pop();
+    opts = args.pop() || {};
+    inclPat = opts.includePattern || DEFAULT_INCLUDE_PAT;
+    exclPat = opts.excludePattern || DEFAULT_EXCLUDE_PAT;
+
+    opts.level = opts.level || 1;
+
+    createWatcher = function (watchPath) {
+      if (!exclPat.test(watchPath)) {
+        fs.watch(watchPath, function (ev, p) {
+          if (inclPat.test(p) && !exclPat.test(p)) {
+            callback(path.join(watchPath, p));
+          }
+        });
+      }
+    };
+
+    fs.stat(filePath, function (err, stats) {
+      if (err) {
+        return false;
+      }
+      // Watch files at the top level
+      if (stats.isFile() && opts.level == 1) {
+        createWatcher(filePath);
+        opts.level++;
+      }
+      else if (stats.isDirectory()) {
+        createWatcher(filePath);
+        opts.level++;
+        fs.readdir(filePath, function (err, files) {
+          if (err) {
+            return log.fatal(err);
+          }
+          for (var f in files) {
+            _watch(path.join(filePath, files[f]), opts, callback);
+          }
+        });
+      }
+    });
+  };
+
+  /**
+    @name file#cpR
+    @public
+    @function
+    @description Copies a directory/file to a destination
+    @param {String} fromPath The source path to copy from
+    @param {String} toPath The destination path to copy to
+    @param {Object} opts Options to use
+      @param {Boolean} [opts.silent] If false then will log the command
+  */
+  this.cpR = function (fromPath, toPath, options) {
+    var from = path.normalize(fromPath)
+      , to = path.normalize(toPath)
+      , toStat
+      , doesNotExistErr
+      , paths
+      , filename
+      , opts = options || {};
+
+    if (!opts.silent) {
+      logger.log('cp -r ' + fromPath + ' ' + toPath);
+    }
+
+    if (from == to) {
+      throw new Error('Cannot copy ' + from + ' to itself.');
+    }
+
+    // Handle rename-via-copy
+    try {
+      toStat = fs.statSync(to);
+    }
+    catch(e) {
+      doesNotExistErr = e;
+
+      // Get abs path so it's possible to check parent dir
+      if (!this.isAbsolute(to)) {
+        to = path.join(process.cwd() , to);
+      }
+
+      // Save the file/dir name
+      filename = path.basename(to);
+      // See if a parent dir exists, so there's a place to put the
+      /// renamed file/dir (resets the destination for the copy)
+      to = path.dirname(to);
+      try {
+        toStat = fs.statSync(to);
+      }
+      catch(e) {}
+      if (toStat && toStat.isDirectory()) {
+        // Set the rename opt to pass to the copy func, will be used
+        // as the new file/dir name
+        opts.rename = filename;
+        //console.log('filename ' + filename);
+      }
+      else {
+        throw doesNotExistErr;
+      }
+    }
+
+    _copyFile(from, to, opts);
+  };
+
+  /**
+    @name file#mkdirP
+    @public
+    @function
+    @description Create the given directory(ies) using the given mode permissions
+    @param {String} dir The directory to create
+    @param {Number} mode The mode to give the created directory(ies)(Default: 0755)
+  */
+  this.mkdirP = function (dir, mode) {
+    var dirPath = path.normalize(dir)
+      , paths = dirPath.split(/\/|\\/)
+      , currPath = ''
+      , next;
+
+    if (paths[0] == '' || /^[A-Za-z]+:/.test(paths[0])) {
+      currPath = paths.shift() || '/';
+      currPath = path.join(currPath, paths.shift());
+      //console.log('basedir');
+    }
+    while ((next = paths.shift())) {
+      if (next == '..') {
+        currPath = path.join(currPath, next);
+        continue;
+      }
+      currPath = path.join(currPath, next);
+      try {
+        //console.log('making ' + currPath);
+        fs.mkdirSync(currPath, mode || 0755);
+      }
+      catch(e) {
+        if (e.code != 'EEXIST') {
+          throw e;
+        }
+      }
+    }
+  };
+
+  /**
+    @name file#readdirR
+    @public
+    @function
+    @return {Array} Returns the contents as an Array, can be configured via opts.format
+    @description Reads the given directory returning it's contents
+    @param {String} dir The directory to read
+    @param {Object} opts Options to use
+      @param {String} [opts.format] Set the format to return(Default: Array)
+  */
+  this.readdirR = function (dir, opts) {
+    var options = opts || {}
+      , format = options.format || 'array'
+      , ret;
+    ret = _readDir(dir);
+    return format == 'string' ? ret.join('\n') : ret;
+  };
+
+  /**
+    @name file#rmRf
+    @public
+    @function
+    @description Deletes the given directory/file
+    @param {String} p The path to delete, can be a directory or file
+    @param {Object} opts Options to use
+      @param {String} [opts.silent] If false then logs the command
+  */
+  this.rmRf = function (p, options) {
+    var stat
+      , opts = options || {};
+    if (!opts.silent) {
+      logger.log('rm -rf ' + p);
+    }
+    try {
+      stat = fs.statSync(p);
+      if (stat.isDirectory()) {
+        _rmDir(p);
+      }
+      else {
+        fs.unlinkSync(p);
+      }
+    }
+    catch (e) {}
+  };
+
+  /**
+    @name file#isAbsolute
+    @public
+    @function
+    @return {Boolean/String} If it's absolute the first character is returned otherwise false
+    @description Checks if a given path is absolute or relative
+    @param {String} p Path to check
+  */
+  this.isAbsolute = function (p) {
+    var match = /^[A-Za-z]+:\\|^\//.exec(p);
+    if (match && match.length) {
+      return match[0];
+    }
+    return false;
+  };
+
+  /**
+    @name file#absolutize
+    @public
+    @function
+    @return {String} Returns the absolute path for the given path
+    @description Returns the absolute path for the given path
+    @param {String} p The path to get the absolute path for
+  */
+  this.absolutize = function (p) {
+    if (this.isAbsolute(p)) {
+      return p;
+    }
+    else {
+      return path.join(process.cwd(), p);
+    }
+  };
+
+  /**
+    Given a patern, return the base directory of it (ie. the folder
+    that will contain all the files matching the path).
+    eg. file.basedir('/test/**') => '/test/'
+    Path ending by '/' are considerd as folder while other are considerd
+    as files, eg.:
+        file.basedir('/test/a/') => '/test/a'
+        file.basedir('/test/a') => '/test'
+    The returned path always end with a '/' so we have:
+        file.basedir(file.basedir(x)) == file.basedir(x)
+  */
+  this.basedir = function (pathParam) {
+    var basedir = ''
+      , parts
+      , part
+      , pos = 0
+      , p = pathParam || '';
+
+    // If the path has a leading asterisk, basedir is the current dir
+    if (p.indexOf('*') == 0 || p.indexOf('**') == 0) {
+      return '.';
+    }
+
+    // always consider .. at the end as a folder and not a filename
+    if (/(?:^|\/|\\)\.\.$/.test(p.slice(-3))) {
+      p += '/';
+    }
+
+    parts = p.split(/\\|\//);
+    for (var i = 0, l = parts.length - 1; i < l; i++) {
+      part = parts[i];
+      if (part.indexOf('*') > -1 || part.indexOf('**') > -1) {
+        break;
+      }
+      pos += part.length + 1;
+      basedir += part + p[pos - 1];
+    }
+    if (!basedir) {
+      basedir = '.';
+    }
+    // Strip trailing slashes
+    if (!(basedir == '\\' || basedir == '/')) {
+      basedir = basedir.replace(/\\$|\/$/, '');
+    }
+    return basedir;
+
+  };
+
+  /**
+    @name file#searchParentPath
+    @public
+    @function
+    @description Search for a directory/file in the current directory and parent directories
+    @param {String} p The path to search for
+    @param {Function} callback The function to call once the path is found
+  */
+  this.searchParentPath = function (location, beginPath, callback) {
+    if (typeof beginPath === 'function' && !callback) {
+      callback = beginPath;
+      beginPath = process.cwd();
+    }
+    var cwd = beginPath || process.cwd();
+
+    if (!location) {
+      // Return if no path is given
+      return;
+    }
+    var relPath = ''
+      , i = 5 // Only search up to 5 directories
+      , pathLoc
+      , pathExists;
+
+    while (--i >= 0) {
+      pathLoc = path.join(cwd, relPath, location);
+      pathExists = this.existsSync(pathLoc);
+
+      if (pathExists) {
+        callback && callback(undefined, pathLoc);
+        break;
+      } else {
+        // Dir could not be found
+        if (i === 0) {
+          callback && callback(new Error("Path \"" + pathLoc + "\" not found"), undefined);
+          break;
+        }
+
+        // Add a relative parent directory
+        relPath += '../';
+        // Switch to relative parent directory
+        process.chdir(path.join(cwd, relPath));
+      }
+    }
+  };
+
+  /**
+    @name file#watch
+    @public
+    @function
+    @description Watch a given path then calls the callback once a change occurs
+    @param {String} path The path to watch
+    @param {Function} callback The function to call when a change occurs
+  */
+  this.watch = function () {
+    _watch.apply(this, arguments);
+  };
+
+  // Compatibility for fs.exists(0.8) and path.exists(0.6)
+  this.exists = (typeof fs.exists === 'function') ? fs.exists : path.exists;
+
+  // Compatibility for fs.existsSync(0.8) and path.existsSync(0.6)
+  this.existsSync = (typeof fs.existsSync === 'function') ? fs.existsSync : path.existsSync;
+
+  /**
+    @name file#requireLocal
+    @public
+    @function
+    @return {Object} The given module is returned
+    @description Require a local module from the node_modules in the current directory
+    @param {String} module The module to require
+    @param {String} message An option message to throw if the module doesn't exist
+  */
+  this.requireLocal = function (module, message) {
+    // Try to require in the application directory
+    try {
+      dep = require(path.join(process.cwd(), 'node_modules', module));
+    }
+    catch(err) {
+      if (message) {
+        throw new Error(message);
+      }
+      throw new Error('Module "' + module + '" could not be found as a ' +
+          'local module. Please install it by doing "npm install ' +
+          module + '"');
+    }
+    return dep;
+  };
+
+})();
+
+module.exports = fileUtils;
+

+ 73 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/i18n.js

@@ -0,0 +1,73 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+var core = require('./core')
+  , i18n;
+
+var DEFAULT_LOCALE = 'en-us';
+
+i18n = new (function () {
+  var _defaultLocale = DEFAULT_LOCALE
+    , _strings = {};
+
+  this.getText = function (key, opts, locale) {
+    var currentLocale = locale || _defaultLocale
+      , currentLocaleStrings = _strings[currentLocale] || {}
+      , defaultLocaleStrings = _strings[_defaultLocale] || {}
+      , str = currentLocaleStrings[key]
+            || defaultLocaleStrings[key] || "[[" + key + "]]";
+    for (p in opts) {
+      str = str.replace(new RegExp('\\{' + p + '\\}', 'g'), opts[p]);
+    }
+    return str;
+  };
+
+  this.getDefaultLocale = function () {
+    return _defaultLocale;
+  };
+
+  this.setDefaultLocale = function (locale) {
+    _defaultLocale = locale;
+  };
+
+  this.loadLocale = function (locale, strings) {
+    _strings[locale] = _strings[locale] || {};
+    core.mixin(_strings[locale], strings);
+  };
+
+})();
+
+i18n.I18n = function (locale) {
+  var _locale = locale || i18n.getDefaultLocale();
+
+  this.getLocale = function (locale) {
+    return _locale;
+  };
+
+  this.setLocale = function (locale) {
+    _locale = locale;
+  };
+
+  this.getText = function (key, opts, locale) {
+    return i18n.getText(key,
+        opts || {}, locale || _locale);
+  };
+  this.t = this.getText;
+};
+
+module.exports = i18n;
+

+ 59 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/index.js

@@ -0,0 +1,59 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+var utils = {}
+// Core methods
+  , core = require('./core')
+// Namespaces with methods
+  , string = require('./string')
+  , file = require('./file')
+  , async = require('./async')
+  , i18n = require('./i18n')
+  , uri = require('./uri')
+  , array = require('./array')
+  , object = require('./object')
+  , date = require('./date')
+  , request = require('./request')
+  , log = require('./log')
+  , network = require('./network')
+// Third-party -- remove this if possible
+  , inflection = require('./inflection')
+// Constructors
+  , EventBuffer = require('./event_buffer').EventBuffer
+  , XML = require('./xml').XML
+  , SortedCollection = require('./sorted_collection').SortedCollection;
+
+core.mixin(utils, core);
+
+utils.string = string;
+utils.file = file;
+utils.async = async;
+utils.i18n = i18n;
+utils.uri = uri;
+utils.array = array;
+utils.object = object;
+utils.date = date;
+utils.request = request;
+utils.log = log;
+utils.network = network;
+utils.inflection = inflection;
+utils.SortedCollection = SortedCollection;
+utils.EventBuffer = EventBuffer;
+utils.XML = XML;
+
+module.exports = utils;
+

+ 222 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/inflection.js

@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2010 George Moschovitis, http://www.gmosx.com
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * A port of the Rails/ActiveSupport Inflector class
+ * http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html
+*/
+
+/**
+  @name inflection
+  @namespace inflection
+*/
+
+var inflection = new (function () {
+
+  /**
+    @name inflection#inflections
+    @public
+    @object
+    @description A list of rules and replacements for different inflection types
+  */
+  this.inflections = {
+      plurals: []
+    , singulars: []
+    , uncountables: []
+  };
+
+  var self = this
+    , setInflection
+    , setPlural
+    , setSingular
+    , setUncountable
+    , setIrregular;
+
+  // Add a new inflection rule/replacement to the beginning of the array for the
+  // inflection type
+  setInflection = function (type, rule, replacement) {
+    self.inflections[type].unshift([rule, replacement]);
+  };
+
+  // Add a new plural inflection rule
+  setPlural = function (rule, replacement) {
+    setInflection('plurals', rule, replacement);
+  };
+
+  // Add a new singular inflection rule
+  setSingular = function (rule, replacement) {
+    setInflection('singulars', rule, replacement);
+  };
+
+  // Add a new irregular word to the inflection list, by a given singular and plural inflection
+  setIrregular = function (singular, plural) {
+    if (singular.substr(0, 1).toUpperCase() == plural.substr(0, 1).toUpperCase()) {
+      setPlural(new RegExp("(" + singular.substr(0, 1) + ")" + singular.substr(1) + "$", "i"),
+        '$1' + plural.substr(1));
+      setPlural(new RegExp("(" + plural.substr(0, 1) + ")" + plural.substr(1) + "$", "i"),
+        '$1' + plural.substr(1));
+      setSingular(new RegExp("(" + plural.substr(0, 1) + ")" + plural.substr(1) + "$", "i"),
+        '$1' + singular.substr(1));
+    } else {
+      setPlural(new RegExp(singular.substr(0, 1).toUpperCase() + singular.substr(1) + "$"),
+        plural.substr(0, 1).toUpperCase() + plural.substr(1));
+      setPlural(new RegExp(singular.substr(0, 1).toLowerCase() + singular.substr(1) + "$"),
+        plural.substr(0, 1).toLowerCase() + plural.substr(1));
+      setPlural(new RegExp(plural.substr(0, 1).toUpperCase() + plural.substr(1) + "$"),
+        plural.substr(0, 1).toUpperCase() + plural.substr(1));
+      setPlural(new RegExp(plural.substr(0, 1).toLowerCase() + plural.substr(1) + "$"),
+        plural.substr(0, 1).toLowerCase() + plural.substr(1));
+      setSingular(new RegExp(plural.substr(0, 1).toUpperCase() + plural.substr(1) + "$"),
+        singular.substr(0, 1).toUpperCase() + singular.substr(1));
+      setSingular(new RegExp(plural.substr(0, 1).toLowerCase() + plural.substr(1) + "$"),
+        singular.substr(0, 1).toLowerCase() + singular.substr(1));
+    }
+  };
+
+  // Add a new word to the uncountable inflection list
+  setUncountable = function (word) {
+    self.inflections.uncountables[word] = true;
+  };
+
+  // Create inflections
+  (function () {
+    setPlural(/$/, "s");
+    setPlural(/s$/i, "s");
+    setPlural(/(ax|test)is$/i, "$1es");
+    setPlural(/(octop|vir)us$/i, "$1i");
+    setPlural(/(alias|status)$/i, "$1es");
+    setPlural(/(bu)s$/i, "$1ses");
+    setPlural(/(buffal|tomat)o$/i, "$1oes");
+    setPlural(/([ti])um$/i, "$1a");
+    setPlural(/sis$/i, "ses");
+    setPlural(/(?:([^f])fe|([lr])f)$/i, "$1$2ves");
+    setPlural(/(hive)$/i, "$1s");
+    setPlural(/([^aeiouy]|qu)y$/i, "$1ies");
+    setPlural(/(x|ch|ss|sh)$/i, "$1es");
+    setPlural(/(matr|vert|ind)(?:ix|ex)$/i, "$1ices");
+    setPlural(/([m|l])ouse$/i, "$1ice");
+    setPlural(/^(ox)$/i, "$1en");
+    setPlural(/(quiz)$/i, "$1zes");
+
+    setSingular(/s$/i, "")
+		setSingular(/ss$/i, "ss")
+    setSingular(/(n)ews$/i, "$1ews")
+    setSingular(/([ti])a$/i, "$1um")
+    setSingular(/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i, "$1$2sis")
+    setSingular(/(^analy)ses$/i, "$1sis")
+    setSingular(/([^f])ves$/i, "$1fe")
+    setSingular(/(hive)s$/i, "$1")
+    setSingular(/(tive)s$/i, "$1")
+    setSingular(/([lr])ves$/i, "$1f")
+    setSingular(/([^aeiouy]|qu)ies$/i, "$1y")
+    setSingular(/(s)eries$/i, "$1eries")
+    setSingular(/(m)ovies$/i, "$1ovie")
+    setSingular(/(x|ch|ss|sh)es$/i, "$1")
+    setSingular(/([m|l])ice$/i, "$1ouse")
+    setSingular(/(bus)es$/i, "$1")
+    setSingular(/(o)es$/i, "$1")
+    setSingular(/(shoe)s$/i, "$1")
+    setSingular(/(cris|ax|test)es$/i, "$1is")
+    setSingular(/(octop|vir)i$/i, "$1us")
+    setSingular(/(alias|status)es$/i, "$1")
+    setSingular(/^(ox)en/i, "$1")
+    setSingular(/(vert|ind)ices$/i, "$1ex")
+    setSingular(/(matr)ices$/i, "$1ix")
+    setSingular(/(quiz)zes$/i, "$1")
+    setSingular(/(database)s$/i, "$1")
+
+    setIrregular("person", "people");
+    setIrregular("man", "men");
+    setIrregular("child", "children");
+    setIrregular("sex", "sexes");
+    setIrregular("move", "moves");
+    setIrregular("cow", "kine");
+
+    setUncountable("equipment");
+    setUncountable("information");
+    setUncountable("rice");
+    setUncountable("money");
+    setUncountable("species");
+    setUncountable("series");
+    setUncountable("fish");
+    setUncountable("sheep");
+    setUncountable("jeans");
+  })();
+
+  /**
+    @name inflection#parse
+    @public
+    @function
+    @return {String} The inflection of the word from the type given
+    @description Parse a word from the given inflection type
+    @param {String} type A type of the inflection to use
+    @param {String} word the word to parse
+  */
+  this.parse = function (type, word) {
+    var lowWord = word.toLowerCase()
+      , inflections = this.inflections[type];
+
+    if (this.inflections.uncountables[lowWord]) {
+      return word;
+    }
+
+    var i = -1;
+    while (++i < inflections.length) {
+      var rule = inflections[i][0]
+        , replacement = inflections[i][1];
+
+      if (rule.test(word)) {
+        return word.replace(rule, replacement)
+      }
+    }
+
+    return word;
+  };
+
+  /**
+    @name inflection#pluralize
+    @public
+    @function
+    @return {String} The plural inflection for the given word
+    @description Create a plural inflection for a word
+    @param {String} word the word to create a plural version for
+  */
+  this.pluralize = function (word) {
+    return this.parse('plurals', word);
+  };
+
+  /**
+    @name inflection#singularize
+    @public
+    @function
+    @return {String} The singular inflection for the given word
+    @description Create a singular inflection for a word
+    @param {String} word the word to create a singular version for
+  */
+  this.singularize = function (word) {
+    return this.parse('singulars', word);
+  };
+
+})();
+
+module.exports = inflection;

+ 69 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/log.js

@@ -0,0 +1,69 @@
+var util = require('util')
+  , log
+  , _logger
+  , _levels
+  , _serialize
+  , _output;
+
+_levels = {
+  'debug': 'log'
+, 'log' : 'log'
+, 'info': 'info'
+, 'notice': 'info'
+, 'warning': 'warn'
+, 'warn': 'warn'
+, 'error': 'error'
+, 'critical': 'error'
+, 'alert': 'error'
+, 'emergency': 'error'
+};
+
+_serialize = function (obj) {
+  var out;
+  if (typeof obj == 'string') {
+    out = obj;
+  }
+  else {
+    out = util.inspect(obj);
+  }
+  return out;
+};
+
+_output = function (obj, level) {
+  var out = _serialize(obj);
+  if (_logger) {
+    _logger[level](out);
+  }
+  else {
+    console[_levels[level]](out);
+  }
+};
+
+
+log = function (obj) {
+  _output(obj, 'info');
+};
+
+log.registerLogger = function (logger) {
+  // Malkovitch, Malkovitch
+  if (logger === log) {
+    return;
+  }
+  _logger = logger;
+};
+
+(function () {
+  var level;
+  for (var p in _levels) {
+    (function (p) {
+      level = _levels[p];
+      log[p] = function (obj) {
+        _output(obj, p);
+      };
+    })(p);
+  }
+  // Also handle 'access', not an actual level
+  log.access = log.info;
+})();
+
+module.exports = log;

+ 72 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/network.js

@@ -0,0 +1,72 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+var network
+	, net = require('net');
+
+/**
+  @name network
+  @namespace network
+*/
+
+network = new (function () {
+	/**
+		@name network#isPortOpen
+		@public
+		@function
+		@description Checks if the given port in the given host is open
+		@param {Number} port number
+		@param {String} host
+		@param {Function} callback Callback function -- should be in the format
+			of function(err, result) {}
+	*/
+	this.isPortOpen = function (port, host, callback) {
+		if (typeof host === 'function' && !callback) {
+			callback = host;
+			host = 'localhost';
+		}
+
+		var isOpen = false
+			, connection
+			, error;
+
+		connection = net.createConnection(port, host, function () {
+			isOpen = true;
+			connection.end();
+		});
+
+		connection.on('error', function (err) {
+			// We ignore 'ECONNREFUSED' as it simply indicates the port isn't open.
+			// Anything else is reported
+			if(err.code !== 'ECONNREFUSED') {
+				error = err;
+			}
+		});
+
+		connection.setTimeout(400, function () {
+			connection.end();
+		});
+
+		connection.on('close', function () {
+			callback && callback(error, isOpen);
+		});
+	};
+
+})();
+
+module.exports = network;

+ 108 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/object.js

@@ -0,0 +1,108 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+/**
+  @name object
+  @namespace object
+*/
+
+var object = new (function () {
+
+  /**
+    @name object#merge
+    @public
+    @function
+    @return {Object} Returns the merged object
+    @description Merge merges `otherObject` into `object` and takes care of deep
+                 merging of objects
+    @param {Object} object Object to merge into
+    @param {Object} otherObject Object to read from
+  */
+  this.merge = function (object, otherObject) {
+    var obj = object || {}
+      , otherObj = otherObject || {}
+      , key, value;
+
+    for (key in otherObj) {
+      value = otherObj[key];
+
+      // Check if a value is an Object, if so recursively add it's key/values
+      if (typeof value === 'object' && !(value instanceof Array)) {
+        // Update value of object to the one from otherObj
+        obj[key] = this.merge(obj[key], value);
+      }
+      // Value is anything other than an Object, so just add it
+      else {
+        obj[key] = value;
+      }
+    }
+
+    return obj;
+  };
+
+  /**
+    @name object#reverseMerge
+    @public
+    @function
+    @return {Object} Returns the merged object
+    @description ReverseMerge merges `object` into `defaultObject`
+    @param {Object} object Object to read from
+    @param {Object} defaultObject Object to merge into
+  */
+  this.reverseMerge = function (object, defaultObject) {
+    // Same as `merge` except `defaultObject` is the object being changed
+    // - this is useful if we want to easily deal with default object values
+    return this.merge(defaultObject, object);
+  };
+
+  /**
+    @name object#isEmpty
+    @public
+    @function
+    @return {Boolean} Returns true if empty false otherwise
+    @description isEmpty checks if an Object is empty
+    @param {Object} object Object to check if empty
+  */
+  this.isEmpty = function (object) {
+    // Returns true if a object is empty false if not
+    for (var i in object) { return false; }
+    return true;
+  };
+
+  /**
+    @name object#toArray
+    @public
+    @function
+    @return {Array} Returns an array of objects each including the original key and value
+    @description Converts an object to an array of objects each including the original key/value
+    @param {Object} object Object to convert
+  */
+  this.toArray = function (object) {
+    // Converts an object into an array of objects with the original key, values
+    array = [];
+
+    for (var i in object) {
+      array.push({ key: i, value: object[i] });
+    }
+
+    return array;
+  };
+
+})();
+
+module.exports = object;

+ 143 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/request.js

@@ -0,0 +1,143 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+var http = require('http')
+  , https = require('https')
+  , url = require('url')
+  , uri = require('./uri')
+  , log = require('./log')
+  , core = require('./core');
+
+var formatters = {
+  xml: function (data) {
+    return data;
+  }
+, html: function (data) {
+    return data;
+  }
+, txt: function (data) {
+    return data;
+  }
+, json: function (data) {
+    return JSON.parse(data);
+  }
+}
+
+/**
+  @name request
+  @namespace request
+  @public
+  @function
+  @description Sends requests to the given url sending any data if the method is POST or PUT
+  @param {Object} opts The options to use for the request
+    @param {String} [opts.url] The URL to send the request to
+    @param {String} [opts.method=GET] The method to use for the request
+    @param {Object} [opts.headers] Headers to send on requests
+    @param {String} [opts.data] Data to send on POST and PUT requests
+    @param {String} [opts.dataType] The type of data to send
+  @param {Function} callback the function to call after, args are `error, data`
+*/
+var request = function (opts, callback) {
+  var client
+    , options = opts || {}
+    , parsed = url.parse(options.url)
+    , path
+    , requester = parsed.protocol == 'http:' ? http : https
+    , method = (options.method && options.method.toUpperCase()) || 'GET'
+    , headers = core.mixin({}, options.headers || {})
+    , contentLength
+    , port
+    , clientOpts;
+
+  if (parsed.port) {
+    port = parsed.port;
+  }
+  else {
+    port = parsed.protocol == 'http:' ? '80' : '443';
+  }
+
+  path = parsed.pathname;
+  if (parsed.search) {
+    path += parsed.search;
+  }
+
+  if (method == 'POST' || method == 'PUT') {
+    if (options.data) {
+      contentLength = options.data.length;
+    }
+    else {
+      contentLength = 0
+    }
+    headers['Content-Length'] = contentLength;
+  }
+
+  clientOpts = {
+    host: parsed.hostname
+  , port: port
+  , method: method
+  , agent: false
+  , path: path
+  , headers: headers
+  };
+  client = requester.request(clientOpts);
+
+  client.addListener('response', function (resp) {
+    var data = ''
+      , dataType;
+    resp.addListener('data', function (chunk) {
+      data += chunk.toString();
+    });
+    resp.addListener('end', function () {
+      var stat = resp.statusCode
+        , err;
+      // Successful response
+      if ((stat > 199 && stat < 300) || stat == 304) {
+        dataType = options.dataType || uri.getFileExtension(parsed.pathname);
+        if (formatters[dataType]) {
+          try {
+            if (data) {
+              data = formatters[dataType](data);
+            }
+          }
+          catch (e) {
+            callback(e, null);
+          }
+        }
+        callback(null, data);
+      }
+      // Something failed
+      else {
+        err = new Error(data);
+        err.statusCode = resp.statusCode;
+        callback(err, null);
+      }
+
+    });
+  });
+
+  client.addListener('error', function (e) {
+    callback(e, null);
+  });
+
+  if ((method == 'POST' || method == 'PUT') && options.data) {
+    client.write(options.data);
+  }
+
+  client.end();
+};
+
+module.exports = request;

+ 558 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/sorted_collection.js

@@ -0,0 +1,558 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+/**
+  @name SortedCollection
+  @namespace SortedCollection
+  @constructor
+*/
+
+var SortedCollection = function (d) {
+  this.count = 0;
+  this.items = {}; // Hash keys and their values
+  this.order = []; // Array for sort order
+  if (d) {
+    this.defaultValue = d;
+  };
+};
+
+SortedCollection.prototype = new (function () {
+  /**
+    @name SortedCollection#addItem
+    @public
+    @function
+    @return {Any} The given val is returned
+    @description Adds a new key/value to the collection
+    @param {String} key The key for the collection item
+    @param {Any} val The value for the collection item
+  */
+  this.addItem = function (key, val) {
+    if (typeof key != 'string') {
+      throw('Hash only allows string keys.');
+    }
+    return this.setByKey(key, val);
+  };
+
+  /**
+    @name SortedCollection#getItem
+    @public
+    @function
+    @return {Any} The value for the given identifier is returned
+    @description Retrieves the value for the given identifier that being a key or index
+    @param {String/Number} p The identifier to look in the collection for, being a key or index
+  */
+  this.getItem = function (p) {
+    if (typeof p == 'string') {
+      return this.getByKey(p);
+    }
+    else if (typeof p == 'number') {
+      return this.getByIndex(p);
+    }
+  };
+
+  /**
+    @name SortedCollection#setItem
+    @public
+    @function
+    @return {Any} The given val is returned
+    @description Sets the item in the collection with the given val, overwriting the existsing item
+      if identifier is an index
+    @param {String/Number} p The identifier set in the collection, being either a key or index
+    @param {Any} val The value for the collection item
+  */
+  this.setItem = function (p, val) {
+    if (typeof p == 'string') {
+      return this.setByKey(p, val);
+    }
+    else if (typeof p == 'number') {
+      return this.setByIndex(p, val);
+    }
+  };
+
+  /**
+    @name SortedCollection#removeItem
+    @public
+    @function
+    @return {Boolean} Returns true if the item has been removed, false otherwise
+    @description Removes the item for the given identifier
+    @param {String/Number} p The identifier to delete the item for, being a key or index
+  */
+  this.removeItem = function (p) {
+    if (typeof p == 'string') {
+      return this.removeByKey(p);
+    }
+    else if (typeof p == 'number') {
+      return this.removeByIndex(p);
+    }
+  };
+
+  /**
+    @name SortedCollection#getByKey
+    @public
+    @function
+    @return {Any} The value for the given key item is returned
+    @description Retrieves the value for the given key
+    @param {String} key The key for the item to lookup
+  */
+  this.getByKey = function (key) {
+    return this.items[key];
+  };
+
+  /**
+    @name SortedCollection#setByKey
+    @public
+    @function
+    @return {Any} The given val is returned
+    @description Sets a item by key assigning the given val
+    @param {String} key The key for the item
+    @param {Any} val The value to set for the item
+  */
+  this.setByKey = function (key, val) {
+    var v = null;
+    if (typeof val == 'undefined') {
+      v = this.defaultValue;
+    }
+    else { v = val; }
+    if (typeof this.items[key] == 'undefined') {
+      this.order[this.count] = key;
+      this.count++;
+    }
+    this.items[key] = v;
+    return this.items[key];
+  };
+
+  /**
+    @name SortedCollection#removeByKey
+    @public
+    @function
+    @return {Boolean} If the item was removed true is returned, false otherwise
+    @description Removes a collection item by key
+    @param {String} key The key for the item to remove
+  */
+  this.removeByKey = function (key) {
+    if (typeof this.items[key] != 'undefined') {
+      var pos = null;
+      delete this.items[key]; // Remove the value
+      // Find the key in the order list
+      for (var i = 0; i < this.order.length; i++) {
+        if (this.order[i] == key) {
+          pos = i;
+        }
+      }
+      this.order.splice(pos, 1); // Remove the key
+      this.count--; // Decrement the length
+      return true;
+    }
+    else {
+      return false;
+    }
+  };
+
+  /**
+    @name SortedCollection#getByIndex
+    @public
+    @function
+    @return {Any} The value for the given index item is returned
+    @description Retrieves the value for the given index
+    @param {Number} ind The index to lookup for the item
+  */
+  this.getByIndex = function (ind) {
+    return this.items[this.order[ind]];
+  };
+
+  /**
+    @name SortedCollection#setByIndex
+    @public
+    @function
+    @return {Any} The given val is returned
+    @description Sets a item by index assigning the given val
+    @param {Number} ind The index for the item
+    @param {Any} val The value to set for the item
+  */
+  this.setByIndex = function (ind, val) {
+    if (ind < 0 || ind >= this.count) {
+      throw('Index out of bounds. Hash length is ' + this.count);
+    }
+    this.items[this.order[ind]] = val;
+    return this.items[this.order[ind]];
+  };
+
+  /**
+    @name SortedCollection#removeByIndex
+    @public
+    @function
+    @return {Boolean} If the item was removed true is returned, false otherwise
+    @description Removes a collection item by index
+    @param {Number} ind The index for the item to remove
+  */
+  this.removeByIndex = function (ind) {
+    var ret = this.items[this.order[ind]];
+    if (typeof ret != 'undefined') {
+      delete this.items[this.order[ind]]
+      this.order.splice(ind, 1);
+      this.count--;
+      return true;
+    }
+    else {
+      return false;
+    }
+  };
+
+  /**
+    @name SortedCollection#hasKey
+    @public
+    @function
+    @return {Boolean} Returns true if the item exists, false otherwise
+    @description Checks if a key item exists in the collection
+    @param {String} key The key to look for in the collection
+  */
+  this.hasKey = function (key) {
+    return typeof this.items[key] != 'undefined';
+  };
+
+  /**
+    @name SortedCollection#hasValue
+    @public
+    @function
+    @return {Boolean} Returns true if a key with the given value exists, false otherwise
+    @description Checks if a key item in the collection has a given val
+    @param {Any} val The value to check for in the collection
+  */
+  this.hasValue = function (val) {
+    for (var i = 0; i < this.order.length; i++) {
+      if (this.items[this.order[i]] == val) {
+        return true;
+      }
+    }
+    return false;
+  };
+
+  /**
+    @name SortedCollection#allKeys
+    @public
+    @function
+    @return {String} Returns all the keys in a string
+    @description Joins all the keys into a string
+    @param {String} str The string to use between each key
+  */
+  this.allKeys = function (str) {
+    return this.order.join(str);
+  };
+
+  /**
+    @name SortedCollection#replaceKey
+    @public
+    @function
+    @description Joins all the keys into a string
+    @param {String} oldKey The key item to change
+    @param {String} newKey The key item to change the name to
+  */
+  this.replaceKey = function (oldKey, newKey) {
+    // If item for newKey exists, nuke it
+    if (this.hasKey(newKey)) {
+      this.removeItem(newKey);
+    }
+    this.items[newKey] = this.items[oldKey];
+    delete this.items[oldKey];
+    for (var i = 0; i < this.order.length; i++) {
+      if (this.order[i] == oldKey) {
+        this.order[i] = newKey;
+      }
+    }
+  };
+
+  /**
+    @name SortedCollection#insertAtIndex
+    @public
+    @function
+    @return {Boolean} Returns true if the item was set at the given index
+    @description Inserts a key/value at a specific index in the collection
+    @param {Number} ind The index to set the item at
+    @param {String} key The key to use at the item index
+    @param {Any} val The value to set for the item
+  */
+  this.insertAtIndex = function (ind, key, val) {
+    this.order.splice(ind, 0, key);
+    this.items[key] = val;
+    this.count++;
+    return true;
+  };
+
+  /**
+    @name SortedCollection#insertAfterKey
+    @public
+    @function
+    @return {Boolean} Returns true if the item was set for the given key
+    @description Inserts a key/value item after the given reference key in the collection
+    @param {String} refKey The key to insert the new item after
+    @param {String} key The key for the new item
+    @param {Any} val The value to set for the item
+  */
+  this.insertAfterKey = function (refKey, key, val) {
+    var pos = this.getPosition(refKey);
+    return this.insertAtIndex(pos, key, val);
+  };
+
+  /**
+    @name SortedCollection#getPosition
+    @public
+    @function
+    @return {Number} Returns the index for the item of the given key
+    @description Retrieves the index of the key item
+    @param {String} key The key to get the index for
+  */
+  this.getPosition = function (key) {
+    var order = this.order;
+    if (typeof order.indexOf == 'function') {
+      return order.indexOf(key);
+    }
+    else {
+      for (var i = 0; i < order.length; i++) {
+        if (order[i] == key) { return i;}
+      }
+    }
+  };
+
+  /**
+    @name SortedCollection#each
+    @public
+    @function
+    @return {Boolean}
+    @description Loops through the collection and calls the given function
+    @param {Function} func The function to call for each collection item, the arguments
+      are the key and value for the current item
+    @param {Object} opts The options to use
+      @param {Boolean} [opts.keyOnly] Only give the function the key
+      @param {Boolean} [opts.valueOnly] Only give the function the value
+  */
+  this.each = function (func, opts) {
+    var options = opts || {}
+      , order = this.order;
+    for (var i = 0, ii = order.length; i < ii; i++) {
+      var key = order[i];
+      var val = this.items[key];
+      if (options.keyOnly) {
+        func(key);
+      }
+      else if (options.valueOnly) {
+        func(val);
+      }
+      else {
+        func(val, key);
+      }
+    }
+    return true;
+  };
+
+  /**
+    @name SortedCollection#eachKey
+    @public
+    @function
+    @return {Boolean}
+    @description Loops through the collection and calls the given function
+    @param {Function} func The function to call for each collection item, only giving the
+      key to the function
+  */
+  this.eachKey = function (func) {
+    return this.each(func, { keyOnly: true });
+  };
+
+  /**
+    @name SortedCollection#eachValue
+    @public
+    @function
+    @return {Boolean}
+    @description Loops through the collection and calls the given function
+    @param {Function} func The function to call for each collection item, only giving the
+      value to the function
+  */
+  this.eachValue = function (func) {
+    return this.each(func, { valueOnly: true });
+  };
+
+  /**
+    @name SortedCollection#clone
+    @public
+    @function
+    @return {Object} Returns a new SortedCollection with the data of the current one
+    @description Creates a cloned version of the current collection and returns it
+  */
+  this.clone = function () {
+    var coll = new SortedCollection()
+      , key
+      , val;
+    for (var i = 0; i < this.order.length; i++) {
+      key = this.order[i];
+      val = this.items[key];
+      coll.setItem(key, val);
+    }
+    return coll;
+  };
+
+  /**
+    @name SortedCollection#concat
+    @public
+    @function
+    @description Join a given collection with the current one
+    @param {Object} hNew A SortedCollection to join from
+  */
+  this.concat = function (hNew) {
+    for (var i = 0; i < hNew.order.length; i++) {
+      var key = hNew.order[i];
+      var val = hNew.items[key];
+      this.setItem(key, val);
+    }
+  };
+
+  /**
+    @name SortedCollection#push
+    @public
+    @function
+    @return {Number} Returns the count of items
+    @description Appends a new item to the collection
+    @param {String} key The key to use for the item
+    @param {Any} val The value to use for the item
+  */
+  this.push = function (key, val) {
+    this.insertAtIndex(this.count, key, val);
+    return this.count;
+  };
+
+  /**
+    @name SortedCollection#pop
+    @public
+    @function
+    @return {Any} Returns the value for the last item in the collection
+    @description Pops off the last item in the collection and returns it's value
+  */
+  this.pop = function () {
+    var pos = this.count-1;
+    var ret = this.items[this.order[pos]];
+    if (typeof ret != 'undefined') {
+      this.removeByIndex(pos);
+      return ret;
+    }
+    else {
+      return;
+    }
+  };
+
+  /**
+    @name SortedCollection#unshift
+    @public
+    @function
+    @return {Number} Returns the count of items
+    @description Prepends a new item to the beginning of the collection
+    @param {String} key The key to use for the item
+    @param {Any} val The value to use for the item
+  */
+  this.unshift = function (key, val) {
+    this.insertAtIndex(0, key, val);
+    return this.count;
+  };
+
+  /**
+    @name SortedCollection#shift
+    @public
+    @function
+    @return {Number} Returns the removed items value
+    @description Removes the first item in the list and returns it's value
+  */
+  this.shift = function () {
+    var pos = 0;
+    var ret = this.items[this.order[pos]];
+    if (typeof ret != 'undefined') {
+      this.removeByIndex(pos);
+      return ret;
+    }
+    else {
+      return;
+    }
+  };
+
+  /**
+    @name SortedCollection#splice
+    @public
+    @function
+    @description Removes items from index to the given max and then adds the given
+      collections items
+    @param {Number} index The index to start at when removing items
+    @param {Number} numToRemove The number of items to remove before adding the new items
+    @param {Object} hash the collection of items to add
+  */
+  this.splice = function (index, numToRemove, hash) {
+    var _this = this;
+    // Removal
+    if (numToRemove > 0) {
+      // Items
+      var limit = index + numToRemove;
+      for (var i = index; i < limit; i++) {
+        delete this.items[this.order[i]];
+      }
+      // Order
+      this.order.splice(index, numToRemove);
+    }
+    // Adding
+    if (hash) {
+      // Items
+      for (var i in hash.items) {
+        this.items[i] = hash.items[i];
+      }
+      // Order
+      var args = hash.order;
+      args.unshift(0);
+      args.unshift(index);
+      this.order.splice.apply(this.order, args);
+    }
+    this.count = this.order.length;
+  };
+
+  this.sort = function (c) {
+    var arr = [];
+    // Assumes vals are comparable scalars
+    var comp = function (a, b) {
+      return c(a.val, b.val);
+    }
+    for (var i = 0; i < this.order.length; i++) {
+      var key = this.order[i];
+      arr[i] = { key: key, val: this.items[key] };
+    }
+    arr.sort(comp);
+    this.order = [];
+    for (var i = 0; i < arr.length; i++) {
+      this.order.push(arr[i].key);
+    }
+  };
+
+  this.sortByKey = function (comp) {
+    this.order.sort(comp);
+  };
+
+  /**
+    @name SortedCollection#reverse
+    @public
+    @function
+    @description Reverse the collection item list
+  */
+  this.reverse = function () {
+    this.order.reverse();
+  };
+
+})();
+
+module.exports.SortedCollection = SortedCollection;

+ 810 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/string.js

@@ -0,0 +1,810 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+var core = require('./core')
+  , inflection = require('./inflection')
+  , string;
+
+
+/**
+  @name string
+  @namespace string
+*/
+
+string = new (function () {
+
+  // Regexes for trimming, and character maps for escaping
+  var _LTR = /^\s+/
+    , _RTR = /\s+$/
+    , _TR = /^\s+|\s+$/g
+    , _NL = /\n|\r|\r\n/g
+    , _CHARS = {
+          '&': '&amp;'
+        , '<': '&lt;'
+        , '>': '&gt;'
+        , '"': '&quot;'
+        , '\'': '&#39;'
+      }
+    , _UUID_CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('')
+    , _buildEscape
+    , _buildEscapeTest;
+
+  // Builds the escape/unescape methods using a
+  // map of characters
+  _buildEscape = function (direction) {
+    return function (str) {
+      var string = str;
+
+      // If string is NaN, null or undefined then provide an empty default
+      if((typeof string === 'undefined') ||
+          string === null ||
+          (!string && isNaN(string))) {
+        string = '';
+      }
+      string = string.toString();
+
+      var from, to, p;
+      for (p in _CHARS) {
+        from = direction == 'to' ? p : _CHARS[p];
+        to = direction == 'to' ? _CHARS[p] : p;
+
+        string = string.replace(new RegExp(from, 'gm'), to);
+      }
+
+      return string;
+    }
+  };
+
+  // Builds a method that tests for any escapable
+  // characters, useful for avoiding double-scaping if
+  // you're not sure if a string has already been escaped
+  _buildEscapeTest = function (direction) {
+    return function (string) {
+      var pat = ''
+        , p;
+
+      for (p in _CHARS) {
+        pat += direction == 'to' ? p : _CHARS[p];
+        pat += '|';
+      }
+
+      pat = pat.substr(0, pat.length - 1);
+      pat = new RegExp(pat, "gm");
+      return pat.test(string)
+    }
+  };
+
+  // Escape special XMl chars
+  this.escapeXML = _buildEscape('to');
+
+  // Unescape XML chars to literal representation
+  this.unescapeXML = _buildEscape('from');
+
+  // Test if a string includes special chars
+  // that need escaping
+  this.needsEscape = _buildEscapeTest('to');
+
+  // Test if a string includes escaped chars
+  // that need unescaping
+  this.needsUnescape = _buildEscapeTest('from');
+
+  /**
+    @name string#escapeRegExpChars
+    @public
+    @function
+    @return {String} A string of escaped characters
+    @description Escapes regex control-characters in strings
+                 used to build regexes dynamically
+    @param {String} string The string of chars to escape
+  */
+  this.escapeRegExpChars = (function () {
+    var specials = [ '^', '$', '/', '.', '*', '+', '?', '|', '(', ')',
+        '[', ']', '{', '}', '\\' ];
+    sRE = new RegExp('(\\' + specials.join('|\\') + ')', 'g');
+    return function (string) {
+      var str = string || '';
+      str = String(str);
+      return str.replace(sRE, '\\$1');
+    };
+  }).call(this);
+
+  /**
+    @name string#toArray
+    @public
+    @function
+    @return {Array} Returns an array of characters
+    @description Converts a string to an array
+    @param {String} string The string to convert
+  */
+  this.toArray = function (string) {
+    var str = string || ''
+      , arr = []
+      , i = -1;
+    str = String(str);
+
+    while (++i < str.length) {
+      arr.push(str.substr(i, 1));
+    }
+
+    return arr;
+  };
+
+  /**
+    @name string#reverse
+    @public
+    @function
+    @return {String} Returns the `string` reversed
+    @description Reverses a string
+    @param {String} string The string to reverse
+  */
+  this.reverse = function (string) {
+    var str = string || '';
+    str = String(str);
+    return this.toArray(str).reverse().join('');
+  };
+
+  /**
+    @name string#ltrim
+    @public
+    @function
+    @return {String} Returns the trimmed string
+    @description Ltrim trims `char` from the left of a `string` and returns it
+                 if no `char` is given it will trim spaces
+    @param {String} string The string to trim
+    @param {String} character The character to trim
+  */
+  this.ltrim = function (string, character) {
+    var str = string || ''
+      , pat = character ? new RegExp('^' + character + '+') : _LTR;
+    str = String(str);
+
+    return str.replace(pat, '');
+  };
+
+  /**
+    @name string#rtrim
+    @public
+    @function
+    @return {String} Returns the trimmed string
+    @description Rtrim trims `char` from the right of a `string` and returns it
+                 if no `char` is given it will trim spaces
+    @param {String} string The string to trim
+    @param {String} character The character to trim
+  */
+  this.rtrim = function (string, character) {
+    var str = string || ''
+      , pat = character ? new RegExp(character + '+$') : _RTR;
+    str = String(str);
+
+    return str.replace(pat, '');
+  };
+
+  // Alias
+  this.chomp = this.rtrim;
+
+  /**
+    @name string#trim
+    @public
+    @function
+    @return {String} Returns the trimmed string
+    @description Trim trims `char` from the left and right of a `string` and returns it
+                 if no `char` is given it will trim spaces
+    @param {String} string The string to trim
+    @param {String} character The character to trim
+  */
+  this.trim = function (string, character) {
+    var str = string || ''
+      , pat = character ? new RegExp('^' + character + '+|' + character + '+$', 'g') : _TR;
+    str = String(str);
+
+    return str.replace(pat, '');
+  };
+
+  /**
+    @name string#chop
+    @public
+    @function
+    @description Returns a new String with the last character removed. If the
+                 string ends with \r\n, both characters are removed. Applying chop to an
+                 empty string returns an empty string.
+    @param {String} string to return with the last character removed.
+  */
+  this.chop = function (string) {
+    var index
+      , str = string || '';
+    str = String(str);
+
+    if (str.length) {
+      // Special-case for \r\n
+      index = str.indexOf('\r\n');
+      if (index == str.length - 2) {
+        return str.substring(0, index);
+      }
+      return str.substring(0, str.length - 1);
+    }
+    else {
+      return '';
+    }
+  };
+
+  /**
+    @name string#lpad
+    @public
+    @function
+    @return {String} Returns the padded string
+    @description Lpad adds `char` to the left of `string` until the length
+                 of `string` is more than `width`
+    @param {String} string The string to pad
+    @param {String} character The character to pad with
+    @param {Number} width the width to pad to
+  */
+  this.lpad = function (string, character, width) {
+    var str = string || ''
+      , width;
+    str = String(str);
+
+    // Should width be string.length + 1? or the same to be safe
+    width = parseInt(width, 10) || str.length;
+    character = character || ' ';
+
+    while (str.length < width) {
+      str = character + str;
+    }
+    return str;
+  };
+
+  /**
+    @name string#rpad
+    @public
+    @function
+    @return {String} Returns the padded string
+    @description Rpad adds `char` to the right of `string` until the length
+                 of `string` is more than `width`
+    @param {String} string The string to pad
+    @param {String} character The character to pad with
+    @param {Number} width the width to pad to
+  */
+  this.rpad = function (string, character, width) {
+    var str = string || ''
+      , width;
+    str = String(str);
+
+    // Should width be string.length + 1? or the same to be safe
+    width = parseInt(width, 10) || str.length;
+    character = character || ' ';
+
+    while (str.length < width) {
+      str += character;
+    }
+    return str;
+  };
+
+  /**
+    @name string#pad
+    @public
+    @function
+    @return {String} Returns the padded string
+    @description Pad adds `char` to the left and right of `string` until the length
+                 of `string` is more than `width`
+    @param {String} string The string to pad
+    @param {String} character The character to pad with
+    @param {Number} width the width to pad to
+  */
+  this.pad = function (string, character, width) {
+    var str = string || ''
+      , width;
+    str = String(str);
+
+    // Should width be string.length + 1? or the same to be safe
+    width = parseInt(width, 10) || str.length;
+    character = character || ' ';
+
+    while (str.length < width) {
+      str = character + str + character;
+    }
+    return str;
+  };
+
+  /**
+    @name string#truncate
+    @public
+    @function
+    @return {String} Returns the truncated string
+    @description Truncates a given `string` after a specified `length` if `string` is longer than
+                 `length`. The last characters will be replaced with an `omission` for a total length
+                 not exceeding `length`. If `callback` is given it will fire if `string` is truncated.
+    @param {String} string The string to truncate
+    @param {Integer/Object} options Options for truncation, If options is an Integer it will be length
+      @param {Integer} [options.length=string.length] Length the output string will be
+      @param {Integer} [options.len] Alias for `length`
+      @param {String} [options.omission='...'] Replace last characters with an omission
+      @param {String} [options.ellipsis='...'] Alias for `omission`
+      @param {String/RegExp} [options.seperator] Break the truncated test at the nearest `seperator`
+    @param {Function} callback Callback is called only if a truncation is done
+  */
+  this.truncate = function (string, options, callback) {
+    var str = string || ''
+      , stringLen
+      , opts
+      , stringLenWithOmission
+      , last
+      , ignoreCase
+      , multiLine
+      , stringToWorkWith
+      , lastIndexOf
+      , nextStop
+      , result
+      , returnString;
+
+    str = String(str);
+    stringLen = str.length
+
+    // If `options` is a number, assume it's the length and
+    // create a options object with length
+    if (typeof options === 'number') {
+      opts = {
+        length: options
+      };
+    }
+    else {
+      opts = options || {};
+    }
+
+    // Set `opts` defaults
+    opts.length = opts.length || stringLen;
+    opts.omission = opts.omission || opts.ellipsis || '...';
+
+    stringLenWithOmission = opts.length - opts.omission.length;
+
+    // Set the index to stop at for `string`
+    if (opts.seperator) {
+      if (opts.seperator instanceof RegExp) {
+        // If `seperator` is a regex
+        if (opts.seperator.global) {
+          opts.seperator = opts.seperator;
+        } else {
+          ignoreCase = opts.seperator.ignoreCase ? 'i' : ''
+          multiLine = opts.seperator.multiLine ? 'm' : '';
+          opts.seperator = new RegExp(opts.seperator.source,
+              'g' + ignoreCase + multiLine);
+        }
+        stringToWorkWith = str.substring(0, stringLenWithOmission + 1)
+        lastIndexOf = -1
+        nextStop = 0
+
+        while ((result = opts.seperator.exec(stringToWorkWith))) {
+          lastIndexOf = result.index;
+          opts.seperator.lastIndex = ++nextStop;
+        }
+        last = lastIndexOf;
+      }
+      else {
+        // Seperator is a String
+        last = str.lastIndexOf(opts.seperator, stringLenWithOmission);
+      }
+
+      // If the above couldn't be found, they'll default to -1 so,
+      // we need to just set it as `stringLenWithOmission`
+      if (last === -1) {
+        last = stringLenWithOmission;
+      }
+    }
+    else {
+      last = stringLenWithOmission;
+    }
+
+    if (stringLen < opts.length) {
+      return str;
+    }
+    else {
+      returnString = str.substring(0, last) + opts.omission;
+      returnString += callback && typeof callback === 'function' ? callback() : '';
+      return returnString;
+    }
+  };
+
+  /**
+    @name string#truncateHTML
+    @public
+    @function
+    @return {String} Returns the HTML safe truncated string
+    @description Truncates a given `string` inside HTML tags after a specified `length` if string`
+                 is longer than `length`. The last characters will be replaced with an `omission`
+                 for a total length not exceeding `length`. If `callback` is given it will fire if
+                 `string` is truncated. If `once` is true only the first string in the first HTML
+                 tags will be truncated leaving the others as they were
+    @param {String} string The string to truncate
+    @param {Integer/Object} options Options for truncation, If options is an Integer it will be length
+                            all Object options are the same as `truncate`
+      @param {Boolean} [options.once=false] If true, it will only be truncated once, otherwise the
+                                            truncation will loop through all text inside HTML tags
+    @param {Function} callback Callback is called only if a truncation is done
+  */
+  this.truncateHTML = function (string, options, callback) {
+    var str = string || ''
+      , returnString = ''
+      , opts = options;
+
+    str = String(str);
+
+    // If `options` is a number assume it's the length and create a options object with length
+    if (typeof opts === 'number') {
+      var num = opts;
+
+      opts = {};
+      opts.length = num;
+    } else opts = opts || {};
+
+    // Set `default` options for HTML specifics
+    opts.once = opts.once || false;
+
+    var pat = /(<[^>]*>)/ // Patter for matching HTML tags
+      , arr = [] // Holds the HTML tags and content seperately
+      , truncated = false
+      , result = pat.exec(str)
+      , item
+      , firstPos
+      , lastPos
+      , i;
+
+    // Gather the HTML tags and content into the array
+    while (result) {
+      firstPos = result.index;
+      lastPos = pat.lastIndex;
+
+      if (firstPos !== 0) {
+        // Should be content not HTML tags
+        arr.push(str.substring(0, firstPos));
+        // Slice content from string
+        str = str.slice(firstPos);
+      }
+
+      arr.push(result[0]); // Push HTML tags
+      str = str.slice(result[0].length);
+
+      // Re-run the pattern on the new string
+      result = pat.exec(str);
+    }
+    if (str !== '') {
+      arr.push(str);
+    }
+
+    // Loop through array items appending the tags to the string,
+    // - and truncating the text then appending it to content
+    i = -1;
+    while (++i < arr.length) {
+      item = arr[i];
+      switch (true) {
+        // Closing tag
+        case item.indexOf('</') == 0:
+          returnString += item;
+          openTag = null;
+          break;
+        // Opening tag
+        case item.indexOf('<') == 0:
+          returnString += item;
+          openTag = item;
+          break;
+        // Normal text
+        default:
+          if (opts.once && truncated) {
+            returnString += item;
+          } else {
+            returnString += this.truncate(item, opts, callback);
+            truncated = true;
+          }
+          break;
+      }
+    }
+
+    return returnString;
+  };
+
+  /**
+    @name string#nl2br
+    @public
+    @function
+    @return {String} The string with converted newlines chars to br tags
+    @description Nl2br returns a string where all newline chars are turned
+                 into line break HTML tags
+    @param {String} string The string to convert
+  */
+  this.nl2br = function (string) {
+    var str = string || '';
+    str = String(str);
+
+    return str.replace(_NL,'<br />');
+  };
+
+  /**
+    @name string#snakeize
+    @public
+    @function
+    @return {String} The string in a snake_case version
+    @description Snakeize converts camelCase and CamelCase strings to snake_case strings
+    @param {String} string The string to convert to snake_case
+    @param {String} separ='_' The seperator to use
+  */
+  this.snakeize = (function () {
+    // Only create regexes once on initial load
+    var repl = /([A-Z]+)/g
+      , lead = /^_/g;
+    return function (string, separ) {
+      var str = string || ''
+        , sep = separ || '_'
+        , leading = separ ? new RegExp('^' + sep, 'g') : lead;
+      str = String(str);
+      return str.replace(repl, sep + '$1').toLowerCase().
+        replace(leading, '');
+    };
+  }).call(this);
+
+  // Aliases
+  /**
+    @name string#underscorize
+    @public
+    @function
+    @return {String} The string in a underscorized version
+    @description Underscorize returns the given `string` converting camelCase and snakeCase to underscores
+    @param {String} string The string to underscorize
+  */
+  this.underscorize = this.snakeize;
+  this.underscoreize = this.snakeize;
+  this.decamelize = this.snakeize;
+
+  /**
+    @name string#camelize
+    @public
+    @function
+    @return {String} The string in a camelCase version
+    @description Camelize takes a string and optional options and
+                 returns a camelCase version of the given `string`
+    @param {String} string The string to convert to camelCase
+    @param {Object} options
+      @param {Boolean} [options.initialCap] If initialCap is true the returned
+                                            string will have a capitalized first letter
+      @param {Boolean} [options.leadingUnderscore] If leadingUnderscore os true then if
+                                                   an underscore exists at the beggining
+                                                   of the string, it will stay there.
+                                                   Otherwise it'll be removed.
+  */
+  this.camelize = (function () {
+    // Only create regex once on initial load
+    var repl = /[-_](\w)/g;
+    return function (string, options) {
+      var str = string || ''
+        , ret
+        , config = {
+            initialCap: false
+          , leadingUnderscore: false
+          }
+        , opts = options || {};
+
+      str = String(str);
+
+      // Backward-compat
+      if (typeof opts == 'boolean') {
+        config = {
+          initialCap: true
+        };
+      }
+      else {
+        core.mixin(config, opts);
+      }
+
+      ret = str.replace(repl, function (m, m1) {
+        return m1.toUpperCase();
+      });
+
+      if (config.leadingUnderscore & str.indexOf('_') === 0) {
+        ret = '_' + this.decapitalize(ret);
+      }
+      // If initialCap is true capitalize it
+      ret = config.initialCap ? this.capitalize(ret) : this.decapitalize(ret);
+
+      return ret;
+    };
+  }).call(this);
+
+  /**
+    @name string#decapitalize
+    @public
+    @function
+    @return {String} The string with the first letter decapitalized
+    @description Decapitalize returns the given string with the first letter uncapitalized.
+    @param {String} string The string to decapitalize
+  */
+  this.decapitalize = function (string) {
+    var str = string || '';
+    str = String(str);
+
+    return str.substr(0, 1).toLowerCase() + str.substr(1);
+  };
+
+  /**
+    @name string#capitalize
+    @public
+    @function
+    @return {String} The string with the first letter capitalized
+    @description capitalize returns the given string with the first letter capitalized.
+    @param {String} string The string to capitalize
+  */
+  this.capitalize = function (string) {
+    var str = string || '';
+    str = String(str);
+
+    return str.substr(0, 1).toUpperCase() + str.substr(1);
+  };
+
+  /**
+    @name string#dasherize
+    @public
+    @function
+    @return {String} The string in a dashed version
+    @description Dasherize returns the given `string` converting camelCase and snakeCase
+                 to dashes or replace them with the `replace` character.
+    @param {String} string The string to dasherize
+    @param {String} replace='-' The character to replace with
+  */
+  this.dasherize = function (string, replace) {
+    var repl = replace || '-'
+    return this.snakeize(string, repl);
+  };
+
+  /**
+    @name string#include
+    @public
+    @function
+    @return {Boolean} Returns true if the string is found in the string to search
+    @description Searches for a particular string in another string
+    @param {String} searchIn The string to search for the other string in
+    @param {String} searchFor The string to search for
+  */
+  this.include = function (searchIn, searchFor) {
+    var str = searchFor;
+    if (!str && typeof string != 'string') {
+      return false;
+    }
+    str = String(str);
+    return (searchIn.indexOf(str) > -1);
+  };
+
+  /*
+   * getInflections(name<String>, initialCap<String>)
+   *
+   * Inflection returns an object that contains different inflections
+   * created from the given `name`
+  */
+
+  /**
+    @name string#getInflections
+    @public
+    @function
+    @return {Object} A Object containing multiple different inflects for the given `name`
+    @description Inflection returns an object that contains different inflections
+                 created from the given `name`
+    @param {String} name The string to create inflections from
+  */
+  this.getInflections = function (name) {
+    if (!name) {
+      return;
+    }
+
+    var self = this
+        // Use plural version to fix possible mistakes(e,g,. thingie instead of thingy)
+      , normalizedName = this.snakeize(inflection.pluralize(name))
+      , nameSingular = inflection.singularize(normalizedName)
+      , namePlural = inflection.pluralize(normalizedName);
+
+    return {
+      // For filepaths or URLs
+      filename: {
+        // neil_peart
+        singular: nameSingular
+        // neil_pearts
+      , plural: namePlural
+      }
+      // Constructor names
+    , constructor: {
+        // NeilPeart
+        singular: self.camelize(nameSingular, {initialCap: true})
+        // NeilPearts
+      , plural: self.camelize(namePlural, {initialCap: true})
+      }
+    , property: {
+        // neilPeart
+        singular: self.camelize(nameSingular)
+        // neilPearts
+      , plural: self.camelize(namePlural)
+      }
+    };
+  };
+
+  /**
+    @name string#getInflection
+    @public
+    @function
+    @return {Object} A Object containing multiple different inflects for the given `name`
+    @description Inflection returns an object that contains different inflections
+                 created from the given `name`
+    @param {String} name The string to create inflections from
+  */
+  this.getInflection = function (name, key, pluralization) {
+    var infl = this.getInflections(name);
+    return infl[key][pluralization];
+  };
+
+  // From Math.uuid.js, https://github.com/broofa/node-uuid
+  // Robert Kieffer ([email protected]), MIT license
+  this.uuid = function (length, radix) {
+    var chars = _UUID_CHARS
+      , uuid = []
+      , r
+      , i;
+
+    radix = radix || chars.length;
+
+    if (length) {
+      // Compact form
+      i = -1;
+      while (++i < length) {
+        uuid[i] = chars[0 | Math.random()*radix];
+      }
+    } else {
+      // rfc4122, version 4 form
+
+      // rfc4122 requires these characters
+      uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
+      uuid[14] = '4';
+
+      // Fill in random data.  At i==19 set the high bits of clock sequence as
+      // per rfc4122, sec. 4.1.5
+      i = -1;
+      while (++i < 36) {
+        if (!uuid[i]) {
+          r = 0 | Math.random()*16;
+          uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
+        }
+      }
+    }
+
+    return uuid.join('');
+  };
+  
+  /**
+    @name string#stripTags
+    @public
+    @function
+    @return {String} A String with HTML tags removed.
+    @description Strips HTML tags from a string.
+    @param {String} The string to strip HTML tags from
+    @param {String|Array} A String or Array containing allowed tags. e.g. "<br><p>"
+  */
+  this.stripTags = function(string, allowed) {
+    // taken from http://phpjs.org/functions/strip_tags/
+    var allowed = (((allowed || "") + "").toLowerCase().match(/<[a-z][a-z0-9]*>/g) || []).join(''); // making sure the allowed arg is a string containing only tags in lowercase (<a><b><c>)
+    var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi,
+    comments = /<!--[\s\S]*?-->/gi;
+    return string.replace(comments, '').replace(tags, function ($0, $1) {
+      return allowed.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : '';
+    });
+  }
+
+})();
+
+module.exports = string;
+

+ 238 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/uri.js

@@ -0,0 +1,238 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+var uri
+  , string = require('./string')
+  , mixin = require('./core').mixin;
+
+/**
+  @name uri
+  @namespace uri
+*/
+
+uri = new (function () {
+  var _isArray = function (obj) {
+    return obj &&
+      typeof obj === 'object' &&
+      typeof obj.length === 'number' &&
+      typeof obj.splice === 'function' &&
+      !(obj.propertyIsEnumerable('length'));
+  };
+
+  /**
+    @name uri#getFileExtension
+    @public
+    @function
+    @return {String} Returns the file extension for a given path
+    @description Gets the file extension for a path and returns it
+    @param {String} path The path to get the extension for
+  */
+  this.getFileExtension = function (path) {
+    var match;
+    if (path) {
+      match = /.+\.(\w{2,4}$)/.exec(path);
+    }
+    return (match && match[1]) || '';
+  };
+
+  /**
+    @name uri#paramify
+    @public
+    @function
+    @return {String} Returns a querystring contains the given values
+    @description Convert a JS Object to a querystring (key=val&key=val). Values in arrays
+      will be added as multiple parameters
+    @param {Object} obj An Object containing only scalars and arrays
+    @param {Object} o The options to use for formatting
+      @param {Boolean} [o.consolidate=false] take values from elements that can return
+        multiple values (multi-select, checkbox groups) and collapse into a single,
+        comman-delimited value.
+      @param {Boolean} [o.includeEmpty=false] include keys in the string for all elements, even
+        they have no value set (e.g., even if elemB has no value: elemA=foo&elemB=&elemC=bar).
+        Note that some false-y values are always valid even without this option, [0, ''].
+        This option extends coverage to [null, undefined, NaN]
+      @param {Boolean} [o.snakeize=false] change param names from camelCase to snake_case.
+      @param {Boolean} [o.escapeVals=false] escape the values for XML entities.
+      @param {Boolean} [o.index=false] use numeric indices for arrays
+  */
+  this.paramify = function (obj, o) {
+    var opts = o || {},
+        _opts,
+        str = '',
+        key,
+        val,
+        isValid,
+        itemArray,
+        arr = [],
+        arrVal,
+        prefix = opts.prefix || '',
+        self = this;
+
+    function getParamName(key)
+    {
+      if (opts.prefix) {
+        return prefix + '[' + key + ']';
+      }
+      else {
+        return key;
+      }
+    }
+
+    for (var p in obj) {
+      if (Object.prototype.hasOwnProperty.call(obj, p)) {
+        val = obj[p];
+
+        // This keeps valid falsy values like false and 0
+        // It's duplicated in the array block below. Could
+        // put it in a function but don't want the overhead
+        isValid = !( val === null || val === undefined ||
+                    (typeof val === 'number' && isNaN(val)) );
+
+        key = opts.snakeize ? string.snakeize(p) : p;
+        if (isValid) {
+          // Multiple vals -- array
+          if (_isArray(val) && val.length) {
+            itemArray = [];
+            for (var i = 0, ii = val.length; i < ii; i++) {
+              arrVal = val[i];
+              // This keeps valid falsy values like false and 0
+              isValid = !( arrVal === null || arrVal === undefined ||
+                           (typeof arrVal === 'number' && isNaN(arrVal)) );
+
+              // for index mode, which works recursive
+              // objects and array must not be encoded
+              if (opts.index && typeof arrVal === 'object') {
+                itemArray[i] = arrVal;
+              }
+              else {
+                itemArray[i] = isValid ? encodeURIComponent(arrVal) : '';
+
+                if (opts.escapeVals) {
+                  itemArray[i] = string.escapeXML(itemArray[i]);
+                }
+              }
+            }
+            // Consolidation mode -- single value joined on comma
+            if (opts.consolidate) {
+              arr.push(getParamName(key) + '=' + itemArray.join(','));
+            }
+            // Indexed mode -- multiple, same-named params with numeric indices
+            else if (opts.index) {
+              // {foo: [1, 2, 3]} => 'foo[0]=1&foo[1]=2&foo[2]=3'
+
+              itemArray.forEach(function(item, i) {
+                // recursion of arrays
+                if (_isArray(item) && item.length) {
+                  _opts = mixin(opts, {});
+                  item.forEach(function(_item, ii) {
+
+                    if (typeof _item === 'object') {
+                      _opts.prefix = getParamName(key) + '[' + i + '][' + ii + ']';
+                      arr.push(self.paramify(_item, _opts));
+                    }
+                    else {
+                      arr.push(getParamName(key) + '[' + i + '][' + ii + ']=' + _item);
+                    }
+                  });
+                }
+                // recursion of object in array
+                else if (typeof item === 'object') {
+                  _opts = mixin(opts, {});
+                  _opts.prefix = getParamName(key) + '[' + i + ']';
+                  arr.push(self.paramify(item, _opts));
+                }
+                // primitive
+                else {
+                  arr.push(getParamName(key) + '[' + i + ']=' + item);
+                }
+              });
+            }
+            // Normal mode -- multiple, same-named params with each val
+            else {
+              // {foo: [1, 2, 3]} => 'foo=1&foo=2&foo=3'
+              // Add into results array, as this just ends up getting
+              // joined on ampersand at the end anyhow
+              arr.push(getParamName(key) + '=' + itemArray.join('&' + getParamName(key) + '='));
+            }
+          }
+          // Object -- recursion
+          else if (typeof val === 'object') {
+            _opts = mixin(opts, {});
+            _opts.prefix = getParamName(key);
+
+            arr.push(this.paramify(val, _opts));
+          }
+          // Single val -- string
+          else {
+            if (opts.escapeVals) {
+              val = string.escapeXML(val);
+            }
+            arr.push(getParamName(key) + '=' + encodeURIComponent(val));
+          }
+          str += '&';
+        }
+        else {
+          if (opts.includeEmpty) { arr.push(getParamName(key) + '='); }
+        }
+      }
+    }
+    return arr.join('&');
+  };
+
+  /**
+    @name uri#objectify
+    @public
+    @function
+    @return {Object} JavaScript key/val object with the values from the querystring
+    @description Convert the values in a query string (key=val&key=val) to an Object
+    @param {String} str The querystring to convert to an object
+    @param {Object} o The options to use for formatting
+      @param {Boolean} [o.consolidate=true] Convert multiple instances of the same
+        key into an array of values instead of overwriting
+  */
+  this.objectify = function (str, o) {
+    var opts = o || {};
+    var d = {};
+    var consolidate = typeof opts.consolidate == 'undefined' ?
+        true : opts.consolidate;
+    if (str) {
+      var arr = str.split('&');
+      for (var i = 0; i < arr.length; i++) {
+        var pair = arr[i].split('=');
+        var name = pair[0];
+        var val = decodeURIComponent(pair[1] || '');
+        // "We've already got one!" -- arrayize if the flag
+        // is set
+        if (typeof d[name] != 'undefined' && consolidate) {
+          if (typeof d[name] == 'string') {
+            d[name] = [d[name]];
+          }
+          d[name].push(val);
+        }
+        // Otherwise just set the value
+        else {
+          d[name] = val;
+        }
+      }
+    }
+    return d;
+  };
+
+})();
+
+module.exports = uri;
+

+ 282 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/xml.js

@@ -0,0 +1,282 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+var core = require('./core')
+  , inflection = require('./inflection')
+
+/**
+  @name xml
+  @namespace xml
+*/
+
+exports.XML = new (function () {
+
+  // Default indention level
+  var indentLevel = 4
+    , tagFromType
+    , obj2xml;
+
+  tagFromType = function (item, prev) {
+    var ret
+      , type
+      , types;
+
+    if (item instanceof Array) {
+      ret = 'array';
+    } else {
+      types = ['string', 'number', 'boolean', 'object'];
+      for (var i = 0, ii = types.length; i < ii; i++) {
+        type = types[i];
+        if (typeof item == type) {
+          ret = type;
+        }
+      }
+    }
+
+    if (prev && ret != prev) {
+      return 'record'
+    } else {
+      return ret;
+    }
+  };
+
+  obj2xml = function (o, opts) {
+    var name = opts.name
+      , level = opts.level
+      , arrayRoot = opts.arrayRoot
+      , pack
+      , item
+      , n
+      , currentIndent = (new Array(level * indentLevel)).join(' ')
+      , nextIndent = (new Array((level + 1) * indentLevel)).join(' ')
+      , xml = '';
+
+    switch (typeof o) {
+      case 'string':
+      case 'number':
+      case 'boolean':
+        xml = o.toString();
+        break;
+      case 'object':
+        // Arrays
+        if (o instanceof Array) {
+
+          // Pack the processed version of each item into an array that
+          // can be turned into a tag-list with a `join` method below
+          // As the list gets iterated, if all items are the same type,
+          // that's the tag-name for the individual tags. If the items are
+          // a mixed, the tag-name is 'record'
+          pack = [];
+          for (var i = 0, ii = o.length; i < ii; i++) {
+            item = o[i];
+            if (!name) {
+              // Pass any previous tag-name, so it's possible to know if
+              // all items are the same type, or it's mixed types
+              n = tagFromType(item, n);
+            }
+            pack.push(obj2xml(item, {
+              name: name
+            , level: level + 1
+            , arrayRoot: arrayRoot
+            }));
+          }
+
+          // If this thing is attached to a named property on an object,
+          // use the name for the containing tag-name
+          if (name) {
+            n = name;
+          }
+
+          // If this is a top-level item, wrap in a top-level containing tag
+          if (level == 0) {
+            xml += currentIndent + '<' + inflection.pluralize(n) + ' type="array">\n'
+          }
+          xml += nextIndent + '<' + n + '>' +
+              pack.join('</' + n + '>\n' + nextIndent +
+                  '<' + n + '>') + '</' + n + '>\n';
+
+          // If this is a top-level item, close the top-level containing tag
+          if (level == 0) {
+            xml += currentIndent + '</' + inflection.pluralize(n) + '>';
+          }
+        }
+        // Generic objects
+        else {
+          n = name || 'object';
+
+          // If this is a top-level item, wrap in a top-level containing tag
+          if (level == 0) {
+            xml += currentIndent + '<' + n;
+            // Lookahead hack to allow tags to have attributes
+            for (var p in o) {
+              if (p.indexOf('attr:') == 0) {
+                xml += ' ' + p.replace(/^attr:/, '') + '="' +
+                    o[p] + '"'
+              }
+            }
+            xml += '>\n';
+          }
+          for (var p in o) {
+            item = o[p];
+
+            // Data properties only
+            if (typeof item == 'function') {
+              continue;
+            }
+            // No attr hack properties
+            if (p.indexOf('attr:') == 0) {
+              continue;
+            }
+
+            xml += nextIndent;
+
+            if (p == '#cdata') {
+              xml += '<![CDATA[' + item + ']]>\n';
+            }
+            else {
+
+              // Complex values, going to have items with multiple tags
+              // inside
+              if (typeof item == 'object') {
+                if (item instanceof Array) {
+                  if (arrayRoot) {
+                    xml += '<' + p + ' type="array">\n'
+                  }
+                }
+                else {
+                  xml += '<' + p;
+                  // Lookahead hack to allow tags to have attributes
+                  for (var q in item) {
+                    if (q.indexOf('attr:') == 0) {
+                      xml += ' ' + q.replace(/^attr:/, '') + '="' +
+                          item[q] + '"'
+                    }
+                  }
+                  xml += '>\n';
+                }
+              }
+              // Scalars, just a value and closing tag
+              else {
+                xml += '<' + p + '>'
+              }
+              xml += obj2xml(item, {
+                name: p
+              , level: level + 1
+              , arrayRoot: arrayRoot
+              });
+
+              // Objects and Arrays, need indentation before closing tag
+              if (typeof item == 'object') {
+                if (item instanceof Array) {
+                  if (arrayRoot) {
+                    xml += nextIndent;
+                    xml += '</' + p + '>\n';
+                  }
+                }
+                else {
+                  xml += nextIndent;
+                  xml += '</' + p + '>\n';
+                }
+              }
+              // Scalars, just close
+              else {
+                xml += '</' + p + '>\n';
+              }
+            }
+          }
+          // If this is a top-level item, close the top-level containing tag
+          if (level == 0) {
+            xml += currentIndent + '</' + n + '>\n';
+          }
+        }
+        break;
+      default:
+        // No default
+    }
+    return xml;
+  }
+
+  /*
+   * XML configuration
+   *
+  */
+  this.config = {
+      whitespace: true
+    , name: null
+    , fragment: false
+    , level: 0
+    , arrayRoot: true
+  };
+
+  /**
+    @name xml#setIndentLevel
+    @public
+    @function
+    @return {Number} Return the given `level`
+    @description SetIndentLevel changes the indent level for XML.stringify and returns it
+    @param {Number} level The indent level to use
+  */
+  this.setIndentLevel = function (level) {
+    if(!level) {
+      return;
+    }
+
+    return indentLevel = level;
+  };
+
+  /**
+    @name xml#stringify
+    @public
+    @function
+    @return {String} Return the XML entities of the given `obj`
+    @description Stringify returns an XML representation of the given `obj`
+    @param {Object} obj The object containing the XML entities to use
+    @param {Object} opts
+      @param {Boolean} [opts.whitespace=true] Don't insert indents and newlines after xml entities
+      @param {String} [opts.name=typeof obj] Use custom name as global namespace
+      @param {Boolean} [opts.fragment=false] If true no header fragment is added to the top
+      @param {Number} [opts.level=0] Remove this many levels from the output
+      @param {Boolean} [opts.arrayRoot=true]
+  */
+  this.stringify = function (obj, opts) {
+    var config = core.mixin({}, this.config)
+      , xml = '';
+    core.mixin(config, (opts || {}));
+
+    if (!config.whitespace) {
+      indentLevel = 0;
+    }
+
+    if (!config.fragment) {
+      xml += '<?xml version="1.0" encoding="UTF-8"?>\n';
+    }
+
+    xml += obj2xml(obj, {
+      name: config.name
+    , level: config.level
+    , arrayRoot: config.arrayRoot
+    });
+
+    if (!config.whitespace) {
+      xml = xml.replace(/>\n/g, '>');
+    }
+
+    return xml;
+  };
+
+})();
+

+ 55 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/package.json

@@ -0,0 +1,55 @@
+{
+  "name": "utilities",
+  "description": "A classic collection of JavaScript utilities",
+  "keywords": [
+    "utilities",
+    "utils",
+    "jake",
+    "geddy"
+  ],
+  "version": "0.0.37",
+  "author": {
+    "name": "Matthew Eernisse",
+    "email": "[email protected]",
+    "url": "http://fleegix.org"
+  },
+  "main": "./lib/index.js",
+  "scripts": {
+    "test": "jake test"
+  },
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/mde/utilities.git"
+  },
+  "devDependencies": {
+    "jake": "latest"
+  },
+  "engines": {
+    "node": "*"
+  },
+  "bugs": {
+    "url": "https://github.com/mde/utilities/issues"
+  },
+  "homepage": "https://github.com/mde/utilities",
+  "_id": "[email protected]",
+  "_shasum": "a3470d0a7f688142d9e8a57cee1128f12e19e196",
+  "_resolved": "https://registry.npmjs.org/utilities/-/utilities-0.0.37.tgz",
+  "_from": "[email protected]",
+  "_npmVersion": "1.4.9",
+  "_npmUser": {
+    "name": "mde",
+    "email": "[email protected]"
+  },
+  "maintainers": [
+    {
+      "name": "mde",
+      "email": "[email protected]"
+    }
+  ],
+  "dist": {
+    "shasum": "a3470d0a7f688142d9e8a57cee1128f12e19e196",
+    "tarball": "http://registry.npmjs.org/utilities/-/utilities-0.0.37.tgz"
+  },
+  "directories": {},
+  "readme": "ERROR: No README data found!"
+}

+ 71 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/test/array.js

@@ -0,0 +1,71 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+var assert = require('assert')
+  , array = require('../lib/array')
+  , tests;
+
+tests = {
+
+  'test basic humanize for array': function () {
+    var actual = array.humanize(["array", "array", "array"])
+      , expected = "array, array and array";
+    assert.equal(expected, actual);
+  }
+
+, 'test humanize with two items for array': function () {
+    var actual = array.humanize(["array", "array"])
+      , expected = "array and array";
+    assert.equal(expected, actual);
+  }
+
+, 'test humanize with a single item for array': function () {
+    var actual = array.humanize(["array"])
+      , expected = "array";
+    assert.equal(expected, actual);
+  }
+
+, 'test humanize with no items for array': function () {
+    var actual = array.humanize([])
+      , expected = "";
+    assert.equal(expected, actual);
+  }
+
+, 'test basic include for array': function () {
+    var test = ["array"]
+      , actual = array.include(test, "array");
+    assert.equal(true, actual);
+  }
+
+, 'test false include for array': function () {
+    var test = ["array"]
+      , actual = array.include(test, 'nope');
+    assert.equal(false, actual);
+  }
+
+, 'test false boolean include for array': function () {
+    var test = ["array", false]
+      , actual = array.include(test, false);
+    assert.equal(true, actual);
+  }
+
+};
+
+module.exports = tests;
+
+

+ 97 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/test/core.js

@@ -0,0 +1,97 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+var assert = require('assert')
+  , core = require('../lib/core')
+  , tests;
+
+tests = {
+
+  'simple mixin for core': function () {
+    var expected = {secret: 'asdf', geddy: 'geddyKey'}
+      , result = core.mixin({secret: 'asdf'}, {geddy: 'geddyKey'});
+    assert.deepEqual(expected, result);
+  }
+
+, 'mixin with overiding key for core': function () {
+    var expected = {secret: 'geddySecret', geddy: 'geddyKey'}
+      , result = core.mixin({secret: 'asdf'}, {geddy: 'geddyKey', secret: 'geddySecret'});
+    assert.deepEqual(expected, result);
+  }
+
+, 'simple enhance for core': function () {
+    var expected = {secret: 'asdf', geddy: 'geddyKey'}
+      , result = core.enhance({secret: 'asdf'}, {geddy: 'geddyKey'});
+    assert.deepEqual(expected, result);
+  }
+
+, 'enhance with overiding key for core': function () {
+    var expected = {secret: 'geddySecret', geddy: 'geddyKey'}
+      , result = core.enhance({secret: 'asdf'}, {geddy: 'geddyKey', secret: 'geddySecret'});
+    assert.deepEqual(expected, result);
+  }
+
+, 'isEmpty, empty string (true)': function () {
+    assert.ok(core.isEmpty(''));
+  }
+
+, 'isEmpty, null (true)': function () {
+    assert.ok(core.isEmpty(null));
+  }
+
+, 'isEmpty, undefined (true)': function () {
+    assert.ok(core.isEmpty(null));
+  }
+
+, 'isEmpty, NaN (true)': function () {
+    assert.ok(core.isEmpty(NaN));
+  }
+
+, 'isEmpty, invalid Date (true)': function () {
+    assert.ok(core.isEmpty(new Date(NaN)));
+  }
+
+, 'isEmpty, zero (false)': function () {
+    assert.ok(!core.isEmpty(0));
+  }
+,
+  'bind': function () {
+    function bar() {}
+
+    function foo() {
+      assert.equal(this.name, 'bar');
+    }
+
+    var fooBoundToBar = core.bind(bar, foo);
+    fooBoundToBar();
+  }
+,
+  'bind, arguments': function () {
+    function bar() {}
+
+    function foo(arg) {
+      assert.equal(this.name, 'bar');
+      assert.equal(arg, 'cats');
+    }
+
+    var fooBoundToBarWithCats = core.bind(bar, foo, 'cats');
+    fooBoundToBarWithCats();
+  }
+};
+
+module.exports = tests;

+ 84 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/test/date.js

@@ -0,0 +1,84 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+var date = require('../lib/date')
+  , assert = require('assert')
+  , tests = {}
+  , _date = new Date();
+
+tests = {
+
+  'test strftime for date': function () {
+    var data = date.strftime(_date, "%w")
+      , actual = _date.getDay();
+    assert.equal(actual, data);
+  }
+
+, 'test calcCentury using current year for date': function () {
+    var data = date.calcCentury()
+      , actual = '21';
+    assert.equal(actual, data);
+  }
+
+, 'test calcCentury using 20th century year for date': function () {
+    var data = date.calcCentury(2000)
+      , actual = '20';
+    assert.equal(actual, data);
+  }
+
+, 'test calcCentury using 1st century year for date': function () {
+    var data = date.calcCentury(10)
+      , actual = '1';
+    assert.equal(actual, data);
+  }
+
+, 'test getMeridiem for date': function () {
+    var data = date.getMeridiem(_date.getHours())
+      , actual = (_date.getHours() > 11) ? 'PM' : 'AM';
+    assert.equal(actual, data);
+  }
+
+, 'test parse UTC': function () {
+    var dt = date.parse('1970-01-01T00:00:00Z');
+    assert.equal(0, dt.getTime());
+  }
+
+, 'test parse with offset basic': function () {
+    var dt;
+    dt = date.parse('1970-01-01T00:00:00-0100');
+    assert.equal(3600000, dt.getTime());
+    dt = date.parse('1970-01-01T00:00:00+0100');
+    assert.equal(-3600000, dt.getTime());
+  }
+
+, 'test parse with offset extended': function () {
+    var dt;
+    dt = date.parse('1970-01-01T00:00:00-01:00');
+    assert.equal(3600000, dt.getTime());
+    dt = date.parse('1970-01-01T00:00:00+01:00');
+    assert.equal(-3600000, dt.getTime());
+  }
+
+, 'test parse floating (i.e., local offset)': function () {
+    var dt;
+    dt = date.parse('1970-01-01T00:00:00');
+    assert.equal(dt.getTime() / 1000 / 60, dt.getTimezoneOffset());
+  }
+
+};
+
+module.exports = tests;

+ 45 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/test/event_buffer.js

@@ -0,0 +1,45 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+var Stream = require('stream').Stream
+  , EventEmitter = require('events').EventEmitter
+  , EventBuffer = require('../lib/event_buffer.js').EventBuffer
+  , assert = require('assert')
+  , tests;
+
+tests = {
+
+  'test basic event buffer functionality': function () {
+    var source = new Stream()
+      , dest = new EventEmitter()
+      , buff = new EventBuffer(source)
+      , data = '';
+    dest.on('data', function (d) { data += d; });
+    source.writeable = true;
+    source.readable = true;
+    source.emit('data', 'abcdef');
+    source.emit('data', '123456');
+    buff.sync(dest);
+    assert.equal('abcdef123456', data);
+    source.emit('data', '---');
+    assert.equal('abcdef123456---', data);
+  }
+
+};
+
+module.exports = tests;

+ 228 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/test/file.js

@@ -0,0 +1,228 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+var assert = require('assert')
+  , fs = require('fs')
+  , path = require('path')
+  , file = require('../lib/file')
+  , existsSync = fs.existsSync || path.existsSync
+  , tests;
+
+tests = {
+
+  'before': function () {
+    process.chdir('./test');
+  }
+
+, 'after': function () {
+    process.chdir('../');
+  }
+
+, 'test mkdirP': function () {
+    var expected = [
+          ['foo']
+        , ['foo', 'bar']
+        , ['foo', 'bar', 'baz']
+        , ['foo', 'bar', 'baz', 'qux']
+        ]
+      , res;
+    file.mkdirP('foo/bar/baz/qux');
+    res = file.readdirR('foo');
+    for (var i = 0, ii = res.length; i < ii; i++) {
+      assert.equal(path.join.apply(path, expected[i]), res[i]);
+    }
+    file.rmRf('foo', {silent: true});
+  }
+
+, 'test rmRf': function () {
+    file.mkdirP('foo/bar/baz/qux', {silent: true});
+    file.rmRf('foo/bar', {silent: true});
+    res = file.readdirR('foo');
+    assert.equal(1, res.length);
+    assert.equal('foo', res[0]);
+    fs.rmdirSync('foo');
+  }
+  
+, 'test cpR with same name and different directory': function () {
+      file.mkdirP('foo', {silent: true});
+      fs.writeFileSync('foo/bar.txt', 'w00t');
+      file.cpR('foo', 'bar', {silent: true});
+      assert.ok(existsSync('bar/bar.txt'));
+      file.rmRf('foo', {silent: true});
+      file.rmRf('bar', {silent: true});
+      
+  }
+
+, 'test cpR with same to and from will throw': function () {
+    assert.throws(function () {
+      file.cpR('foo.txt', 'foo.txt', {silent: true});
+    });
+  }
+
+, 'test cpR rename via copy in directory': function () {
+    file.mkdirP('foo', {silent: true});
+    fs.writeFileSync('foo/bar.txt', 'w00t');
+    file.cpR('foo/bar.txt', 'foo/baz.txt', {silent: true});
+    assert.ok(existsSync('foo/baz.txt'));
+    file.rmRf('foo', {silent: true});
+  }
+
+, 'test cpR rename via copy in base': function () {
+    fs.writeFileSync('bar.txt', 'w00t');
+    file.cpR('bar.txt', 'baz.txt', {silent: true});
+    assert.ok(existsSync('baz.txt'));
+    file.rmRf('bar.txt', {silent: true});
+    file.rmRf('baz.txt', {silent: true});
+  }
+
+, 'test readdirR': function () {
+    var expected = [
+          ['foo']
+        , ['foo', 'bar']
+        , ['foo', 'bar', 'baz']
+        , ['foo', 'bar', 'baz', 'qux']
+        ]
+      , res;
+
+    file.mkdirP('foo/bar/baz/qux', {silent: true});
+    res = file.readdirR('foo');
+
+    for (var i = 0, ii = res.length; i < ii; i++) {
+      assert.equal(path.join.apply(path, expected[i]), res[i]);
+    }
+    file.rmRf('foo', {silent: true});
+  }
+
+, 'test isAbsolute with Unix absolute path': function () {
+    var p = '/foo/bar/baz';
+    assert.equal('/', file.isAbsolute(p));
+  }
+
+, 'test isAbsolute with Unix relative path': function () {
+    var p = 'foo/bar/baz';
+    assert.equal(false, file.isAbsolute(p));
+  }
+
+, 'test isAbsolute with Win absolute path': function () {
+    var p = 'C:\\foo\\bar\\baz';
+    assert.equal('C:\\', file.isAbsolute(p));
+  }
+
+, 'test isAbsolute with Win relative path': function () {
+    var p = 'foo\\bar\\baz';
+    assert.equal(false, file.isAbsolute(p));
+  }
+
+, 'test absolutize with Unix absolute path': function () {
+    var expected = '/foo/bar/baz'
+      , actual = file.absolutize('/foo/bar/baz');
+    assert.equal(expected, actual);
+  }
+
+, 'test absolutize with Win absolute path': function () {
+    var expected = 'C:\\foo\\bar\\baz'
+      , actual = file.absolutize('C:\\foo\\bar\\baz');
+    assert.equal(expected, actual);
+  }
+
+, 'test absolutize with relative path': function () {
+    var expected = process.cwd()
+      , actual = '';
+
+    // We can't just create two different tests here
+    // because file.absolutize uses process.cwd()
+    // to get absolute path which is platform
+    // specific
+    if (process.platform === 'win32') {
+      expected += '\\foo\\bar\\baz'
+      actual = file.absolutize('foo\\bar\\baz')
+    }
+    else {
+      expected += '/foo/bar/baz'
+      actual = file.absolutize('foo/bar/baz');
+    }
+
+    assert.equal(expected, actual);
+  }
+
+, 'test basedir with Unix absolute path': function () {
+    var p = '/foo/bar/baz';
+    assert.equal('/foo/bar', file.basedir(p));
+  }
+
+, 'test basedir with Win absolute path': function () {
+    var p = 'C:\\foo\\bar\\baz';
+    assert.equal('C:\\foo\\bar', file.basedir(p));
+  }
+
+, 'test basedir with Unix root path': function () {
+    var p = '/';
+    assert.equal('/', file.basedir(p));
+  }
+
+, 'test basedir with Unix absolute path and double-asterisk': function () {
+    var p = '/**/foo/bar/baz';
+    assert.equal('/', file.basedir(p));
+  }
+
+, 'test basedir with leading double-asterisk': function () {
+    var p = '**/foo';
+    assert.equal('.', file.basedir(p));
+  }
+
+, 'test basedir with leading asterisk': function () {
+    var p = '*.js';
+    assert.equal('.', file.basedir(p));
+  }
+
+, 'test basedir with leading dot-slash and double-asterisk': function () {
+    var p = './**/foo';
+    assert.equal('.', file.basedir(p));
+  }
+
+, 'test basedir with leading dirname and double-asterisk': function () {
+    var p = 'a/**/*.js';
+    assert.equal('a', file.basedir(p));
+  }
+
+, 'test basedir with leading dot-dot-slash and double-asterisk': function () {
+    var p = '../../test/**/*.js';
+    assert.equal('../../test', file.basedir(p));
+  }
+
+, 'test basedir with single-asterisk in dirname': function () {
+    var p = 'a/test*/file';
+    assert.equal('a', file.basedir(p));
+  }
+
+, 'test basedir with single filename': function () {
+    var p = 'filename';
+    assert.equal('.', file.basedir(p));
+  }
+
+, 'test basedir with empty path': function () {
+    var p = '';
+    assert.equal('.', file.basedir(p));
+    assert.equal('.', file.basedir());
+  }
+
+};
+
+module.exports = tests;
+
+

+ 60 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/test/i18n.js

@@ -0,0 +1,60 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+var i18n = require('../lib/i18n')
+  , assert = require('assert')
+  , tests
+  , inst = {};
+
+tests = {
+
+  'before': function () {
+    i18n.loadLocale('en-us', {foo: 'FOO', bar: 'BAR', baz: 'BAZ'});
+    i18n.loadLocale('ja-jp', {foo: 'フー', bar: 'バー'});
+    inst.en = new i18n.I18n('en-us');
+    inst.jp = new i18n.I18n('ja-jp');
+    inst.de = new i18n.I18n('de-de');
+  }
+
+, 'test default-locale fallback, defined strings': function () {
+    var expected = 'BAZ'
+      , actual = inst.jp.t('baz');
+    assert.equal(expected, actual);
+  }
+
+, 'test default-locale fallback, no defined strings': function () {
+    var expected = 'BAZ'
+      , actual = inst.de.t('baz');
+    assert.equal(expected, actual);
+  }
+
+, 'test key lookup, default-locale': function () {
+    var expected = 'FOO'
+      , actual = inst.en.t('foo');
+    assert.equal(expected, actual);
+  }
+
+, 'test key lookup, non-default-locale': function () {
+    var expected = 'フー'
+      , actual = inst.jp.t('foo');
+    assert.equal(expected, actual);
+  }
+
+};
+
+module.exports = tests;

+ 388 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/test/inflection.js

@@ -0,0 +1,388 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+var inflection = require('../lib/inflection')
+  , assert = require('assert')
+  , esInflections
+  , sInflections
+  , iesInflections
+  , vesInflections
+  , icesInflections
+  , renInflections
+  , oesInflections
+  , iInflections
+  , genInflections
+  , irregularInflections
+  , noInflections
+  , tests;
+
+/**
+ * Most test inflections are from Ruby on Rails:
+ *   https://github.com/rails/rails/blob/master/activesupport/test/inflector_test_cases.rb
+ *
+ * Ruby on Rails is MIT licensed: http://www.opensource.org/licenses/MIT
+*/
+esInflections = [
+    ["search", "searches"]
+  , ["switch", "switches"]
+  , ["fix", "fixes"]
+  , ["box", "boxes"]
+  , ["process", "processes"]
+  , ["address", "addresses"]
+  , ["wish", "wishes"]
+  , ["status", "statuses"]
+  , ["alias", "aliases"]
+  , ["basis", "bases"]
+  , ["diagnosis", "diagnoses"]
+  , ["bus", "buses"]
+];
+
+sInflections = [
+    ["stack", "stacks"]
+  , ["shoe", "shoes"]
+  , ["status_code", "status_codes"]
+  , ["case", "cases"]
+  , ["edge", "edges"]
+  , ["archive", "archives"]
+  , ["experience", "experiences"]
+  , ["day", "days"]
+  , ["comment", "comments"]
+  , ["foobar", "foobars"]
+  , ["newsletter", "newsletters"]
+  , ["old_news", "old_news"]
+  , ["perspective", "perspectives"]
+  , ["diagnosis_a", "diagnosis_as"]
+  , ["horse", "horses"]
+  , ["prize", "prizes"]
+];
+
+iesInflections = [
+    ["category", "categories"]
+  , ["query", "queries"]
+  , ["ability", "abilities"]
+  , ["agency", "agencies"]
+];
+
+vesInflections = [
+    ["wife", "wives"]
+  , ["safe", "saves"]
+  , ["half", "halves"]
+  , ["elf", "elves"]
+  , ["dwarf", "dwarves"]
+];
+
+icesInflections = [
+    ["index", "indices"]
+  , ["vertex", "vertices"]
+  , ["matrix", "matrices"]
+];
+
+renInflections = [
+    ["node_child", "node_children"]
+  , ["child", "children"]
+];
+
+oesInflections = [
+    ["buffalo", "buffaloes"]
+  , ["tomato", "tomatoes"]
+];
+
+iInflections = [
+    ["octopus", "octopi"]
+  , ["virus", "viri"]
+];
+
+genInflections = [
+    ["salesperson", "salespeople"]
+  , ["person", "people"]
+  , ["spokesman", "spokesmen"]
+  , ["man", "men"]
+  , ["woman", "women"]
+];
+
+irregularInflections = [
+    ["datum", "data"]
+  , ["medium", "media"]
+  , ["ox", "oxen"]
+  , ["cow", "kine"]
+  , ["mouse", "mice"]
+  , ["louse", "lice"]
+  , ["axis", "axes"]
+  , ["testis", "testes"]
+  , ["crisis", "crises"]
+  , ["analysis", "analyses"]
+  , ["quiz", "quizzes"]
+];
+
+noInflections = [
+    ["fish", "fish"]
+  , ["news", "news"]
+  , ["series", "series"]
+  , ["species", "species"]
+  , ["rice", "rice"]
+  , ["information", "information"]
+  , ["equipment", "equipment"]
+];
+
+tests = {
+
+  'test es plural words for inflection': function () {
+    var i = esInflections.length
+      , value;
+
+    while (--i >= 0) {
+      value = esInflections[i];
+
+      assert.equal(value[1], inflection.pluralize(value[0]))
+    }
+  }
+
+, 'test es singular words for inflection': function () {
+    var i = esInflections.length
+      , value;
+
+    while (--i >= 0) {
+      value = esInflections[i];
+
+      assert.equal(value[0], inflection.singularize(value[1]))
+    }
+  }
+
+, 'test s plural words for inflection': function () {
+    var i = sInflections.length
+      , value;
+
+    while (--i >= 0) {
+      value = sInflections[i];
+
+      assert.equal(value[1], inflection.pluralize(value[0]))
+    }
+  }
+
+, 'test s singular words for inflection': function () {
+    var i = sInflections.length
+      , value;
+
+    while (--i >= 0) {
+      value = sInflections[i];
+
+      assert.equal(value[0], inflection.singularize(value[1]))
+    }
+  }
+
+, 'test ies plural words for inflection': function () {
+    var i = iesInflections.length
+      , value;
+
+    while (--i >= 0) {
+      value = iesInflections[i];
+
+      assert.equal(value[1], inflection.pluralize(value[0]))
+    }
+  }
+
+, 'test ies singular words for inflection': function () {
+    var i = iesInflections.length
+      , value;
+
+    while (--i >= 0) {
+      value = iesInflections[i];
+
+      assert.equal(value[0], inflection.singularize(value[1]))
+    }
+  }
+
+, 'test ves plural words for inflection': function () {
+    var i = vesInflections.length
+      , value;
+
+    while (--i >= 0) {
+      value = vesInflections[i];
+
+      assert.equal(value[1], inflection.pluralize(value[0]))
+    }
+  }
+
+, 'test ves singular words for inflection': function () {
+    var i = vesInflections.length
+      , value;
+
+    while (--i >= 0) {
+      value = vesInflections[i];
+
+      assert.equal(value[0], inflection.singularize(value[1]))
+    }
+  }
+
+, 'test ices plural words for inflection': function () {
+    var i = icesInflections.length
+      , value;
+
+    while (--i >= 0) {
+      value = icesInflections[i];
+
+      assert.equal(value[1], inflection.pluralize(value[0]))
+    }
+  }
+
+, 'test ices singular words for inflection': function () {
+    var i = icesInflections.length
+      , value;
+
+    while (--i >= 0) {
+      value = icesInflections[i];
+
+      assert.equal(value[0], inflection.singularize(value[1]))
+    }
+  }
+
+, 'test ren plural words for inflection': function () {
+    var i = renInflections.length
+      , value;
+
+    while (--i >= 0) {
+      value = renInflections[i];
+
+      assert.equal(value[1], inflection.pluralize(value[0]))
+    }
+  }
+
+, 'test ren singular words for inflection': function () {
+    var i = renInflections.length
+      , value;
+
+    while (--i >= 0) {
+      value = renInflections[i];
+
+      assert.equal(value[0], inflection.singularize(value[1]))
+    }
+  }
+
+, 'test oes plural words for inflection': function () {
+    var i = oesInflections.length
+      , value;
+
+    while (--i >= 0) {
+      value = oesInflections[i];
+
+      assert.equal(value[1], inflection.pluralize(value[0]))
+    }
+  }
+
+, 'test oes singular words for inflection': function () {
+    var i = oesInflections.length
+      , value;
+
+    while (--i >= 0) {
+      value = oesInflections[i];
+
+      assert.equal(value[0], inflection.singularize(value[1]))
+    }
+  }
+
+, 'test i plural words for inflection': function () {
+    var i = iInflections.length
+      , value;
+
+    while (--i >= 0) {
+      value = iInflections[i];
+
+      assert.equal(value[1], inflection.pluralize(value[0]))
+    }
+  }
+
+, 'test i singular words for inflection': function () {
+    var i = iInflections.length
+      , value;
+
+    while (--i >= 0) {
+      value = iInflections[i];
+
+      assert.equal(value[0], inflection.singularize(value[1]))
+    }
+  }
+
+, 'test gender and people plural words for inflection': function () {
+    var i = genInflections.length
+      , value;
+
+    while (--i >= 0) {
+      value = genInflections[i];
+
+      assert.equal(value[1], inflection.pluralize(value[0]))
+    }
+  }
+
+, 'test gender and people singular words for inflection': function () {
+    var i = genInflections.length
+      , value;
+
+    while (--i >= 0) {
+      value = genInflections[i];
+
+      assert.equal(value[0], inflection.singularize(value[1]))
+    }
+  }
+
+, 'test irregular plural words for inflection': function () {
+    var i = irregularInflections.length
+      , value;
+
+    while (--i >= 0) {
+      value = irregularInflections[i];
+
+      assert.equal(value[1], inflection.pluralize(value[0]))
+    }
+  }
+
+, 'test irregular singular words for inflection': function () {
+    var i = irregularInflections.length
+      , value;
+
+    while (--i >= 0) {
+      value = irregularInflections[i];
+
+      assert.equal(value[0], inflection.singularize(value[1]))
+    }
+  }
+
+, 'test no change plural words for inflection': function () {
+    var i = noInflections.length
+      , value;
+
+    while (--i >= 0) {
+      value = noInflections[i];
+
+      assert.equal(value[1], inflection.pluralize(value[0]))
+    }
+  }
+
+, 'test no change singular words for inflection': function () {
+    var i = noInflections.length
+      , value;
+
+    while (--i >= 0) {
+      value = noInflections[i];
+
+      assert.equal(value[0], inflection.singularize(value[1]))
+    }
+  }
+
+};
+
+module.exports = tests;

Some files were not shown because too many files changed in this diff