aboutsummaryrefslogtreecommitdiff
path: root/node_modules/chokidar
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/chokidar')
-rw-r--r--node_modules/chokidar/CHANGELOG.md290
-rw-r--r--node_modules/chokidar/README.md293
-rw-r--r--node_modules/chokidar/index.js743
-rw-r--r--node_modules/chokidar/lib/fsevents-handler.js405
-rw-r--r--node_modules/chokidar/lib/nodefs-handler.js488
-rw-r--r--node_modules/chokidar/package.json92
6 files changed, 2311 insertions, 0 deletions
diff --git a/node_modules/chokidar/CHANGELOG.md b/node_modules/chokidar/CHANGELOG.md
new file mode 100644
index 0000000..0900987
--- /dev/null
+++ b/node_modules/chokidar/CHANGELOG.md
@@ -0,0 +1,290 @@
+# Chokidar 2.0.2 (Feb 14, 2018)
+* Allow semver range updates for upath dependency
+
+# Chokidar 2.0.1 (Feb 8, 2018)
+ * Fix #668 glob issue on Windows when using `ignore` and `cwd`. Thanks @remy!
+ * Fix #546 possible uncaught exception when using `awaitWriteFinish`.
+ Thanks @dsagal!
+
+# Chokidar 2.0.0 (Dec 29, 2017)
+* Breaking: Upgrade globbing dependencies which require globs to be more strict and always use POSIX-style slashes because Windows-style slashes are used as escape sequences
+* Update tests to work with upgraded globbing dependencies
+* Add ability to log FSEvents require error by setting `CHOKIDAR_PRINT_FSEVENTS_REQUIRE_ERROR` env
+* Fix for handling braces in globs
+* Add node 8 & 9 to CI configs
+* Allow node 0.10 failures on Windows
+
+# Chokidar 1.7.0 (May 8, 2017)
+* Add `disableGlobbing` option
+* Add ability to force interval value by setting CHOKIDAR_INTERVAL env
+ variable
+* Fix issue with `.close()` being called before `ready`
+
+# Chokidar 1.6.0 (Jun 22, 2016)
+* Added ability for force `usePolling` mode by setting `CHOKIDAR_USEPOLLING`
+ env variable
+
+# Chokidar 1.5.2 (Jun 7, 2016)
+* Fix missing `addDir` events when using `cwd` and `alwaysStat` options
+* Fix missing `add` events for files within a renamed directory
+
+# Chokidar 1.5.1 (May 20, 2016)
+* To help prevent exhaustion of FSEvents system limitations, consolidate watch
+ instances to the common parent upon detection of separate watch instances on
+ many siblings
+
+# Chokidar 1.5.0 (May 10, 2016)
+* Make debounce delay setting used with `atomic: true` user-customizable
+* Fixes and improvements to `awaitWriteFinish` features
+
+# Chokidar 1.4.3 (Feb 26, 2016)
+* Update async-each dependency to ^1.0.0
+
+# Chokidar 1.4.2 (Dec 30, 2015)
+* Now correctly emitting `stats` with `awaitWriteFinish` option.
+
+# Chokidar 1.4.1 (Dec 9, 2015)
+* The watcher could now be correctly subclassed with ES6 class syntax.
+
+# Chokidar 1.4.0 (Dec 3, 2015)
+* Add `.getWatched()` method, exposing all file system entries being watched
+* Apply `awaitWriteFinish` methodology to `change` events (in addition to `add`)
+* Fix handling of symlinks within glob paths (#293)
+* Fix `addDir` and `unlinkDir` events under globs (#337, #401)
+* Fix issues with `.unwatch()` (#374, #403)
+
+# Chokidar 1.3.0 (Nov 18, 2015)
+* Improve `awaitWriteFinish` option behavior
+* Fix some `cwd` option behavior on Windows
+* `awaitWriteFinish` and `cwd` are now compatible
+* Fix some race conditions.
+* #379: Recreating deleted directory doesn't trigger event
+* When adding a previously-deleted file, emit 'add', not 'change'
+
+# Chokidar 1.2.0 (Oct 1, 2015)
+* Allow nested arrays of paths to be provided to `.watch()` and `.add()`
+* Add `awaitWriteFinish` option
+
+# Chokidar 1.1.0 (Sep 23, 2015)
+* Dependency updates including fsevents@1.0.0, improving installation
+
+# Chokidar 1.0.6 (Sep 18, 2015)
+* Fix issue with `.unwatch()` method and relative paths
+
+# Chokidar 1.0.5 (Jul 20, 2015)
+* Fix regression with regexes/fns using in `ignored`
+
+# Chokidar 1.0.4 (Jul 15, 2015)
+* Fix bug with `ignored` files/globs while `cwd` option is set
+
+# Chokidar 1.0.3 (Jun 4, 2015)
+* Fix race issue with `alwaysStat` option and removed files
+
+# Chokidar 1.0.2 (May 30, 2015)
+* Fix bug with absolute paths and ENAMETOOLONG error
+
+# Chokidar 1.0.1 (Apr 8, 2015)
+* Fix bug with `.close()` method in `fs.watch` mode with `persistent: false`
+ option
+
+# Chokidar 1.0.0 (Apr 7, 2015)
+* Glob support! Use globs in `watch`, `add`, and `unwatch` methods
+* Comprehensive symlink support
+* New `unwatch` method to turn off watching of previously watched paths
+* More flexible `ignored` option allowing regex, function, glob, or array
+ courtesy of [anymatch](https://github.com/es128/anymatch)
+* New `cwd` option to set base dir from which relative paths are derived
+* New `depth` option for limiting recursion
+* New `alwaysStat` option to ensure
+ [`fs.Stats`](https://nodejs.org/api/fs.html#fs_class_fs_stats) gets passed
+ with every add/change event
+* New `ready` event emitted when initial fs tree scan is done and watcher is
+ ready for changes
+* New `raw` event exposing data and events from the lower-level watch modules
+* New `followSymlinks` option to impact whether symlinks' targets or the symlink
+ files themselves are watched
+* New `atomic` option for normalizing artifacts from text editors that use
+ atomic write methods
+* Ensured watcher's stability with lots of bugfixes.
+
+# Chokidar 0.12.6 (Jan 6, 2015)
+* Fix bug which breaks `persistent: false` mode when change events occur
+
+# Chokidar 0.12.5 (Dec 17, 2014)
+* Fix bug with matching parent path detection for fsevents instance sharing
+* Fix bug with ignored watch path in nodefs modes
+
+# Chokidar 0.12.4 (Dec 14, 2014)
+* Fix bug in `fs.watch` mode that caused watcher to leak into `cwd`
+* Fix bug preventing ready event when there are symlinks to ignored paths
+
+# Chokidar 0.12.3 (Dec 13, 2014)
+* Fix handling of special files such as named pipes and sockets
+
+# Chokidar 0.12.2 (Dec 12, 2014)
+* Fix recursive symlink handling and some other path resolution problems
+
+# Chokidar 0.12.1 (Dec 10, 2014)
+* Fix a case where file symlinks were not followed properly
+
+# Chokidar 0.12.0 (Dec 8, 2014)
+* Symlink support
+ * Add `followSymlinks` option, which defaults to `true`
+* Change default watch mode on Linux to non-polling `fs.watch`
+* Add `atomic` option to normalize events from editors using atomic writes
+ * Particularly Vim and Sublime
+* Add `raw` event which exposes data from the underlying watch method
+
+# Chokidar 0.11.1 (Nov 19, 2014)
+* Fix a bug where an error is thrown when `fs.watch` instantiation fails
+
+# Chokidar 0.11.0 (Nov 16, 2014)
+* Add a `ready` event, which is emitted after initial file scan completes
+* Fix issue with options keys passed in defined as `undefined`
+* Rename some internal `FSWatcher` properties to indicate they're private
+
+# Chokidar 0.10.9 (Nov 15, 2014)
+* Fix some leftover issues from adding watcher reuse
+
+# Chokidar 0.10.8 (Nov 14, 2014)
+* Remove accidentally committed/published `console.log` statement.
+* Sry 'bout that :crying_cat_face:
+
+# Chokidar 0.10.7 (Nov 14, 2014)
+* Apply watcher reuse methodology to `fs.watch` and `fs.watchFile` as well
+
+# Chokidar 0.10.6 (Nov 12, 2014)
+* More efficient creation/reuse of FSEvents instances to avoid system limits
+* Reduce simultaneous FSEvents instances allowed in a process
+* Handle errors thrown by `fs.watch` upon invocation
+
+# Chokidar 0.10.5 (Nov 6, 2014)
+* Limit number of simultaneous FSEvents instances (fall back to other methods)
+* Prevent some cases of EMFILE errors during initialization
+* Fix ignored files emitting events in some fsevents-mode circumstances
+
+# Chokidar 0.10.4 (Nov 5, 2014)
+* Bump fsevents dependency to ~0.3.1
+ * Should resolve build warnings and `npm rebuild` on non-Macs
+
+# Chokidar 0.10.3 (Oct 28, 2014)
+* Fix removed dir emitting as `unlink` instead of `unlinkDir`
+* Fix issues with file changing to dir or vice versa (gh-165)
+* Fix handling of `ignored` option in fsevents mode
+
+# Chokidar 0.10.2 (Oct 23, 2014)
+* Improve individual file watching
+* Fix fsevents keeping process alive when `persistent: false`
+
+# Chokidar 0.10.1 (19 October 2014)
+* Improve handling of text editor atomic writes
+
+# Chokidar 0.10.0 (Oct 18, 2014)
+* Many stability and consistency improvements
+* Resolve many cases of duplicate or wrong events
+* Correct for fsevents inconsistencies
+* Standardize handling of errors and relative paths
+* Fix issues with watching `./`
+
+# Chokidar 0.9.0 (Sep 25, 2014)
+* Updated fsevents to 0.3
+* Update per-system defaults
+* Fix issues with closing chokidar instance
+* Fix duplicate change events on win32
+
+# Chokidar 0.8.2 (Mar 26, 2014)
+* Fixed npm issues related to fsevents dep.
+* Updated fsevents to 0.2.
+
+# Chokidar 0.8.1 (Dec 16, 2013)
+* Optional deps are now truly optional on windows and
+ linux.
+* Rewritten in JS, again.
+* Fixed some FSEvents-related bugs.
+
+# Chokidar 0.8.0 (Nov 29, 2013)
+* Added ultra-fast low-CPU OS X file watching with FSEvents.
+ It is enabled by default.
+* Added `addDir` and `unlinkDir` events.
+* Polling is now disabled by default on all platforms.
+
+# Chokidar 0.7.1 (Nov 18, 2013)
+* `Watcher#close` now also removes all event listeners.
+
+# Chokidar 0.7.0 (Oct 22, 2013)
+* When `options.ignored` is two-argument function, it will
+ also be called after stating the FS, with `stats` argument.
+* `unlink` is no longer emitted on directories.
+
+# Chokidar 0.6.3 (Aug 12, 2013)
+* Added `usePolling` option (default: `true`).
+ When `false`, chokidar will use `fs.watch` as backend.
+ `fs.watch` is much faster, but not like super reliable.
+
+# Chokidar 0.6.2 (Mar 19, 2013)
+* Fixed watching initially empty directories with `ignoreInitial` option.
+
+# Chokidar 0.6.1 (Mar 19, 2013)
+* Added node.js 0.10 support.
+
+# Chokidar 0.6.0 (Mar 10, 2013)
+* File attributes (stat()) are now passed to `add` and `change` events as second
+ arguments.
+* Changed default polling interval for binary files to 300ms.
+
+# Chokidar 0.5.3 (Jan 13, 2013)
+* Removed emitting of `change` events before `unlink`.
+
+# Chokidar 0.5.2 (Jan 13, 2013)
+* Removed postinstall script to prevent various npm bugs.
+
+# Chokidar 0.5.1 (Jan 6, 2013)
+* When starting to watch non-existing paths, chokidar will no longer throw
+ ENOENT error.
+* Fixed bug with absolute path.
+
+# Chokidar 0.5.0 (Dec 9, 2012)
+* Added a bunch of new options:
+ * `ignoreInitial` that allows to ignore initial `add` events.
+ * `ignorePermissionErrors` that allows to ignore ENOENT etc perm errors.
+ * `interval` and `binaryInterval` that allow to change default
+ fs polling intervals.
+
+# Chokidar 0.4.0 (Jul 26, 2012)
+* Added `all` event that receives two args (event name and path) that combines
+ `add`, `change` and `unlink` events.
+* Switched to `fs.watchFile` on node.js 0.8 on windows.
+* Files are now correctly unwatched after unlink.
+
+# Chokidar 0.3.0 (Jun 24, 2012)
+* `unlink` event are no longer emitted for directories, for consistency with
+ `add`.
+
+# Chokidar 0.2.6 (Jun 8, 2012)
+* Prevented creating of duplicate 'add' events.
+
+# Chokidar 0.2.5 (Jun 8, 2012)
+* Fixed a bug when new files in new directories hadn't been added.
+
+# Chokidar 0.2.4 (Jun 7, 2012)
+* Fixed a bug when unlinked files emitted events after unlink.
+
+# Chokidar 0.2.3 (May 12, 2012)
+* Fixed watching of files on windows.
+
+# Chokidar 0.2.2 (May 4, 2012)
+* Fixed watcher signature.
+
+# Chokidar 0.2.1 (May 4, 2012)
+* Fixed invalid API bug when using `watch()`.
+
+# Chokidar 0.2.0 (May 4, 2012)
+* Rewritten in js.
+
+# Chokidar 0.1.1 (Apr 26, 2012)
+* Changed api to `chokidar.watch()`.
+* Fixed compilation on windows.
+
+# Chokidar 0.1.0 (Apr 20, 2012)
+* Initial release, extracted from
+ [Brunch](https://github.com/brunch/brunch/blob/9847a065aea300da99bd0753f90354cde9de1261/src/helpers.coffee#L66)
diff --git a/node_modules/chokidar/README.md b/node_modules/chokidar/README.md
new file mode 100644
index 0000000..9758774
--- /dev/null
+++ b/node_modules/chokidar/README.md
@@ -0,0 +1,293 @@
+# Chokidar [![Mac/Linux Build Status](https://img.shields.io/travis/paulmillr/chokidar/master.svg?label=Mac%20OSX%20%26%20Linux)](https://travis-ci.org/paulmillr/chokidar) [![Windows Build status](https://img.shields.io/appveyor/ci/paulmillr/chokidar/master.svg?label=Windows)](https://ci.appveyor.com/project/paulmillr/chokidar/branch/master) [![Coverage Status](https://coveralls.io/repos/paulmillr/chokidar/badge.svg)](https://coveralls.io/r/paulmillr/chokidar) [![Join the chat at https://gitter.im/paulmillr/chokidar](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/paulmillr/chokidar?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+
+> A neat wrapper around node.js fs.watch / fs.watchFile / fsevents.
+
+[![NPM](https://nodei.co/npm-dl/chokidar.png)](https://nodei.co/npm/chokidar/)
+[![NPM](https://nodei.co/npm/chokidar.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/chokidar/)
+
+## Why?
+Node.js `fs.watch`:
+
+* Doesn't report filenames on OS X.
+* Doesn't report events at all when using editors like Sublime on OS X.
+* Often reports events twice.
+* Emits most changes as `rename`.
+* Has [a lot of other issues](https://github.com/nodejs/node/search?q=fs.watch&type=Issues)
+* Does not provide an easy way to recursively watch file trees.
+
+Node.js `fs.watchFile`:
+
+* Almost as bad at event handling.
+* Also does not provide any recursive watching.
+* Results in high CPU utilization.
+
+Chokidar resolves these problems.
+
+Initially made for [brunch](http://brunch.io) (an ultra-swift web app build tool), it is now used in
+[gulp](https://github.com/gulpjs/gulp/),
+[karma](http://karma-runner.github.io),
+[PM2](https://github.com/Unitech/PM2),
+[browserify](http://browserify.org/),
+[webpack](http://webpack.github.io/),
+[BrowserSync](http://www.browsersync.io/),
+[Microsoft's Visual Studio Code](https://github.com/microsoft/vscode),
+and [many others](https://www.npmjs.org/browse/depended/chokidar/).
+It has proven itself in production environments.
+
+## How?
+Chokidar does still rely on the Node.js core `fs` module, but when using
+`fs.watch` and `fs.watchFile` for watching, it normalizes the events it
+receives, often checking for truth by getting file stats and/or dir contents.
+
+On Mac OS X, chokidar by default uses a native extension exposing the Darwin
+`FSEvents` API. This provides very efficient recursive watching compared with
+implementations like `kqueue` available on most \*nix platforms. Chokidar still
+does have to do some work to normalize the events received that way as well.
+
+On other platforms, the `fs.watch`-based implementation is the default, which
+avoids polling and keeps CPU usage down. Be advised that chokidar will initiate
+watchers recursively for everything within scope of the paths that have been
+specified, so be judicious about not wasting system resources by watching much
+more than needed.
+
+## Getting started
+Install with npm:
+
+ npm install chokidar --save
+
+Then `require` and use it in your code:
+
+```javascript
+var chokidar = require('chokidar');
+
+// One-liner for current directory, ignores .dotfiles
+chokidar.watch('.', {ignored: /(^|[\/\\])\../}).on('all', (event, path) => {
+ console.log(event, path);
+});
+```
+
+```javascript
+// Example of a more typical implementation structure:
+
+// Initialize watcher.
+var watcher = chokidar.watch('file, dir, glob, or array', {
+ ignored: /(^|[\/\\])\../,
+ persistent: true
+});
+
+// Something to use when events are received.
+var log = console.log.bind(console);
+// Add event listeners.
+watcher
+ .on('add', path => log(`File ${path} has been added`))
+ .on('change', path => log(`File ${path} has been changed`))
+ .on('unlink', path => log(`File ${path} has been removed`));
+
+// More possible events.
+watcher
+ .on('addDir', path => log(`Directory ${path} has been added`))
+ .on('unlinkDir', path => log(`Directory ${path} has been removed`))
+ .on('error', error => log(`Watcher error: ${error}`))
+ .on('ready', () => log('Initial scan complete. Ready for changes'))
+ .on('raw', (event, path, details) => {
+ log('Raw event info:', event, path, details);
+ });
+
+// 'add', 'addDir' and 'change' events also receive stat() results as second
+// argument when available: http://nodejs.org/api/fs.html#fs_class_fs_stats
+watcher.on('change', (path, stats) => {
+ if (stats) console.log(`File ${path} changed size to ${stats.size}`);
+});
+
+// Watch new files.
+watcher.add('new-file');
+watcher.add(['new-file-2', 'new-file-3', '**/other-file*']);
+
+// Get list of actual paths being watched on the filesystem
+var watchedPaths = watcher.getWatched();
+
+// Un-watch some files.
+watcher.unwatch('new-file*');
+
+// Stop watching.
+watcher.close();
+
+// Full list of options. See below for descriptions. (do not use this example)
+chokidar.watch('file', {
+ persistent: true,
+
+ ignored: '*.txt',
+ ignoreInitial: false,
+ followSymlinks: true,
+ cwd: '.',
+ disableGlobbing: false,
+
+ usePolling: true,
+ interval: 100,
+ binaryInterval: 300,
+ alwaysStat: false,
+ depth: 99,
+ awaitWriteFinish: {
+ stabilityThreshold: 2000,
+ pollInterval: 100
+ },
+
+ ignorePermissionErrors: false,
+ atomic: true // or a custom 'atomicity delay', in milliseconds (default 100)
+});
+
+```
+
+## API
+
+`chokidar.watch(paths, [options])`
+
+* `paths` (string or array of strings). Paths to files, dirs to be watched
+recursively, or glob patterns.
+* `options` (object) Options object as defined below:
+
+#### Persistence
+
+* `persistent` (default: `true`). Indicates whether the process
+should continue to run as long as files are being watched. If set to
+`false` when using `fsevents` to watch, no more events will be emitted
+after `ready`, even if the process continues to run.
+
+#### Path filtering
+
+* `ignored` ([anymatch](https://github.com/es128/anymatch)-compatible definition)
+Defines files/paths to be ignored. The whole relative or absolute path is
+tested, not just filename. If a function with two arguments is provided, it
+gets called twice per path - once with a single argument (the path), second
+time with two arguments (the path and the
+[`fs.Stats`](http://nodejs.org/api/fs.html#fs_class_fs_stats)
+object of that path).
+* `ignoreInitial` (default: `false`). If set to `false` then `add`/`addDir` events are also emitted for matching paths while
+instantiating the watching as chokidar discovers these file paths (before the `ready` event).
+* `followSymlinks` (default: `true`). When `false`, only the
+symlinks themselves will be watched for changes instead of following
+the link references and bubbling events through the link's path.
+* `cwd` (no default). The base directory from which watch `paths` are to be
+derived. Paths emitted with events will be relative to this.
+* `disableGlobbing` (default: `false`). If set to `true` then the strings passed to `.watch()` and `.add()` are treated as
+literal path names, even if they look like globs.
+
+#### Performance
+
+* `usePolling` (default: `false`).
+Whether to use fs.watchFile (backed by polling), or fs.watch. If polling
+leads to high CPU utilization, consider setting this to `false`. It is
+typically necessary to **set this to `true` to successfully watch files over
+a network**, and it may be necessary to successfully watch files in other
+non-standard situations. Setting to `true` explicitly on OS X overrides the
+`useFsEvents` default. You may also set the CHOKIDAR_USEPOLLING env variable
+to true (1) or false (0) in order to override this option.
+* _Polling-specific settings_ (effective when `usePolling: true`)
+ * `interval` (default: `100`). Interval of file system polling. You may also
+ set the CHOKIDAR_INTERVAL env variable to override this option.
+ * `binaryInterval` (default: `300`). Interval of file system
+ polling for binary files.
+ ([see list of binary extensions](https://github.com/sindresorhus/binary-extensions/blob/master/binary-extensions.json))
+* `useFsEvents` (default: `true` on OS X). Whether to use the
+`fsevents` watching interface if available. When set to `true` explicitly
+and `fsevents` is available this supercedes the `usePolling` setting. When
+set to `false` on OS X, `usePolling: true` becomes the default.
+* `alwaysStat` (default: `false`). If relying upon the
+[`fs.Stats`](http://nodejs.org/api/fs.html#fs_class_fs_stats)
+object that may get passed with `add`, `addDir`, and `change` events, set
+this to `true` to ensure it is provided even in cases where it wasn't
+already available from the underlying watch events.
+* `depth` (default: `undefined`). If set, limits how many levels of
+subdirectories will be traversed.
+* `awaitWriteFinish` (default: `false`).
+By default, the `add` event will fire when a file first appears on disk, before
+the entire file has been written. Furthermore, in some cases some `change`
+events will be emitted while the file is being written. In some cases,
+especially when watching for large files there will be a need to wait for the
+write operation to finish before responding to a file creation or modification.
+Setting `awaitWriteFinish` to `true` (or a truthy value) will poll file size,
+holding its `add` and `change` events until the size does not change for a
+configurable amount of time. The appropriate duration setting is heavily
+dependent on the OS and hardware. For accurate detection this parameter should
+be relatively high, making file watching much less responsive.
+Use with caution.
+ * *`options.awaitWriteFinish` can be set to an object in order to adjust
+ timing params:*
+ * `awaitWriteFinish.stabilityThreshold` (default: 2000). Amount of time in
+ milliseconds for a file size to remain constant before emitting its event.
+ * `awaitWriteFinish.pollInterval` (default: 100). File size polling interval.
+
+#### Errors
+* `ignorePermissionErrors` (default: `false`). Indicates whether to watch files
+that don't have read permissions if possible. If watching fails due to `EPERM`
+or `EACCES` with this set to `true`, the errors will be suppressed silently.
+* `atomic` (default: `true` if `useFsEvents` and `usePolling` are `false`).
+Automatically filters out artifacts that occur when using editors that use
+"atomic writes" instead of writing directly to the source file. If a file is
+re-added within 100 ms of being deleted, Chokidar emits a `change` event
+rather than `unlink` then `add`. If the default of 100 ms does not work well
+for you, you can override it by setting `atomic` to a custom value, in
+milliseconds.
+
+### Methods & Events
+
+`chokidar.watch()` produces an instance of `FSWatcher`. Methods of `FSWatcher`:
+
+* `.add(path / paths)`: Add files, directories, or glob patterns for tracking.
+Takes an array of strings or just one string.
+* `.on(event, callback)`: Listen for an FS event.
+Available events: `add`, `addDir`, `change`, `unlink`, `unlinkDir`, `ready`,
+`raw`, `error`.
+Additionally `all` is available which gets emitted with the underlying event
+name and path for every event other than `ready`, `raw`, and `error`.
+* `.unwatch(path / paths)`: Stop watching files, directories, or glob patterns.
+Takes an array of strings or just one string.
+* `.close()`: Removes all listeners from watched files.
+* `.getWatched()`: Returns an object representing all the paths on the file
+system being watched by this `FSWatcher` instance. The object's keys are all the
+directories (using absolute paths unless the `cwd` option was used), and the
+values are arrays of the names of the items contained in each directory.
+
+## CLI
+
+If you need a CLI interface for your file watching, check out
+[chokidar-cli](https://github.com/kimmobrunfeldt/chokidar-cli), allowing you to
+execute a command on each change, or get a stdio stream of change events.
+
+## Install Troubleshooting
+
+* `npm WARN optional dep failed, continuing fsevents@n.n.n`
+ * This message is normal part of how `npm` handles optional dependencies and is
+ not indicative of a problem. Even if accompanied by other related error messages,
+ Chokidar should function properly.
+
+* `ERR! stack Error: Python executable "python" is v3.4.1, which is not supported by gyp.`
+ * You should be able to resolve this by installing python 2.7 and running:
+ `npm config set python python2.7`
+
+* `gyp ERR! stack Error: not found: make`
+ * On Mac, install the XCode command-line tools
+
+## License
+
+The MIT License (MIT)
+
+Copyright (c) 2016 Paul Miller (http://paulmillr.com) & Elan Shanker
+
+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/chokidar/index.js b/node_modules/chokidar/index.js
new file mode 100644
index 0000000..121703a
--- /dev/null
+++ b/node_modules/chokidar/index.js
@@ -0,0 +1,743 @@
+'use strict';
+var EventEmitter = require('events').EventEmitter;
+var fs = require('fs');
+var sysPath = require('path');
+var asyncEach = require('async-each');
+var anymatch = require('anymatch');
+var globParent = require('glob-parent');
+var isGlob = require('is-glob');
+var isAbsolute = require('path-is-absolute');
+var inherits = require('inherits');
+var braces = require('braces');
+var normalizePath = require('normalize-path');
+var upath = require('upath');
+
+var NodeFsHandler = require('./lib/nodefs-handler');
+var FsEventsHandler = require('./lib/fsevents-handler');
+
+var arrify = function(value) {
+ if (value == null) return [];
+ return Array.isArray(value) ? value : [value];
+};
+
+var flatten = function(list, result) {
+ if (result == null) result = [];
+ list.forEach(function(item) {
+ if (Array.isArray(item)) {
+ flatten(item, result);
+ } else {
+ result.push(item);
+ }
+ });
+ return result;
+};
+
+// Little isString util for use in Array#every.
+var isString = function(thing) {
+ return typeof thing === 'string';
+};
+
+// Public: Main class.
+// Watches files & directories for changes.
+//
+// * _opts - object, chokidar options hash
+//
+// Emitted events:
+// `add`, `addDir`, `change`, `unlink`, `unlinkDir`, `all`, `error`
+//
+// Examples
+//
+// var watcher = new FSWatcher()
+// .add(directories)
+// .on('add', path => console.log('File', path, 'was added'))
+// .on('change', path => console.log('File', path, 'was changed'))
+// .on('unlink', path => console.log('File', path, 'was removed'))
+// .on('all', (event, path) => console.log(path, ' emitted ', event))
+//
+function FSWatcher(_opts) {
+ EventEmitter.call(this);
+ var opts = {};
+ // in case _opts that is passed in is a frozen object
+ if (_opts) for (var opt in _opts) opts[opt] = _opts[opt];
+ this._watched = Object.create(null);
+ this._closers = Object.create(null);
+ this._ignoredPaths = Object.create(null);
+ Object.defineProperty(this, '_globIgnored', {
+ get: function() { return Object.keys(this._ignoredPaths); }
+ });
+ this.closed = false;
+ this._throttled = Object.create(null);
+ this._symlinkPaths = Object.create(null);
+
+ function undef(key) {
+ return opts[key] === undefined;
+ }
+
+ // Set up default options.
+ if (undef('persistent')) opts.persistent = true;
+ if (undef('ignoreInitial')) opts.ignoreInitial = false;
+ if (undef('ignorePermissionErrors')) opts.ignorePermissionErrors = false;
+ if (undef('interval')) opts.interval = 100;
+ if (undef('binaryInterval')) opts.binaryInterval = 300;
+ if (undef('disableGlobbing')) opts.disableGlobbing = false;
+ this.enableBinaryInterval = opts.binaryInterval !== opts.interval;
+
+ // Enable fsevents on OS X when polling isn't explicitly enabled.
+ if (undef('useFsEvents')) opts.useFsEvents = !opts.usePolling;
+
+ // If we can't use fsevents, ensure the options reflect it's disabled.
+ if (!FsEventsHandler.canUse()) opts.useFsEvents = false;
+
+ // Use polling on Mac if not using fsevents.
+ // Other platforms use non-polling fs.watch.
+ if (undef('usePolling') && !opts.useFsEvents) {
+ opts.usePolling = process.platform === 'darwin';
+ }
+
+ // Global override (useful for end-developers that need to force polling for all
+ // instances of chokidar, regardless of usage/dependency depth)
+ var envPoll = process.env.CHOKIDAR_USEPOLLING;
+ if (envPoll !== undefined) {
+ var envLower = envPoll.toLowerCase();
+
+ if (envLower === 'false' || envLower === '0') {
+ opts.usePolling = false;
+ } else if (envLower === 'true' || envLower === '1') {
+ opts.usePolling = true;
+ } else {
+ opts.usePolling = !!envLower
+ }
+ }
+ var envInterval = process.env.CHOKIDAR_INTERVAL;
+ if (envInterval) {
+ opts.interval = parseInt(envInterval);
+ }
+
+ // Editor atomic write normalization enabled by default with fs.watch
+ if (undef('atomic')) opts.atomic = !opts.usePolling && !opts.useFsEvents;
+ if (opts.atomic) this._pendingUnlinks = Object.create(null);
+
+ if (undef('followSymlinks')) opts.followSymlinks = true;
+
+ if (undef('awaitWriteFinish')) opts.awaitWriteFinish = false;
+ if (opts.awaitWriteFinish === true) opts.awaitWriteFinish = {};
+ var awf = opts.awaitWriteFinish;
+ if (awf) {
+ if (!awf.stabilityThreshold) awf.stabilityThreshold = 2000;
+ if (!awf.pollInterval) awf.pollInterval = 100;
+
+ this._pendingWrites = Object.create(null);
+ }
+ if (opts.ignored) opts.ignored = arrify(opts.ignored);
+
+ this._isntIgnored = function(path, stat) {
+ return !this._isIgnored(path, stat);
+ }.bind(this);
+
+ var readyCalls = 0;
+ this._emitReady = function() {
+ if (++readyCalls >= this._readyCount) {
+ this._emitReady = Function.prototype;
+ this._readyEmitted = true;
+ // use process.nextTick to allow time for listener to be bound
+ process.nextTick(this.emit.bind(this, 'ready'));
+ }
+ }.bind(this);
+
+ this.options = opts;
+
+ // You’re frozen when your heart’s not open.
+ Object.freeze(opts);
+}
+
+inherits(FSWatcher, EventEmitter);
+
+// Common helpers
+// --------------
+
+// Private method: Normalize and emit events
+//
+// * event - string, type of event
+// * path - string, file or directory path
+// * val[1..3] - arguments to be passed with event
+//
+// Returns the error if defined, otherwise the value of the
+// FSWatcher instance's `closed` flag
+FSWatcher.prototype._emit = function(event, path, val1, val2, val3) {
+ if (this.options.cwd) path = sysPath.relative(this.options.cwd, path);
+ var args = [event, path];
+ if (val3 !== undefined) args.push(val1, val2, val3);
+ else if (val2 !== undefined) args.push(val1, val2);
+ else if (val1 !== undefined) args.push(val1);
+
+ var awf = this.options.awaitWriteFinish;
+ if (awf && this._pendingWrites[path]) {
+ this._pendingWrites[path].lastChange = new Date();
+ return this;
+ }
+
+ if (this.options.atomic) {
+ if (event === 'unlink') {
+ this._pendingUnlinks[path] = args;
+ setTimeout(function() {
+ Object.keys(this._pendingUnlinks).forEach(function(path) {
+ this.emit.apply(this, this._pendingUnlinks[path]);
+ this.emit.apply(this, ['all'].concat(this._pendingUnlinks[path]));
+ delete this._pendingUnlinks[path];
+ }.bind(this));
+ }.bind(this), typeof this.options.atomic === "number"
+ ? this.options.atomic
+ : 100);
+ return this;
+ } else if (event === 'add' && this._pendingUnlinks[path]) {
+ event = args[0] = 'change';
+ delete this._pendingUnlinks[path];
+ }
+ }
+
+ var emitEvent = function() {
+ this.emit.apply(this, args);
+ if (event !== 'error') this.emit.apply(this, ['all'].concat(args));
+ }.bind(this);
+
+ if (awf && (event === 'add' || event === 'change') && this._readyEmitted) {
+ var awfEmit = function(err, stats) {
+ if (err) {
+ event = args[0] = 'error';
+ args[1] = err;
+ emitEvent();
+ } else if (stats) {
+ // if stats doesn't exist the file must have been deleted
+ if (args.length > 2) {
+ args[2] = stats;
+ } else {
+ args.push(stats);
+ }
+ emitEvent();
+ }
+ };
+
+ this._awaitWriteFinish(path, awf.stabilityThreshold, event, awfEmit);
+ return this;
+ }
+
+ if (event === 'change') {
+ if (!this._throttle('change', path, 50)) return this;
+ }
+
+ if (
+ this.options.alwaysStat && val1 === undefined &&
+ (event === 'add' || event === 'addDir' || event === 'change')
+ ) {
+ var fullPath = this.options.cwd ? sysPath.join(this.options.cwd, path) : path;
+ fs.stat(fullPath, function(error, stats) {
+ // Suppress event when fs.stat fails, to avoid sending undefined 'stat'
+ if (error || !stats) return;
+
+ args.push(stats);
+ emitEvent();
+ });
+ } else {
+ emitEvent();
+ }
+
+ return this;
+};
+
+// Private method: Common handler for errors
+//
+// * error - object, Error instance
+//
+// Returns the error if defined, otherwise the value of the
+// FSWatcher instance's `closed` flag
+FSWatcher.prototype._handleError = function(error) {
+ var code = error && error.code;
+ var ipe = this.options.ignorePermissionErrors;
+ if (error &&
+ code !== 'ENOENT' &&
+ code !== 'ENOTDIR' &&
+ (!ipe || (code !== 'EPERM' && code !== 'EACCES'))
+ ) this.emit('error', error);
+ return error || this.closed;
+};
+
+// Private method: Helper utility for throttling
+//
+// * action - string, type of action being throttled
+// * path - string, path being acted upon
+// * timeout - int, duration of time to suppress duplicate actions
+//
+// Returns throttle tracking object or false if action should be suppressed
+FSWatcher.prototype._throttle = function(action, path, timeout) {
+ if (!(action in this._throttled)) {
+ this._throttled[action] = Object.create(null);
+ }
+ var throttled = this._throttled[action];
+ if (path in throttled) {
+ throttled[path].count++;
+ return false;
+ }
+ function clear() {
+ var count = throttled[path] ? throttled[path].count : 0;
+ delete throttled[path];
+ clearTimeout(timeoutObject);
+ return count;
+ }
+ var timeoutObject = setTimeout(clear, timeout);
+ throttled[path] = {timeoutObject: timeoutObject, clear: clear, count: 0};
+ return throttled[path];
+};
+
+// Private method: Awaits write operation to finish
+//
+// * path - string, path being acted upon
+// * threshold - int, time in milliseconds a file size must be fixed before
+// acknowledgeing write operation is finished
+// * awfEmit - function, to be called when ready for event to be emitted
+// Polls a newly created file for size variations. When files size does not
+// change for 'threshold' milliseconds calls callback.
+FSWatcher.prototype._awaitWriteFinish = function(path, threshold, event, awfEmit) {
+ var timeoutHandler;
+
+ var fullPath = path;
+ if (this.options.cwd && !isAbsolute(path)) {
+ fullPath = sysPath.join(this.options.cwd, path);
+ }
+
+ var now = new Date();
+
+ var awaitWriteFinish = (function (prevStat) {
+ fs.stat(fullPath, function(err, curStat) {
+ if (err || !(path in this._pendingWrites)) {
+ if (err && err.code !== 'ENOENT') awfEmit(err);
+ return;
+ }
+
+ var now = new Date();
+
+ if (prevStat && curStat.size != prevStat.size) {
+ this._pendingWrites[path].lastChange = now;
+ }
+
+ if (now - this._pendingWrites[path].lastChange >= threshold) {
+ delete this._pendingWrites[path];
+ awfEmit(null, curStat);
+ } else {
+ timeoutHandler = setTimeout(
+ awaitWriteFinish.bind(this, curStat),
+ this.options.awaitWriteFinish.pollInterval
+ );
+ }
+ }.bind(this));
+ }.bind(this));
+
+ if (!(path in this._pendingWrites)) {
+ this._pendingWrites[path] = {
+ lastChange: now,
+ cancelWait: function() {
+ delete this._pendingWrites[path];
+ clearTimeout(timeoutHandler);
+ return event;
+ }.bind(this)
+ };
+ timeoutHandler = setTimeout(
+ awaitWriteFinish.bind(this),
+ this.options.awaitWriteFinish.pollInterval
+ );
+ }
+};
+
+// Private method: Determines whether user has asked to ignore this path
+//
+// * path - string, path to file or directory
+// * stats - object, result of fs.stat
+//
+// Returns boolean
+var dotRe = /\..*\.(sw[px])$|\~$|\.subl.*\.tmp/;
+FSWatcher.prototype._isIgnored = function(path, stats) {
+ if (this.options.atomic && dotRe.test(path)) return true;
+
+ if (!this._userIgnored) {
+ var cwd = this.options.cwd;
+ var ignored = this.options.ignored;
+ if (cwd && ignored) {
+ ignored = ignored.map(function (path) {
+ if (typeof path !== 'string') return path;
+ return upath.normalize(isAbsolute(path) ? path : sysPath.join(cwd, path));
+ });
+ }
+ var paths = arrify(ignored)
+ .filter(function(path) {
+ return typeof path === 'string' && !isGlob(path);
+ }).map(function(path) {
+ return path + '/**';
+ });
+ this._userIgnored = anymatch(
+ this._globIgnored.concat(ignored).concat(paths)
+ );
+ }
+
+ return this._userIgnored([path, stats]);
+};
+
+// Private method: Provides a set of common helpers and properties relating to
+// symlink and glob handling
+//
+// * path - string, file, directory, or glob pattern being watched
+// * depth - int, at any depth > 0, this isn't a glob
+//
+// Returns object containing helpers for this path
+var replacerRe = /^\.[\/\\]/;
+FSWatcher.prototype._getWatchHelpers = function(path, depth) {
+ path = path.replace(replacerRe, '');
+ var watchPath = depth || this.options.disableGlobbing || !isGlob(path) ? path : globParent(path);
+ var fullWatchPath = sysPath.resolve(watchPath);
+ var hasGlob = watchPath !== path;
+ var globFilter = hasGlob ? anymatch(path) : false;
+ var follow = this.options.followSymlinks;
+ var globSymlink = hasGlob && follow ? null : false;
+
+ var checkGlobSymlink = function(entry) {
+ // only need to resolve once
+ // first entry should always have entry.parentDir === ''
+ if (globSymlink == null) {
+ globSymlink = entry.fullParentDir === fullWatchPath ? false : {
+ realPath: entry.fullParentDir,
+ linkPath: fullWatchPath
+ };
+ }
+
+ if (globSymlink) {
+ return entry.fullPath.replace(globSymlink.realPath, globSymlink.linkPath);
+ }
+
+ return entry.fullPath;
+ };
+
+ var entryPath = function(entry) {
+ return sysPath.join(watchPath,
+ sysPath.relative(watchPath, checkGlobSymlink(entry))
+ );
+ };
+
+ var filterPath = function(entry) {
+ if (entry.stat && entry.stat.isSymbolicLink()) return filterDir(entry);
+ var resolvedPath = entryPath(entry);
+ return (!hasGlob || globFilter(resolvedPath)) &&
+ this._isntIgnored(resolvedPath, entry.stat) &&
+ (this.options.ignorePermissionErrors ||
+ this._hasReadPermissions(entry.stat));
+ }.bind(this);
+
+ var getDirParts = function(path) {
+ if (!hasGlob) return false;
+ var parts = [];
+ var expandedPath = braces.expand(path);
+ expandedPath.forEach(function(path) {
+ parts.push(sysPath.relative(watchPath, path).split(/[\/\\]/));
+ });
+ return parts;
+ };
+
+ var dirParts = getDirParts(path);
+ if (dirParts) {
+ dirParts.forEach(function(parts) {
+ if (parts.length > 1) parts.pop();
+ });
+ }
+ var unmatchedGlob;
+
+ var filterDir = function(entry) {
+ if (hasGlob) {
+ var entryParts = getDirParts(checkGlobSymlink(entry));
+ var globstar = false;
+ unmatchedGlob = !dirParts.some(function(parts) {
+ return parts.every(function(part, i) {
+ if (part === '**') globstar = true;
+ return globstar || !entryParts[0][i] || anymatch(part, entryParts[0][i]);
+ });
+ });
+ }
+ return !unmatchedGlob && this._isntIgnored(entryPath(entry), entry.stat);
+ }.bind(this);
+
+ return {
+ followSymlinks: follow,
+ statMethod: follow ? 'stat' : 'lstat',
+ path: path,
+ watchPath: watchPath,
+ entryPath: entryPath,
+ hasGlob: hasGlob,
+ globFilter: globFilter,
+ filterPath: filterPath,
+ filterDir: filterDir
+ };
+};
+
+// Directory helpers
+// -----------------
+
+// Private method: Provides directory tracking objects
+//
+// * directory - string, path of the directory
+//
+// Returns the directory's tracking object
+FSWatcher.prototype._getWatchedDir = function(directory) {
+ var dir = sysPath.resolve(directory);
+ var watcherRemove = this._remove.bind(this);
+ if (!(dir in this._watched)) this._watched[dir] = {
+ _items: Object.create(null),
+ add: function(item) {
+ if (item !== '.' && item !== '..') this._items[item] = true;
+ },
+ remove: function(item) {
+ delete this._items[item];
+ if (!this.children().length) {
+ fs.readdir(dir, function(err) {
+ if (err) watcherRemove(sysPath.dirname(dir), sysPath.basename(dir));
+ });
+ }
+ },
+ has: function(item) {return item in this._items;},
+ children: function() {return Object.keys(this._items);}
+ };
+ return this._watched[dir];
+};
+
+// File helpers
+// ------------
+
+// Private method: Check for read permissions
+// Based on this answer on SO: http://stackoverflow.com/a/11781404/1358405
+//
+// * stats - object, result of fs.stat
+//
+// Returns boolean
+FSWatcher.prototype._hasReadPermissions = function(stats) {
+ return Boolean(4 & parseInt(((stats && stats.mode) & 0x1ff).toString(8)[0], 10));
+};
+
+// Private method: Handles emitting unlink events for
+// files and directories, and via recursion, for
+// files and directories within directories that are unlinked
+//
+// * directory - string, directory within which the following item is located
+// * item - string, base path of item/directory
+//
+// Returns nothing
+FSWatcher.prototype._remove = function(directory, item) {
+ // if what is being deleted is a directory, get that directory's paths
+ // for recursive deleting and cleaning of watched object
+ // if it is not a directory, nestedDirectoryChildren will be empty array
+ var path = sysPath.join(directory, item);
+ var fullPath = sysPath.resolve(path);
+ var isDirectory = this._watched[path] || this._watched[fullPath];
+
+ // prevent duplicate handling in case of arriving here nearly simultaneously
+ // via multiple paths (such as _handleFile and _handleDir)
+ if (!this._throttle('remove', path, 100)) return;
+
+ // if the only watched file is removed, watch for its return
+ var watchedDirs = Object.keys(this._watched);
+ if (!isDirectory && !this.options.useFsEvents && watchedDirs.length === 1) {
+ this.add(directory, item, true);
+ }
+
+ // This will create a new entry in the watched object in either case
+ // so we got to do the directory check beforehand
+ var nestedDirectoryChildren = this._getWatchedDir(path).children();
+
+ // Recursively remove children directories / files.
+ nestedDirectoryChildren.forEach(function(nestedItem) {
+ this._remove(path, nestedItem);
+ }, this);
+
+ // Check if item was on the watched list and remove it
+ var parent = this._getWatchedDir(directory);
+ var wasTracked = parent.has(item);
+ parent.remove(item);
+
+ // If we wait for this file to be fully written, cancel the wait.
+ var relPath = path;
+ if (this.options.cwd) relPath = sysPath.relative(this.options.cwd, path);
+ if (this.options.awaitWriteFinish && this._pendingWrites[relPath]) {
+ var event = this._pendingWrites[relPath].cancelWait();
+ if (event === 'add') return;
+ }
+
+ // The Entry will either be a directory that just got removed
+ // or a bogus entry to a file, in either case we have to remove it
+ delete this._watched[path];
+ delete this._watched[fullPath];
+ var eventName = isDirectory ? 'unlinkDir' : 'unlink';
+ if (wasTracked && !this._isIgnored(path)) this._emit(eventName, path);
+
+ // Avoid conflicts if we later create another file with the same name
+ if (!this.options.useFsEvents) {
+ this._closePath(path);
+ }
+};
+
+FSWatcher.prototype._closePath = function(path) {
+ if (!this._closers[path]) return;
+ this._closers[path]();
+ delete this._closers[path];
+ this._getWatchedDir(sysPath.dirname(path)).remove(sysPath.basename(path));
+}
+
+// Public method: Adds paths to be watched on an existing FSWatcher instance
+
+// * paths - string or array of strings, file/directory paths and/or globs
+// * _origAdd - private boolean, for handling non-existent paths to be watched
+// * _internal - private boolean, indicates a non-user add
+
+// Returns an instance of FSWatcher for chaining.
+FSWatcher.prototype.add = function(paths, _origAdd, _internal) {
+ var disableGlobbing = this.options.disableGlobbing;
+ var cwd = this.options.cwd;
+ this.closed = false;
+ paths = flatten(arrify(paths));
+
+ if (!paths.every(isString)) {
+ throw new TypeError('Non-string provided as watch path: ' + paths);
+ }
+
+ if (cwd) paths = paths.map(function(path) {
+ var absPath;
+ if (isAbsolute(path)) {
+ absPath = path;
+ } else if (path[0] === '!') {
+ absPath = '!' + sysPath.join(cwd, path.substring(1));
+ } else {
+ absPath = sysPath.join(cwd, path);
+ }
+
+ // Check `path` instead of `absPath` because the cwd portion can't be a glob
+ if (disableGlobbing || !isGlob(path)) {
+ return absPath;
+ } else {
+ return normalizePath(absPath);
+ }
+ });
+
+ // set aside negated glob strings
+ paths = paths.filter(function(path) {
+ if (path[0] === '!') {
+ this._ignoredPaths[path.substring(1)] = true;
+ } else {
+ // if a path is being added that was previously ignored, stop ignoring it
+ delete this._ignoredPaths[path];
+ delete this._ignoredPaths[path + '/**'];
+
+ // reset the cached userIgnored anymatch fn
+ // to make ignoredPaths changes effective
+ this._userIgnored = null;
+
+ return true;
+ }
+ }, this);
+
+ if (this.options.useFsEvents && FsEventsHandler.canUse()) {
+ if (!this._readyCount) this._readyCount = paths.length;
+ if (this.options.persistent) this._readyCount *= 2;
+ paths.forEach(this._addToFsEvents, this);
+ } else {
+ if (!this._readyCount) this._readyCount = 0;
+ this._readyCount += paths.length;
+ asyncEach(paths, function(path, next) {
+ this._addToNodeFs(path, !_internal, 0, 0, _origAdd, function(err, res) {
+ if (res) this._emitReady();
+ next(err, res);
+ }.bind(this));
+ }.bind(this), function(error, results) {
+ results.forEach(function(item) {
+ if (!item || this.closed) return;
+ this.add(sysPath.dirname(item), sysPath.basename(_origAdd || item));
+ }, this);
+ }.bind(this));
+ }
+
+ return this;
+};
+
+// Public method: Close watchers or start ignoring events from specified paths.
+
+// * paths - string or array of strings, file/directory paths and/or globs
+
+// Returns instance of FSWatcher for chaining.
+FSWatcher.prototype.unwatch = function(paths) {
+ if (this.closed) return this;
+ paths = flatten(arrify(paths));
+
+ paths.forEach(function(path) {
+ // convert to absolute path unless relative path already matches
+ if (!isAbsolute(path) && !this._closers[path]) {
+ if (this.options.cwd) path = sysPath.join(this.options.cwd, path);
+ path = sysPath.resolve(path);
+ }
+
+ this._closePath(path);
+
+ this._ignoredPaths[path] = true;
+ if (path in this._watched) {
+ this._ignoredPaths[path + '/**'] = true;
+ }
+
+ // reset the cached userIgnored anymatch fn
+ // to make ignoredPaths changes effective
+ this._userIgnored = null;
+ }, this);
+
+ return this;
+};
+
+// Public method: Close watchers and remove all listeners from watched paths.
+
+// Returns instance of FSWatcher for chaining.
+FSWatcher.prototype.close = function() {
+ if (this.closed) return this;
+
+ this.closed = true;
+ Object.keys(this._closers).forEach(function(watchPath) {
+ this._closers[watchPath]();
+ delete this._closers[watchPath];
+ }, this);
+ this._watched = Object.create(null);
+
+ this.removeAllListeners();
+ return this;
+};
+
+// Public method: Expose list of watched paths
+
+// Returns object w/ dir paths as keys and arrays of contained paths as values.
+FSWatcher.prototype.getWatched = function() {
+ var watchList = {};
+ Object.keys(this._watched).forEach(function(dir) {
+ var key = this.options.cwd ? sysPath.relative(this.options.cwd, dir) : dir;
+ watchList[key || '.'] = Object.keys(this._watched[dir]._items).sort();
+ }.bind(this));
+ return watchList;
+};
+
+// Attach watch handler prototype methods
+function importHandler(handler) {
+ Object.keys(handler.prototype).forEach(function(method) {
+ FSWatcher.prototype[method] = handler.prototype[method];
+ });
+}
+importHandler(NodeFsHandler);
+if (FsEventsHandler.canUse()) importHandler(FsEventsHandler);
+
+// Export FSWatcher class
+exports.FSWatcher = FSWatcher;
+
+// Public function: Instantiates watcher with paths to be tracked.
+
+// * paths - string or array of strings, file/directory paths and/or globs
+// * options - object, chokidar options
+
+// Returns an instance of FSWatcher for chaining.
+exports.watch = function(paths, options) {
+ return new FSWatcher(options).add(paths);
+};
diff --git a/node_modules/chokidar/lib/fsevents-handler.js b/node_modules/chokidar/lib/fsevents-handler.js
new file mode 100644
index 0000000..a748a1b
--- /dev/null
+++ b/node_modules/chokidar/lib/fsevents-handler.js
@@ -0,0 +1,405 @@
+'use strict';
+
+var fs = require('fs');
+var sysPath = require('path');
+var readdirp = require('readdirp');
+var fsevents;
+try { fsevents = require('fsevents'); } catch (error) {
+ if (process.env.CHOKIDAR_PRINT_FSEVENTS_REQUIRE_ERROR) console.error(error)
+}
+
+// fsevents instance helper functions
+
+// object to hold per-process fsevents instances
+// (may be shared across chokidar FSWatcher instances)
+var FSEventsWatchers = Object.create(null);
+
+// Threshold of duplicate path prefixes at which to start
+// consolidating going forward
+var consolidateThreshhold = 10;
+
+// Private function: Instantiates the fsevents interface
+
+// * path - string, path to be watched
+// * callback - function, called when fsevents is bound and ready
+
+// Returns new fsevents instance
+function createFSEventsInstance(path, callback) {
+ return (new fsevents(path)).on('fsevent', callback).start();
+}
+
+// Private function: Instantiates the fsevents interface or binds listeners
+// to an existing one covering the same file tree
+
+// * path - string, path to be watched
+// * realPath - string, real path (in case of symlinks)
+// * listener - function, called when fsevents emits events
+// * rawEmitter - function, passes data to listeners of the 'raw' event
+
+// Returns close function
+function setFSEventsListener(path, realPath, listener, rawEmitter) {
+ var watchPath = sysPath.extname(path) ? sysPath.dirname(path) : path;
+ var watchContainer;
+ var parentPath = sysPath.dirname(watchPath);
+
+ // If we've accumulated a substantial number of paths that
+ // could have been consolidated by watching one directory
+ // above the current one, create a watcher on the parent
+ // path instead, so that we do consolidate going forward.
+ if (couldConsolidate(parentPath)) {
+ watchPath = parentPath;
+ }
+
+ var resolvedPath = sysPath.resolve(path);
+ var hasSymlink = resolvedPath !== realPath;
+ function filteredListener(fullPath, flags, info) {
+ if (hasSymlink) fullPath = fullPath.replace(realPath, resolvedPath);
+ if (
+ fullPath === resolvedPath ||
+ !fullPath.indexOf(resolvedPath + sysPath.sep)
+ ) listener(fullPath, flags, info);
+ }
+
+ // check if there is already a watcher on a parent path
+ // modifies `watchPath` to the parent path when it finds a match
+ function watchedParent() {
+ return Object.keys(FSEventsWatchers).some(function(watchedPath) {
+ // condition is met when indexOf returns 0
+ if (!realPath.indexOf(sysPath.resolve(watchedPath) + sysPath.sep)) {
+ watchPath = watchedPath;
+ return true;
+ }
+ });
+ }
+
+ if (watchPath in FSEventsWatchers || watchedParent()) {
+ watchContainer = FSEventsWatchers[watchPath];
+ watchContainer.listeners.push(filteredListener);
+ } else {
+ watchContainer = FSEventsWatchers[watchPath] = {
+ listeners: [filteredListener],
+ rawEmitters: [rawEmitter],
+ watcher: createFSEventsInstance(watchPath, function(fullPath, flags) {
+ var info = fsevents.getInfo(fullPath, flags);
+ watchContainer.listeners.forEach(function(listener) {
+ listener(fullPath, flags, info);
+ });
+ watchContainer.rawEmitters.forEach(function(emitter) {
+ emitter(info.event, fullPath, info);
+ });
+ })
+ };
+ }
+ var listenerIndex = watchContainer.listeners.length - 1;
+
+ // removes this instance's listeners and closes the underlying fsevents
+ // instance if there are no more listeners left
+ return function close() {
+ delete watchContainer.listeners[listenerIndex];
+ delete watchContainer.rawEmitters[listenerIndex];
+ if (!Object.keys(watchContainer.listeners).length) {
+ watchContainer.watcher.stop();
+ delete FSEventsWatchers[watchPath];
+ }
+ };
+}
+
+// Decide whether or not we should start a new higher-level
+// parent watcher
+function couldConsolidate(path) {
+ var keys = Object.keys(FSEventsWatchers);
+ var count = 0;
+
+ for (var i = 0, len = keys.length; i < len; ++i) {
+ var watchPath = keys[i];
+ if (watchPath.indexOf(path) === 0) {
+ count++;
+ if (count >= consolidateThreshhold) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+// returns boolean indicating whether fsevents can be used
+function canUse() {
+ return fsevents && Object.keys(FSEventsWatchers).length < 128;
+}
+
+// determines subdirectory traversal levels from root to path
+function depth(path, root) {
+ var i = 0;
+ while (!path.indexOf(root) && (path = sysPath.dirname(path)) !== root) i++;
+ return i;
+}
+
+// fake constructor for attaching fsevents-specific prototype methods that
+// will be copied to FSWatcher's prototype
+function FsEventsHandler() {}
+
+// Private method: Handle symlinks encountered during directory scan
+
+// * watchPath - string, file/dir path to be watched with fsevents
+// * realPath - string, real path (in case of symlinks)
+// * transform - function, path transformer
+// * globFilter - function, path filter in case a glob pattern was provided
+
+// Returns close function for the watcher instance
+FsEventsHandler.prototype._watchWithFsEvents =
+function(watchPath, realPath, transform, globFilter) {
+ if (this._isIgnored(watchPath)) return;
+ var watchCallback = function(fullPath, flags, info) {
+ if (
+ this.options.depth !== undefined &&
+ depth(fullPath, realPath) > this.options.depth
+ ) return;
+ var path = transform(sysPath.join(
+ watchPath, sysPath.relative(watchPath, fullPath)
+ ));
+ if (globFilter && !globFilter(path)) return;
+ // ensure directories are tracked
+ var parent = sysPath.dirname(path);
+ var item = sysPath.basename(path);
+ var watchedDir = this._getWatchedDir(
+ info.type === 'directory' ? path : parent
+ );
+ var checkIgnored = function(stats) {
+ if (this._isIgnored(path, stats)) {
+ this._ignoredPaths[path] = true;
+ if (stats && stats.isDirectory()) {
+ this._ignoredPaths[path + '/**/*'] = true;
+ }
+ return true;
+ } else {
+ delete this._ignoredPaths[path];
+ delete this._ignoredPaths[path + '/**/*'];
+ }
+ }.bind(this);
+
+ var handleEvent = function(event) {
+ if (checkIgnored()) return;
+
+ if (event === 'unlink') {
+ // suppress unlink events on never before seen files
+ if (info.type === 'directory' || watchedDir.has(item)) {
+ this._remove(parent, item);
+ }
+ } else {
+ if (event === 'add') {
+ // track new directories
+ if (info.type === 'directory') this._getWatchedDir(path);
+
+ if (info.type === 'symlink' && this.options.followSymlinks) {
+ // push symlinks back to the top of the stack to get handled
+ var curDepth = this.options.depth === undefined ?
+ undefined : depth(fullPath, realPath) + 1;
+ return this._addToFsEvents(path, false, true, curDepth);
+ } else {
+ // track new paths
+ // (other than symlinks being followed, which will be tracked soon)
+ this._getWatchedDir(parent).add(item);
+ }
+ }
+ var eventName = info.type === 'directory' ? event + 'Dir' : event;
+ this._emit(eventName, path);
+ if (eventName === 'addDir') this._addToFsEvents(path, false, true);
+ }
+ }.bind(this);
+
+ function addOrChange() {
+ handleEvent(watchedDir.has(item) ? 'change' : 'add');
+ }
+ function checkFd() {
+ fs.open(path, 'r', function(error, fd) {
+ if (error) {
+ error.code !== 'EACCES' ?
+ handleEvent('unlink') : addOrChange();
+ } else {
+ fs.close(fd, function(err) {
+ err && err.code !== 'EACCES' ?
+ handleEvent('unlink') : addOrChange();
+ });
+ }
+ });
+ }
+ // correct for wrong events emitted
+ var wrongEventFlags = [
+ 69888, 70400, 71424, 72704, 73472, 131328, 131840, 262912
+ ];
+ if (wrongEventFlags.indexOf(flags) !== -1 || info.event === 'unknown') {
+ if (typeof this.options.ignored === 'function') {
+ fs.stat(path, function(error, stats) {
+ if (checkIgnored(stats)) return;
+ stats ? addOrChange() : handleEvent('unlink');
+ });
+ } else {
+ checkFd();
+ }
+ } else {
+ switch (info.event) {
+ case 'created':
+ case 'modified':
+ return addOrChange();
+ case 'deleted':
+ case 'moved':
+ return checkFd();
+ }
+ }
+ }.bind(this);
+
+ var closer = setFSEventsListener(
+ watchPath,
+ realPath,
+ watchCallback,
+ this.emit.bind(this, 'raw')
+ );
+
+ this._emitReady();
+ return closer;
+};
+
+// Private method: Handle symlinks encountered during directory scan
+
+// * linkPath - string, path to symlink
+// * fullPath - string, absolute path to the symlink
+// * transform - function, pre-existing path transformer
+// * curDepth - int, level of subdirectories traversed to where symlink is
+
+// Returns nothing
+FsEventsHandler.prototype._handleFsEventsSymlink =
+function(linkPath, fullPath, transform, curDepth) {
+ // don't follow the same symlink more than once
+ if (this._symlinkPaths[fullPath]) return;
+ else this._symlinkPaths[fullPath] = true;
+
+ this._readyCount++;
+
+ fs.realpath(linkPath, function(error, linkTarget) {
+ if (this._handleError(error) || this._isIgnored(linkTarget)) {
+ return this._emitReady();
+ }
+
+ this._readyCount++;
+
+ // add the linkTarget for watching with a wrapper for transform
+ // that causes emitted paths to incorporate the link's path
+ this._addToFsEvents(linkTarget || linkPath, function(path) {
+ var dotSlash = '.' + sysPath.sep;
+ var aliasedPath = linkPath;
+ if (linkTarget && linkTarget !== dotSlash) {
+ aliasedPath = path.replace(linkTarget, linkPath);
+ } else if (path !== dotSlash) {
+ aliasedPath = sysPath.join(linkPath, path);
+ }
+ return transform(aliasedPath);
+ }, false, curDepth);
+ }.bind(this));
+};
+
+// Private method: Handle added path with fsevents
+
+// * path - string, file/directory path or glob pattern
+// * transform - function, converts working path to what the user expects
+// * forceAdd - boolean, ensure add is emitted
+// * priorDepth - int, level of subdirectories already traversed
+
+// Returns nothing
+FsEventsHandler.prototype._addToFsEvents =
+function(path, transform, forceAdd, priorDepth) {
+
+ // applies transform if provided, otherwise returns same value
+ var processPath = typeof transform === 'function' ?
+ transform : function(val) { return val; };
+
+ var emitAdd = function(newPath, stats) {
+ var pp = processPath(newPath);
+ var isDir = stats.isDirectory();
+ var dirObj = this._getWatchedDir(sysPath.dirname(pp));
+ var base = sysPath.basename(pp);
+
+ // ensure empty dirs get tracked
+ if (isDir) this._getWatchedDir(pp);
+
+ if (dirObj.has(base)) return;
+ dirObj.add(base);
+
+ if (!this.options.ignoreInitial || forceAdd === true) {
+ this._emit(isDir ? 'addDir' : 'add', pp, stats);
+ }
+ }.bind(this);
+
+ var wh = this._getWatchHelpers(path);
+
+ // evaluate what is at the path we're being asked to watch
+ fs[wh.statMethod](wh.watchPath, function(error, stats) {
+ if (this._handleError(error) || this._isIgnored(wh.watchPath, stats)) {
+ this._emitReady();
+ return this._emitReady();
+ }
+
+ if (stats.isDirectory()) {
+ // emit addDir unless this is a glob parent
+ if (!wh.globFilter) emitAdd(processPath(path), stats);
+
+ // don't recurse further if it would exceed depth setting
+ if (priorDepth && priorDepth > this.options.depth) return;
+
+ // scan the contents of the dir
+ readdirp({
+ root: wh.watchPath,
+ entryType: 'all',
+ fileFilter: wh.filterPath,
+ directoryFilter: wh.filterDir,
+ lstat: true,
+ depth: this.options.depth - (priorDepth || 0)
+ }).on('data', function(entry) {
+ // need to check filterPath on dirs b/c filterDir is less restrictive
+ if (entry.stat.isDirectory() && !wh.filterPath(entry)) return;
+
+ var joinedPath = sysPath.join(wh.watchPath, entry.path);
+ var fullPath = entry.fullPath;
+
+ if (wh.followSymlinks && entry.stat.isSymbolicLink()) {
+ // preserve the current depth here since it can't be derived from
+ // real paths past the symlink
+ var curDepth = this.options.depth === undefined ?
+ undefined : depth(joinedPath, sysPath.resolve(wh.watchPath)) + 1;
+
+ this._handleFsEventsSymlink(joinedPath, fullPath, processPath, curDepth);
+ } else {
+ emitAdd(joinedPath, entry.stat);
+ }
+ }.bind(this)).on('error', function() {
+ // Ignore readdirp errors
+ }).on('end', this._emitReady);
+ } else {
+ emitAdd(wh.watchPath, stats);
+ this._emitReady();
+ }
+ }.bind(this));
+
+ if (this.options.persistent && forceAdd !== true) {
+ var initWatch = function(error, realPath) {
+ if (this.closed) return;
+ var closer = this._watchWithFsEvents(
+ wh.watchPath,
+ sysPath.resolve(realPath || wh.watchPath),
+ processPath,
+ wh.globFilter
+ );
+ if (closer) this._closers[path] = closer;
+ }.bind(this);
+
+ if (typeof transform === 'function') {
+ // realpath has already been resolved
+ initWatch();
+ } else {
+ fs.realpath(wh.watchPath, initWatch);
+ }
+ }
+};
+
+module.exports = FsEventsHandler;
+module.exports.canUse = canUse;
diff --git a/node_modules/chokidar/lib/nodefs-handler.js b/node_modules/chokidar/lib/nodefs-handler.js
new file mode 100644
index 0000000..c287732
--- /dev/null
+++ b/node_modules/chokidar/lib/nodefs-handler.js
@@ -0,0 +1,488 @@
+'use strict';
+
+var fs = require('fs');
+var sysPath = require('path');
+var readdirp = require('readdirp');
+var isBinaryPath = require('is-binary-path');
+
+// fs.watch helpers
+
+// object to hold per-process fs.watch instances
+// (may be shared across chokidar FSWatcher instances)
+var FsWatchInstances = Object.create(null);
+
+// Private function: Instantiates the fs.watch interface
+
+// * path - string, path to be watched
+// * options - object, options to be passed to fs.watch
+// * listener - function, main event handler
+// * errHandler - function, handler which emits info about errors
+// * emitRaw - function, handler which emits raw event data
+
+// Returns new fsevents instance
+function createFsWatchInstance(path, options, listener, errHandler, emitRaw) {
+ var handleEvent = function(rawEvent, evPath) {
+ listener(path);
+ emitRaw(rawEvent, evPath, {watchedPath: path});
+
+ // emit based on events occuring for files from a directory's watcher in
+ // case the file's watcher misses it (and rely on throttling to de-dupe)
+ if (evPath && path !== evPath) {
+ fsWatchBroadcast(
+ sysPath.resolve(path, evPath), 'listeners', sysPath.join(path, evPath)
+ );
+ }
+ };
+ try {
+ return fs.watch(path, options, handleEvent);
+ } catch (error) {
+ errHandler(error);
+ }
+}
+
+// Private function: Helper for passing fs.watch event data to a
+// collection of listeners
+
+// * fullPath - string, absolute path bound to the fs.watch instance
+// * type - string, listener type
+// * val[1..3] - arguments to be passed to listeners
+
+// Returns nothing
+function fsWatchBroadcast(fullPath, type, val1, val2, val3) {
+ if (!FsWatchInstances[fullPath]) return;
+ FsWatchInstances[fullPath][type].forEach(function(listener) {
+ listener(val1, val2, val3);
+ });
+}
+
+// Private function: Instantiates the fs.watch interface or binds listeners
+// to an existing one covering the same file system entry
+
+// * path - string, path to be watched
+// * fullPath - string, absolute path
+// * options - object, options to be passed to fs.watch
+// * handlers - object, container for event listener functions
+
+// Returns close function
+function setFsWatchListener(path, fullPath, options, handlers) {
+ var listener = handlers.listener;
+ var errHandler = handlers.errHandler;
+ var rawEmitter = handlers.rawEmitter;
+ var container = FsWatchInstances[fullPath];
+ var watcher;
+ if (!options.persistent) {
+ watcher = createFsWatchInstance(
+ path, options, listener, errHandler, rawEmitter
+ );
+ return watcher.close.bind(watcher);
+ }
+ if (!container) {
+ watcher = createFsWatchInstance(
+ path,
+ options,
+ fsWatchBroadcast.bind(null, fullPath, 'listeners'),
+ errHandler, // no need to use broadcast here
+ fsWatchBroadcast.bind(null, fullPath, 'rawEmitters')
+ );
+ if (!watcher) return;
+ var broadcastErr = fsWatchBroadcast.bind(null, fullPath, 'errHandlers');
+ watcher.on('error', function(error) {
+ container.watcherUnusable = true; // documented since Node 10.4.1
+ // Workaround for https://github.com/joyent/node/issues/4337
+ if (process.platform === 'win32' && error.code === 'EPERM') {
+ fs.open(path, 'r', function(err, fd) {
+ if (!err) fs.close(fd, function(err) {
+ if (!err) broadcastErr(error);
+ });
+ });
+ } else {
+ broadcastErr(error);
+ }
+ });
+ container = FsWatchInstances[fullPath] = {
+ listeners: [listener],
+ errHandlers: [errHandler],
+ rawEmitters: [rawEmitter],
+ watcher: watcher
+ };
+ } else {
+ container.listeners.push(listener);
+ container.errHandlers.push(errHandler);
+ container.rawEmitters.push(rawEmitter);
+ }
+ var listenerIndex = container.listeners.length - 1;
+
+ // removes this instance's listeners and closes the underlying fs.watch
+ // instance if there are no more listeners left
+ return function close() {
+ delete container.listeners[listenerIndex];
+ delete container.errHandlers[listenerIndex];
+ delete container.rawEmitters[listenerIndex];
+ if (!Object.keys(container.listeners).length) {
+ if (!container.watcherUnusable) { // check to protect against issue #730
+ container.watcher.close();
+ }
+ delete FsWatchInstances[fullPath];
+ }
+ };
+}
+
+// fs.watchFile helpers
+
+// object to hold per-process fs.watchFile instances
+// (may be shared across chokidar FSWatcher instances)
+var FsWatchFileInstances = Object.create(null);
+
+// Private function: Instantiates the fs.watchFile interface or binds listeners
+// to an existing one covering the same file system entry
+
+// * path - string, path to be watched
+// * fullPath - string, absolute path
+// * options - object, options to be passed to fs.watchFile
+// * handlers - object, container for event listener functions
+
+// Returns close function
+function setFsWatchFileListener(path, fullPath, options, handlers) {
+ var listener = handlers.listener;
+ var rawEmitter = handlers.rawEmitter;
+ var container = FsWatchFileInstances[fullPath];
+ var listeners = [];
+ var rawEmitters = [];
+ if (
+ container && (
+ container.options.persistent < options.persistent ||
+ container.options.interval > options.interval
+ )
+ ) {
+ // "Upgrade" the watcher to persistence or a quicker interval.
+ // This creates some unlikely edge case issues if the user mixes
+ // settings in a very weird way, but solving for those cases
+ // doesn't seem worthwhile for the added complexity.
+ listeners = container.listeners;
+ rawEmitters = container.rawEmitters;
+ fs.unwatchFile(fullPath);
+ container = false;
+ }
+ if (!container) {
+ listeners.push(listener);
+ rawEmitters.push(rawEmitter);
+ container = FsWatchFileInstances[fullPath] = {
+ listeners: listeners,
+ rawEmitters: rawEmitters,
+ options: options,
+ watcher: fs.watchFile(fullPath, options, function(curr, prev) {
+ container.rawEmitters.forEach(function(rawEmitter) {
+ rawEmitter('change', fullPath, {curr: curr, prev: prev});
+ });
+ var currmtime = curr.mtime.getTime();
+ if (curr.size !== prev.size || currmtime > prev.mtime.getTime() || currmtime === 0) {
+ container.listeners.forEach(function(listener) {
+ listener(path, curr);
+ });
+ }
+ })
+ };
+ } else {
+ container.listeners.push(listener);
+ container.rawEmitters.push(rawEmitter);
+ }
+ var listenerIndex = container.listeners.length - 1;
+
+ // removes this instance's listeners and closes the underlying fs.watchFile
+ // instance if there are no more listeners left
+ return function close() {
+ delete container.listeners[listenerIndex];
+ delete container.rawEmitters[listenerIndex];
+ if (!Object.keys(container.listeners).length) {
+ fs.unwatchFile(fullPath);
+ delete FsWatchFileInstances[fullPath];
+ }
+ };
+}
+
+// fake constructor for attaching nodefs-specific prototype methods that
+// will be copied to FSWatcher's prototype
+function NodeFsHandler() {}
+
+// Private method: Watch file for changes with fs.watchFile or fs.watch.
+
+// * path - string, path to file or directory.
+// * listener - function, to be executed on fs change.
+
+// Returns close function for the watcher instance
+NodeFsHandler.prototype._watchWithNodeFs =
+function(path, listener) {
+ var directory = sysPath.dirname(path);
+ var basename = sysPath.basename(path);
+ var parent = this._getWatchedDir(directory);
+ parent.add(basename);
+ var absolutePath = sysPath.resolve(path);
+ var options = {persistent: this.options.persistent};
+ if (!listener) listener = Function.prototype; // empty function
+
+ var closer;
+ if (this.options.usePolling) {
+ options.interval = this.enableBinaryInterval && isBinaryPath(basename) ?
+ this.options.binaryInterval : this.options.interval;
+ closer = setFsWatchFileListener(path, absolutePath, options, {
+ listener: listener,
+ rawEmitter: this.emit.bind(this, 'raw')
+ });
+ } else {
+ closer = setFsWatchListener(path, absolutePath, options, {
+ listener: listener,
+ errHandler: this._handleError.bind(this),
+ rawEmitter: this.emit.bind(this, 'raw')
+ });
+ }
+ return closer;
+};
+
+// Private method: Watch a file and emit add event if warranted
+
+// * file - string, the file's path
+// * stats - object, result of fs.stat
+// * initialAdd - boolean, was the file added at watch instantiation?
+// * callback - function, called when done processing as a newly seen file
+
+// Returns close function for the watcher instance
+NodeFsHandler.prototype._handleFile =
+function(file, stats, initialAdd, callback) {
+ var dirname = sysPath.dirname(file);
+ var basename = sysPath.basename(file);
+ var parent = this._getWatchedDir(dirname);
+
+ // if the file is already being watched, do nothing
+ if (parent.has(basename)) return callback();
+
+ // kick off the watcher
+ var closer = this._watchWithNodeFs(file, function(path, newStats) {
+ if (!this._throttle('watch', file, 5)) return;
+ if (!newStats || newStats && newStats.mtime.getTime() === 0) {
+ fs.stat(file, function(error, newStats) {
+ // Fix issues where mtime is null but file is still present
+ if (error) {
+ this._remove(dirname, basename);
+ } else {
+ this._emit('change', file, newStats);
+ }
+ }.bind(this));
+ // add is about to be emitted if file not already tracked in parent
+ } else if (parent.has(basename)) {
+ this._emit('change', file, newStats);
+ }
+ }.bind(this));
+
+ // emit an add event if we're supposed to
+ if (!(initialAdd && this.options.ignoreInitial)) {
+ if (!this._throttle('add', file, 0)) return;
+ this._emit('add', file, stats);
+ }
+
+ if (callback) callback();
+ return closer;
+};
+
+// Private method: Handle symlinks encountered while reading a dir
+
+// * entry - object, entry object returned by readdirp
+// * directory - string, path of the directory being read
+// * path - string, path of this item
+// * item - string, basename of this item
+
+// Returns true if no more processing is needed for this entry.
+NodeFsHandler.prototype._handleSymlink =
+function(entry, directory, path, item) {
+ var full = entry.fullPath;
+ var dir = this._getWatchedDir(directory);
+
+ if (!this.options.followSymlinks) {
+ // watch symlink directly (don't follow) and detect changes
+ this._readyCount++;
+ fs.realpath(path, function(error, linkPath) {
+ if (dir.has(item)) {
+ if (this._symlinkPaths[full] !== linkPath) {
+ this._symlinkPaths[full] = linkPath;
+ this._emit('change', path, entry.stat);
+ }
+ } else {
+ dir.add(item);
+ this._symlinkPaths[full] = linkPath;
+ this._emit('add', path, entry.stat);
+ }
+ this._emitReady();
+ }.bind(this));
+ return true;
+ }
+
+ // don't follow the same symlink more than once
+ if (this._symlinkPaths[full]) return true;
+ else this._symlinkPaths[full] = true;
+};
+
+// Private method: Read directory to add / remove files from `@watched` list
+// and re-read it on change.
+
+// * dir - string, fs path.
+// * stats - object, result of fs.stat
+// * initialAdd - boolean, was the file added at watch instantiation?
+// * depth - int, depth relative to user-supplied path
+// * target - string, child path actually targeted for watch
+// * wh - object, common watch helpers for this path
+// * callback - function, called when dir scan is complete
+
+// Returns close function for the watcher instance
+NodeFsHandler.prototype._handleDir =
+function(dir, stats, initialAdd, depth, target, wh, callback) {
+ var parentDir = this._getWatchedDir(sysPath.dirname(dir));
+ var tracked = parentDir.has(sysPath.basename(dir));
+ if (!(initialAdd && this.options.ignoreInitial) && !target && !tracked) {
+ if (!wh.hasGlob || wh.globFilter(dir)) this._emit('addDir', dir, stats);
+ }
+
+ // ensure dir is tracked (harmless if redundant)
+ parentDir.add(sysPath.basename(dir));
+ this._getWatchedDir(dir);
+
+ var read = function(directory, initialAdd, done) {
+ // Normalize the directory name on Windows
+ directory = sysPath.join(directory, '');
+
+ if (!wh.hasGlob) {
+ var throttler = this._throttle('readdir', directory, 1000);
+ if (!throttler) return;
+ }
+
+ var previous = this._getWatchedDir(wh.path);
+ var current = [];
+
+ readdirp({
+ root: directory,
+ entryType: 'all',
+ fileFilter: wh.filterPath,
+ directoryFilter: wh.filterDir,
+ depth: 0,
+ lstat: true
+ }).on('data', function(entry) {
+ var item = entry.path;
+ var path = sysPath.join(directory, item);
+ current.push(item);
+
+ if (entry.stat.isSymbolicLink() &&
+ this._handleSymlink(entry, directory, path, item)) return;
+
+ // Files that present in current directory snapshot
+ // but absent in previous are added to watch list and
+ // emit `add` event.
+ if (item === target || !target && !previous.has(item)) {
+ this._readyCount++;
+
+ // ensure relativeness of path is preserved in case of watcher reuse
+ path = sysPath.join(dir, sysPath.relative(dir, path));
+
+ this._addToNodeFs(path, initialAdd, wh, depth + 1);
+ }
+ }.bind(this)).on('end', function() {
+ var wasThrottled = throttler ? throttler.clear() : false;
+ if (done) done();
+
+ // Files that absent in current directory snapshot
+ // but present in previous emit `remove` event
+ // and are removed from @watched[directory].
+ previous.children().filter(function(item) {
+ return item !== directory &&
+ current.indexOf(item) === -1 &&
+ // in case of intersecting globs;
+ // a path may have been filtered out of this readdir, but
+ // shouldn't be removed because it matches a different glob
+ (!wh.hasGlob || wh.filterPath({
+ fullPath: sysPath.resolve(directory, item)
+ }));
+ }).forEach(function(item) {
+ this._remove(directory, item);
+ }, this);
+
+ // one more time for any missed in case changes came in extremely quickly
+ if (wasThrottled) read(directory, false);
+ }.bind(this)).on('error', this._handleError.bind(this));
+ }.bind(this);
+
+ var closer;
+
+ if (this.options.depth == null || depth <= this.options.depth) {
+ if (!target) read(dir, initialAdd, callback);
+ closer = this._watchWithNodeFs(dir, function(dirPath, stats) {
+ // if current directory is removed, do nothing
+ if (stats && stats.mtime.getTime() === 0) return;
+
+ read(dirPath, false);
+ });
+ } else {
+ callback();
+ }
+ return closer;
+};
+
+// Private method: Handle added file, directory, or glob pattern.
+// Delegates call to _handleFile / _handleDir after checks.
+
+// * path - string, path to file or directory.
+// * initialAdd - boolean, was the file added at watch instantiation?
+// * depth - int, depth relative to user-supplied path
+// * target - string, child path actually targeted for watch
+// * callback - function, indicates whether the path was found or not
+
+// Returns nothing
+NodeFsHandler.prototype._addToNodeFs =
+function(path, initialAdd, priorWh, depth, target, callback) {
+ if (!callback) callback = Function.prototype;
+ var ready = this._emitReady;
+ if (this._isIgnored(path) || this.closed) {
+ ready();
+ return callback(null, false);
+ }
+
+ var wh = this._getWatchHelpers(path, depth);
+ if (!wh.hasGlob && priorWh) {
+ wh.hasGlob = priorWh.hasGlob;
+ wh.globFilter = priorWh.globFilter;
+ wh.filterPath = priorWh.filterPath;
+ wh.filterDir = priorWh.filterDir;
+ }
+
+ // evaluate what is at the path we're being asked to watch
+ fs[wh.statMethod](wh.watchPath, function(error, stats) {
+ if (this._handleError(error)) return callback(null, path);
+ if (this._isIgnored(wh.watchPath, stats)) {
+ ready();
+ return callback(null, false);
+ }
+
+ var initDir = function(dir, target) {
+ return this._handleDir(dir, stats, initialAdd, depth, target, wh, ready);
+ }.bind(this);
+
+ var closer;
+ if (stats.isDirectory()) {
+ closer = initDir(wh.watchPath, target);
+ } else if (stats.isSymbolicLink()) {
+ var parent = sysPath.dirname(wh.watchPath);
+ this._getWatchedDir(parent).add(wh.watchPath);
+ this._emit('add', wh.watchPath, stats);
+ closer = initDir(parent, path);
+
+ // preserve this symlink's target path
+ fs.realpath(path, function(error, targetPath) {
+ this._symlinkPaths[sysPath.resolve(path)] = targetPath;
+ ready();
+ }.bind(this));
+ } else {
+ closer = this._handleFile(wh.watchPath, stats, initialAdd, ready);
+ }
+
+ if (closer) this._closers[path] = closer;
+ callback(null, false);
+ }.bind(this));
+};
+
+module.exports = NodeFsHandler;
diff --git a/node_modules/chokidar/package.json b/node_modules/chokidar/package.json
new file mode 100644
index 0000000..1fdf259
--- /dev/null
+++ b/node_modules/chokidar/package.json
@@ -0,0 +1,92 @@
+{
+ "_args": [
+ [
+ "chokidar@2.0.4",
+ "/home/dstaesse/git/website"
+ ]
+ ],
+ "_development": true,
+ "_from": "chokidar@2.0.4",
+ "_id": "chokidar@2.0.4",
+ "_inBundle": false,
+ "_integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==",
+ "_location": "/chokidar",
+ "_phantomChildren": {},
+ "_requested": {
+ "type": "version",
+ "registry": true,
+ "raw": "chokidar@2.0.4",
+ "name": "chokidar",
+ "escapedName": "chokidar",
+ "rawSpec": "2.0.4",
+ "saveSpec": null,
+ "fetchSpec": "2.0.4"
+ },
+ "_requiredBy": [
+ "/postcss-cli"
+ ],
+ "_resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz",
+ "_spec": "2.0.4",
+ "_where": "/home/dstaesse/git/website",
+ "author": {
+ "name": "Paul Miller",
+ "url": "http://paulmillr.com"
+ },
+ "bugs": {
+ "url": "http://github.com/paulmillr/chokidar/issues"
+ },
+ "dependencies": {
+ "anymatch": "^2.0.0",
+ "async-each": "^1.0.0",
+ "braces": "^2.3.0",
+ "fsevents": "^1.2.2",
+ "glob-parent": "^3.1.0",
+ "inherits": "^2.0.1",
+ "is-binary-path": "^1.0.0",
+ "is-glob": "^4.0.0",
+ "lodash.debounce": "^4.0.8",
+ "normalize-path": "^2.1.1",
+ "path-is-absolute": "^1.0.0",
+ "readdirp": "^2.0.0",
+ "upath": "^1.0.5"
+ },
+ "description": "A neat wrapper around node.js fs.watch / fs.watchFile / fsevents.",
+ "devDependencies": {
+ "chai": "^3.2.0",
+ "coveralls": "^3.0.1",
+ "graceful-fs": "4.1.4",
+ "mocha": "^5.2.0",
+ "nyc": "^11.8.0",
+ "rimraf": "^2.4.3",
+ "sinon": "^1.10.3",
+ "sinon-chai": "^2.6.0"
+ },
+ "files": [
+ "index.js",
+ "lib/"
+ ],
+ "homepage": "https://github.com/paulmillr/chokidar",
+ "keywords": [
+ "fs",
+ "watch",
+ "watchFile",
+ "watcher",
+ "watching",
+ "file",
+ "fsevents"
+ ],
+ "license": "MIT",
+ "name": "chokidar",
+ "optionalDependencies": {
+ "fsevents": "^1.2.2"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/paulmillr/chokidar.git"
+ },
+ "scripts": {
+ "coveralls": "nyc report --reporter=text-lcov | coveralls",
+ "test": "nyc mocha --exit"
+ },
+ "version": "2.0.4"
+}