Demo for query storing
Change-Id: I947bcac841992c3f6cfd01ab337c265b0d01cb70
diff --git a/node_modules/grunt/CHANGELOG b/node_modules/grunt/CHANGELOG
new file mode 100644
index 0000000..ad86af2
--- /dev/null
+++ b/node_modules/grunt/CHANGELOG
@@ -0,0 +1,171 @@
+v1.3.0
+ date: 2020-08-18
+ changes:
+ - Switch to use `safeLoad` for loading YML files via `file.readYAML`.
+ - Upgrade legacy-log to ~3.0.0.
+ - Upgrade legacy-util to ~2.0.0.
+v1.2.1
+ date: 2020-07-07
+ changes:
+ - Remove path-is-absolute dependency.
+ (PR: https://github.com/gruntjs/grunt/pull/1715)
+v1.2.0
+ date: 2020-07-03
+ changes:
+ - Allow usage of grunt plugins that are located in any location that
+ is visible to Node.js and NPM, instead of node_modules directly
+ inside package that have a dev dependency to these plugins.
+ (PR: https://github.com/gruntjs/grunt/pull/1677)
+ - Removed coffeescript from dependencies. To ease transition, if
+ coffeescript is still around, Grunt will attempt to load it.
+ If it is not, and the user loads a CoffeeScript file,
+ Grunt will print a useful error indicating that the
+ coffeescript package should be installed as a dev dependency.
+ This is considerably more user-friendly than dropping the require entirely,
+ but doing so is feasible with the latest grunt-cli as users
+ may simply use grunt --require coffeescript/register.
+ (PR: https://github.com/gruntjs/grunt/pull/1675)
+ - Exposes Grunt Option keys for ease of use.
+ (PR: https://github.com/gruntjs/grunt/pull/1570)
+ - Avoiding infinite loop on very long command names.
+ (PR: https://github.com/gruntjs/grunt/pull/1697)
+v1.1.0
+ date: 2020-03-16
+ changes:
+ - Update to mkdirp ~1.0.3
+ - Only support versions of Node >= 8
+v1.0.4
+ date: 2019-04-22
+ changes:
+ - Update js-yaml to address https://npmjs.com/advisories/788
+ - Use SOURCE_DATE_EPOCH to render dates in template.
+v1.0.3
+ date: 2018-06-03
+ changes:
+ - Drop support for Node 0.10 and 0.12.
+ - Dependency updates: rimraf, grunt-legacy-log, grunt-legacy-util.
+ - Fix race condition with file.mkdir.
+v1.0.2
+ date: 2018-02-07
+ changes:
+ - Fix for readYAML error messages.
+ - Remove deprecation warning for coffeescript. Pull #1621.
+v1.0.1
+ date: 2016-04-05
+ changes:
+ - minor fix for npm issues when installing grunt and grunt-cli at the same time. Pull #1500.
+v1.0.0
+ date: 2016-04-04
+ changes:
+ - full list of changes is on http://gruntjs.com, please also see changes from 1.0.0-rc1.
+ - if you have a Grunt plugin that includes `grunt` in the `peerDependencies`,
+ we recommend tagging with `"grunt": "">= 0.4.0"` and publishing a new version on npm.
+ - Prevent async callback from being called multiple times. Pull #1464.
+ - Update copyright to jQuery Foundation and remove redundant headers. Fixes #1478.
+ - Update glob to 7.0.x. Fixes #1467.
+ - Removing duplicate BOM strip code. Pull #1482.
+ - Update legacy log and util to 1.0.0.
+ - Update to latest cli ~1.2.0.
+ - Use grunt-known-options for shared options between Grunt and grunt-cli.
+v1.0.0-rc1
+ date: 2016-02-11
+ changes:
+ - full list of changes is on http://gruntjs.com
+ - if you have a Grunt plugin that includes `grunt` in the `peerDependencies`,
+ we recommend tagging with `"grunt": "">= 0.4.0"`
+ - `coffee-script` is upgraded to `~1.10.0` which could incur breaking changes
+ when using the language with plugins and Gruntfiles.
+ - `nopt` is upgraded to `~3.0.6` which has fixed many issues, including passing
+ multiple arguments and dealing with numbers as options. Be aware previously
+ `--foo bar` used to pass the value `'bar'` to the option `foo`. It will now
+ set the option `foo` to `true` and run the task `bar`.
+ -`glob` is upgraded to `~6.0.4` and `minimatch` is upgraded to `~3.0.0`. Results
+ are now sorted by default with `grunt.file.expandMapping()`. Pass the
+ `nosort: true` option if you don't want the results to be sorted.
+ - `lodash` was upgraded to `~4.3.0`. Many changes have occurred. Some of which
+ that directly effect Grunt are `grunt.util._.template()` returns a compile
+ function and `grunt.util._.flatten` no longer flattens deeply.
+ `grunt.util._` is deprecated and we highly encourage you to
+ `npm install lodash` and `var _ = require('lodash')` to use `lodash`.
+ Please see the lodash changelog for a full list of changes: https://github.com/lodash/lodash/wiki/Changelog
+ - `iconv-lite` is upgraded to `~0.4.13` and strips the BOM by default.
+ - `js-yaml` is upgraded to `~3.5.2` and may affect `grunt.file.readYAML`.
+ We encourage you to please `npm install js-yaml` and use
+ `var YAML = require('js-yaml')` directly in case of future deprecations.
+ - A file `mode` option can be passed into
+ [grunt.file.write()](http://gruntjs.com/api/grunt.file#grunt.file.write).
+ - `Done, without errors.` was changed to `Done.` to avoid failing by mistake
+ on the word `errors`.
+v0.4.5:
+ date: 2014-05-12
+ changes:
+ - Updated rimraf to 2.2.8. Closes gh-1134.
+ - Moved grunt.log into separate grunt-legacy-log module.
+ - Updated grunt-legacy-util to 0.2.0. Closes gh-971, gh-1129, gh-1118.
+ - Added grunt.task.exists method to check if a task exists. Closes gh-1131.
+ - Added grunt.config.merge method to deep merge config data. See gh-1039.
+ - Fixed symlink issues with 'file.isPathCwd' and 'file.doesPathContain'. Closes gh-1112.
+ - Config and util.recurse no longer mangle Buffer instances. See gh-971.
+ - Config and util.recurse now enumerate inherited object properties. See gh-1129.
+ - Config and util.recurse now throw useful circular reference error. See gh-1118.
+ - Warn instead of error when no new tasks found via '.loadTasks' method. Closes gh-1059.
+ - Added Windows CI testing. Closes gh-1110.
+ - Removed "CONTRIBUTING.md" from .npmignore. Closes gh-1093.
+v0.4.4:
+ date: 2014-03-12
+ changes:
+ - Only signal completion of tasks async if grunt.task.start is invoked with `{asyncDone:true}`.
+v0.4.3:
+ date: 2014-03-07
+ changes:
+ - When devving Grunt, do "npm install && npm uninstall grunt" (isaacs/npm#3958)
+ - Grunt is now tested on Node.js 0.11
+ - Extracted internal "util" lib to "grunt-legacy-util" lib
+ - task.normalizeMultiTaskFiles now flattens nested "files" arrays. Closes gh-1034.
+ - Better error in renameTask if task doesn't exist. Closes gh-1058.
+ - Update rimraf to latest version. Closes gh-1043.
+ - Empty string "ext" should strip extension. Closes gh-1087.
+ - Add expandMapping .extDot option. Can be 'first' or 'last' but defaults to 'first'. Closes gh-979.
+ - Add default array for util.spawn optional args. Closes gh-1064.
+ - util.spawn "grunt" option now uses proper Node, passes Node exec options. Closes gh-980, gh-981, gh-877.
+ - Make all tasks asynchronous to reduce call stack. Closes gh-1026.
+ - Fix <%= grunt.task.current.target %> in Multitask files. Closes gh-994.
+ - Generalize cli tests, see gh-983, gh-991.
+ - --debug option can optionally be Boolean. Closes Gh-983, gh-991.
+v0.4.2:
+ date: 2013-11-21
+ changes:
+ - Extract internal "namespace" lib to external "getobject" lib.
+ - '"Grunt collections" are now deprecated, use peerDependencies. See "grunt-contrib" 0.8.0 for details.'
+ - Fix stdout / stderr issues on Windows. Closes gh-940, gh-921, gh-744, gh-792, gh-644, gh-708.
+ - Fix pipe-redirecting on Windows. Closes gh-510.
+ - Fixed this.options() in renamed basic tasks. Closes gh-855.
+ - Update underscore.string dependency to follow semver. Closes gh-886.
+ - Output task options in verbose mode. Closes gh-749.
+ - Add file.preserveBOM property. Closes gh-806, gh-937.
+ - Test that file methods warn. Closes gh-909.
+ - Fixed a few spelling errors in code comments. Closes gh-849.
+ - Updated watch, jshint and nodeunit deps. Closes gh-914.
+v0.4.1:
+ date: 2013-03-13
+ changes:
+ - Fix path.join thrown errors with expandMapping rename. Closes gh-725.
+ - Update copyright date to 2013. Closes gh-660.
+ - Remove some side effects from manually requiring Grunt. Closes gh-605.
+ - "grunt.log: add formatting support and implicitly cast msg to a string. Closes gh-703."
+ - Update js-yaml to version 2. Closes gh-683.
+ - The grunt.util.spawn method now falls back to stdout when the `grunt` option is set. Closes gh-691.
+ - Making --verbose "Files:" warnings less scary. Closes gh-657.
+ - "Fixing typo: the grunt.fatal method now defaults to FATAL_ERROR. Closes gh-656, gh-707."
+ - Removed a duplicate line. Closes gh-702.
+ - Gruntfile name should no longer be case sensitive. Closes gh-685.
+ - The grunt.file.delete method warns and returns false if file doesn't exist. Closes gh-635, gh-714.
+ - The grunt.package property is now resolved via require(). Closes gh-704.
+ - The grunt.util.spawn method no longer breaks on multibyte stdio. Closes gh-710.
+ - Fix "path.join arguments must be strings" error in file.expand/recurse when options.cwd is not set. Closes gh-722.
+ - Adding a fairly relevant keyword to package.json (task).
+v0.4.0:
+ date: 2013-02-18
+ changes:
+ - Initial release of 0.4.0.
+ - See http://gruntjs.com/upgrading-from-0.3-to-0.4 for a list of changes / migration guide.
diff --git a/node_modules/grunt/LICENSE b/node_modules/grunt/LICENSE
new file mode 100644
index 0000000..dcf8a0c
--- /dev/null
+++ b/node_modules/grunt/LICENSE
@@ -0,0 +1,35 @@
+Copyright jQuery Foundation and other contributors, https://jquery.org/
+
+This software consists of voluntary contributions made by many
+individuals. For exact contribution history, see the revision history
+available at https://github.com/gruntjs/grunt .
+
+The following license applies to all parts of this software except as
+documented below:
+
+====
+
+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.
+
+====
+
+All files located in the node_modules directory are externally maintained
+libraries used by this software which have their own licenses; we recommend
+you read them, as their terms may differ from the terms above.
\ No newline at end of file
diff --git a/node_modules/grunt/README.md b/node_modules/grunt/README.md
new file mode 100644
index 0000000..f997653
--- /dev/null
+++ b/node_modules/grunt/README.md
@@ -0,0 +1,25 @@
+# Grunt: The JavaScript Task Runner
+
+[](https://travis-ci.org/gruntjs/grunt)
+[](https://ci.appveyor.com/project/gruntjs/grunt/branch/master)
+[](http://gruntjs.com/)
+[](https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fgruntjs%2Fgrunt?ref=badge_shield)
+
+<img align="right" height="260" src="http://gruntjs.com/img/grunt-logo-no-wordmark.svg">
+
+
+### Documentation
+
+Visit the [gruntjs.com](https://gruntjs.com/) website for all the things.
+
+### Support / Contributing
+Before you make an issue, please read our [Contributing](https://gruntjs.com/contributing) guide.
+
+You can find the grunt team in [#grunt on irc.freenode.net](https://webchat.freenode.net/?channels=grunt).
+
+### Release History
+See the [CHANGELOG](CHANGELOG).
+
+### License
+
+[MIT](LICENSE)
diff --git a/node_modules/grunt/bin/grunt b/node_modules/grunt/bin/grunt
new file mode 100644
index 0000000..9ffa444
--- /dev/null
+++ b/node_modules/grunt/bin/grunt
@@ -0,0 +1,3 @@
+#!/usr/bin/env node
+
+require('grunt-cli/bin/grunt');
diff --git a/node_modules/grunt/lib/grunt.js b/node_modules/grunt/lib/grunt.js
new file mode 100644
index 0000000..0253333
--- /dev/null
+++ b/node_modules/grunt/lib/grunt.js
@@ -0,0 +1,174 @@
+'use strict';
+
+// Nodejs libs.
+var path = require('path');
+
+// This allows grunt to require() .coffee files.
+try {
+ // Note: grunt no longer depends on CoffeeScript, it will only use it if it is intentionally
+ // installed in the project.
+ require('coffeescript/register');
+} catch (e) {
+ // This is fine, and will cause no problems so long as the user doesn't load .coffee files.
+ // Print a useful error if we attempt to load a .coffee file.
+ if (require.extensions) {
+ var FILE_EXTENSIONS = ['.coffee', '.litcoffee', '.coffee.md'];
+ for (var i = 0; i < FILE_EXTENSIONS.length; i++) {
+ require.extensions[FILE_EXTENSIONS[i]] = function() {
+ throw new Error(
+ 'Grunt attempted to load a .coffee file but CoffeeScript was not installed.\n' +
+ 'Please run `npm install --dev coffeescript` to enable loading CoffeeScript.'
+ );
+ };
+ }
+ }
+}
+
+// The module to be exported.
+var grunt = module.exports = {};
+
+// Expose internal grunt libs.
+function gRequire(name) {
+ return grunt[name] = require('./grunt/' + name);
+}
+
+var util = require('grunt-legacy-util');
+grunt.util = util;
+grunt.util.task = require('./util/task');
+
+var Log = require('grunt-legacy-log').Log;
+var log = new Log({grunt: grunt});
+grunt.log = log;
+
+gRequire('template');
+gRequire('event');
+var fail = gRequire('fail');
+gRequire('file');
+var option = gRequire('option');
+var config = gRequire('config');
+var task = gRequire('task');
+var help = gRequire('help');
+gRequire('cli');
+var verbose = grunt.verbose = log.verbose;
+
+// Expose some grunt metadata.
+grunt.package = require('../package.json');
+grunt.version = grunt.package.version;
+
+// Expose specific grunt lib methods on grunt.
+function gExpose(obj, methodName, newMethodName) {
+ grunt[newMethodName || methodName] = obj[methodName].bind(obj);
+}
+gExpose(task, 'registerTask');
+gExpose(task, 'registerMultiTask');
+gExpose(task, 'registerInitTask');
+gExpose(task, 'renameTask');
+gExpose(task, 'loadTasks');
+gExpose(task, 'loadNpmTasks');
+gExpose(config, 'init', 'initConfig');
+gExpose(fail, 'warn');
+gExpose(fail, 'fatal');
+
+// Expose the task interface. I've never called this manually, and have no idea
+// how it will work. But it might.
+grunt.tasks = function(tasks, options, done) {
+ // Update options with passed-in options.
+ option.init(options);
+
+ // Display the grunt version and quit if the user did --version.
+ var _tasks, _options;
+ if (option('version')) {
+ // Not --verbose.
+ log.writeln('grunt v' + grunt.version);
+
+ if (option('verbose')) {
+ // --verbose
+ verbose.writeln('Install path: ' + path.resolve(__dirname, '..'));
+ // Yes, this is a total hack, but we don't want to log all that verbose
+ // task initialization stuff here.
+ grunt.log.muted = true;
+ // Initialize task system so that available tasks can be listed.
+ grunt.task.init([], {help: true});
+ // Re-enable logging.
+ grunt.log.muted = false;
+
+ // Display available tasks (for shell completion, etc).
+ _tasks = Object.keys(grunt.task._tasks).sort();
+ verbose.writeln('Available tasks: ' + _tasks.join(' '));
+
+ // Display available options (for shell completion, etc).
+ _options = [];
+ Object.keys(grunt.cli.optlist).forEach(function(long) {
+ var o = grunt.cli.optlist[long];
+ _options.push('--' + (o.negate ? 'no-' : '') + long);
+ if (o.short) { _options.push('-' + o.short); }
+ });
+ verbose.writeln('Available options: ' + _options.join(' '));
+ }
+
+ return;
+ }
+
+ // Init colors.
+ log.initColors();
+
+ // Display help and quit if the user did --help.
+ if (option('help')) {
+ help.display();
+ return;
+ }
+
+ // A little header stuff.
+ verbose.header('Initializing').writeflags(option.flags(), 'Command-line options');
+
+ // Determine and output which tasks will be run.
+ var tasksSpecified = tasks && tasks.length > 0;
+ tasks = task.parseArgs([tasksSpecified ? tasks : 'default']);
+
+ // Initialize tasks.
+ task.init(tasks, options);
+
+ verbose.writeln();
+ if (!tasksSpecified) {
+ verbose.writeln('No tasks specified, running default tasks.');
+ }
+ verbose.writeflags(tasks, 'Running tasks');
+
+ // Handle otherwise unhandleable (probably asynchronous) exceptions.
+ var uncaughtHandler = function(e) {
+ fail.fatal(e, fail.code.TASK_FAILURE);
+ };
+ process.on('uncaughtException', uncaughtHandler);
+
+ // Report, etc when all tasks have completed.
+ task.options({
+ error: function(e) {
+ fail.warn(e, fail.code.TASK_FAILURE);
+ },
+ done: function() {
+ // Stop handling uncaught exceptions so that we don't leave any
+ // unwanted process-level side effects behind. There is no need to do
+ // this in the error callback, because fail.warn() will either kill
+ // the process, or with --force keep on going all the way here.
+ process.removeListener('uncaughtException', uncaughtHandler);
+
+ // Output a final fail / success report.
+ fail.report();
+
+ if (done) {
+ // Execute "done" function when done (only if passed, of course).
+ done();
+ } else {
+ // Otherwise, explicitly exit.
+ util.exit(0);
+ }
+ }
+ });
+
+ // Execute all tasks, in order. Passing each task individually in a forEach
+ // allows the error callback to execute multiple times.
+ tasks.forEach(function(name) { task.run(name); });
+ // Run tasks async internally to reduce call-stack, per:
+ // https://github.com/gruntjs/grunt/pull/1026
+ task.start({asyncDone: true});
+};
diff --git a/node_modules/grunt/lib/grunt/cli.js b/node_modules/grunt/lib/grunt/cli.js
new file mode 100644
index 0000000..1252f54
--- /dev/null
+++ b/node_modules/grunt/lib/grunt/cli.js
@@ -0,0 +1,55 @@
+'use strict';
+
+var grunt = require('../grunt');
+
+// External libs.
+var nopt = require('nopt');
+var gruntOptions = require('grunt-known-options');
+
+// This is only executed when run via command line.
+var cli = module.exports = function(options, done) {
+ // CLI-parsed options override any passed-in "default" options.
+ if (options) {
+ // For each default option...
+ Object.keys(options).forEach(function(key) {
+ if (!(key in cli.options)) {
+ // If this option doesn't exist in the parsed cli.options, add it in.
+ cli.options[key] = options[key];
+ } else if (cli.optlist[key].type === Array) {
+ // If this option's type is Array, append it to any existing array
+ // (or create a new array).
+ [].push.apply(cli.options[key], options[key]);
+ }
+ });
+ }
+
+ // Run tasks.
+ grunt.tasks(cli.tasks, cli.options, done);
+};
+
+// Default options.
+var optlist = cli.optlist = gruntOptions;
+
+// Parse `optlist` into a form that nopt can handle.
+var aliases = {};
+var known = {};
+
+Object.keys(optlist).forEach(function(key) {
+ var short = optlist[key].short;
+ if (short) {
+ aliases[short] = '--' + key;
+ }
+ known[key] = optlist[key].type;
+});
+
+var parsed = nopt(known, aliases, process.argv, 2);
+cli.tasks = parsed.argv.remain;
+cli.options = parsed;
+delete parsed.argv;
+
+// Initialize any Array options that weren't initialized.
+Object.keys(optlist).forEach(function(key) {
+ if (optlist[key].type === Array && !(key in cli.options)) {
+ cli.options[key] = [];
+ }
+});
diff --git a/node_modules/grunt/lib/grunt/config.js b/node_modules/grunt/lib/grunt/config.js
new file mode 100644
index 0000000..ef2bf80
--- /dev/null
+++ b/node_modules/grunt/lib/grunt/config.js
@@ -0,0 +1,115 @@
+'use strict';
+
+var grunt = require('../grunt');
+
+// Get/set config data. If value was passed, set. Otherwise, get.
+var config = module.exports = function(prop, value) {
+ if (arguments.length === 2) {
+ // Two arguments were passed, set the property's value.
+ return config.set(prop, value);
+ } else {
+ // Get the property's value (or the entire data object).
+ return config.get(prop);
+ }
+};
+
+// The actual config data.
+config.data = {};
+
+// Escape any . in name with \. so dot-based namespacing works properly.
+config.escape = function(str) {
+ return str.replace(/\./g, '\\.');
+};
+
+// Return prop as a string.
+config.getPropString = function(prop) {
+ return Array.isArray(prop) ? prop.map(config.escape).join('.') : prop;
+};
+
+// Get raw, unprocessed config data.
+config.getRaw = function(prop) {
+ if (prop) {
+ // Prop was passed, get that specific property's value.
+ return grunt.util.namespace.get(config.data, config.getPropString(prop));
+ } else {
+ // No prop was passed, return the entire config.data object.
+ return config.data;
+ }
+};
+
+// Match '<%= FOO %>' where FOO is a propString, eg. foo or foo.bar but not
+// a method call like foo() or foo.bar().
+var propStringTmplRe = /^<%=\s*([a-z0-9_$]+(?:\.[a-z0-9_$]+)*)\s*%>$/i;
+
+// Get config data, recursively processing templates.
+config.get = function(prop) {
+ return config.process(config.getRaw(prop));
+};
+
+// Expand a config value recursively. Used for post-processing raw values
+// already retrieved from the config.
+config.process = function(raw) {
+ return grunt.util.recurse(raw, function(value) {
+ // If the value is not a string, return it.
+ if (typeof value !== 'string') { return value; }
+ // If possible, access the specified property via config.get, in case it
+ // doesn't refer to a string, but instead refers to an object or array.
+ var matches = value.match(propStringTmplRe);
+ var result;
+ if (matches) {
+ result = config.get(matches[1]);
+ // If the result retrieved from the config data wasn't null or undefined,
+ // return it.
+ if (result != null) { return result; }
+ }
+ // Process the string as a template.
+ return grunt.template.process(value, {data: config.data});
+ });
+};
+
+// Set config data.
+config.set = function(prop, value) {
+ return grunt.util.namespace.set(config.data, config.getPropString(prop), value);
+};
+
+// Deep merge config data.
+config.merge = function(obj) {
+ grunt.util._.merge(config.data, obj);
+ return config.data;
+};
+
+// Initialize config data.
+config.init = function(obj) {
+ grunt.verbose.write('Initializing config...').ok();
+ // Initialize and return data.
+ return (config.data = obj || {});
+};
+
+// Test to see if required config params have been defined. If not, throw an
+// exception (use this inside of a task).
+config.requires = function() {
+ var p = grunt.util.pluralize;
+ var props = grunt.util.toArray(arguments).map(config.getPropString);
+ var msg = 'Verifying propert' + p(props.length, 'y/ies') +
+ ' ' + grunt.log.wordlist(props) + ' exist' + p(props.length, 's') +
+ ' in config...';
+ grunt.verbose.write(msg);
+ var failProps = config.data && props.filter(function(prop) {
+ return config.get(prop) == null;
+ }).map(function(prop) {
+ return '"' + prop + '"';
+ });
+ if (config.data && failProps.length === 0) {
+ grunt.verbose.ok();
+ return true;
+ } else {
+ grunt.verbose.or.write(msg);
+ grunt.log.error().error('Unable to process task.');
+ if (!config.data) {
+ throw grunt.util.error('Unable to load config.');
+ } else {
+ throw grunt.util.error('Required config propert' +
+ p(failProps.length, 'y/ies') + ' ' + failProps.join(', ') + ' missing.');
+ }
+ }
+};
diff --git a/node_modules/grunt/lib/grunt/event.js b/node_modules/grunt/lib/grunt/event.js
new file mode 100644
index 0000000..7ec1027
--- /dev/null
+++ b/node_modules/grunt/lib/grunt/event.js
@@ -0,0 +1,7 @@
+'use strict';
+
+// External lib.
+var EventEmitter2 = require('eventemitter2').EventEmitter2;
+
+// Awesome.
+module.exports = new EventEmitter2({wildcard: true});
diff --git a/node_modules/grunt/lib/grunt/fail.js b/node_modules/grunt/lib/grunt/fail.js
new file mode 100644
index 0000000..631e249
--- /dev/null
+++ b/node_modules/grunt/lib/grunt/fail.js
@@ -0,0 +1,75 @@
+'use strict';
+
+var grunt = require('../grunt');
+
+// The module to be exported.
+var fail = module.exports = {};
+
+// Error codes.
+fail.code = {
+ FATAL_ERROR: 1,
+ MISSING_GRUNTFILE: 2,
+ TASK_FAILURE: 3,
+ TEMPLATE_ERROR: 4,
+ INVALID_AUTOCOMPLETE: 5,
+ WARNING: 6,
+};
+
+// DRY it up!
+function writeln(e, mode) {
+ grunt.log.muted = false;
+ var msg = String(e.message || e);
+ if (!grunt.option('no-color')) { msg += '\x07'; } // Beep!
+ if (mode === 'warn') {
+ msg = 'Warning: ' + msg + ' ';
+ msg += (grunt.option('force') ? 'Used --force, continuing.'.underline : 'Use --force to continue.');
+ msg = msg.yellow;
+ } else {
+ msg = ('Fatal error: ' + msg).red;
+ }
+ grunt.log.writeln(msg);
+}
+
+// If --stack is enabled, log the appropriate error stack (if it exists).
+function dumpStack(e) {
+ if (grunt.option('stack')) {
+ if (e.origError && e.origError.stack) {
+ console.log(e.origError.stack);
+ } else if (e.stack) {
+ console.log(e.stack);
+ }
+ }
+}
+
+// A fatal error occurred. Abort immediately.
+fail.fatal = function(e, errcode) {
+ writeln(e, 'fatal');
+ dumpStack(e);
+ grunt.util.exit(typeof errcode === 'number' ? errcode : fail.code.FATAL_ERROR);
+};
+
+// Keep track of error and warning counts.
+fail.errorcount = 0;
+fail.warncount = 0;
+
+// A warning occurred. Abort immediately unless -f or --force was used.
+fail.warn = function(e, errcode) {
+ var message = typeof e === 'string' ? e : e.message;
+ fail.warncount++;
+ writeln(message, 'warn');
+ // If -f or --force aren't used, stop script processing.
+ if (!grunt.option('force')) {
+ dumpStack(e);
+ grunt.log.writeln().fail('Aborted due to warnings.');
+ grunt.util.exit(typeof errcode === 'number' ? errcode : fail.code.WARNING);
+ }
+};
+
+// This gets called at the very end.
+fail.report = function() {
+ if (fail.warncount > 0) {
+ grunt.log.writeln().fail('Done, but with warnings.');
+ } else {
+ grunt.log.writeln().success('Done.');
+ }
+};
diff --git a/node_modules/grunt/lib/grunt/file.js b/node_modules/grunt/lib/grunt/file.js
new file mode 100644
index 0000000..7e0e2fb
--- /dev/null
+++ b/node_modules/grunt/lib/grunt/file.js
@@ -0,0 +1,460 @@
+'use strict';
+
+var grunt = require('../grunt');
+
+// Nodejs libs.
+var fs = require('fs');
+var path = require('path');
+
+// The module to be exported.
+var file = module.exports = {};
+
+// External libs.
+file.glob = require('glob');
+file.minimatch = require('minimatch');
+file.findup = require('findup-sync');
+var YAML = require('js-yaml');
+var rimraf = require('rimraf');
+var iconv = require('iconv-lite');
+var mkdirp = require('mkdirp').sync;
+
+// Windows?
+var win32 = process.platform === 'win32';
+
+// Normalize \\ paths to / paths.
+var unixifyPath = function(filepath) {
+ if (win32) {
+ return filepath.replace(/\\/g, '/');
+ } else {
+ return filepath;
+ }
+};
+
+// Change the current base path (ie, CWD) to the specified path.
+file.setBase = function() {
+ var dirpath = path.join.apply(path, arguments);
+ process.chdir(dirpath);
+};
+
+// Process specified wildcard glob patterns or filenames against a
+// callback, excluding and uniquing files in the result set.
+var processPatterns = function(patterns, fn) {
+ // Filepaths to return.
+ var result = [];
+ // Iterate over flattened patterns array.
+ grunt.util._.flattenDeep(patterns).forEach(function(pattern) {
+ // If the first character is ! it should be omitted
+ var exclusion = pattern.indexOf('!') === 0;
+ // If the pattern is an exclusion, remove the !
+ if (exclusion) { pattern = pattern.slice(1); }
+ // Find all matching files for this pattern.
+ var matches = fn(pattern);
+ if (exclusion) {
+ // If an exclusion, remove matching files.
+ result = grunt.util._.difference(result, matches);
+ } else {
+ // Otherwise add matching files.
+ result = grunt.util._.union(result, matches);
+ }
+ });
+ return result;
+};
+
+// Match a filepath or filepaths against one or more wildcard patterns. Returns
+// all matching filepaths.
+file.match = function(options, patterns, filepaths) {
+ if (grunt.util.kindOf(options) !== 'object') {
+ filepaths = patterns;
+ patterns = options;
+ options = {};
+ }
+ // Return empty set if either patterns or filepaths was omitted.
+ if (patterns == null || filepaths == null) { return []; }
+ // Normalize patterns and filepaths to arrays.
+ if (!Array.isArray(patterns)) { patterns = [patterns]; }
+ if (!Array.isArray(filepaths)) { filepaths = [filepaths]; }
+ // Return empty set if there are no patterns or filepaths.
+ if (patterns.length === 0 || filepaths.length === 0) { return []; }
+ // Return all matching filepaths.
+ return processPatterns(patterns, function(pattern) {
+ return file.minimatch.match(filepaths, pattern, options);
+ });
+};
+
+// Match a filepath or filepaths against one or more wildcard patterns. Returns
+// true if any of the patterns match.
+file.isMatch = function() {
+ return file.match.apply(file, arguments).length > 0;
+};
+
+// Return an array of all file paths that match the given wildcard patterns.
+file.expand = function() {
+ var args = grunt.util.toArray(arguments);
+ // If the first argument is an options object, save those options to pass
+ // into the file.glob.sync method.
+ var options = grunt.util.kindOf(args[0]) === 'object' ? args.shift() : {};
+ // Use the first argument if it's an Array, otherwise convert the arguments
+ // object to an array and use that.
+ var patterns = Array.isArray(args[0]) ? args[0] : args;
+ // Return empty set if there are no patterns or filepaths.
+ if (patterns.length === 0) { return []; }
+ // Return all matching filepaths.
+ var matches = processPatterns(patterns, function(pattern) {
+ // Find all matching files for this pattern.
+ return file.glob.sync(pattern, options);
+ });
+ // Filter result set?
+ if (options.filter) {
+ matches = matches.filter(function(filepath) {
+ filepath = path.join(options.cwd || '', filepath);
+ try {
+ if (typeof options.filter === 'function') {
+ return options.filter(filepath);
+ } else {
+ // If the file is of the right type and exists, this should work.
+ return fs.statSync(filepath)[options.filter]();
+ }
+ } catch (e) {
+ // Otherwise, it's probably not the right type.
+ return false;
+ }
+ });
+ }
+ return matches;
+};
+
+var pathSeparatorRe = /[\/\\]/g;
+
+// The "ext" option refers to either everything after the first dot (default)
+// or everything after the last dot.
+var extDotRe = {
+ first: /(\.[^\/]*)?$/,
+ last: /(\.[^\/\.]*)?$/,
+};
+
+// Build a multi task "files" object dynamically.
+file.expandMapping = function(patterns, destBase, options) {
+ options = grunt.util._.defaults({}, options, {
+ extDot: 'first',
+ rename: function(destBase, destPath) {
+ return path.join(destBase || '', destPath);
+ }
+ });
+ var files = [];
+ var fileByDest = {};
+ // Find all files matching pattern, using passed-in options.
+ file.expand(options, patterns).forEach(function(src) {
+ var destPath = src;
+ // Flatten?
+ if (options.flatten) {
+ destPath = path.basename(destPath);
+ }
+ // Change the extension?
+ if ('ext' in options) {
+ destPath = destPath.replace(extDotRe[options.extDot], options.ext);
+ }
+ // Generate destination filename.
+ var dest = options.rename(destBase, destPath, options);
+ // Prepend cwd to src path if necessary.
+ if (options.cwd) { src = path.join(options.cwd, src); }
+ // Normalize filepaths to be unix-style.
+ dest = dest.replace(pathSeparatorRe, '/');
+ src = src.replace(pathSeparatorRe, '/');
+ // Map correct src path to dest path.
+ if (fileByDest[dest]) {
+ // If dest already exists, push this src onto that dest's src array.
+ fileByDest[dest].src.push(src);
+ } else {
+ // Otherwise create a new src-dest file mapping object.
+ files.push({
+ src: [src],
+ dest: dest,
+ });
+ // And store a reference for later use.
+ fileByDest[dest] = files[files.length - 1];
+ }
+ });
+ return files;
+};
+
+// Like mkdir -p. Create a directory and any intermediary directories.
+file.mkdir = function(dirpath, mode) {
+ if (grunt.option('no-write')) { return; }
+ try {
+ mkdirp(dirpath, { mode: mode });
+ } catch (e) {
+ throw grunt.util.error('Unable to create directory "' + dirpath + '" (Error code: ' + e.code + ').', e);
+ }
+};
+
+// Recurse into a directory, executing callback for each file.
+file.recurse = function recurse(rootdir, callback, subdir) {
+ var abspath = subdir ? path.join(rootdir, subdir) : rootdir;
+ fs.readdirSync(abspath).forEach(function(filename) {
+ var filepath = path.join(abspath, filename);
+ if (fs.statSync(filepath).isDirectory()) {
+ recurse(rootdir, callback, unixifyPath(path.join(subdir || '', filename || '')));
+ } else {
+ callback(unixifyPath(filepath), rootdir, subdir, filename);
+ }
+ });
+};
+
+// The default file encoding to use.
+file.defaultEncoding = 'utf8';
+// Whether to preserve the BOM on file.read rather than strip it.
+file.preserveBOM = false;
+
+// Read a file, return its contents.
+file.read = function(filepath, options) {
+ if (!options) { options = {}; }
+ var contents;
+ grunt.verbose.write('Reading ' + filepath + '...');
+ try {
+ contents = fs.readFileSync(String(filepath));
+ // If encoding is not explicitly null, convert from encoded buffer to a
+ // string. If no encoding was specified, use the default.
+ if (options.encoding !== null) {
+ contents = iconv.decode(contents, options.encoding || file.defaultEncoding, {stripBOM: !file.preserveBOM});
+ }
+ grunt.verbose.ok();
+ return contents;
+ } catch (e) {
+ grunt.verbose.error();
+ throw grunt.util.error('Unable to read "' + filepath + '" file (Error code: ' + e.code + ').', e);
+ }
+};
+
+// Read a file, parse its contents, return an object.
+file.readJSON = function(filepath, options) {
+ var src = file.read(filepath, options);
+ var result;
+ grunt.verbose.write('Parsing ' + filepath + '...');
+ try {
+ result = JSON.parse(src);
+ grunt.verbose.ok();
+ return result;
+ } catch (e) {
+ grunt.verbose.error();
+ throw grunt.util.error('Unable to parse "' + filepath + '" file (' + e.message + ').', e);
+ }
+};
+
+// Read a YAML file, parse its contents, return an object.
+file.readYAML = function(filepath, options, yamlOptions) {
+ if (!options) { options = {}; }
+ if (!yamlOptions) { yamlOptions = {}; }
+
+ var src = file.read(filepath, options);
+ var result;
+ grunt.verbose.write('Parsing ' + filepath + '...');
+ try {
+ // use the recommended way of reading YAML files
+ // https://github.com/nodeca/js-yaml#safeload-string---options-
+ if (yamlOptions.unsafeLoad) {
+ result = YAML.load(src);
+ } else {
+ result = YAML.safeLoad(src);
+ }
+ grunt.verbose.ok();
+ return result;
+ } catch (e) {
+ grunt.verbose.error();
+ throw grunt.util.error('Unable to parse "' + filepath + '" file (' + e.message + ').', e);
+ }
+};
+
+// Write a file.
+file.write = function(filepath, contents, options) {
+ if (!options) { options = {}; }
+ var nowrite = grunt.option('no-write');
+ grunt.verbose.write((nowrite ? 'Not actually writing ' : 'Writing ') + filepath + '...');
+ // Create path, if necessary.
+ file.mkdir(path.dirname(filepath));
+ try {
+ // If contents is already a Buffer, don't try to encode it. If no encoding
+ // was specified, use the default.
+ if (!Buffer.isBuffer(contents)) {
+ contents = iconv.encode(contents, options.encoding || file.defaultEncoding);
+ }
+ // Actually write file.
+ if (!nowrite) {
+ fs.writeFileSync(filepath, contents, 'mode' in options ? {mode: options.mode} : {});
+ }
+ grunt.verbose.ok();
+ return true;
+ } catch (e) {
+ grunt.verbose.error();
+ throw grunt.util.error('Unable to write "' + filepath + '" file (Error code: ' + e.code + ').', e);
+ }
+};
+
+// Read a file, optionally processing its content, then write the output.
+// Or read a directory, recursively creating directories, reading files,
+// processing content, writing output.
+file.copy = function copy(srcpath, destpath, options) {
+ if (file.isDir(srcpath)) {
+ // Copy a directory, recursively.
+ // Explicitly create new dest directory.
+ file.mkdir(destpath);
+ // Iterate over all sub-files/dirs, recursing.
+ fs.readdirSync(srcpath).forEach(function(filepath) {
+ copy(path.join(srcpath, filepath), path.join(destpath, filepath), options);
+ });
+ } else {
+ // Copy a single file.
+ file._copy(srcpath, destpath, options);
+ }
+};
+
+// Read a file, optionally processing its content, then write the output.
+file._copy = function(srcpath, destpath, options) {
+ if (!options) { options = {}; }
+ // If a process function was specified, and noProcess isn't true or doesn't
+ // match the srcpath, process the file's source.
+ var process = options.process && options.noProcess !== true &&
+ !(options.noProcess && file.isMatch(options.noProcess, srcpath));
+ // If the file will be processed, use the encoding as-specified. Otherwise,
+ // use an encoding of null to force the file to be read/written as a Buffer.
+ var readWriteOptions = process ? options : {encoding: null};
+ // Actually read the file.
+ var contents = file.read(srcpath, readWriteOptions);
+ if (process) {
+ grunt.verbose.write('Processing source...');
+ try {
+ contents = options.process(contents, srcpath, destpath);
+ grunt.verbose.ok();
+ } catch (e) {
+ grunt.verbose.error();
+ throw grunt.util.error('Error while processing "' + srcpath + '" file.', e);
+ }
+ }
+ // Abort copy if the process function returns false.
+ if (contents === false) {
+ grunt.verbose.writeln('Write aborted.');
+ } else {
+ file.write(destpath, contents, readWriteOptions);
+ }
+};
+
+// Delete folders and files recursively
+file.delete = function(filepath, options) {
+ filepath = String(filepath);
+
+ var nowrite = grunt.option('no-write');
+ if (!options) {
+ options = {force: grunt.option('force') || false};
+ }
+
+ grunt.verbose.write((nowrite ? 'Not actually deleting ' : 'Deleting ') + filepath + '...');
+
+ if (!file.exists(filepath)) {
+ grunt.verbose.error();
+ grunt.log.warn('Cannot delete nonexistent file.');
+ return false;
+ }
+
+ // Only delete cwd or outside cwd if --force enabled. Be careful, people!
+ if (!options.force) {
+ if (file.isPathCwd(filepath)) {
+ grunt.verbose.error();
+ grunt.fail.warn('Cannot delete the current working directory.');
+ return false;
+ } else if (!file.isPathInCwd(filepath)) {
+ grunt.verbose.error();
+ grunt.fail.warn('Cannot delete files outside the current working directory.');
+ return false;
+ }
+ }
+
+ try {
+ // Actually delete. Or not.
+ if (!nowrite) {
+ rimraf.sync(filepath);
+ }
+ grunt.verbose.ok();
+ return true;
+ } catch (e) {
+ grunt.verbose.error();
+ throw grunt.util.error('Unable to delete "' + filepath + '" file (' + e.message + ').', e);
+ }
+};
+
+// True if the file path exists.
+file.exists = function() {
+ var filepath = path.join.apply(path, arguments);
+ return fs.existsSync(filepath);
+};
+
+// True if the file is a symbolic link.
+file.isLink = function() {
+ var filepath = path.join.apply(path, arguments);
+ try {
+ return fs.lstatSync(filepath).isSymbolicLink();
+ } catch (e) {
+ if (e.code === 'ENOENT') {
+ // The file doesn't exist, so it's not a symbolic link.
+ return false;
+ }
+ throw grunt.util.error('Unable to read "' + filepath + '" file (Error code: ' + e.code + ').', e);
+ }
+};
+
+// True if the path is a directory.
+file.isDir = function() {
+ var filepath = path.join.apply(path, arguments);
+ return file.exists(filepath) && fs.statSync(filepath).isDirectory();
+};
+
+// True if the path is a file.
+file.isFile = function() {
+ var filepath = path.join.apply(path, arguments);
+ return file.exists(filepath) && fs.statSync(filepath).isFile();
+};
+
+// Is a given file path absolute?
+file.isPathAbsolute = function() {
+ var filepath = path.join.apply(path, arguments);
+ return path.isAbsolute(filepath);
+};
+
+// Do all the specified paths refer to the same path?
+file.arePathsEquivalent = function(first) {
+ first = path.resolve(first);
+ for (var i = 1; i < arguments.length; i++) {
+ if (first !== path.resolve(arguments[i])) { return false; }
+ }
+ return true;
+};
+
+// Are descendant path(s) contained within ancestor path? Note: does not test
+// if paths actually exist.
+file.doesPathContain = function(ancestor) {
+ ancestor = path.resolve(ancestor);
+ var relative;
+ for (var i = 1; i < arguments.length; i++) {
+ relative = path.relative(path.resolve(arguments[i]), ancestor);
+ if (relative === '' || /\w+/.test(relative)) { return false; }
+ }
+ return true;
+};
+
+// Test to see if a filepath is the CWD.
+file.isPathCwd = function() {
+ var filepath = path.join.apply(path, arguments);
+ try {
+ return file.arePathsEquivalent(fs.realpathSync(process.cwd()), fs.realpathSync(filepath));
+ } catch (e) {
+ return false;
+ }
+};
+
+// Test to see if a filepath is contained within the CWD.
+file.isPathInCwd = function() {
+ var filepath = path.join.apply(path, arguments);
+ try {
+ return file.doesPathContain(fs.realpathSync(process.cwd()), fs.realpathSync(filepath));
+ } catch (e) {
+ return false;
+ }
+};
diff --git a/node_modules/grunt/lib/grunt/help.js b/node_modules/grunt/lib/grunt/help.js
new file mode 100644
index 0000000..d761ef5
--- /dev/null
+++ b/node_modules/grunt/lib/grunt/help.js
@@ -0,0 +1,120 @@
+'use strict';
+
+var grunt = require('../grunt');
+
+// Nodejs libs.
+var path = require('path');
+
+// Set column widths.
+var col1len = 0;
+exports.initCol1 = function(str) {
+ col1len = Math.max(col1len, str.length);
+};
+exports.initWidths = function() {
+ // Widths for options/tasks table output.
+ var commandWidth = Math.max(col1len + 20, 76);
+ exports.widths = [1, col1len, 2, commandWidth - col1len];
+};
+
+// Render an array in table form.
+exports.table = function(arr) {
+ arr.forEach(function(item) {
+ grunt.log.writetableln(exports.widths, ['', grunt.util._.pad(item[0], col1len), '', item[1]]);
+ });
+};
+
+// Methods to run, in-order.
+exports.queue = [
+ 'initOptions',
+ 'initTasks',
+ 'initWidths',
+ 'header',
+ 'usage',
+ 'options',
+ 'optionsFooter',
+ 'tasks',
+ 'footer',
+];
+
+// Actually display stuff.
+exports.display = function() {
+ exports.queue.forEach(function(name) { exports[name](); });
+};
+
+// Header.
+exports.header = function() {
+ grunt.log.writeln('Grunt: The JavaScript Task Runner (v' + grunt.version + ')');
+};
+
+// Usage info.
+exports.usage = function() {
+ grunt.log.header('Usage');
+ grunt.log.writeln(' ' + path.basename(process.argv[1]) + ' [options] [task [task ...]]');
+};
+
+// Options.
+exports.initOptions = function() {
+ // Build 2-column array for table view.
+ exports._options = Object.keys(grunt.cli.optlist).map(function(long) {
+ var o = grunt.cli.optlist[long];
+ var col1 = '--' + (o.negate ? 'no-' : '') + long + (o.short ? ', -' + o.short : '');
+ exports.initCol1(col1);
+ return [col1, o.info];
+ });
+};
+
+exports.options = function() {
+ grunt.log.header('Options');
+ exports.table(exports._options);
+};
+
+exports.optionsFooter = function() {
+ grunt.log.writeln().writelns(
+ 'Options marked with * have methods exposed via the grunt API and should ' +
+ 'instead be specified inside the Gruntfile wherever possible.'
+ );
+};
+
+// Tasks.
+exports.initTasks = function() {
+ // Initialize task system so that the tasks can be listed.
+ grunt.task.init([], {help: true});
+
+ // Build object of tasks by info (where they were loaded from).
+ exports._tasks = [];
+ Object.keys(grunt.task._tasks).forEach(function(name) {
+ exports.initCol1(name);
+ var task = grunt.task._tasks[name];
+ exports._tasks.push(task);
+ });
+};
+
+exports.tasks = function() {
+ grunt.log.header('Available tasks');
+ if (exports._tasks.length === 0) {
+ grunt.log.writeln('(no tasks found)');
+ } else {
+ exports.table(exports._tasks.map(function(task) {
+ var info = task.info;
+ if (task.multi) { info += ' *'; }
+ return [task.name, info];
+ }));
+
+ grunt.log.writeln().writelns(
+ 'Tasks run in the order specified. Arguments may be passed to tasks that ' +
+ 'accept them by using colons, like "lint:files". Tasks marked with * are ' +
+ '"multi tasks" and will iterate over all sub-targets if no argument is ' +
+ 'specified.'
+ );
+ }
+
+ grunt.log.writeln().writelns(
+ 'The list of available tasks may change based on tasks directories or ' +
+ 'grunt plugins specified in the Gruntfile or via command-line options.'
+ );
+};
+
+// Footer.
+exports.footer = function() {
+ grunt.log.writeln().writeln('For more information, see http://gruntjs.com/');
+};
diff --git a/node_modules/grunt/lib/grunt/option.js b/node_modules/grunt/lib/grunt/option.js
new file mode 100644
index 0000000..bfb4074
--- /dev/null
+++ b/node_modules/grunt/lib/grunt/option.js
@@ -0,0 +1,38 @@
+'use strict';
+
+// The actual option data.
+var data = {};
+
+// Get or set an option value.
+var option = module.exports = function(key, value) {
+ var no = key.match(/^no-(.+)$/);
+ if (arguments.length === 2) {
+ return (data[key] = value);
+ } else if (no) {
+ return data[no[1]] === false;
+ } else {
+ return data[key];
+ }
+};
+
+// Initialize option data.
+option.init = function(obj) {
+ return (data = obj || {});
+};
+
+// List of options as flags.
+option.flags = function() {
+ return Object.keys(data).filter(function(key) {
+ // Don't display empty arrays.
+ return !(Array.isArray(data[key]) && data[key].length === 0);
+ }).map(function(key) {
+ var val = data[key];
+ return '--' + (val === false ? 'no-' : '') + key +
+ (typeof val === 'boolean' ? '' : '=' + val);
+ });
+};
+
+// Get all option keys
+option.keys = function() {
+ return Object.keys(data);
+};
diff --git a/node_modules/grunt/lib/grunt/task.js b/node_modules/grunt/lib/grunt/task.js
new file mode 100644
index 0000000..ffd119e
--- /dev/null
+++ b/node_modules/grunt/lib/grunt/task.js
@@ -0,0 +1,471 @@
+'use strict';
+
+// Keep track of the number of log.error() calls and the last specified tasks message.
+var errorcount, lastInfo;
+
+var grunt = require('../grunt');
+
+// Nodejs libs.
+var path = require('path');
+
+// Extend generic "task" util lib.
+var parent = grunt.util.task.create();
+
+// The module to be exported.
+var task = module.exports = Object.create(parent);
+
+// A temporary registry of tasks and metadata.
+var registry = {tasks: [], untasks: [], meta: {}};
+
+// Number of levels of recursion when loading tasks in collections.
+var loadTaskDepth = 0;
+
+// Override built-in registerTask.
+task.registerTask = function(name) {
+ // Add task to registry.
+ registry.tasks.push(name);
+ // Register task.
+ parent.registerTask.apply(task, arguments);
+ // This task, now that it's been registered.
+ var thisTask = task._tasks[name];
+ // Metadata about the current task.
+ thisTask.meta = grunt.util._.clone(registry.meta);
+ // Override task function.
+ var _fn = thisTask.fn;
+ thisTask.fn = function(arg) {
+ // Guaranteed to always be the actual task name.
+ var name = thisTask.name;
+ // Initialize the errorcount for this task.
+ errorcount = grunt.fail.errorcount;
+ // Return the number of errors logged during this task.
+ Object.defineProperty(this, 'errorCount', {
+ enumerable: true,
+ get: function() {
+ return grunt.fail.errorcount - errorcount;
+ }
+ });
+ // Expose task.requires on `this`.
+ this.requires = task.requires.bind(task);
+ // Expose config.requires on `this`.
+ this.requiresConfig = grunt.config.requires;
+ // Return an options object with the specified defaults overwritten by task-
+ // specific overrides, via the "options" property.
+ this.options = function() {
+ var args = [{}].concat(grunt.util.toArray(arguments)).concat([
+ grunt.config([name, 'options'])
+ ]);
+ var options = grunt.util._.extend.apply(null, args);
+ grunt.verbose.writeflags(options, 'Options');
+ return options;
+ };
+ // If this task was an alias or a multi task called without a target,
+ // only log if in verbose mode.
+ var logger = _fn.alias || (thisTask.multi && (!arg || arg === '*')) ? 'verbose' : 'log';
+ // Actually log.
+ grunt[logger].header('Running "' + this.nameArgs + '"' +
+ (this.name !== this.nameArgs ? ' (' + this.name + ')' : '') + ' task');
+ // If --debug was specified, log the path to this task's source file.
+ grunt[logger].debug('Task source: ' + thisTask.meta.filepath);
+ // Actually run the task.
+ return _fn.apply(this, arguments);
+ };
+ return task;
+};
+
+// Multi task targets can't start with _ or be a reserved property (options).
+function isValidMultiTaskTarget(target) {
+ return !/^_|^options$/.test(target);
+}
+
+// Normalize multi task files.
+task.normalizeMultiTaskFiles = function(data, target) {
+ var prop, obj;
+ var files = [];
+ if (grunt.util.kindOf(data) === 'object') {
+ if ('src' in data || 'dest' in data) {
+ obj = {};
+ for (prop in data) {
+ if (prop !== 'options') {
+ obj[prop] = data[prop];
+ }
+ }
+ files.push(obj);
+ } else if (grunt.util.kindOf(data.files) === 'object') {
+ for (prop in data.files) {
+ files.push({src: data.files[prop], dest: grunt.config.process(prop)});
+ }
+ } else if (Array.isArray(data.files)) {
+ grunt.util._.flattenDeep(data.files).forEach(function(obj) {
+ var prop;
+ if ('src' in obj || 'dest' in obj) {
+ files.push(obj);
+ } else {
+ for (prop in obj) {
+ files.push({src: obj[prop], dest: grunt.config.process(prop)});
+ }
+ }
+ });
+ }
+ } else {
+ files.push({src: data, dest: grunt.config.process(target)});
+ }
+
+ // If no src/dest or files were specified, return an empty files array.
+ if (files.length === 0) {
+ grunt.verbose.writeln('File: ' + '[no files]'.yellow);
+ return [];
+ }
+
+ // Process all normalized file objects.
+ files = grunt.util._(files).chain().forEach(function(obj) {
+ if (!('src' in obj) || !obj.src) { return; }
+ // Normalize .src properties to flattened array.
+ if (Array.isArray(obj.src)) {
+ obj.src = grunt.util._.flatten(obj.src);
+ } else {
+ obj.src = [obj.src];
+ }
+ }).map(function(obj) {
+ // Build options object, removing unwanted properties.
+ var expandOptions = grunt.util._.extend({}, obj);
+ delete expandOptions.src;
+ delete expandOptions.dest;
+
+ // Expand file mappings.
+ if (obj.expand) {
+ return grunt.file.expandMapping(obj.src, obj.dest, expandOptions).map(function(mapObj) {
+ // Copy obj properties to result.
+ var result = grunt.util._.extend({}, obj);
+ // Make a clone of the orig obj available.
+ result.orig = grunt.util._.extend({}, obj);
+ // Set .src and .dest, processing both as templates.
+ result.src = grunt.config.process(mapObj.src);
+ result.dest = grunt.config.process(mapObj.dest);
+ // Remove unwanted properties.
+ ['expand', 'cwd', 'flatten', 'rename', 'ext'].forEach(function(prop) {
+ delete result[prop];
+ });
+ return result;
+ });
+ }
+
+ // Copy obj properties to result, adding an .orig property.
+ var result = grunt.util._.extend({}, obj);
+ // Make a clone of the orig obj available.
+ result.orig = grunt.util._.extend({}, obj);
+
+ if ('src' in result) {
+ // Expose an expand-on-demand getter method as .src.
+ Object.defineProperty(result, 'src', {
+ enumerable: true,
+ get: function fn() {
+ var src;
+ if (!('result' in fn)) {
+ src = obj.src;
+ // If src is an array, flatten it. Otherwise, make it into an array.
+ src = Array.isArray(src) ? grunt.util._.flatten(src) : [src];
+ // Expand src files, memoizing result.
+ fn.result = grunt.file.expand(expandOptions, src);
+ }
+ return fn.result;
+ }
+ });
+ }
+
+ if ('dest' in result) {
+ result.dest = obj.dest;
+ }
+
+ return result;
+ }).flatten().value();
+
+ // Log this.file src and dest properties when --verbose is specified.
+ if (grunt.option('verbose')) {
+ files.forEach(function(obj) {
+ var output = [];
+ if ('src' in obj) {
+ output.push(obj.src.length > 0 ? grunt.log.wordlist(obj.src) : '[no src]'.yellow);
+ }
+ if ('dest' in obj) {
+ output.push('-> ' + (obj.dest ? String(obj.dest).cyan : '[no dest]'.yellow));
+ }
+ if (output.length > 0) {
+ grunt.verbose.writeln('Files: ' + output.join(' '));
+ }
+ });
+ }
+
+ return files;
+};
+
+// This is the most common "multi task" pattern.
+task.registerMultiTask = function(name, info, fn) {
+ // If optional "info" string is omitted, shuffle arguments a bit.
+ if (fn == null) {
+ fn = info;
+ info = 'Custom multi task.';
+ }
+ // Store a reference to the task object, in case the task gets renamed.
+ var thisTask;
+ task.registerTask(name, info, function(target) {
+ // Guaranteed to always be the actual task name.
+ var name = thisTask.name;
+ // Arguments (sans target) as an array.
+ this.args = grunt.util.toArray(arguments).slice(1);
+ // If a target wasn't specified, run this task once for each target.
+ if (!target || target === '*') {
+ return task.runAllTargets(name, this.args);
+ } else if (!isValidMultiTaskTarget(target)) {
+ throw new Error('Invalid target "' + target + '" specified.');
+ }
+ // Fail if any required config properties have been omitted.
+ this.requiresConfig([name, target]);
+ // Return an options object with the specified defaults overwritten by task-
+ // and/or target-specific overrides, via the "options" property.
+ this.options = function() {
+ var targetObj = grunt.config([name, target]);
+ var args = [{}].concat(grunt.util.toArray(arguments)).concat([
+ grunt.config([name, 'options']),
+ grunt.util.kindOf(targetObj) === 'object' ? targetObj.options : {}
+ ]);
+ var options = grunt.util._.extend.apply(null, args);
+ grunt.verbose.writeflags(options, 'Options');
+ return options;
+ };
+ // Expose the current target.
+ this.target = target;
+ // Recreate flags object so that the target isn't set as a flag.
+ this.flags = {};
+ this.args.forEach(function(arg) { this.flags[arg] = true; }, this);
+ // Expose data on `this` (as well as task.current).
+ this.data = grunt.config([name, target]);
+ // Expose normalized files object.
+ this.files = task.normalizeMultiTaskFiles(this.data, target);
+ // Expose normalized, flattened, uniqued array of src files.
+ Object.defineProperty(this, 'filesSrc', {
+ enumerable: true,
+ get: function() {
+ return grunt.util._(this.files).chain().map('src').flatten().uniq().value();
+ }.bind(this)
+ });
+ // Call original task function, passing in the target and any other args.
+ return fn.apply(this, this.args);
+ });
+
+ thisTask = task._tasks[name];
+ thisTask.multi = true;
+};
+
+// Init tasks don't require properties in config, and as such will preempt
+// config loading errors.
+task.registerInitTask = function(name, info, fn) {
+ task.registerTask(name, info, fn);
+ task._tasks[name].init = true;
+};
+
+// Override built-in renameTask to use the registry.
+task.renameTask = function(oldname, newname) {
+ var result;
+ try {
+ // Actually rename task.
+ result = parent.renameTask.apply(task, arguments);
+ // Add and remove task.
+ registry.untasks.push(oldname);
+ registry.tasks.push(newname);
+ // Return result.
+ return result;
+ } catch (e) {
+ grunt.log.error(e.message);
+ }
+};
+
+// If a property wasn't passed, run all task targets in turn.
+task.runAllTargets = function(taskname, args) {
+ // Get an array of sub-property keys under the given config object.
+ var targets = Object.keys(grunt.config.getRaw(taskname) || {});
+ // Remove invalid target properties.
+ targets = targets.filter(isValidMultiTaskTarget);
+ // Fail if there are no actual properties to iterate over.
+ if (targets.length === 0) {
+ grunt.log.error('No "' + taskname + '" targets found.');
+ return false;
+ }
+ // Iterate over all targets, running a task for each.
+ targets.forEach(function(target) {
+ // Be sure to pass in any additionally specified args.
+ task.run([taskname, target].concat(args || []).join(':'));
+ });
+};
+
+// Load tasks and handlers from a given tasks file.
+var loadTaskStack = [];
+function loadTask(filepath) {
+ // In case this was called recursively, save registry for later.
+ loadTaskStack.push(registry);
+ // Reset registry.
+ registry = {tasks: [], untasks: [], meta: {info: lastInfo, filepath: filepath}};
+ var filename = path.basename(filepath);
+ var msg = 'Loading "' + filename + '" tasks...';
+ var regCount = 0;
+ var fn;
+ try {
+ // Load taskfile.
+ fn = require(path.resolve(filepath));
+ if (typeof fn === 'function') {
+ fn.call(grunt, grunt);
+ }
+ grunt.verbose.write(msg).ok();
+ // Log registered/renamed/unregistered tasks.
+ ['un', ''].forEach(function(prefix) {
+ var list = grunt.util._.chain(registry[prefix + 'tasks']).uniq().sort().value();
+ if (list.length > 0) {
+ regCount++;
+ grunt.verbose.writeln((prefix ? '- ' : '+ ') + grunt.log.wordlist(list));
+ }
+ });
+ if (regCount === 0) {
+ grunt.verbose.warn('No tasks were registered or unregistered.');
+ }
+ } catch (e) {
+ // Something went wrong.
+ grunt.log.write(msg).error().verbose.error(e.stack).or.error(e);
+ }
+ // Restore registry.
+ registry = loadTaskStack.pop() || {};
+}
+
+// Log a message when loading tasks.
+function loadTasksMessage(info) {
+ // Only keep track of names of top-level loaded tasks and collections,
+ // not sub-tasks.
+ if (loadTaskDepth === 0) { lastInfo = info; }
+ grunt.verbose.subhead('Registering ' + info + ' tasks.');
+}
+
+// Load tasks and handlers from a given directory.
+function loadTasks(tasksdir) {
+ try {
+ var files = grunt.file.glob.sync('*.{js,coffee}', {cwd: tasksdir, maxDepth: 1});
+ // Load tasks from files.
+ files.forEach(function(filename) {
+ loadTask(path.join(tasksdir, filename));
+ });
+ } catch (e) {
+ grunt.log.verbose.error(e.stack).or.error(e);
+ }
+}
+
+// Load tasks and handlers from a given directory.
+task.loadTasks = function(tasksdir) {
+ loadTasksMessage('"' + tasksdir + '"');
+ if (grunt.file.exists(tasksdir)) {
+ loadTasks(tasksdir);
+ } else {
+ grunt.log.error('Tasks directory "' + tasksdir + '" not found.');
+ }
+};
+
+// Load tasks and handlers from a given locally-installed Npm module (installed
+// relative to the base dir).
+task.loadNpmTasks = function(name) {
+ loadTasksMessage('"' + name + '" local Npm module');
+ var root = path.resolve('node_modules');
+ var pkgpath = path.join(root, name);
+ var pkgfile = path.join(pkgpath, 'package.json');
+ // If package does not exist where grunt expects it to be,
+ // try to find it using Node's package path resolution mechanism
+ if (!grunt.file.exists(pkgpath)) {
+ var nameParts = name.split('/');
+ // In case name points to directory inside module,
+ // get real name of the module with respect to scope (if any)
+ var normailzedName = (name[0] === '@' ? nameParts.slice(0,2).join('/') : nameParts[0]);
+ try {
+ pkgfile = require.resolve(normailzedName + '/package.json');
+ root = pkgfile.substr(0, pkgfile.length - normailzedName.length - '/package.json'.length);
+ } catch (err) {
+ grunt.log.error('Local Npm module "' + normailzedName + '" not found. Is it installed?');
+ return;
+ }
+ }
+ var pkg = grunt.file.exists(pkgfile) ? grunt.file.readJSON(pkgfile) : {keywords: []};
+
+ // Process collection plugins.
+ if (pkg.keywords && pkg.keywords.indexOf('gruntcollection') !== -1) {
+ loadTaskDepth++;
+ Object.keys(pkg.dependencies).forEach(function(depName) {
+ // Npm sometimes pulls dependencies out if they're shared, so find
+ // upwards if not found locally.
+ var filepath = grunt.file.findup('node_modules/' + depName, {
+ cwd: path.resolve('node_modules', name),
+ nocase: true
+ });
+ if (filepath) {
+ // Load this task plugin recursively.
+ task.loadNpmTasks(path.relative(root, filepath));
+ }
+ });
+ loadTaskDepth--;
+ return;
+ }
+
+ // Process task plugins.
+ var tasksdir = path.join(root, name, 'tasks');
+ if (grunt.file.exists(tasksdir)) {
+ loadTasks(tasksdir);
+ } else {
+ grunt.log.error('Local Npm module "' + name + '" not found. Is it installed?');
+ }
+};
+
+// Initialize tasks.
+task.init = function(tasks, options) {
+ if (!options) { options = {}; }
+
+ // Were only init tasks specified?
+ var allInit = tasks.length > 0 && tasks.every(function(name) {
+ var obj = task._taskPlusArgs(name).task;
+ return obj && obj.init;
+ });
+
+ // Get any local Gruntfile or tasks that might exist. Use --gruntfile override
+ // if specified, otherwise search the current directory or any parent.
+ var gruntfile, msg;
+ if (allInit || options.gruntfile === false) {
+ gruntfile = null;
+ } else {
+ gruntfile = grunt.option('gruntfile') ||
+ grunt.file.findup('Gruntfile.{js,coffee}', {nocase: true});
+ msg = 'Reading "' + (gruntfile ? path.basename(gruntfile) : '???') + '" Gruntfile...';
+ }
+
+ if (options.gruntfile === false) {
+ // Grunt was run as a lib with {gruntfile: false}.
+ } else if (gruntfile && grunt.file.exists(gruntfile)) {
+ grunt.verbose.writeln().write(msg).ok();
+ // Change working directory so that all paths are relative to the
+ // Gruntfile's location (or the --base option, if specified).
+ process.chdir(grunt.option('base') || path.dirname(gruntfile));
+ // Load local tasks, if the file exists.
+ loadTasksMessage('Gruntfile');
+ loadTask(gruntfile);
+ } else if (options.help || allInit) {
+ // Don't complain about missing Gruntfile.
+ } else if (grunt.option('gruntfile')) {
+ // If --config override was specified and it doesn't exist, complain.
+ grunt.log.writeln().write(msg).error();
+ grunt.fatal('Unable to find "' + gruntfile + '" Gruntfile.', grunt.fail.code.MISSING_GRUNTFILE);
+ } else if (!grunt.option('help')) {
+ grunt.verbose.writeln().write(msg).error();
+ grunt.log.writelns(
+ 'A valid Gruntfile could not be found. Please see the getting ' +
+ 'started guide for more information on how to configure grunt: ' +
+ 'http://gruntjs.com/getting-started'
+ );
+ grunt.fatal('Unable to find Gruntfile.', grunt.fail.code.MISSING_GRUNTFILE);
+ }
+
+ // Load all user-specified --npm tasks.
+ (grunt.option('npm') || []).map(String).forEach(task.loadNpmTasks);
+ // Load all user-specified --tasks.
+ (grunt.option('tasks') || []).map(String).forEach(task.loadTasks);
+};
diff --git a/node_modules/grunt/lib/grunt/template.js b/node_modules/grunt/lib/grunt/template.js
new file mode 100644
index 0000000..15e1fe1
--- /dev/null
+++ b/node_modules/grunt/lib/grunt/template.js
@@ -0,0 +1,90 @@
+'use strict';
+
+var grunt = require('../grunt');
+
+// The module to be exported.
+var template = module.exports = {};
+
+// External libs.
+template.date = require('dateformat');
+
+// Format today's date.
+template.today = function(format) {
+ var now = new Date();
+ if (process.env.SOURCE_DATE_EPOCH) {
+ now = new Date((process.env.SOURCE_DATE_EPOCH * 1000) + (now.getTimezoneOffset() * 60000));
+ }
+ return template.date(now, format);
+};
+
+// Template delimiters.
+var allDelimiters = {};
+
+// Initialize template delimiters.
+template.addDelimiters = function(name, opener, closer) {
+ var delimiters = allDelimiters[name] = {};
+ // Used by grunt.
+ delimiters.opener = opener;
+ delimiters.closer = closer;
+ // Generate RegExp patterns dynamically.
+ var a = delimiters.opener.replace(/(.)/g, '\\$1');
+ var b = '([\\s\\S]+?)' + delimiters.closer.replace(/(.)/g, '\\$1');
+ // Used by Lo-Dash.
+ delimiters.lodash = {
+ evaluate: new RegExp(a + b, 'g'),
+ interpolate: new RegExp(a + '=' + b, 'g'),
+ escape: new RegExp(a + '-' + b, 'g')
+ };
+};
+
+// The underscore default template syntax should be a pretty sane default for
+// the config system.
+template.addDelimiters('config', '<%', '%>');
+
+// Set Lo-Dash template delimiters.
+template.setDelimiters = function(name) {
+ // Get the appropriate delimiters.
+ var delimiters = allDelimiters[name in allDelimiters ? name : 'config'];
+ // Tell Lo-Dash which delimiters to use.
+ grunt.util._.extend(grunt.util._.templateSettings, delimiters.lodash);
+ // Return the delimiters.
+ return delimiters;
+};
+
+// Process template + data with Lo-Dash.
+template.process = function(tmpl, options) {
+ if (!options) { options = {}; }
+ // Set delimiters, and get a opening match character.
+ var delimiters = template.setDelimiters(options.delimiters);
+ // Clone data, initializing to config data or empty object if omitted.
+ var data = Object.create(options.data || grunt.config.data || {});
+ // Expose grunt so that grunt utilities can be accessed, but only if it
+ // doesn't conflict with an existing .grunt property.
+ if (!('grunt' in data)) { data.grunt = grunt; }
+ // Keep track of last change.
+ var last = tmpl;
+ try {
+ // As long as tmpl contains template tags, render it and get the result,
+ // otherwise just use the template string.
+ while (tmpl.indexOf(delimiters.opener) >= 0) {
+ tmpl = grunt.util._.template(tmpl, options)(data);
+ // Abort if template didn't change - nothing left to process!
+ if (tmpl === last) { break; }
+ last = tmpl;
+ }
+ } catch (e) {
+ // In upgrading to Lo-Dash (or Underscore.js 1.3.3), \n and \r in template
+ // tags now causes an exception to be thrown. Warn the user why this is
+ // happening. https://github.com/documentcloud/underscore/issues/553
+ if (String(e) === 'SyntaxError: Unexpected token ILLEGAL' && /\n|\r/.test(tmpl)) {
+ grunt.log.errorlns('A special character was detected in this template. ' +
+ 'Inside template tags, the \\n and \\r special characters must be ' +
+ 'escaped as \\\\n and \\\\r. (grunt 0.4.0+)');
+ }
+ // Slightly better error message.
+ e.message = 'An error occurred while processing a template (' + e.message + ').';
+ grunt.warn(e, grunt.fail.code.TEMPLATE_ERROR);
+ }
+ // Normalize linefeeds and return.
+ return grunt.util.normalizelf(tmpl);
+};
diff --git a/node_modules/grunt/lib/util/task.js b/node_modules/grunt/lib/util/task.js
new file mode 100644
index 0000000..d39ce1b
--- /dev/null
+++ b/node_modules/grunt/lib/util/task.js
@@ -0,0 +1,335 @@
+(function(exports) {
+
+ 'use strict';
+
+ var grunt = require('../grunt');
+
+ // Construct-o-rama.
+ function Task() {
+ // Information about the currently-running task.
+ this.current = {};
+ // Tasks.
+ this._tasks = {};
+ // Task queue.
+ this._queue = [];
+ // Queue placeholder (for dealing with nested tasks).
+ this._placeholder = {placeholder: true};
+ // Queue marker (for clearing the queue programmatically).
+ this._marker = {marker: true};
+ // Options.
+ this._options = {};
+ // Is the queue running?
+ this._running = false;
+ // Success status of completed tasks.
+ this._success = {};
+ }
+
+ // Expose the constructor function.
+ exports.Task = Task;
+
+ // Create a new Task instance.
+ exports.create = function() {
+ return new Task();
+ };
+
+ // If the task runner is running or an error handler is not defined, throw
+ // an exception. Otherwise, call the error handler directly.
+ Task.prototype._throwIfRunning = function(obj) {
+ if (this._running || !this._options.error) {
+ // Throw an exception that the task runner will catch.
+ throw obj;
+ } else {
+ // Not inside the task runner. Call the error handler and abort.
+ this._options.error.call({name: null}, obj);
+ }
+ };
+
+ // Register a new task.
+ Task.prototype.registerTask = function(name, info, fn) {
+ // If optional "info" string is omitted, shuffle arguments a bit.
+ if (fn == null) {
+ fn = info;
+ info = null;
+ }
+ // String or array of strings was passed instead of fn.
+ var tasks;
+ if (typeof fn !== 'function') {
+ // Array of task names.
+ tasks = this.parseArgs([fn]);
+ // This task function just runs the specified tasks.
+ fn = this.run.bind(this, fn);
+ fn.alias = true;
+ // Generate an info string if one wasn't explicitly passed.
+ if (!info) {
+ info = 'Alias for "' + tasks.join('", "') + '" task' +
+ (tasks.length === 1 ? '' : 's') + '.';
+ }
+ } else if (!info) {
+ info = 'Custom task.';
+ }
+ // Add task into cache.
+ this._tasks[name] = {name: name, info: info, fn: fn};
+ // Make chainable!
+ return this;
+ };
+
+ // Is the specified task an alias?
+ Task.prototype.isTaskAlias = function(name) {
+ return !!this._tasks[name].fn.alias;
+ };
+
+ // Has the specified task been registered?
+ Task.prototype.exists = function(name) {
+ return name in this._tasks;
+ };
+
+ // Rename a task. This might be useful if you want to override the default
+ // behavior of a task, while retaining the old name. This is a billion times
+ // easier to implement than some kind of in-task "super" functionality.
+ Task.prototype.renameTask = function(oldname, newname) {
+ if (!this._tasks[oldname]) {
+ throw new Error('Cannot rename missing "' + oldname + '" task.');
+ }
+ // Rename task.
+ this._tasks[newname] = this._tasks[oldname];
+ // Update name property of task.
+ this._tasks[newname].name = newname;
+ // Remove old name.
+ delete this._tasks[oldname];
+ // Make chainable!
+ return this;
+ };
+
+ // Argument parsing helper. Supports these signatures:
+ // fn('foo') // ['foo']
+ // fn('foo', 'bar', 'baz') // ['foo', 'bar', 'baz']
+ // fn(['foo', 'bar', 'baz']) // ['foo', 'bar', 'baz']
+ Task.prototype.parseArgs = function(args) {
+ // Return the first argument if it's an array, otherwise return an array
+ // of all arguments.
+ return Array.isArray(args[0]) ? args[0] : [].slice.call(args);
+ };
+
+ // Split a colon-delimited string into an array, unescaping (but not
+ // splitting on) any \: escaped colons.
+ Task.prototype.splitArgs = function(str) {
+ if (!str) { return []; }
+ // Store placeholder for \\ followed by \:
+ str = str.replace(/\\\\/g, '\uFFFF').replace(/\\:/g, '\uFFFE');
+ // Split on :
+ return str.split(':').map(function(s) {
+ // Restore place-held : followed by \\
+ return s.replace(/\uFFFE/g, ':').replace(/\uFFFF/g, '\\');
+ });
+ };
+
+ // Given a task name, determine which actual task will be called, and what
+ // arguments will be passed into the task callback. "foo" -> task "foo", no
+ // args. "foo:bar:baz" -> task "foo:bar:baz" with no args (if "foo:bar:baz"
+ // task exists), otherwise task "foo:bar" with arg "baz" (if "foo:bar" task
+ // exists), otherwise task "foo" with args "bar" and "baz".
+ Task.prototype._taskPlusArgs = function(name) {
+ // Get task name / argument parts.
+ var parts = this.splitArgs(name);
+ // Start from the end, not the beginning!
+ var i = parts.length;
+ var task;
+ do {
+ // Get a task.
+ task = this._tasks[parts.slice(0, i).join(':')];
+ // If the task doesn't exist, decrement `i`, and if `i` is greater than
+ // 0, repeat.
+ } while (!task && --i > 0);
+ // Just the args.
+ var args = parts.slice(i);
+ // Maybe you want to use them as flags instead of as positional args?
+ var flags = {};
+ args.forEach(function(arg) { flags[arg] = true; });
+ // The task to run and the args to run it with.
+ return {task: task, nameArgs: name, args: args, flags: flags};
+ };
+
+ // Append things to queue in the correct spot.
+ Task.prototype._push = function(things) {
+ // Get current placeholder index.
+ var index = this._queue.indexOf(this._placeholder);
+ if (index === -1) {
+ // No placeholder, add task+args objects to end of queue.
+ this._queue = this._queue.concat(things);
+ } else {
+ // Placeholder exists, add task+args objects just before placeholder.
+ [].splice.apply(this._queue, [index, 0].concat(things));
+ }
+ };
+
+ // Enqueue a task.
+ Task.prototype.run = function() {
+ // Parse arguments into an array, returning an array of task+args objects.
+ var things = this.parseArgs(arguments).map(this._taskPlusArgs, this);
+ // Throw an exception if any tasks weren't found.
+ var fails = things.filter(function(thing) { return !thing.task; });
+ if (fails.length > 0) {
+ this._throwIfRunning(new Error('Task "' + fails[0].nameArgs + '" not found.'));
+ return this;
+ }
+ // Append things to queue in the correct spot.
+ this._push(things);
+ // Make chainable!
+ return this;
+ };
+
+ // Add a marker to the queue to facilitate clearing it programmatically.
+ Task.prototype.mark = function() {
+ this._push(this._marker);
+ // Make chainable!
+ return this;
+ };
+
+ // Run a task function, handling this.async / return value.
+ Task.prototype.runTaskFn = function(context, fn, done, asyncDone) {
+ // Async flag.
+ var async = false;
+
+ // Update the internal status object and run the next task.
+ var complete = function(success) {
+ var err = null;
+ if (success === false) {
+ // Since false was passed, the task failed generically.
+ err = new Error('Task "' + context.nameArgs + '" failed.');
+ } else if (success instanceof Error || {}.toString.call(success) === '[object Error]') {
+ // An error object was passed, so the task failed specifically.
+ err = success;
+ success = false;
+ } else {
+ // The task succeeded.
+ success = true;
+ }
+ // The task has ended, reset the current task object.
+ this.current = {};
+ // A task has "failed" only if it returns false (async) or if the
+ // function returned by .async is passed false.
+ this._success[context.nameArgs] = success;
+ // If task failed, call error handler.
+ if (!success && this._options.error) {
+ this._options.error.call({name: context.name, nameArgs: context.nameArgs}, err);
+ }
+ // only call done async if explicitly requested to
+ // see: https://github.com/gruntjs/grunt/pull/1026
+ if (asyncDone) {
+ process.nextTick(function() {
+ done(err, success);
+ });
+ } else {
+ done(err, success);
+ }
+ }.bind(this);
+
+ // When called, sets the async flag and returns a function that can
+ // be used to continue processing the queue.
+ context.async = function() {
+ async = true;
+ // The returned function should execute asynchronously in case
+ // someone tries to do this.async()(); inside a task (WTF).
+ return grunt.util._.once(function(success) {
+ setTimeout(function() { complete(success); }, 1);
+ });
+ };
+
+ // Expose some information about the currently-running task.
+ this.current = context;
+
+ try {
+ // Get the current task and run it, setting `this` inside the task
+ // function to be something useful.
+ var success = fn.call(context);
+ // If the async flag wasn't set, process the next task in the queue.
+ if (!async) {
+ complete(success);
+ }
+ } catch (err) {
+ complete(err);
+ }
+ };
+
+ // Begin task queue processing. Ie. run all tasks.
+ Task.prototype.start = function(opts) {
+ if (!opts) {
+ opts = {};
+ }
+ // Abort if already running.
+ if (this._running) { return false; }
+ // Actually process the next task.
+ var nextTask = function() {
+ // Get next task+args object from queue.
+ var thing;
+ // Skip any placeholders or markers.
+ do {
+ thing = this._queue.shift();
+ } while (thing === this._placeholder || thing === this._marker);
+ // If queue was empty, we're all done.
+ if (!thing) {
+ this._running = false;
+ if (this._options.done) {
+ this._options.done();
+ }
+ return;
+ }
+ // Add a placeholder to the front of the queue.
+ this._queue.unshift(this._placeholder);
+
+ // Expose some information about the currently-running task.
+ var context = {
+ // The current task name plus args, as-passed.
+ nameArgs: thing.nameArgs,
+ // The current task name.
+ name: thing.task.name,
+ // The current task arguments.
+ args: thing.args,
+ // The current arguments, available as named flags.
+ flags: thing.flags
+ };
+
+ // Actually run the task function (handling this.async, etc)
+ this.runTaskFn(context, function() {
+ return thing.task.fn.apply(this, this.args);
+ }, nextTask, !!opts.asyncDone);
+
+ }.bind(this);
+
+ // Update flag.
+ this._running = true;
+ // Process the next task.
+ nextTask();
+ };
+
+ // Clear remaining tasks from the queue.
+ Task.prototype.clearQueue = function(options) {
+ if (!options) { options = {}; }
+ if (options.untilMarker) {
+ this._queue.splice(0, this._queue.indexOf(this._marker) + 1);
+ } else {
+ this._queue = [];
+ }
+ // Make chainable!
+ return this;
+ };
+
+ // Test to see if all of the given tasks have succeeded.
+ Task.prototype.requires = function() {
+ this.parseArgs(arguments).forEach(function(name) {
+ var success = this._success[name];
+ if (!success) {
+ throw new Error('Required task "' + name +
+ '" ' + (success === false ? 'failed' : 'must be run first') + '.');
+ }
+ }.bind(this));
+ };
+
+ // Override default options.
+ Task.prototype.options = function(options) {
+ Object.keys(options).forEach(function(name) {
+ this._options[name] = options[name];
+ }.bind(this));
+ };
+
+}(typeof exports === 'object' && exports || this));
diff --git a/node_modules/grunt/node_modules/.bin/grunt b/node_modules/grunt/node_modules/.bin/grunt
new file mode 100644
index 0000000..a716049
--- /dev/null
+++ b/node_modules/grunt/node_modules/.bin/grunt
@@ -0,0 +1,15 @@
+#!/bin/sh
+basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
+
+case `uname` in
+ *CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
+esac
+
+if [ -x "$basedir/node" ]; then
+ "$basedir/node" "$basedir/../grunt-cli/bin/grunt" "$@"
+ ret=$?
+else
+ node "$basedir/../grunt-cli/bin/grunt" "$@"
+ ret=$?
+fi
+exit $ret
diff --git a/node_modules/grunt/node_modules/.bin/grunt.cmd b/node_modules/grunt/node_modules/.bin/grunt.cmd
new file mode 100644
index 0000000..7f9f258
--- /dev/null
+++ b/node_modules/grunt/node_modules/.bin/grunt.cmd
@@ -0,0 +1,17 @@
+@ECHO off
+SETLOCAL
+CALL :find_dp0
+
+IF EXIST "%dp0%\node.exe" (
+ SET "_prog=%dp0%\node.exe"
+) ELSE (
+ SET "_prog=node"
+ SET PATHEXT=%PATHEXT:;.JS;=;%
+)
+
+"%_prog%" "%dp0%\..\grunt-cli\bin\grunt" %*
+ENDLOCAL
+EXIT /b %errorlevel%
+:find_dp0
+SET dp0=%~dp0
+EXIT /b
diff --git a/node_modules/grunt/node_modules/.bin/grunt.ps1 b/node_modules/grunt/node_modules/.bin/grunt.ps1
new file mode 100644
index 0000000..cc011bc
--- /dev/null
+++ b/node_modules/grunt/node_modules/.bin/grunt.ps1
@@ -0,0 +1,18 @@
+#!/usr/bin/env pwsh
+$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
+
+$exe=""
+if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
+ # Fix case when both the Windows and Linux builds of Node
+ # are installed in the same directory
+ $exe=".exe"
+}
+$ret=0
+if (Test-Path "$basedir/node$exe") {
+ & "$basedir/node$exe" "$basedir/../grunt-cli/bin/grunt" $args
+ $ret=$LASTEXITCODE
+} else {
+ & "node$exe" "$basedir/../grunt-cli/bin/grunt" $args
+ $ret=$LASTEXITCODE
+}
+exit $ret
diff --git a/node_modules/grunt/node_modules/grunt-cli/CHANGELOG.md b/node_modules/grunt/node_modules/grunt-cli/CHANGELOG.md
new file mode 100644
index 0000000..411ee5b
--- /dev/null
+++ b/node_modules/grunt/node_modules/grunt-cli/CHANGELOG.md
@@ -0,0 +1,37 @@
+- v1.3.2:
+ - date: 2018-11-04
+ - changes:
+ - bump v8 flags dependency
+- v1.3.1:
+ - date: 2018-08-18
+ - changes:
+ - cwd option fix
+- v1.3.0:
+ - date: 2018-08-15
+ - changes:
+ - Switch to 'liftoff' module for CLI
+ - Dropped support for node 0.10, 0.12.
+- v1.2.0
+ - date: 2016-04-01
+ - changes:
+ - Use shared grunt-known-options module.
+- v1.1.0
+ - date: 2016-03-22
+ - changes:
+ - Update to "nopt": "~3.0.6".
+ - nopt is upgraded to ~3.0.6 which has fixed many issues, including passing multiple arguments and dealing with numbers as options.
+ Be aware previously --foo bar used to pass the value 'bar' to the option foo. It will now set the option foo to true and run the task bar.
+- v1.0.1
+ - date: 2016-03-22
+ - changes:
+ - Revert to "nopt": "~1.0.10" due to issues with the update.
+- v1.0.0
+ - date: 2016-03-21
+ - changes:
+ - Update dev deps
+ - Update error message when Gruntfile is not found
+- v1.0.0-rc1
+ - date: 2016-02-11
+ - changes:
+ - Update findup-sync and other deps
+ - remove prefer global warning
diff --git a/node_modules/grunt/node_modules/grunt-cli/README.md b/node_modules/grunt/node_modules/grunt-cli/README.md
new file mode 100644
index 0000000..df9848a
--- /dev/null
+++ b/node_modules/grunt/node_modules/grunt-cli/README.md
@@ -0,0 +1,31 @@
+# grunt-cli [](https://travis-ci.org/gruntjs/grunt-cli) [](https://ci.appveyor.com/project/gruntjs/grunt-cli/branch/master)
+
+> The Grunt command line interface.
+
+Install this globally and you'll have access to the `grunt` command anywhere on your system.
+
+```shell
+npm install -g grunt-cli
+```
+
+**Note:** The job of the `grunt` command is to load and run the version of Grunt you have installed locally to your project, irrespective of its version. Starting with Grunt v0.4, you should never install Grunt itself globally. For more information about why, [please read this](http://nodejs.org/en/blog/npm/npm-1-0-global-vs-local-installation).
+
+See the [Getting Started](http://gruntjs.com/getting-started) guide for more information.
+
+## Shell tab auto-completion
+To enable tab auto-completion for Grunt, add one of the following lines to your `~/.bashrc` or `~/.zshrc` file.
+
+```bash
+# Bash, ~/.bashrc
+eval "$(grunt --completion=bash)"
+```
+
+```bash
+# Zsh, ~/.zshrc
+eval "$(grunt --completion=zsh)"
+```
+
+## Installing grunt-cli locally
+If you prefer the idiomatic Node.js method to get started with a project (`npm install && npm test`) then install grunt-cli locally with `npm install grunt-cli --save-dev`. Then add a script to your `package.json` to run the associated grunt command: `"scripts": { "test": "grunt test" } `. Now `npm test` will use the locally installed `./node_modules/.bin/grunt` executable to run your Grunt commands.
+
+To read more about npm scripts, please visit the npm docs: <https://docs.npmjs.com/misc/scripts>.
diff --git a/node_modules/grunt/node_modules/grunt-cli/bin/grunt b/node_modules/grunt/node_modules/grunt-cli/bin/grunt
new file mode 100644
index 0000000..3186e44
--- /dev/null
+++ b/node_modules/grunt/node_modules/grunt-cli/bin/grunt
@@ -0,0 +1,69 @@
+#!/usr/bin/env node
+
+'use strict';
+
+process.title = 'grunt';
+
+var Liftoff = require('liftoff');
+var v8flags = require('v8flags');
+var extensions = require('interpret').jsVariants;
+var nopt = require('nopt');
+var gruntOptions = require('grunt-known-options');
+var completion = require('../lib/completion.js');
+var info = require('../lib/info.js');
+var pkg = require('../package.json');
+
+// Parse `gruntOptions` into a form that nopt can handle.
+var aliases = {};
+var known = {};
+
+Object.keys(gruntOptions).forEach(function(key) {
+ var short = gruntOptions[key].short;
+ if (short) {
+ aliases[short] = '--' + key;
+ }
+ known[key] = gruntOptions[key].type;
+});
+
+// Parse them and return an options object.
+var options = nopt(known, aliases, process.argv, 2);
+
+if ('completion' in options) {
+ completion.print(options.completion);
+} else if (options.version) {
+ console.log('grunt-cli v' + pkg.version);
+}
+
+v8flags(function (err, v8flags) {
+ var Grunt = new Liftoff({
+ name: 'grunt',
+ configName: 'Gruntfile',
+ // Support a number of languages based on file extension
+ extensions: extensions,
+ // Flags that are v8 flags will be loaded into node instead of Gruntfile
+ v8flags: v8flags
+ });
+ Grunt.launch({
+ cwd: options.base,
+ configPath: options.gruntfile,
+ require: options.require,
+ verbose: options.verbose
+ }, function (env) {
+ var tasks = options.argv.remain;
+ delete options.argv;
+ // No grunt install found!
+ if (!env.modulePath) {
+ if (options.version) {
+ process.exit();
+ }
+ if (options.help) {
+ info.help();
+ }
+ info.fatal('Unable to find local grunt.', 99);
+ } else {
+ options.gruntfile = env.configPath;
+ var grunt = require(env.modulePath);
+ grunt.tasks(tasks, options);
+ }
+ });
+});
diff --git a/node_modules/grunt/node_modules/grunt-cli/completion/bash b/node_modules/grunt/node_modules/grunt-cli/completion/bash
new file mode 100644
index 0000000..eb03ae8
--- /dev/null
+++ b/node_modules/grunt/node_modules/grunt-cli/completion/bash
@@ -0,0 +1,49 @@
+#!/bin/bash
+
+# grunt-cli
+# http://gruntjs.com/
+#
+# Copyright (c) 2016 Tyler Kellen, contributors
+# Licensed under the MIT license.
+# https://github.com/gruntjs/grunt/blob/master/LICENSE-MIT
+
+# Usage:
+#
+# To enable bash <tab> completion for grunt, add the following line (minus the
+# leading #, which is the bash comment character) to your ~/.bashrc file:
+#
+# eval "$(grunt --completion=bash)"
+
+# Search the current directory and all parent directories for a gruntfile.
+function _grunt_gruntfile() {
+ local curpath="$PWD"
+ while [[ "$curpath" ]]; do
+ for gruntfile in "$curpath/"{G,g}runtfile.{js,coffee}; do
+ if [[ -e "$gruntfile" ]]; then
+ echo "$gruntfile"
+ return
+ fi
+ done
+ curpath="${curpath%/*}"
+ done
+ return 1
+}
+
+# Enable bash autocompletion.
+function _grunt_completions() {
+ # The currently-being-completed word.
+ local cur="${COMP_WORDS[COMP_CWORD]}"
+ # The current gruntfile, if it exists.
+ local gruntfile="$(_grunt_gruntfile)"
+ # The current grunt version, available tasks, options, etc.
+ local gruntinfo="$(grunt --version --verbose 2>/dev/null)"
+ # Options and tasks.
+ local opts="$(echo "$gruntinfo" | awk '/Available options: / {$1=$2=""; print $0}')"
+ local compls="$(echo "$gruntinfo" | awk '/Available tasks: / {$1=$2=""; print $0}')"
+ # Only add -- or - options if the user has started typing -
+ [[ "$cur" == -* ]] && compls="$compls $opts"
+ # Tell complete what stuff to show.
+ COMPREPLY=($(compgen -W "$compls" -- "$cur"))
+}
+
+complete -o default -F _grunt_completions grunt
diff --git a/node_modules/grunt/node_modules/grunt-cli/completion/zsh b/node_modules/grunt/node_modules/grunt-cli/completion/zsh
new file mode 100644
index 0000000..c2841ff
--- /dev/null
+++ b/node_modules/grunt/node_modules/grunt-cli/completion/zsh
@@ -0,0 +1,37 @@
+#!/bin/zsh
+
+# grunt-cli
+# http://gruntjs.com/
+#
+# Copyright (c) 2016 Tyler Kellen, contributors
+# Licensed under the MIT license.
+# https://github.com/gruntjs/grunt/blob/master/LICENSE-MIT
+
+# Usage:
+#
+# To enable zsh <tab> completion for grunt, add the following line (minus the
+# leading #, which is the zsh comment character) to your ~/.zshrc file:
+#
+# eval "$(grunt --completion=zsh)"
+
+# Enable zsh autocompletion.
+function _grunt_completion() {
+ local completions
+ # The currently-being-completed word.
+ local cur="${words[@]}"
+ # The current grunt version, available tasks, options, etc.
+ local gruntinfo="$(grunt --version --verbose 2>/dev/null)"
+ # Options and tasks.
+ local opts="$(echo "$gruntinfo" | awk '/Available options: / {$1=$2=""; print $0}')"
+ local compls="$(echo "$gruntinfo" | awk '/Available tasks: / {$1=$2=""; print $0}')"
+ # Only add -- or - options if the user has started typing -
+ [[ "$cur" == -* ]] && compls="$compls $opts"
+ # Trim whitespace.
+ compls=$(echo "$compls" | sed -e 's/^ *//g' -e 's/ *$//g')
+ # Turn compls into an array to of completions.
+ completions=(${=compls})
+ # Tell complete what stuff to show.
+ compadd -- $completions
+}
+
+compdef _grunt_completion grunt
diff --git a/node_modules/grunt/node_modules/grunt-cli/lib/completion.js b/node_modules/grunt/node_modules/grunt-cli/lib/completion.js
new file mode 100644
index 0000000..ace3cd5
--- /dev/null
+++ b/node_modules/grunt/node_modules/grunt-cli/lib/completion.js
@@ -0,0 +1,34 @@
+/*
+ * grunt-cli
+ * http://gruntjs.com/
+ *
+ * Copyright (c) 2016 Tyler Kellen, contributors
+ * Licensed under the MIT license.
+ * https://github.com/gruntjs/grunt-init/blob/master/LICENSE-MIT
+ */
+
+'use strict';
+
+// Nodejs libs.
+var fs = require('fs');
+var path = require('path');
+
+exports.print = function(name) {
+ var code = 0;
+ var filepath = path.join(__dirname, '../completion', name);
+ var output;
+ try {
+ // Attempt to read shell completion file.
+ output = String(fs.readFileSync(filepath));
+ } catch (err) {
+ code = 5;
+ output = 'echo "Specified grunt shell auto-completion rules ';
+ if (name && name !== 'true') {
+ output += 'for \'' + name + '\' ';
+ }
+ output += 'not found."';
+ }
+
+ console.log(output);
+ process.exit(code);
+};
diff --git a/node_modules/grunt/node_modules/grunt-cli/lib/info.js b/node_modules/grunt/node_modules/grunt-cli/lib/info.js
new file mode 100644
index 0000000..ba56f52
--- /dev/null
+++ b/node_modules/grunt/node_modules/grunt-cli/lib/info.js
@@ -0,0 +1,51 @@
+/*
+ * grunt-cli
+ * http://gruntjs.com/
+ *
+ * Copyright (c) 2016 Tyler Kellen, contributors
+ * Licensed under the MIT license.
+ * https://github.com/gruntjs/grunt-init/blob/master/LICENSE-MIT
+ */
+
+'use strict';
+
+// Project metadata.
+var pkg = require('../package.json');
+
+// Display grunt-cli version.
+exports.version = function() {
+ console.log('grunt-cli v' + pkg.version);
+};
+
+// Show help, then exit with a message and error code.
+exports.fatal = function(msg, code) {
+ exports.helpHeader();
+ console.log('Fatal error: ' + msg);
+ console.log('');
+ exports.helpFooter();
+ process.exit(code);
+};
+
+// Show help and exit.
+exports.help = function() {
+ exports.helpHeader();
+ exports.helpFooter();
+ process.exit();
+};
+
+// Help header.
+exports.helpHeader = function() {
+ console.log('grunt-cli: ' + pkg.description + ' (v' + pkg.version + ')');
+ console.log('');
+};
+
+// Help footer.
+exports.helpFooter = function() {
+ [
+ 'If you\'re seeing this message, grunt hasn\'t been installed locally to',
+ 'your project. For more information about installing and configuring grunt,',
+ 'please see the Getting Started guide:',
+ '',
+ 'https://gruntjs.com/getting-started',
+ ].forEach(function(str) { console.log(str); });
+};
diff --git a/node_modules/grunt/node_modules/grunt-cli/node_modules/.bin/nopt b/node_modules/grunt/node_modules/grunt-cli/node_modules/.bin/nopt
new file mode 100644
index 0000000..e658aac
--- /dev/null
+++ b/node_modules/grunt/node_modules/grunt-cli/node_modules/.bin/nopt
@@ -0,0 +1,15 @@
+#!/bin/sh
+basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
+
+case `uname` in
+ *CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
+esac
+
+if [ -x "$basedir/node" ]; then
+ "$basedir/node" "$basedir/../nopt/bin/nopt.js" "$@"
+ ret=$?
+else
+ node "$basedir/../nopt/bin/nopt.js" "$@"
+ ret=$?
+fi
+exit $ret
diff --git a/node_modules/grunt/node_modules/grunt-cli/node_modules/.bin/nopt.cmd b/node_modules/grunt/node_modules/grunt-cli/node_modules/.bin/nopt.cmd
new file mode 100644
index 0000000..c92ec03
--- /dev/null
+++ b/node_modules/grunt/node_modules/grunt-cli/node_modules/.bin/nopt.cmd
@@ -0,0 +1,17 @@
+@ECHO off
+SETLOCAL
+CALL :find_dp0
+
+IF EXIST "%dp0%\node.exe" (
+ SET "_prog=%dp0%\node.exe"
+) ELSE (
+ SET "_prog=node"
+ SET PATHEXT=%PATHEXT:;.JS;=;%
+)
+
+"%_prog%" "%dp0%\..\nopt\bin\nopt.js" %*
+ENDLOCAL
+EXIT /b %errorlevel%
+:find_dp0
+SET dp0=%~dp0
+EXIT /b
diff --git a/node_modules/grunt/node_modules/grunt-cli/node_modules/.bin/nopt.ps1 b/node_modules/grunt/node_modules/grunt-cli/node_modules/.bin/nopt.ps1
new file mode 100644
index 0000000..68c40bf
--- /dev/null
+++ b/node_modules/grunt/node_modules/grunt-cli/node_modules/.bin/nopt.ps1
@@ -0,0 +1,18 @@
+#!/usr/bin/env pwsh
+$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
+
+$exe=""
+if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
+ # Fix case when both the Windows and Linux builds of Node
+ # are installed in the same directory
+ $exe=".exe"
+}
+$ret=0
+if (Test-Path "$basedir/node$exe") {
+ & "$basedir/node$exe" "$basedir/../nopt/bin/nopt.js" $args
+ $ret=$LASTEXITCODE
+} else {
+ & "node$exe" "$basedir/../nopt/bin/nopt.js" $args
+ $ret=$LASTEXITCODE
+}
+exit $ret
diff --git a/node_modules/grunt/node_modules/grunt-cli/node_modules/nopt/CHANGELOG.md b/node_modules/grunt/node_modules/grunt-cli/node_modules/nopt/CHANGELOG.md
new file mode 100644
index 0000000..82a09fb
--- /dev/null
+++ b/node_modules/grunt/node_modules/grunt-cli/node_modules/nopt/CHANGELOG.md
@@ -0,0 +1,58 @@
+### v4.0.1 (2016-12-14)
+
+#### WHOOPS
+
+* [`fb9b1ce`](https://github.com/npm/nopt/commit/fb9b1ce57b3c69b4f7819015be87719204f77ef6)
+ Merged so many patches at once that the code fencing
+ ([@adius](https://github.com/adius)) added got broken. Sorry,
+ ([@adius](https://github.com/adius))!
+ ([@othiym23](https://github.com/othiym23))
+
+### v4.0.0 (2016-12-13)
+
+#### BREAKING CHANGES
+
+* [`651d447`](https://github.com/npm/nopt/commit/651d4473946096d341a480bbe56793de3fc706aa)
+ When parsing String-typed arguments, if the next value is `""`, don't simply
+ swallow it. ([@samjonester](https://github.com/samjonester))
+
+#### PERFORMANCE TWEAKS
+
+* [`3370ce8`](https://github.com/npm/nopt/commit/3370ce87a7618ba228883861db84ddbcdff252a9)
+ Simplify initialization. ([@elidoran](https://github.com/elidoran))
+* [`356e58e`](https://github.com/npm/nopt/commit/356e58e3b3b431a4b1af7fd7bdee44c2c0526a09)
+ Store `Array.isArray(types[arg])` for reuse.
+ ([@elidoran](https://github.com/elidoran))
+* [`0d95e90`](https://github.com/npm/nopt/commit/0d95e90515844f266015b56d2c80b94e5d14a07e)
+ Interpret single-item type arrays as a single type.
+ ([@samjonester](https://github.com/samjonester))
+* [`07c69d3`](https://github.com/npm/nopt/commit/07c69d38b5186450941fbb505550becb78a0e925)
+ Simplify key-value extraction. ([@elidoran](https://github.com/elidoran))
+* [`39b6e5c`](https://github.com/npm/nopt/commit/39b6e5c65ac47f60cd43a1fbeece5cd4c834c254)
+ Only call `Date.parse(val)` once. ([@elidoran](https://github.com/elidoran))
+* [`934943d`](https://github.com/npm/nopt/commit/934943dffecb55123a2b15959fe2a359319a5dbd)
+ Use `osenv.home()` to find a user's home directory instead of assuming it's
+ always `$HOME`. ([@othiym23](https://github.com/othiym23))
+
+#### TEST & CI IMPROVEMENTS
+
+* [`326ffff`](https://github.com/npm/nopt/commit/326ffff7f78a00bcd316adecf69075f8a8093619)
+ Fix `/tmp` test to work on Windows.
+ ([@elidoran](https://github.com/elidoran))
+* [`c89d31a`](https://github.com/npm/nopt/commit/c89d31a49d14f2238bc6672db08da697bbc57f1b)
+ Only run Windows tests on Windows, only run Unix tests on a Unix.
+ ([@elidoran](https://github.com/elidoran))
+* [`affd3d1`](https://github.com/npm/nopt/commit/affd3d1d0addffa93006397b2013b18447339366)
+ Refresh Travis to run the tests against the currently-supported batch of npm
+ versions. ([@helio](https://github.com/helio)-frota)
+* [`55f9449`](https://github.com/npm/nopt/commit/55f94497d163ed4d16dd55fd6c4fb95cc440e66d)
+ `tap@8.0.1` ([@othiym23](https://github.com/othiym23))
+
+#### DOC TWEAKS
+
+* [`5271229`](https://github.com/npm/nopt/commit/5271229ee7c810217dd51616c086f5d9ab224581)
+ Use JavaScript code block for syntax highlighting.
+ ([@adius](https://github.com/adius))
+* [`c0d156f`](https://github.com/npm/nopt/commit/c0d156f229f9994c5dfcec4a8886eceff7a07682)
+ The code sample in the README had `many2: [ oneThing ]`, and now it has
+ `many2: [ two, things ]`. ([@silkentrance](https://github.com/silkentrance))
diff --git a/node_modules/grunt/node_modules/grunt-cli/node_modules/nopt/LICENSE b/node_modules/grunt/node_modules/grunt-cli/node_modules/nopt/LICENSE
new file mode 100644
index 0000000..19129e3
--- /dev/null
+++ b/node_modules/grunt/node_modules/grunt-cli/node_modules/nopt/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.
diff --git a/node_modules/grunt/node_modules/grunt-cli/node_modules/nopt/README.md b/node_modules/grunt/node_modules/grunt-cli/node_modules/nopt/README.md
new file mode 100644
index 0000000..a99531c
--- /dev/null
+++ b/node_modules/grunt/node_modules/grunt-cli/node_modules/nopt/README.md
@@ -0,0 +1,213 @@
+If you want to write an option parser, and have it be good, there are
+two ways to do it. The Right Way, and the Wrong Way.
+
+The Wrong Way is to sit down and write an option parser. We've all done
+that.
+
+The Right Way is to write some complex configurable program with so many
+options that you hit the limit of your frustration just trying to
+manage them all, and defer it with duct-tape solutions until you see
+exactly to the core of the problem, and finally snap and write an
+awesome option parser.
+
+If you want to write an option parser, don't write an option parser.
+Write a package manager, or a source control system, or a service
+restarter, or an operating system. You probably won't end up with a
+good one of those, but if you don't give up, and you are relentless and
+diligent enough in your procrastination, you may just end up with a very
+nice option parser.
+
+## USAGE
+
+```javascript
+// my-program.js
+var nopt = require("nopt")
+ , Stream = require("stream").Stream
+ , path = require("path")
+ , knownOpts = { "foo" : [String, null]
+ , "bar" : [Stream, Number]
+ , "baz" : path
+ , "bloo" : [ "big", "medium", "small" ]
+ , "flag" : Boolean
+ , "pick" : Boolean
+ , "many1" : [String, Array]
+ , "many2" : [path, Array]
+ }
+ , shortHands = { "foofoo" : ["--foo", "Mr. Foo"]
+ , "b7" : ["--bar", "7"]
+ , "m" : ["--bloo", "medium"]
+ , "p" : ["--pick"]
+ , "f" : ["--flag"]
+ }
+ // everything is optional.
+ // knownOpts and shorthands default to {}
+ // arg list defaults to process.argv
+ // slice defaults to 2
+ , parsed = nopt(knownOpts, shortHands, process.argv, 2)
+console.log(parsed)
+```
+
+This would give you support for any of the following:
+
+```console
+$ node my-program.js --foo "blerp" --no-flag
+{ "foo" : "blerp", "flag" : false }
+
+$ node my-program.js ---bar 7 --foo "Mr. Hand" --flag
+{ bar: 7, foo: "Mr. Hand", flag: true }
+
+$ node my-program.js --foo "blerp" -f -----p
+{ foo: "blerp", flag: true, pick: true }
+
+$ node my-program.js -fp --foofoo
+{ foo: "Mr. Foo", flag: true, pick: true }
+
+$ node my-program.js --foofoo -- -fp # -- stops the flag parsing.
+{ foo: "Mr. Foo", argv: { remain: ["-fp"] } }
+
+$ node my-program.js --blatzk -fp # unknown opts are ok.
+{ blatzk: true, flag: true, pick: true }
+
+$ node my-program.js --blatzk=1000 -fp # but you need to use = if they have a value
+{ blatzk: 1000, flag: true, pick: true }
+
+$ node my-program.js --no-blatzk -fp # unless they start with "no-"
+{ blatzk: false, flag: true, pick: true }
+
+$ node my-program.js --baz b/a/z # known paths are resolved.
+{ baz: "/Users/isaacs/b/a/z" }
+
+# if Array is one of the types, then it can take many
+# values, and will always be an array. The other types provided
+# specify what types are allowed in the list.
+
+$ node my-program.js --many1 5 --many1 null --many1 foo
+{ many1: ["5", "null", "foo"] }
+
+$ node my-program.js --many2 foo --many2 bar
+{ many2: ["/path/to/foo", "path/to/bar"] }
+```
+
+Read the tests at the bottom of `lib/nopt.js` for more examples of
+what this puppy can do.
+
+## Types
+
+The following types are supported, and defined on `nopt.typeDefs`
+
+* String: A normal string. No parsing is done.
+* path: A file system path. Gets resolved against cwd if not absolute.
+* url: A url. If it doesn't parse, it isn't accepted.
+* Number: Must be numeric.
+* Date: Must parse as a date. If it does, and `Date` is one of the options,
+ then it will return a Date object, not a string.
+* Boolean: Must be either `true` or `false`. If an option is a boolean,
+ then it does not need a value, and its presence will imply `true` as
+ the value. To negate boolean flags, do `--no-whatever` or `--whatever
+ false`
+* NaN: Means that the option is strictly not allowed. Any value will
+ fail.
+* Stream: An object matching the "Stream" class in node. Valuable
+ for use when validating programmatically. (npm uses this to let you
+ supply any WriteStream on the `outfd` and `logfd` config options.)
+* Array: If `Array` is specified as one of the types, then the value
+ will be parsed as a list of options. This means that multiple values
+ can be specified, and that the value will always be an array.
+
+If a type is an array of values not on this list, then those are
+considered valid values. For instance, in the example above, the
+`--bloo` option can only be one of `"big"`, `"medium"`, or `"small"`,
+and any other value will be rejected.
+
+When parsing unknown fields, `"true"`, `"false"`, and `"null"` will be
+interpreted as their JavaScript equivalents.
+
+You can also mix types and values, or multiple types, in a list. For
+instance `{ blah: [Number, null] }` would allow a value to be set to
+either a Number or null. When types are ordered, this implies a
+preference, and the first type that can be used to properly interpret
+the value will be used.
+
+To define a new type, add it to `nopt.typeDefs`. Each item in that
+hash is an object with a `type` member and a `validate` method. The
+`type` member is an object that matches what goes in the type list. The
+`validate` method is a function that gets called with `validate(data,
+key, val)`. Validate methods should assign `data[key]` to the valid
+value of `val` if it can be handled properly, or return boolean
+`false` if it cannot.
+
+You can also call `nopt.clean(data, types, typeDefs)` to clean up a
+config object and remove its invalid properties.
+
+## Error Handling
+
+By default, nopt outputs a warning to standard error when invalid values for
+known options are found. You can change this behavior by assigning a method
+to `nopt.invalidHandler`. This method will be called with
+the offending `nopt.invalidHandler(key, val, types)`.
+
+If no `nopt.invalidHandler` is assigned, then it will console.error
+its whining. If it is assigned to boolean `false` then the warning is
+suppressed.
+
+## Abbreviations
+
+Yes, they are supported. If you define options like this:
+
+```javascript
+{ "foolhardyelephants" : Boolean
+, "pileofmonkeys" : Boolean }
+```
+
+Then this will work:
+
+```bash
+node program.js --foolhar --pil
+node program.js --no-f --pileofmon
+# etc.
+```
+
+## Shorthands
+
+Shorthands are a hash of shorter option names to a snippet of args that
+they expand to.
+
+If multiple one-character shorthands are all combined, and the
+combination does not unambiguously match any other option or shorthand,
+then they will be broken up into their constituent parts. For example:
+
+```json
+{ "s" : ["--loglevel", "silent"]
+, "g" : "--global"
+, "f" : "--force"
+, "p" : "--parseable"
+, "l" : "--long"
+}
+```
+
+```bash
+npm ls -sgflp
+# just like doing this:
+npm ls --loglevel silent --global --force --long --parseable
+```
+
+## The Rest of the args
+
+The config object returned by nopt is given a special member called
+`argv`, which is an object with the following fields:
+
+* `remain`: The remaining args after all the parsing has occurred.
+* `original`: The args as they originally appeared.
+* `cooked`: The args after flags and shorthands are expanded.
+
+## Slicing
+
+Node programs are called with more or less the exact argv as it appears
+in C land, after the v8 and node-specific options have been plucked off.
+As such, `argv[0]` is always `node` and `argv[1]` is always the
+JavaScript program being run.
+
+That's usually not very useful to you. So they're sliced off by
+default. If you want them, then you can pass in `0` as the last
+argument, or any other number that you'd like to slice off the start of
+the list.
diff --git a/node_modules/grunt/node_modules/grunt-cli/node_modules/nopt/bin/nopt.js b/node_modules/grunt/node_modules/grunt-cli/node_modules/nopt/bin/nopt.js
new file mode 100644
index 0000000..3232d4c
--- /dev/null
+++ b/node_modules/grunt/node_modules/grunt-cli/node_modules/nopt/bin/nopt.js
@@ -0,0 +1,54 @@
+#!/usr/bin/env node
+var nopt = require("../lib/nopt")
+ , path = require("path")
+ , types = { num: Number
+ , bool: Boolean
+ , help: Boolean
+ , list: Array
+ , "num-list": [Number, Array]
+ , "str-list": [String, Array]
+ , "bool-list": [Boolean, Array]
+ , str: String
+ , clear: Boolean
+ , config: Boolean
+ , length: Number
+ , file: path
+ }
+ , shorthands = { s: [ "--str", "astring" ]
+ , b: [ "--bool" ]
+ , nb: [ "--no-bool" ]
+ , tft: [ "--bool-list", "--no-bool-list", "--bool-list", "true" ]
+ , "?": ["--help"]
+ , h: ["--help"]
+ , H: ["--help"]
+ , n: [ "--num", "125" ]
+ , c: ["--config"]
+ , l: ["--length"]
+ , f: ["--file"]
+ }
+ , parsed = nopt( types
+ , shorthands
+ , process.argv
+ , 2 )
+
+console.log("parsed", parsed)
+
+if (parsed.help) {
+ console.log("")
+ console.log("nopt cli tester")
+ console.log("")
+ console.log("types")
+ console.log(Object.keys(types).map(function M (t) {
+ var type = types[t]
+ if (Array.isArray(type)) {
+ return [t, type.map(function (type) { return type.name })]
+ }
+ return [t, type && type.name]
+ }).reduce(function (s, i) {
+ s[i[0]] = i[1]
+ return s
+ }, {}))
+ console.log("")
+ console.log("shorthands")
+ console.log(shorthands)
+}
diff --git a/node_modules/grunt/node_modules/grunt-cli/node_modules/nopt/lib/nopt.js b/node_modules/grunt/node_modules/grunt-cli/node_modules/nopt/lib/nopt.js
new file mode 100644
index 0000000..0ec5753
--- /dev/null
+++ b/node_modules/grunt/node_modules/grunt-cli/node_modules/nopt/lib/nopt.js
@@ -0,0 +1,441 @@
+// info about each config option.
+
+var debug = process.env.DEBUG_NOPT || process.env.NOPT_DEBUG
+ ? function () { console.error.apply(console, arguments) }
+ : function () {}
+
+var url = require("url")
+ , path = require("path")
+ , Stream = require("stream").Stream
+ , abbrev = require("abbrev")
+ , osenv = require("osenv")
+
+module.exports = exports = nopt
+exports.clean = clean
+
+exports.typeDefs =
+ { String : { type: String, validate: validateString }
+ , Boolean : { type: Boolean, validate: validateBoolean }
+ , url : { type: url, validate: validateUrl }
+ , Number : { type: Number, validate: validateNumber }
+ , path : { type: path, validate: validatePath }
+ , Stream : { type: Stream, validate: validateStream }
+ , Date : { type: Date, validate: validateDate }
+ }
+
+function nopt (types, shorthands, args, slice) {
+ args = args || process.argv
+ types = types || {}
+ shorthands = shorthands || {}
+ if (typeof slice !== "number") slice = 2
+
+ debug(types, shorthands, args, slice)
+
+ args = args.slice(slice)
+ var data = {}
+ , key
+ , argv = {
+ remain: [],
+ cooked: args,
+ original: args.slice(0)
+ }
+
+ parse(args, data, argv.remain, types, shorthands)
+ // now data is full
+ clean(data, types, exports.typeDefs)
+ data.argv = argv
+ Object.defineProperty(data.argv, 'toString', { value: function () {
+ return this.original.map(JSON.stringify).join(" ")
+ }, enumerable: false })
+ return data
+}
+
+function clean (data, types, typeDefs) {
+ typeDefs = typeDefs || exports.typeDefs
+ var remove = {}
+ , typeDefault = [false, true, null, String, Array]
+
+ Object.keys(data).forEach(function (k) {
+ if (k === "argv") return
+ var val = data[k]
+ , isArray = Array.isArray(val)
+ , type = types[k]
+ if (!isArray) val = [val]
+ if (!type) type = typeDefault
+ if (type === Array) type = typeDefault.concat(Array)
+ if (!Array.isArray(type)) type = [type]
+
+ debug("val=%j", val)
+ debug("types=", type)
+ val = val.map(function (val) {
+ // if it's an unknown value, then parse false/true/null/numbers/dates
+ if (typeof val === "string") {
+ debug("string %j", val)
+ val = val.trim()
+ if ((val === "null" && ~type.indexOf(null))
+ || (val === "true" &&
+ (~type.indexOf(true) || ~type.indexOf(Boolean)))
+ || (val === "false" &&
+ (~type.indexOf(false) || ~type.indexOf(Boolean)))) {
+ val = JSON.parse(val)
+ debug("jsonable %j", val)
+ } else if (~type.indexOf(Number) && !isNaN(val)) {
+ debug("convert to number", val)
+ val = +val
+ } else if (~type.indexOf(Date) && !isNaN(Date.parse(val))) {
+ debug("convert to date", val)
+ val = new Date(val)
+ }
+ }
+
+ if (!types.hasOwnProperty(k)) {
+ return val
+ }
+
+ // allow `--no-blah` to set 'blah' to null if null is allowed
+ if (val === false && ~type.indexOf(null) &&
+ !(~type.indexOf(false) || ~type.indexOf(Boolean))) {
+ val = null
+ }
+
+ var d = {}
+ d[k] = val
+ debug("prevalidated val", d, val, types[k])
+ if (!validate(d, k, val, types[k], typeDefs)) {
+ if (exports.invalidHandler) {
+ exports.invalidHandler(k, val, types[k], data)
+ } else if (exports.invalidHandler !== false) {
+ debug("invalid: "+k+"="+val, types[k])
+ }
+ return remove
+ }
+ debug("validated val", d, val, types[k])
+ return d[k]
+ }).filter(function (val) { return val !== remove })
+
+ // if we allow Array specifically, then an empty array is how we
+ // express 'no value here', not null. Allow it.
+ if (!val.length && type.indexOf(Array) === -1) {
+ debug('VAL HAS NO LENGTH, DELETE IT', val, k, type.indexOf(Array))
+ delete data[k]
+ }
+ else if (isArray) {
+ debug(isArray, data[k], val)
+ data[k] = val
+ } else data[k] = val[0]
+
+ debug("k=%s val=%j", k, val, data[k])
+ })
+}
+
+function validateString (data, k, val) {
+ data[k] = String(val)
+}
+
+function validatePath (data, k, val) {
+ if (val === true) return false
+ if (val === null) return true
+
+ val = String(val)
+
+ var isWin = process.platform === 'win32'
+ , homePattern = isWin ? /^~(\/|\\)/ : /^~\//
+ , home = osenv.home()
+
+ if (home && val.match(homePattern)) {
+ data[k] = path.resolve(home, val.substr(2))
+ } else {
+ data[k] = path.resolve(val)
+ }
+ return true
+}
+
+function validateNumber (data, k, val) {
+ debug("validate Number %j %j %j", k, val, isNaN(val))
+ if (isNaN(val)) return false
+ data[k] = +val
+}
+
+function validateDate (data, k, val) {
+ var s = Date.parse(val)
+ debug("validate Date %j %j %j", k, val, s)
+ if (isNaN(s)) return false
+ data[k] = new Date(val)
+}
+
+function validateBoolean (data, k, val) {
+ if (val instanceof Boolean) val = val.valueOf()
+ else if (typeof val === "string") {
+ if (!isNaN(val)) val = !!(+val)
+ else if (val === "null" || val === "false") val = false
+ else val = true
+ } else val = !!val
+ data[k] = val
+}
+
+function validateUrl (data, k, val) {
+ val = url.parse(String(val))
+ if (!val.host) return false
+ data[k] = val.href
+}
+
+function validateStream (data, k, val) {
+ if (!(val instanceof Stream)) return false
+ data[k] = val
+}
+
+function validate (data, k, val, type, typeDefs) {
+ // arrays are lists of types.
+ if (Array.isArray(type)) {
+ for (var i = 0, l = type.length; i < l; i ++) {
+ if (type[i] === Array) continue
+ if (validate(data, k, val, type[i], typeDefs)) return true
+ }
+ delete data[k]
+ return false
+ }
+
+ // an array of anything?
+ if (type === Array) return true
+
+ // NaN is poisonous. Means that something is not allowed.
+ if (type !== type) {
+ debug("Poison NaN", k, val, type)
+ delete data[k]
+ return false
+ }
+
+ // explicit list of values
+ if (val === type) {
+ debug("Explicitly allowed %j", val)
+ // if (isArray) (data[k] = data[k] || []).push(val)
+ // else data[k] = val
+ data[k] = val
+ return true
+ }
+
+ // now go through the list of typeDefs, validate against each one.
+ var ok = false
+ , types = Object.keys(typeDefs)
+ for (var i = 0, l = types.length; i < l; i ++) {
+ debug("test type %j %j %j", k, val, types[i])
+ var t = typeDefs[types[i]]
+ if (t &&
+ ((type && type.name && t.type && t.type.name) ? (type.name === t.type.name) : (type === t.type))) {
+ var d = {}
+ ok = false !== t.validate(d, k, val)
+ val = d[k]
+ if (ok) {
+ // if (isArray) (data[k] = data[k] || []).push(val)
+ // else data[k] = val
+ data[k] = val
+ break
+ }
+ }
+ }
+ debug("OK? %j (%j %j %j)", ok, k, val, types[i])
+
+ if (!ok) delete data[k]
+ return ok
+}
+
+function parse (args, data, remain, types, shorthands) {
+ debug("parse", args, data, remain)
+
+ var key = null
+ , abbrevs = abbrev(Object.keys(types))
+ , shortAbbr = abbrev(Object.keys(shorthands))
+
+ for (var i = 0; i < args.length; i ++) {
+ var arg = args[i]
+ debug("arg", arg)
+
+ if (arg.match(/^-{2,}$/)) {
+ // done with keys.
+ // the rest are args.
+ remain.push.apply(remain, args.slice(i + 1))
+ args[i] = "--"
+ break
+ }
+ var hadEq = false
+ if (arg.charAt(0) === "-" && arg.length > 1) {
+ var at = arg.indexOf('=')
+ if (at > -1) {
+ hadEq = true
+ var v = arg.substr(at + 1)
+ arg = arg.substr(0, at)
+ args.splice(i, 1, arg, v)
+ }
+
+ // see if it's a shorthand
+ // if so, splice and back up to re-parse it.
+ var shRes = resolveShort(arg, shorthands, shortAbbr, abbrevs)
+ debug("arg=%j shRes=%j", arg, shRes)
+ if (shRes) {
+ debug(arg, shRes)
+ args.splice.apply(args, [i, 1].concat(shRes))
+ if (arg !== shRes[0]) {
+ i --
+ continue
+ }
+ }
+ arg = arg.replace(/^-+/, "")
+ var no = null
+ while (arg.toLowerCase().indexOf("no-") === 0) {
+ no = !no
+ arg = arg.substr(3)
+ }
+
+ if (abbrevs[arg]) arg = abbrevs[arg]
+
+ var argType = types[arg]
+ var isTypeArray = Array.isArray(argType)
+ if (isTypeArray && argType.length === 1) {
+ isTypeArray = false
+ argType = argType[0]
+ }
+
+ var isArray = argType === Array ||
+ isTypeArray && argType.indexOf(Array) !== -1
+
+ // allow unknown things to be arrays if specified multiple times.
+ if (!types.hasOwnProperty(arg) && data.hasOwnProperty(arg)) {
+ if (!Array.isArray(data[arg]))
+ data[arg] = [data[arg]]
+ isArray = true
+ }
+
+ var val
+ , la = args[i + 1]
+
+ var isBool = typeof no === 'boolean' ||
+ argType === Boolean ||
+ isTypeArray && argType.indexOf(Boolean) !== -1 ||
+ (typeof argType === 'undefined' && !hadEq) ||
+ (la === "false" &&
+ (argType === null ||
+ isTypeArray && ~argType.indexOf(null)))
+
+ if (isBool) {
+ // just set and move along
+ val = !no
+ // however, also support --bool true or --bool false
+ if (la === "true" || la === "false") {
+ val = JSON.parse(la)
+ la = null
+ if (no) val = !val
+ i ++
+ }
+
+ // also support "foo":[Boolean, "bar"] and "--foo bar"
+ if (isTypeArray && la) {
+ if (~argType.indexOf(la)) {
+ // an explicit type
+ val = la
+ i ++
+ } else if ( la === "null" && ~argType.indexOf(null) ) {
+ // null allowed
+ val = null
+ i ++
+ } else if ( !la.match(/^-{2,}[^-]/) &&
+ !isNaN(la) &&
+ ~argType.indexOf(Number) ) {
+ // number
+ val = +la
+ i ++
+ } else if ( !la.match(/^-[^-]/) && ~argType.indexOf(String) ) {
+ // string
+ val = la
+ i ++
+ }
+ }
+
+ if (isArray) (data[arg] = data[arg] || []).push(val)
+ else data[arg] = val
+
+ continue
+ }
+
+ if (argType === String) {
+ if (la === undefined) {
+ la = ""
+ } else if (la.match(/^-{1,2}[^-]+/)) {
+ la = ""
+ i --
+ }
+ }
+
+ if (la && la.match(/^-{2,}$/)) {
+ la = undefined
+ i --
+ }
+
+ val = la === undefined ? true : la
+ if (isArray) (data[arg] = data[arg] || []).push(val)
+ else data[arg] = val
+
+ i ++
+ continue
+ }
+ remain.push(arg)
+ }
+}
+
+function resolveShort (arg, shorthands, shortAbbr, abbrevs) {
+ // handle single-char shorthands glommed together, like
+ // npm ls -glp, but only if there is one dash, and only if
+ // all of the chars are single-char shorthands, and it's
+ // not a match to some other abbrev.
+ arg = arg.replace(/^-+/, '')
+
+ // if it's an exact known option, then don't go any further
+ if (abbrevs[arg] === arg)
+ return null
+
+ // if it's an exact known shortopt, same deal
+ if (shorthands[arg]) {
+ // make it an array, if it's a list of words
+ if (shorthands[arg] && !Array.isArray(shorthands[arg]))
+ shorthands[arg] = shorthands[arg].split(/\s+/)
+
+ return shorthands[arg]
+ }
+
+ // first check to see if this arg is a set of single-char shorthands
+ var singles = shorthands.___singles
+ if (!singles) {
+ singles = Object.keys(shorthands).filter(function (s) {
+ return s.length === 1
+ }).reduce(function (l,r) {
+ l[r] = true
+ return l
+ }, {})
+ shorthands.___singles = singles
+ debug('shorthand singles', singles)
+ }
+
+ var chrs = arg.split("").filter(function (c) {
+ return singles[c]
+ })
+
+ if (chrs.join("") === arg) return chrs.map(function (c) {
+ return shorthands[c]
+ }).reduce(function (l, r) {
+ return l.concat(r)
+ }, [])
+
+
+ // if it's an arg abbrev, and not a literal shorthand, then prefer the arg
+ if (abbrevs[arg] && !shorthands[arg])
+ return null
+
+ // if it's an abbr for a shorthand, then use that
+ if (shortAbbr[arg])
+ arg = shortAbbr[arg]
+
+ // make it an array, if it's a list of words
+ if (shorthands[arg] && !Array.isArray(shorthands[arg]))
+ shorthands[arg] = shorthands[arg].split(/\s+/)
+
+ return shorthands[arg]
+}
diff --git a/node_modules/grunt/node_modules/grunt-cli/node_modules/nopt/package.json b/node_modules/grunt/node_modules/grunt-cli/node_modules/nopt/package.json
new file mode 100644
index 0000000..a5cc9a9
--- /dev/null
+++ b/node_modules/grunt/node_modules/grunt-cli/node_modules/nopt/package.json
@@ -0,0 +1,65 @@
+{
+ "_from": "nopt@~4.0.1",
+ "_id": "nopt@4.0.3",
+ "_inBundle": false,
+ "_integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==",
+ "_location": "/grunt/grunt-cli/nopt",
+ "_phantomChildren": {},
+ "_requested": {
+ "type": "range",
+ "registry": true,
+ "raw": "nopt@~4.0.1",
+ "name": "nopt",
+ "escapedName": "nopt",
+ "rawSpec": "~4.0.1",
+ "saveSpec": null,
+ "fetchSpec": "~4.0.1"
+ },
+ "_requiredBy": [
+ "/grunt/grunt-cli"
+ ],
+ "_resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz",
+ "_shasum": "a375cad9d02fd921278d954c2254d5aa57e15e48",
+ "_spec": "nopt@~4.0.1",
+ "_where": "C:\\Users\\marcr\\Desktop\\KorAp\\Git\\Kalamar\\node_modules\\grunt\\node_modules\\grunt-cli",
+ "author": {
+ "name": "Isaac Z. Schlueter",
+ "email": "i@izs.me",
+ "url": "http://blog.izs.me/"
+ },
+ "bin": {
+ "nopt": "bin/nopt.js"
+ },
+ "bugs": {
+ "url": "https://github.com/npm/nopt/issues"
+ },
+ "bundleDependencies": false,
+ "dependencies": {
+ "abbrev": "1",
+ "osenv": "^0.1.4"
+ },
+ "deprecated": false,
+ "description": "Option parsing for Node, supporting types, shorthands, etc. Used by npm.",
+ "devDependencies": {
+ "tap": "^14.10.6"
+ },
+ "files": [
+ "bin",
+ "lib"
+ ],
+ "homepage": "https://github.com/npm/nopt#readme",
+ "license": "ISC",
+ "main": "lib/nopt.js",
+ "name": "nopt",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/npm/nopt.git"
+ },
+ "scripts": {
+ "postversion": "npm publish",
+ "prepublishOnly": "git push origin --follow-tags",
+ "preversion": "npm test",
+ "test": "tap test/*.js"
+ },
+ "version": "4.0.3"
+}
diff --git a/node_modules/grunt/node_modules/grunt-cli/package.json b/node_modules/grunt/node_modules/grunt-cli/package.json
new file mode 100644
index 0000000..1b7bcbe
--- /dev/null
+++ b/node_modules/grunt/node_modules/grunt-cli/package.json
@@ -0,0 +1,72 @@
+{
+ "_from": "grunt-cli@~1.3.2",
+ "_id": "grunt-cli@1.3.2",
+ "_inBundle": false,
+ "_integrity": "sha512-8OHDiZZkcptxVXtMfDxJvmN7MVJNE8L/yIcPb4HB7TlyFD1kDvjHrb62uhySsU14wJx9ORMnTuhRMQ40lH/orQ==",
+ "_location": "/grunt/grunt-cli",
+ "_phantomChildren": {
+ "abbrev": "1.1.1",
+ "osenv": "0.1.5"
+ },
+ "_requested": {
+ "type": "range",
+ "registry": true,
+ "raw": "grunt-cli@~1.3.2",
+ "name": "grunt-cli",
+ "escapedName": "grunt-cli",
+ "rawSpec": "~1.3.2",
+ "saveSpec": null,
+ "fetchSpec": "~1.3.2"
+ },
+ "_requiredBy": [
+ "/grunt"
+ ],
+ "_resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.3.2.tgz",
+ "_shasum": "60f12d12c1b5aae94ae3469c6b5fe24e960014e8",
+ "_spec": "grunt-cli@~1.3.2",
+ "_where": "C:\\Users\\marcr\\Desktop\\KorAp\\Git\\Kalamar\\node_modules\\grunt",
+ "appveyor_id": "prp6g944b05jsq6d",
+ "author": {
+ "name": "Grunt Development Team",
+ "url": "http://gruntjs.com/development-team"
+ },
+ "bin": {
+ "grunt": "bin/grunt"
+ },
+ "bugs": {
+ "url": "https://github.com/gruntjs/grunt-cli/issues"
+ },
+ "bundleDependencies": false,
+ "dependencies": {
+ "grunt-known-options": "~1.1.0",
+ "interpret": "~1.1.0",
+ "liftoff": "~2.5.0",
+ "nopt": "~4.0.1",
+ "v8flags": "~3.1.1"
+ },
+ "deprecated": false,
+ "description": "The grunt command line interface",
+ "devDependencies": {
+ "grunt": "~1.0.2",
+ "grunt-contrib-jshint": "~1.1.0"
+ },
+ "engines": {
+ "node": ">=4"
+ },
+ "files": [
+ "bin",
+ "completion",
+ "lib"
+ ],
+ "homepage": "https://github.com/gruntjs/grunt-cli#readme",
+ "license": "MIT",
+ "name": "grunt-cli",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/gruntjs/grunt-cli.git"
+ },
+ "scripts": {
+ "test": "node bin/grunt test"
+ },
+ "version": "1.3.2"
+}
diff --git a/node_modules/grunt/package.json b/node_modules/grunt/package.json
new file mode 100644
index 0000000..315a6a4
--- /dev/null
+++ b/node_modules/grunt/package.json
@@ -0,0 +1,110 @@
+{
+ "_from": "grunt@^1.0.4",
+ "_id": "grunt@1.3.0",
+ "_inBundle": false,
+ "_integrity": "sha512-6ILlMXv11/4cxuhSMfSU+SfvbxrPuqZrAtLN64+tZpQ3DAKfSQPQHRbTjSbdtxfyQhGZPtN0bDZJ/LdCM5WXXA==",
+ "_location": "/grunt",
+ "_phantomChildren": {
+ "abbrev": "1.1.1",
+ "grunt-known-options": "1.1.1",
+ "interpret": "1.1.0",
+ "liftoff": "2.5.0",
+ "osenv": "0.1.5",
+ "v8flags": "3.1.3"
+ },
+ "_requested": {
+ "type": "range",
+ "registry": true,
+ "raw": "grunt@^1.0.4",
+ "name": "grunt",
+ "escapedName": "grunt",
+ "rawSpec": "^1.0.4",
+ "saveSpec": null,
+ "fetchSpec": "^1.0.4"
+ },
+ "_requiredBy": [
+ "#DEV:/"
+ ],
+ "_resolved": "https://registry.npmjs.org/grunt/-/grunt-1.3.0.tgz",
+ "_shasum": "55db6ccd80c6fb53722e496f680620a2e681f809",
+ "_spec": "grunt@^1.0.4",
+ "_where": "C:\\Users\\marcr\\Desktop\\KorAp\\Git\\Kalamar",
+ "author": {
+ "name": "Grunt Development Team",
+ "url": "https://gruntjs.com/development-team"
+ },
+ "bin": {
+ "grunt": "bin/grunt"
+ },
+ "bugs": {
+ "url": "https://github.com/gruntjs/grunt/issues"
+ },
+ "bundleDependencies": false,
+ "dependencies": {
+ "dateformat": "~3.0.3",
+ "eventemitter2": "~0.4.13",
+ "exit": "~0.1.2",
+ "findup-sync": "~0.3.0",
+ "glob": "~7.1.6",
+ "grunt-cli": "~1.3.2",
+ "grunt-known-options": "~1.1.0",
+ "grunt-legacy-log": "~3.0.0",
+ "grunt-legacy-util": "~2.0.0",
+ "iconv-lite": "~0.4.13",
+ "js-yaml": "~3.14.0",
+ "minimatch": "~3.0.4",
+ "mkdirp": "~1.0.4",
+ "nopt": "~3.0.6",
+ "rimraf": "~3.0.2"
+ },
+ "deprecated": false,
+ "description": "The JavaScript Task Runner",
+ "devDependencies": {
+ "difflet": "~1.0.1",
+ "eslint-config-grunt": "~1.0.1",
+ "grunt-contrib-nodeunit": "~2.1.0",
+ "grunt-contrib-watch": "~1.1.0",
+ "grunt-eslint": "~18.1.0",
+ "temporary": "~0.0.4",
+ "through2": "~2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "files": [
+ "lib",
+ "bin"
+ ],
+ "homepage": "https://gruntjs.com/",
+ "keywords": [
+ "task",
+ "async",
+ "cli",
+ "minify",
+ "uglify",
+ "build",
+ "lodash",
+ "unit",
+ "test",
+ "qunit",
+ "nodeunit",
+ "server",
+ "init",
+ "scaffold",
+ "make",
+ "jake",
+ "tool"
+ ],
+ "license": "MIT",
+ "main": "lib/grunt",
+ "name": "grunt",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/gruntjs/grunt.git"
+ },
+ "scripts": {
+ "test": "node bin/grunt test",
+ "test-tap": "node bin/grunt test:tap"
+ },
+ "version": "1.3.0"
+}