diff options
Diffstat (limited to 'node_modules/gaze')
-rw-r--r-- | node_modules/gaze/LICENSE-MIT | 22 | ||||
-rw-r--r-- | node_modules/gaze/README.md | 181 | ||||
-rw-r--r-- | node_modules/gaze/lib/gaze.js | 439 | ||||
-rw-r--r-- | node_modules/gaze/lib/helper.js | 67 | ||||
-rw-r--r-- | node_modules/gaze/package.json | 151 |
5 files changed, 860 insertions, 0 deletions
diff --git a/node_modules/gaze/LICENSE-MIT b/node_modules/gaze/LICENSE-MIT new file mode 100644 index 000000000..8c1a83323 --- /dev/null +++ b/node_modules/gaze/LICENSE-MIT @@ -0,0 +1,22 @@ +Copyright (c) 2013 Kyle Robinson Young + +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. diff --git a/node_modules/gaze/README.md b/node_modules/gaze/README.md new file mode 100644 index 000000000..f7d6c3bad --- /dev/null +++ b/node_modules/gaze/README.md @@ -0,0 +1,181 @@ +# gaze [](https://travis-ci.org/shama/gaze) + +A globbing fs.watch wrapper built from the best parts of other fine watch libs. +Compatible with Node.js 0.10/0.8, Windows, OSX and Linux. + + + +## Usage +Install the module with: `npm install gaze` or place into your `package.json` +and run `npm install`. + +```javascript +var gaze = require('gaze'); + +// Watch all .js files/dirs in process.cwd() +gaze('**/*.js', function(err, watcher) { + // Files have all started watching + // watcher === this + + // Get all watched files + console.log(this.watched()); + + // On file changed + this.on('changed', function(filepath) { + console.log(filepath + ' was changed'); + }); + + // On file added + this.on('added', function(filepath) { + console.log(filepath + ' was added'); + }); + + // On file deleted + this.on('deleted', function(filepath) { + console.log(filepath + ' was deleted'); + }); + + // On changed/added/deleted + this.on('all', function(event, filepath) { + console.log(filepath + ' was ' + event); + }); + + // Get watched files with relative paths + console.log(this.relative()); +}); + +// Also accepts an array of patterns +gaze(['stylesheets/*.css', 'images/**/*.png'], function() { + // Add more patterns later to be watched + this.add(['js/*.js']); +}); +``` + +### Alternate Interface + +```javascript +var Gaze = require('gaze').Gaze; + +var gaze = new Gaze('**/*'); + +// Files have all started watching +gaze.on('ready', function(watcher) { }); + +// A file has been added/changed/deleted has occurred +gaze.on('all', function(event, filepath) { }); +``` + +### Errors + +```javascript +gaze('**/*', function() { + this.on('error', function(err) { + // Handle error here + }); +}); +``` + +### Minimatch / Glob + +See [isaacs's minimatch](https://github.com/isaacs/minimatch) for more +information on glob patterns. + +## Documentation + +### gaze(patterns, [options], callback) + +* `patterns` {String|Array} File patterns to be matched +* `options` {Object} +* `callback` {Function} + * `err` {Error | null} + * `watcher` {Object} Instance of the Gaze watcher + +### Class: gaze.Gaze + +Create a Gaze object by instanting the `gaze.Gaze` class. + +```javascript +var Gaze = require('gaze').Gaze; +var gaze = new Gaze(pattern, options, callback); +``` + +#### Properties + +* `options` The options object passed in. + * `interval` {integer} Interval to pass to fs.watchFile + * `debounceDelay` {integer} Delay for events called in succession for the same + file/event + +#### Events + +* `ready(watcher)` When files have been globbed and watching has begun. +* `all(event, filepath)` When an `added`, `changed` or `deleted` event occurs. +* `added(filepath)` When a file has been added to a watch directory. +* `changed(filepath)` When a file has been changed. +* `deleted(filepath)` When a file has been deleted. +* `renamed(newPath, oldPath)` When a file has been renamed. +* `end()` When the watcher is closed and watches have been removed. +* `error(err)` When an error occurs. +* `nomatch` When no files have been matched. + +#### Methods + +* `emit(event, [...])` Wrapper for the EventEmitter.emit. + `added`|`changed`|`deleted` events will also trigger the `all` event. +* `close()` Unwatch all files and reset the watch instance. +* `add(patterns, callback)` Adds file(s) patterns to be watched. +* `remove(filepath)` removes a file or directory from being watched. Does not + recurse directories. +* `watched()` Returns the currently watched files. +* `relative([dir, unixify])` Returns the currently watched files with relative paths. + * `dir` {string} Only return relative files for this directory. + * `unixify` {boolean} Return paths with `/` instead of `\\` if on Windows. + +## FAQs + +### Why Another `fs.watch` Wrapper? +I liked parts of other `fs.watch` wrappers but none had all the features I +needed. This lib combines the features I needed from other fine watch libs: +Speedy data behavior from +[paulmillr's chokidar](https://github.com/paulmillr/chokidar), API interface +from [mikeal's watch](https://github.com/mikeal/watch) and file globbing using +[isaacs's glob](https://github.com/isaacs/node-glob) which is also used by +[cowboy's Grunt](https://github.com/gruntjs/grunt). + +### How do I fix the error `EMFILE: Too many opened files.`? +This is because of your system's max opened file limit. For OSX the default is +very low (256). Increase your limit temporarily with `ulimit -n 10480`, the +number being the new max limit. + +## Contributing +In lieu of a formal styleguide, take care to maintain the existing coding style. +Add unit tests for any new or changed functionality. Lint and test your code +using [grunt](http://gruntjs.com/). + +## Release History +* 0.5.2 - Fix for ENOENT error with non-existent symlinks. +* 0.5.1 - Use setImmediate (process.nextTick for node v0.8) to defer ready/nomatch events (@amasad). +* 0.5.0 - Process is now kept alive while watching files. Emits a nomatch event when no files are matching. +* 0.4.3 - Track file additions in newly created folders (@brett-shwom). +* 0.4.2 - Fix .remove() method to remove a single file in a directory (@kaelzhang). Fixing Cannot call method 'call' of undefined (@krasimir). Track new file additions within folders (@brett-shwom). +* 0.4.1 - Fix watchDir not respecting close in race condition (@chrisirhc). +* 0.4.0 - Drop support for node v0.6. Use globule for file matching. Avoid node v0.10 path.resolve/join errors. Register new files when added to non-existent folder. Multiple instances can now poll the same files (@jpommerening). +* 0.3.4 - Code clean up. Fix path must be strings errors (@groner). Fix incorrect added events (@groner). +* 0.3.3 - Fix for multiple patterns with negate. +* 0.3.2 - Emit `end` before removeAllListeners. +* 0.3.1 - Fix added events within subfolder patterns. +* 0.3.0 - Handle safewrite events, `forceWatchMethod` option removed, bug fixes and watch optimizations (@rgaskill). +* 0.2.2 - Fix issue where subsequent add calls dont get watched (@samcday). removeAllListeners on close. +* 0.2.1 - Fix issue with invalid `added` events in current working dir. +* 0.2.0 - Support and mark folders with `path.sep`. Add `forceWatchMethod` option. Support `renamed` events. +* 0.1.6 - Recognize the `cwd` option properly +* 0.1.5 - Catch too many open file errors +* 0.1.4 - Really fix the race condition with 2 watches +* 0.1.3 - Fix race condition with 2 watches +* 0.1.2 - Read triggering changed event fix +* 0.1.1 - Minor fixes +* 0.1.0 - Initial release + +## License +Copyright (c) 2013 Kyle Robinson Young +Licensed under the MIT license. diff --git a/node_modules/gaze/lib/gaze.js b/node_modules/gaze/lib/gaze.js new file mode 100644 index 000000000..28c26533b --- /dev/null +++ b/node_modules/gaze/lib/gaze.js @@ -0,0 +1,439 @@ +/* + * gaze + * https://github.com/shama/gaze + * + * Copyright (c) 2013 Kyle Robinson Young + * Licensed under the MIT license. + */ + +'use strict'; + +// libs +var util = require('util'); +var EE = require('events').EventEmitter; +var fs = require('fs'); +var path = require('path'); +var globule = require('globule'); +var helper = require('./helper'); + +// shim setImmediate for node v0.8 +var setImmediate = require('timers').setImmediate; +if (typeof setImmediate !== 'function') { + setImmediate = process.nextTick; +} + +// globals +var delay = 10; + +// `Gaze` EventEmitter object to return in the callback +function Gaze(patterns, opts, done) { + var self = this; + EE.call(self); + + // If second arg is the callback + if (typeof opts === 'function') { + done = opts; + opts = {}; + } + + // Default options + opts = opts || {}; + opts.mark = true; + opts.interval = opts.interval || 100; + opts.debounceDelay = opts.debounceDelay || 500; + opts.cwd = opts.cwd || process.cwd(); + this.options = opts; + + // Default done callback + done = done || function() {}; + + // Remember our watched dir:files + this._watched = Object.create(null); + + // Store watchers + this._watchers = Object.create(null); + + // Store watchFile listeners + this._pollers = Object.create(null); + + // Store patterns + this._patterns = []; + + // Cached events for debouncing + this._cached = Object.create(null); + + // Set maxListeners + if (this.options.maxListeners) { + this.setMaxListeners(this.options.maxListeners); + Gaze.super_.prototype.setMaxListeners(this.options.maxListeners); + delete this.options.maxListeners; + } + + // Initialize the watch on files + if (patterns) { + this.add(patterns, done); + } + + // keep the process alive + this._keepalive = setInterval(function() {}, 200); + + return this; +} +util.inherits(Gaze, EE); + +// Main entry point. Start watching and call done when setup +module.exports = function gaze(patterns, opts, done) { + return new Gaze(patterns, opts, done); +}; +module.exports.Gaze = Gaze; + +// Override the emit function to emit `all` events +// and debounce on duplicate events per file +Gaze.prototype.emit = function() { + var self = this; + var args = arguments; + + var e = args[0]; + var filepath = args[1]; + var timeoutId; + + // If not added/deleted/changed/renamed then just emit the event + if (e.slice(-2) !== 'ed') { + Gaze.super_.prototype.emit.apply(self, args); + return this; + } + + // Detect rename event, if added and previous deleted is in the cache + if (e === 'added') { + Object.keys(this._cached).forEach(function(oldFile) { + if (self._cached[oldFile].indexOf('deleted') !== -1) { + args[0] = e = 'renamed'; + [].push.call(args, oldFile); + delete self._cached[oldFile]; + return false; + } + }); + } + + // If cached doesnt exist, create a delay before running the next + // then emit the event + var cache = this._cached[filepath] || []; + if (cache.indexOf(e) === -1) { + helper.objectPush(self._cached, filepath, e); + clearTimeout(timeoutId); + timeoutId = setTimeout(function() { + delete self._cached[filepath]; + }, this.options.debounceDelay); + // Emit the event and `all` event + Gaze.super_.prototype.emit.apply(self, args); + Gaze.super_.prototype.emit.apply(self, ['all', e].concat([].slice.call(args, 1))); + } + + // Detect if new folder added to trigger for matching files within folder + if (e === 'added') { + if (helper.isDir(filepath)) { + fs.readdirSync(filepath).map(function(file) { + return path.join(filepath, file); + }).filter(function(file) { + return globule.isMatch(self._patterns, file, self.options); + }).forEach(function(file) { + self.emit('added', file); + }); + } + } + + return this; +}; + +// Close watchers +Gaze.prototype.close = function(_reset) { + var self = this; + _reset = _reset === false ? false : true; + Object.keys(self._watchers).forEach(function(file) { + self._watchers[file].close(); + }); + self._watchers = Object.create(null); + Object.keys(this._watched).forEach(function(dir) { + self._unpollDir(dir); + }); + if (_reset) { + self._watched = Object.create(null); + setTimeout(function() { + self.emit('end'); + self.removeAllListeners(); + clearInterval(self._keepalive); + }, delay + 100); + } + return self; +}; + +// Add file patterns to be watched +Gaze.prototype.add = function(files, done) { + if (typeof files === 'string') { files = [files]; } + this._patterns = helper.unique.apply(null, [this._patterns, files]); + files = globule.find(this._patterns, this.options); + this._addToWatched(files); + this.close(false); + this._initWatched(done); +}; + +// Dont increment patterns and dont call done if nothing added +Gaze.prototype._internalAdd = function(file, done) { + var files = []; + if (helper.isDir(file)) { + files = [helper.markDir(file)].concat(globule.find(this._patterns, this.options)); + } else { + if (globule.isMatch(this._patterns, file, this.options)) { + files = [file]; + } + } + if (files.length > 0) { + this._addToWatched(files); + this.close(false); + this._initWatched(done); + } +}; + +// Remove file/dir from `watched` +Gaze.prototype.remove = function(file) { + var self = this; + if (this._watched[file]) { + // is dir, remove all files + this._unpollDir(file); + delete this._watched[file]; + } else { + // is a file, find and remove + Object.keys(this._watched).forEach(function(dir) { + var index = self._watched[dir].indexOf(file); + if (index !== -1) { + self._unpollFile(file); + self._watched[dir].splice(index, 1); + return false; + } + }); + } + if (this._watchers[file]) { + this._watchers[file].close(); + } + return this; +}; + +// Return watched files +Gaze.prototype.watched = function() { + return this._watched; +}; + +// Returns `watched` files with relative paths to process.cwd() +Gaze.prototype.relative = function(dir, unixify) { + var self = this; + var relative = Object.create(null); + var relDir, relFile, unixRelDir; + var cwd = this.options.cwd || process.cwd(); + if (dir === '') { dir = '.'; } + dir = helper.markDir(dir); + unixify = unixify || false; + Object.keys(this._watched).forEach(function(dir) { + relDir = path.relative(cwd, dir) + path.sep; + if (relDir === path.sep) { relDir = '.'; } + unixRelDir = unixify ? helper.unixifyPathSep(relDir) : relDir; + relative[unixRelDir] = self._watched[dir].map(function(file) { + relFile = path.relative(path.join(cwd, relDir) || '', file || ''); + if (helper.isDir(file)) { + relFile = helper.markDir(relFile); + } + if (unixify) { + relFile = helper.unixifyPathSep(relFile); + } + return relFile; + }); + }); + if (dir && unixify) { + dir = helper.unixifyPathSep(dir); + } + return dir ? relative[dir] || [] : relative; +}; + +// Adds files and dirs to watched +Gaze.prototype._addToWatched = function(files) { + for (var i = 0; i < files.length; i++) { + var file = files[i]; + var filepath = path.resolve(this.options.cwd, file); + + var dirname = (helper.isDir(file)) ? filepath : path.dirname(filepath); + dirname = helper.markDir(dirname); + + // If a new dir is added + if (helper.isDir(file) && !(filepath in this._watched)) { + helper.objectPush(this._watched, filepath, []); + } + + if (file.slice(-1) === '/') { filepath += path.sep; } + helper.objectPush(this._watched, path.dirname(filepath) + path.sep, filepath); + + // add folders into the mix + var readdir = fs.readdirSync(dirname); + for (var j = 0; j < readdir.length; j++) { + var dirfile = path.join(dirname, readdir[j]); + if (fs.lstatSync(dirfile).isDirectory()) { + helper.objectPush(this._watched, dirname, dirfile + path.sep); + } + } + } + return this; +}; + +Gaze.prototype._watchDir = function(dir, done) { + var self = this; + var timeoutId; + try { + this._watchers[dir] = fs.watch(dir, function(event) { + // race condition. Let's give the fs a little time to settle down. so we + // don't fire events on non existent files. + clearTimeout(timeoutId); + timeoutId = setTimeout(function() { + // race condition. Ensure that this directory is still being watched + // before continuing. + if ((dir in self._watchers) && fs.existsSync(dir)) { + done(null, dir); + } + }, delay + 100); + }); + } catch (err) { + return this._handleError(err); + } + return this; +}; + +Gaze.prototype._unpollFile = function(file) { + if (this._pollers[file]) { + fs.unwatchFile(file, this._pollers[file] ); + delete this._pollers[file]; + } + return this; +}; + +Gaze.prototype._unpollDir = function(dir) { + this._unpollFile(dir); + for (var i = 0; i < this._watched[dir].length; i++) { + this._unpollFile(this._watched[dir][i]); + } +}; + +Gaze.prototype._pollFile = function(file, done) { + var opts = { persistent: true, interval: this.options.interval }; + if (!this._pollers[file]) { + this._pollers[file] = function(curr, prev) { + done(null, file); + }; + try { + fs.watchFile(file, opts, this._pollers[file]); + } catch (err) { + return this._handleError(err); + } + } + return this; +}; + +// Initialize the actual watch on `watched` files +Gaze.prototype._initWatched = function(done) { + var self = this; + var cwd = this.options.cwd || process.cwd(); + var curWatched = Object.keys(self._watched); + + // if no matching files + if (curWatched.length < 1) { + // Defer to emitting to give a chance to attach event handlers. + setImmediate(function () { + self.emit('ready', self); + if (done) { done.call(self, null, self); } + self.emit('nomatch'); + }); + return; + } + + helper.forEachSeries(curWatched, function(dir, next) { + dir = dir || ''; + var files = self._watched[dir]; + // Triggered when a watched dir has an event + self._watchDir(dir, function(event, dirpath) { + var relDir = cwd === dir ? '.' : path.relative(cwd, dir); + relDir = relDir || ''; + + fs.readdir(dirpath, function(err, current) { + if (err) { return self.emit('error', err); } + if (!current) { return; } + + try { + // append path.sep to directories so they match previous. + current = current.map(function(curPath) { + if (fs.existsSync(path.join(dir, curPath)) && fs.lstatSync(path.join(dir, curPath)).isDirectory()) { + return curPath + path.sep; + } else { + return curPath; + } + }); + } catch (err) { + // race condition-- sometimes the file no longer exists + } + + // Get watched files for this dir + var previous = self.relative(relDir); + + // If file was deleted + previous.filter(function(file) { + return current.indexOf(file) < 0; + }).forEach(function(file) { + if (!helper.isDir(file)) { + var filepath = path.join(dir, file); + self.remove(filepath); + self.emit('deleted', filepath); + } + }); + + // If file was added + current.filter(function(file) { + return previous.indexOf(file) < 0; + }).forEach(function(file) { + // Is it a matching pattern? + var relFile = path.join(relDir, file); + // Add to watch then emit event + self._internalAdd(relFile, function() { + self.emit('added', path.join(dir, file)); + }); + }); + + }); + }); + + // Watch for change/rename events on files + files.forEach(function(file) { + if (helper.isDir(file)) { return; } + self._pollFile(file, function(err, filepath) { + // Only emit changed if the file still exists + // Prevents changed/deleted duplicate events + if (fs.existsSync(filepath)) { + self.emit('changed', filepath); + } + }); + }); + + next(); + }, function() { + + // Return this instance of Gaze + // delay before ready solves a lot of issues + setTimeout(function() { + self.emit('ready', self); + if (done) { done.call(self, null, self); } + }, delay + 100); + + }); +}; + +// If an error, handle it here +Gaze.prototype._handleError = function(err) { + if (err.code === 'EMFILE') { + return this.emit('error', new Error('EMFILE: Too many opened files.')); + } + return this.emit('error', err); +}; diff --git a/node_modules/gaze/lib/helper.js b/node_modules/gaze/lib/helper.js new file mode 100644 index 000000000..e1ccc80ed --- /dev/null +++ b/node_modules/gaze/lib/helper.js @@ -0,0 +1,67 @@ +'use strict'; + +var path = require('path'); +var helper = module.exports = {}; + +// Returns boolean whether filepath is dir terminated +helper.isDir = function isDir(dir) { + if (typeof dir !== 'string') { return false; } + return (dir.slice(-(path.sep.length)) === path.sep); +}; + +// Create a `key:[]` if doesnt exist on `obj` then push or concat the `val` +helper.objectPush = function objectPush(obj, key, val) { + if (obj[key] == null) { obj[key] = []; } + if (Array.isArray(val)) { obj[key] = obj[key].concat(val); } + else if (val) { obj[key].push(val); } + return obj[key] = helper.unique(obj[key]); +}; + +// Ensures the dir is marked with path.sep +helper.markDir = function markDir(dir) { + if (typeof dir === 'string' && + dir.slice(-(path.sep.length)) !== path.sep && + dir !== '.') { + dir += path.sep; + } + return dir; +}; + +// Changes path.sep to unix ones for testing +helper.unixifyPathSep = function unixifyPathSep(filepath) { + return (process.platform === 'win32') ? String(filepath).replace(/\\/g, '/') : filepath; +}; + +/** + * Lo-Dash 1.0.1 <http://lodash.com/> + * Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/> + * Based on Underscore.js 1.4.4 <http://underscorejs.org/> + * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud Inc. + * Available under MIT license <http://lodash.com/license> + */ +helper.unique = function unique() { var array = Array.prototype.concat.apply(Array.prototype, arguments); var result = []; for (var i = 0; i < array.length; i++) { if (result.indexOf(array[i]) === -1) { result.push(array[i]); } } return result; }; + +/** + * Copyright (c) 2010 Caolan McMahon + * Available under MIT license <https://raw.github.com/caolan/async/master/LICENSE> + */ +helper.forEachSeries = function forEachSeries(arr, iterator, callback) { + if (!arr.length) { return callback(); } + var completed = 0; + var iterate = function() { + iterator(arr[completed], function (err) { + if (err) { + callback(err); + callback = function() {}; + } else { + completed += 1; + if (completed === arr.length) { + callback(null); + } else { + iterate(); + } + } + }); + }; + iterate(); +}; diff --git a/node_modules/gaze/package.json b/node_modules/gaze/package.json new file mode 100644 index 000000000..ddfc15f6f --- /dev/null +++ b/node_modules/gaze/package.json @@ -0,0 +1,151 @@ +{ + "_args": [ + [ + { + "raw": "gaze@^0.5.1", + "scope": null, + "escapedName": "gaze", + "name": "gaze", + "rawSpec": "^0.5.1", + "spec": ">=0.5.1 <0.6.0", + "type": "range" + }, + "/home/dold/repos/taler/wallet-webex/node_modules/glob-watcher" + ] + ], + "_from": "gaze@>=0.5.1 <0.6.0", + "_id": "gaze@0.5.2", + "_inCache": true, + "_location": "/gaze", + "_nodeVersion": "4.0.0", + "_npmUser": { + "name": "shama", + "email": "kyle@dontkry.com" + }, + "_npmVersion": "3.3.4", + "_phantomChildren": {}, + "_requested": { + "raw": "gaze@^0.5.1", + "scope": null, + "escapedName": "gaze", + "name": "gaze", + "rawSpec": "^0.5.1", + "spec": ">=0.5.1 <0.6.0", + "type": "range" + }, + "_requiredBy": [ + "/glob-watcher" + ], + "_resolved": "https://registry.npmjs.org/gaze/-/gaze-0.5.2.tgz", + "_shasum": "40b709537d24d1d45767db5a908689dfe69ac44f", + "_shrinkwrap": null, + "_spec": "gaze@^0.5.1", + "_where": "/home/dold/repos/taler/wallet-webex/node_modules/glob-watcher", + "author": { + "name": "Kyle Robinson Young", + "email": "kyle@dontkry.com" + }, + "bugs": { + "url": "https://github.com/shama/gaze/issues" + }, + "contributors": [ + { + "name": "Kyle Robinson Young", + "url": "http://dontkry.com" + }, + { + "name": "Sam Day", + "url": "http://sam.is-super-awesome.com" + }, + { + "name": "Roarke Gaskill", + "url": "http://starkinvestments.com" + }, + { + "name": "Lance Pollard", + "url": "http://lancepollard.com/" + }, + { + "name": "Daniel Fagnan", + "url": "http://hydrocodedesign.com/" + }, + { + "name": "Jonas", + "url": "http://jpommerening.github.io/" + }, + { + "name": "Chris Chua", + "url": "http://sirh.cc/" + }, + { + "name": "Kael Zhang", + "url": "http://kael.me" + }, + { + "name": "Krasimir Tsonev", + "url": "http://krasimirtsonev.com/blog" + }, + { + "name": "brett-shwom" + } + ], + "dependencies": { + "globule": "~0.1.0" + }, + "description": "A globbing fs.watch wrapper built from the best parts of other fine watch libs.", + "devDependencies": { + "async": "~0.2.10", + "grunt": "~0.4.1", + "grunt-benchmark": "~0.2.0", + "grunt-cli": "~0.1.13", + "grunt-contrib-jshint": "~0.6.0", + "grunt-contrib-nodeunit": "~0.2.0", + "rimraf": "~2.2.6" + }, + "directories": {}, + "dist": { + "shasum": "40b709537d24d1d45767db5a908689dfe69ac44f", + "tarball": "https://registry.npmjs.org/gaze/-/gaze-0.5.2.tgz" + }, + "engines": { + "node": ">= 0.8.0" + }, + "files": [ + "lib", + "LICENSE-MIT" + ], + "gitHead": "52007df64a841ccf52b9f9cd617cd24a4e2ddf8b", + "homepage": "https://github.com/shama/gaze", + "keywords": [ + "watch", + "glob" + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/shama/gaze/blob/master/LICENSE-MIT" + } + ], + "main": "lib/gaze", + "maintainers": [ + { + "name": "joshperry", + "email": "josh@6bit.com" + }, + { + "name": "shama", + "email": "kyle@dontkry.com" + } + ], + "name": "gaze", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/shama/gaze.git" + }, + "scripts": { + "test": "grunt nodeunit -v" + }, + "version": "0.5.2" +} |