diff --git a/.eslintrc b/.eslintrc
index f2463e9b6..c445390a4 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -83,6 +83,10 @@
"space-infix-ops": 1,
"valid-typeof": 2,
"vars-on-top": 0,
- "wrap-iife": [2, "inside"]
+ "wrap-iife": [2, "inside"],
+ "prefer-const": ["error", {
+ "destructuring": "any",
+ "ignoreReadBeforeAssign": false
+ }]
}
}
diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index 3e44b6493..aee9a60ce 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -1,29 +1,61 @@
-# Contributing to Pattern Lab Node
+Contributing to Pattern Lab Node
+================================
+
If you'd like to contribute to Pattern Lab Node, please do so! There is always a lot of ground to cover and something for your wheelhouse.
No pull request is too small. Check out any [up for grabs issues](https://github.com/pattern-lab/patternlab-node/labels/up%20for%20grabs) as a good way to get your feet wet, or add some more unit tests.
-## Developing Locally
+Developing Locally
+------------------
The best way to make changes to the Pattern Lab Node core and test them is through your existing edition.
-* Fork this repository on Github.
-* Create a new branch in your fork and push your changes in that fork.
-* `npm install`
-* `npm link`
-* `cd /path/to/your/edition`
-* `npm link patternlab-node`
+- Fork this repository on Github.
+- Create a new branch in your fork and push your changes in that fork.
+- `npm install`
+- `npm link`
+- `cd /path/to/your/edition`
+- `npm link patternlab-node`
+
+Guidelines
+----------
+
+- *ALWAYS* submit pull requests against the [dev branch](https://github.com/pattern-lab/patternlab-node/tree/dev). If this does not occur, I will first, try to redirect you gently, second, attempt to redirect the target branch myself, thirdly, port over your contribution manually if time allows, and/or lastly, close your pull request. If you have a major feature to stabilize over time, talk to @bmuenzenmeyer via an issue about making a dedicated `feature-branch`
+- Keep your pull requests concise and limited to **ONE** substantive change at a time. This makes reviewing and testing so much easier.
+- Commits should reference the issue you are adressing. For any Pull Request that you send, use the template provided.
+- Commits are best formatted using the [conventional commits pattern](https://conventionalcommits.org/).
+- If you can, add some unit tests using the existing patterns in the `./test` directory
+- Large enhancements should begin with opening an issue. This will result in a more systematic way for us to review your contribution and determine if a [specifcation discussion](https://github.com/pattern-lab/the-spec/issues) needs to occur.
+- Mention the issue number in commits, so anyone can see to which issue your changes belong to. For instance:
+ - `#123 Fix resolving patterns in pattern_hunter`
+ - `Feature #42: improve improbability drive`
+
+Coding style
+------------
-## Guidelines
+Two files combine within the project to define and maintain our coding style.
-* _ALWAYS_ submit pull requests against the [dev branch](https://github.com/pattern-lab/patternlab-node/tree/dev). If this does not occur, I will first, try to redirect you gently, second, port over your contribution manually if time allows, and/or third, close your pull request. If you have a major feature to stabilize over time, talk to @bmuenzenmeyer via an issue about making a dedicated `feature-branch`
-* Please keep your pull requests concise and limited to **ONE** substantive change at a time. This makes reviewing and testing so much easier.
-* Commits should reference the issue you are adressing. For any Pull Request that you send, use the template provided.
-* If you can, add some unit tests using the existing patterns in the `./test` directory
-* Large enhancements should begin with opening an issue. This will result in a more systematic way for us to review your contribution and determine if a [specifcation discussion](https://github.com/pattern-lab/the-spec/issues) needs to occur.
+- The `.editorconfig` controls spaces / tabs within supported editors. Check out their [site](http://editorconfig.org/).
+- The `.eslintrc` defines our javascript standards. Some editors will evaluate this real-time - otherwise it's run using `grunt|gulp build`
-## Coding style
-Two files combine within the project to define and maintain our coding style.
+Tests
+-----
+
+Add unit and integration tests if you can. It's always nice if our code coverage improves bit by bit (literally!). We are using [Node Tap](http://www.node-tap.org/) as test framework and [Rewire](https://github.com/jhnns/rewire) for mocking things like file system access.
+
+Branching Scheme
+----------------
+
+ Currently Pattern Lab has the following branches:
+
+- **master** contains the latext stable, released version
+- **dev**: for development. *Target pull requests against this branch.*
+- **feature-branches** for larger changes. Allows merging all changes into both `dev` easily.
+- **long running branches** for changes that involve major changes to the code, architecture and take a lot of time (i.e. making Pattern Lab async)
+
+New features are typically cut off of `dev` branch. When `dev` is stable cut releases by merging `dev` to `master` and creating a release tag.
+
+Gitter.im Chat
+==============
-* The `.editorconfig` controls spaces / tabs within supported editors. Check out their [site](http://editorconfig.org/).
-* The `.eslintrc` defines our javascript standards. Some editors will evaluate this real-time - otherwise it's run using `grunt|gulp build`
+If you have any questions or you would like to help, feel free to ask on [our Gitter.im channel](https://gitter.im/pattern-lab/node) :smiley:
diff --git a/.github/branching-scheme.png b/.github/branching-scheme.png
new file mode 100644
index 000000000..9d7b7628a
Binary files /dev/null and b/.github/branching-scheme.png differ
diff --git a/.github/gitgraph/README.md b/.github/gitgraph/README.md
new file mode 100644
index 000000000..02cc14ca4
--- /dev/null
+++ b/.github/gitgraph/README.md
@@ -0,0 +1,8 @@
+Generating a new graph
+======================
+
+This folder uses http://gitgraphjs.com/ for generating the git graph model.
+
+1. Change `patternlab-flow.js` to your needs according to the documentation on http://gitgraphjs.com/
+2. Open branching-scheme.html in browse, right click the graph and "Save as...".
+3. Overwrite `/.github/branching-scheme.png`
diff --git a/.github/gitgraph/branching-scheme.html b/.github/gitgraph/branching-scheme.html
new file mode 100644
index 000000000..32d2ffb80
--- /dev/null
+++ b/.github/gitgraph/branching-scheme.html
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.github/gitgraph/patternlab-flow.js b/.github/gitgraph/patternlab-flow.js
new file mode 100644
index 000000000..79872b09a
--- /dev/null
+++ b/.github/gitgraph/patternlab-flow.js
@@ -0,0 +1,212 @@
+var graphConfig = new GitGraph.Template({
+ colors: [ "#9993FF", "#47E8D4", "#6BDB52", "#F85BB5", "#FFA657", "#FFCCAA", "#F85BB5" ],
+ branch: {
+ lineWidth: 3,
+ spacingX: 60,
+ mergeStyle: "straight",
+ showLabel: true, // display branch names on graph
+ labelFont: "normal 10pt Arial",
+ labelRotation: 0,
+ color: "black"
+ },
+ commit: {
+ spacingY: -30,
+ dot: {
+ size: 8,
+ strokeColor: "#000000",
+ strokeWidth: 4
+ },
+ tag: {
+ font: "normal 10pt Arial",
+ color: "yellow"
+ },
+ message: {
+ color: "black",
+ font: "normal 12pt Arial",
+ displayAuthor: false,
+ displayBranch: false,
+ displayHash: false,
+ }
+ },
+ arrow: {
+ size: 8,
+ offset: 3,
+
+ }
+});
+
+var config = {
+ template: graphConfig,
+ mode: "extended",
+ orientation: "horizontal"
+};
+
+var bugFixCommit = {
+ messageAuthorDisplay: false,
+ messageBranchDisplay: false,
+ messageHashDisplay: false,
+ message: "Bug fix commit(s)"
+};
+
+var stabilizationCommit = {
+ messageAuthorDisplay: false,
+ messageBranchDisplay: false,
+ messageHashDisplay: false,
+ message: "Release stabilization commit(s)"
+};
+
+// You can manually fix columns to control the display.
+var i = 0;
+var longRunningCol = i++;
+var featureV3Col = i++;
+var developV3Col = i++;
+var featureCol = i++;
+var developCol = i++;
+var releaseCol = i++;
+var masterCol = i++;
+
+var gitgraph = new GitGraph(config);
+
+var master = gitgraph.branch({
+ name: "master",
+ column: masterCol
+});
+master.commit("Initial commit");
+
+var develop = gitgraph.branch({
+ parentBranch: master,
+ name: "dev",
+ column: developCol
+});
+
+var developV3 = gitgraph.branch({
+ parentBranch: master,
+ name: "dev-3.0",
+ column: developV3Col
+});
+
+
+var longRunning = gitgraph.branch({
+ parentBranch: master,
+ name: "long-running-improvement",
+ column: longRunningCol
+});
+
+develop.commit({
+ messageDisplay: false
+});
+developV3.commit({
+ messageDisplay: false
+});
+
+longRunning.commit({
+ messageDisplay: false
+});
+longRunning.merge(developV3);
+
+var feature1 = gitgraph.branch({
+ parentBranch: develop,
+ name: "feature/1-description",
+ column: featureCol
+});
+feature1.commit("#1 A feature to go into v2.8.0").commit({
+ messageDisplay: false
+});
+develop.merge(feature1);
+feature1.commit("Small Bugfix").commit({
+ messageDisplay: false
+});
+feature1.merge(develop);
+
+
+var feature3X = gitgraph.branch({
+ parentBranch: developV3,
+ name: "feature/42-feature-for-3-x-only",
+ column: featureV3Col
+});
+feature3X.commit("#42 A feature to go into v3.X").commit({
+ messageDisplay: false
+});
+feature3X.merge(developV3);
+
+
+var feature2 = gitgraph.branch({
+ parentBranch: develop,
+ name: "feature/2-description",
+ column: featureCol
+});
+feature2.commit("#2 Another feature to go into v2.8.0").commit({
+ messageDisplay: false
+});
+feature2.merge(develop);
+feature2.merge(developV3);
+
+develop.merge(master,{
+ dotStrokeWidth: 10,
+ message: "Release v2.8.1 tagged",
+ tag: "v2.8.1"
+});
+
+
+develop.commit({
+ messageDisplay: false
+});
+
+
+longRunning.commit({
+ messageDisplay: false
+});
+
+developV3.merge(longRunning);
+
+longRunning.commit({
+ messageDisplay: false
+});
+
+var feature3 = gitgraph.branch({
+ parentBranch: develop,
+ name: "bugfix/3-description",
+ column: featureCol
+});
+
+feature3.commit("A feature to go into v2.8.0").commit({
+ messageDisplay: false
+});
+feature3.merge(develop);
+
+longRunning.merge(developV3);
+
+developV3.commit({
+ messageDisplay: false,
+ dotStrokeWidth: 10
+});
+
+
+develop.commit({
+ messageDisplay: false
+});
+
+develop.commit({
+ messageDisplay: false
+});
+
+develop.merge(master, {
+ dotStrokeWidth: 10,
+ message: "Release v2.9.0 tagged",
+ tag: "v2.9.0"
+});
+
+develop.commit({
+ messageDisplay: false,
+ dotStrokeWidth: 10
+});
+
+developV3.checkout();
+
+/*
+developV3.merge(master, {
+ dotStrokeWidth: 10,
+ message: "Release v3.0.0 tagged",
+ tag: "v3.0.0"
+});
+*/
diff --git a/.gitignore b/.gitignore
index d1ddc139e..4e141e644 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,3 +11,4 @@ public
!test/patterns/public/.gitkeep
!test/patterns/testDependencyGraph.json
.nyc_output/
+.vscode/
diff --git a/.nvmrc b/.nvmrc
new file mode 100644
index 000000000..7fcfe2dcd
--- /dev/null
+++ b/.nvmrc
@@ -0,0 +1 @@
+6.11.3
diff --git a/.travis.yml b/.travis.yml
index 6d447035b..70c7614d6 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,12 +3,12 @@ language: node_js
node_js:
- node
- 6
- - 4
before_install:
- phantomjs --version
before_script:
+ - npm install patternengine-node-mustache
- npm install patternengine-node-underscore
- npm install patternengine-node-handlebars
- npm install patternengine-node-twig
@@ -17,6 +17,7 @@ branches:
only:
- master
- dev
+ - dev-3.0
notifications:
webhooks:
diff --git a/README.md b/README.md
index 9eb9eed3b..7a215c591 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@

-[](https://travis-ci.org/pattern-lab/patternlab-node)   [](https://gitter.im/pattern-lab/node)
+[](https://travis-ci.org/pattern-lab/patternlab-node)   [](https://coveralls.io/github/pattern-lab/patternlab-node?branch=master) [](https://gitter.im/pattern-lab/node)
# Pattern Lab Node Core
@@ -21,28 +21,83 @@ Pattern Lab Node wouldn't be what it is today without the support of the communi
## Installation
-Pattern Lab Node Core is designed to be consumed, and by default is included as a dependency within two example [Node Editions](https://github.com/pattern-lab?utf8=%E2%9C%93&query=edition-node).
+Pattern Lab Node can be used different ways. Editions are **example** pairings of Pattern Lab code and do not always have an upgrade path or simple means to run as a dependency within a larger project. Users wishing to be most current and have the greatest flexibility are encouraged to consume `patternlab-node` directly. Users wanting to learn more about Pattern Lab and have a tailored default experience are encouraged to start with an Edition. Both methods still expect to interact with other elements of the [Pattern Lab Ecosystem](#ecosystem).
+### Direct Consumption
+
+As of Pattern Lab Node 3.X, `patternlab-node` can run standalone, without the need for task runners like gulp or grunt.
+
+`npm install patternlab-node`
+
+See [Usage](#Usage) for more information.
+
+### Editions
+
+For users wanting a more pre-packaged experience several editions are available.
* [Pattern Lab/Node: Gulp Edition](https://github.com/pattern-lab/edition-node-gulp) contains info how to get started within a Gulp task running environment.
* [Pattern Lab/Node: Grunt Edition](https://github.com/pattern-lab/edition-node-grunt) contains info how to get started within a Grunt task running environment.
+* [Pattern Lab/Node: Vanilla Edition](https://github.com/pattern-lab/edition-node) contains info how to get started within a pure node environment.
+* [Pattern Lab/Node: Webpack Edition](https://github.com/Comcast/patternlab-edition-node-webpack) contains info how to get started within a webpack environment.
+ >Thanks to the team at Comcast for open-sourcing this stellar work!
+
+## Ecosystem

-Core, and Editions, are part of the [Pattern Lab Ecosystem](http://patternlab.io/docs/advanced-ecosystem-overview.html). With this architecture, we encourage people to write and maintain their own editions.
+Core, and Editions, are part of the [Pattern Lab Ecosystem](http://patternlab.io/docs/advanced-ecosystem-overview.html). With this architecture, we encourage people to write and maintain their own Editions, Starterkits, and even PatternEngines.
## Usage
+`patternlab-node` can be required within any Node environment, taking in a configuration file at instantiation.
+
``` javascript
+
const config = require('./patternlab-config.json');
const patternlab = require('patternlab-node')(config);
-patternlab.build(doneCallBack, boolCleanOutputDir);
+
+
+// build, optionally watching or choosing incremental builds
+patternlab.build({
+ cleanPublic: true,
+ watch: true
+});
+
+// or build, watch, and then self-host
+patternlab.serve({
+ cleanPublic: true
+});
+
```
-* Read more about configuration via `patternlab-config.json`: https://github.com/pattern-lab/patternlab-node/wiki/Configuration
-* The rest of the [api / command line interface](https://github.com/pattern-lab/patternlab-node/wiki/Command-Line-Interface) is documented in the wiki, and already implemented for you within [Node Editions](https://github.com/pattern-lab?utf8=%E2%9C%93&query=edition-node).
-A [full-featured command line interface](https://github.com/pattern-lab/patternlab-node-cli) is in the works, courtesy of [@raphaelokon](https://github.com/raphaelokon).
+* Read more about [configuration](https://github.com/pattern-lab/patternlab-node/wiki/Configuration) via `patternlab-config.json`.
+* Read more about the rest of [api](https://github.com/pattern-lab/patternlab-node/wiki/Public-API), and already implemented for you within [Editions](#editions).
+
+* A full-featured [command line interface](https://github.com/pattern-lab/patternlab-node-cli) is also available courtesy of [@raphaelokon](https://github.com/raphaelokon).
+
+
+### Events
+
+Many [events](https://github.com/pattern-lab/patternlab-node/wiki/Creating-Plugins#events) are emitted during Pattern Lab operations, originally built to support plugins. Below is a sample, allowing users to be informed of asset or pattern changes.
+
+``` javascript
+
+patternlab.serve(...);
+
+patternlab.events.on('patternlab-asset-change', (data) => {
+ console.log(data); // {file: 'path/to/file.css', dest: 'path/to/destination'}
+});
+
+patternlab.events.on('patternlab-pattern-change', (data) => {
+ console.log(data); // {file: 'path/to/file.ext'}
+});
+
+patternlab.events.on('patternlab-global-change', (data) => {
+ console.log(data); // {file: 'path/to/file.ext'}
+});
+
+```
## Development Installation / Workflow
@@ -54,7 +109,7 @@ cd /patternlab-node
git clone https://github.com/pattern-lab/patternlab-node.git
npm install
npm link
-cd location/of/edition
+cd location/of/editionOrSourceAndConfig
npm link patternlab-node
```
@@ -63,7 +118,7 @@ The above is a bit verbose, but illustrates:
1. how to clone this repository to an arbitrary location
2. install all dependencies (run `npm install --dev` if your NODE_ENV is production for some reason)
3. setup the `npm link` to your local copy
-4. use the local copy of patternlab-node in your edition
+4. use the local copy of patternlab-node in your edition / working directory
> Make sure to change to whichever branch you intend to hack on or test within your cloned repository, such as `dev` or `bugfix/fixes-broken-unittest`
diff --git a/core/lib/annotation_exporter.js b/core/lib/annotation_exporter.js
index bd9cb72e8..4f4cb426a 100644
--- a/core/lib/annotation_exporter.js
+++ b/core/lib/annotation_exporter.js
@@ -1,14 +1,14 @@
-"use strict";
+'use strict';
+const path = require('path');
+const glob = require('glob');
+const fs = require('fs-extra');
+const _ = require('lodash');
+const mp = require('./markdown_parser');
-var path = require('path'),
- glob = require('glob'),
- fs = require('fs-extra'),
- _ = require('lodash'),
- mp = require('./markdown_parser');
+const annotations_exporter = function (pl) {
-var annotations_exporter = function (pl) {
-
- var paths = pl.config.paths;
+ const paths = pl.config.paths;
+ let oldAnnotations;
/*
Returns the array of comments that used to be wrapped in raw JS.
@@ -16,7 +16,7 @@ var annotations_exporter = function (pl) {
function parseAnnotationsJS() {
//attempt to read the file
try {
- var oldAnnotations = fs.readFileSync(path.resolve(paths.source.annotations, 'annotations.js'), 'utf8');
+ oldAnnotations = fs.readFileSync(path.resolve(paths.source.annotations, 'annotations.js'), 'utf8');
} catch (ex) {
if (pl.config.debug) {
console.log('annotations.js file missing from ' + paths.source.annotations + '. This may be expected.');
@@ -39,8 +39,8 @@ var annotations_exporter = function (pl) {
}
function buildAnnotationMD(annotationsYAML, markdown_parser) {
- var annotation = {};
- var markdownObj = markdown_parser.parse(annotationsYAML);
+ const annotation = {};
+ const markdownObj = markdown_parser.parse(annotationsYAML);
annotation.el = markdownObj.el || markdownObj.selector;
annotation.title = markdownObj.title;
@@ -49,16 +49,16 @@ var annotations_exporter = function (pl) {
}
function parseMDFile(annotations, parser) {
- var annotations = annotations;
- var markdown_parser = parser;
+ //let annotations = annotations;
+ const markdown_parser = parser;
return function (filePath) {
- var annotationsMD = fs.readFileSync(path.resolve(filePath), 'utf8');
+ const annotationsMD = fs.readFileSync(path.resolve(filePath), 'utf8');
//take the annotation snippets and split them on our custom delimiter
- var annotationsYAML = annotationsMD.split('~*~');
- for (var i = 0; i < annotationsYAML.length; i++) {
- var annotation = buildAnnotationMD(annotationsYAML[i], markdown_parser);
+ const annotationsYAML = annotationsMD.split('~*~');
+ for (let i = 0; i < annotationsYAML.length; i++) {
+ const annotation = buildAnnotationMD(annotationsYAML[i], markdown_parser);
annotations.push(annotation);
}
return false;
@@ -69,17 +69,17 @@ var annotations_exporter = function (pl) {
Converts the *.md file yaml list into an array of annotations
*/
function parseAnnotationsMD() {
- var markdown_parser = new mp();
- var annotations = [];
- var mdFiles = glob.sync(paths.source.annotations + '/*.md');
+ const markdown_parser = new mp();
+ const annotations = [];
+ const mdFiles = glob.sync(paths.source.annotations + '/*.md');
mdFiles.forEach(parseMDFile(annotations, markdown_parser));
return annotations;
}
function gatherAnnotations() {
- var annotationsJS = parseAnnotationsJS();
- var annotationsMD = parseAnnotationsMD();
+ const annotationsJS = parseAnnotationsJS();
+ const annotationsMD = parseAnnotationsMD();
return _.unionBy(annotationsJS, annotationsMD, 'el');
}
diff --git a/core/lib/asset_copy.js b/core/lib/asset_copy.js
new file mode 100644
index 000000000..9ac0d7a3c
--- /dev/null
+++ b/core/lib/asset_copy.js
@@ -0,0 +1,228 @@
+"use strict";
+const _ = require('lodash');
+const path = require('path');
+const process = require('process');
+
+let copy = require('recursive-copy'); // eslint-disable-line prefer-const
+let chokidar = require('chokidar'); // eslint-disable-line prefer-const
+
+const asset_copier = () => {
+
+ const transform_paths = (directories) => {
+ //create array with all source keys minus our blacklist
+ const dirs = {};
+ const blackList = ['root', 'patterns', 'data', 'meta', 'annotations', 'patternlabFiles'];
+ _.each(directories.source, (dir, key) => {
+
+ if (blackList.includes(key)) {
+ return;
+ }
+
+ if (!dirs.key) {
+ dirs[key] = {};
+ }
+ });
+
+ // loop through all source keys
+ _.each(dirs, (dir, key) => {
+ // add source key path
+ dirs[key].source = directories.source[key];
+
+ // add public key path
+ dirs[key].public = directories.public[key];
+ });
+ return dirs;
+ };
+
+ const copyFile = (p, dest, options) => {
+ copy(
+ p,
+ dest,
+ options
+ ).on(copy.events.COPY_FILE_COMPLETE, () => {
+ if (options.debug) {
+ console.log(`Moved ${p} to ${dest}`);
+ }
+ options.emitter.emit('patternlab-asset-change', {
+ file: p,
+ dest: dest
+ });
+ });
+ };
+
+ const asset_copy = (assetDirectories, patternlab, options) => {
+
+ //take our configured paths and sanitize best we can to only the assets
+ const dirs = transform_paths(assetDirectories);
+
+ //find out where we are
+ const basePath = path.resolve(process.cwd());
+
+ const copyOptions =
+ {
+ overwrite: true,
+ emitter: patternlab.events,
+ debug: patternlab.config.debug
+ };
+
+ //loop through each directory asset object (source / public pairing)
+ _.each(dirs, (dir, key) => {
+
+ //if we want to watch files, do so, otherwise just copy each file
+ if (options.watch) {
+ if (patternlab.config.debug) {
+ console.log(`Pattern Lab is watching ${path.resolve(basePath, dir.source)} for changes`);
+ }
+
+ if (patternlab.watchers[key]) {
+ patternlab.watchers[key].close();
+ }
+
+ const assetWatcher = chokidar.watch(
+ path.resolve(basePath, dir.source),
+ {
+ ignored: /(^|[\/\\])\../,
+ ignoreInitial: false,
+ awaitWriteFinish : {
+ stabilityThreshold: 200,
+ pollInterval: 100
+ }
+ }
+ );
+
+ //watch for changes and copy
+ assetWatcher.on('addDir', (p) => {
+ const destination = path.resolve(basePath, dir.public + '/' + path.basename(p));
+ copyFile(p, destination, copyOptions);
+ }).on('add', (p) => {
+ const destination = path.resolve(basePath, dir.public + '/' + path.basename(p));
+ copyFile(p, destination, copyOptions);
+ }).on('change', (p) => {
+ const destination = path.resolve(basePath, dir.public + '/' + path.basename(p));
+ copyFile(p, destination, copyOptions);
+ });
+
+ patternlab.watchers[key] = assetWatcher;
+
+ } else {
+ //just copy
+ const destination = path.resolve(basePath, dir.public);
+ copyFile(dir.source, destination, copyOptions);
+ }
+ });
+
+ // copy the styleguide
+ copyFile(assetDirectories.source.styleguide, assetDirectories.public.root, copyOptions);
+
+ // copy the favicon
+ copyFile(`${assetDirectories.source.root}/favicon.ico`, `${assetDirectories.public.root}/favicon.ico`, copyOptions);
+
+ //we need to special case patterns/**/*.md|.json|.pattern-extensions as well as the global structures
+ if (options.watch) {
+
+ // watch global structures, such as _data/* and _meta/
+ const globalSources = [assetDirectories.source.data, assetDirectories.source.meta];
+ const globalPaths = globalSources.map(globalSource => path.join(
+ basePath,
+ globalSource,
+ '*'
+ ));
+
+ _.each(globalPaths, (globalPath) => {
+
+ if (patternlab.config.debug) {
+ console.log(`Pattern Lab is watching ${globalPath} for changes`);
+ }
+
+ if (patternlab.watchers[globalPath]) {
+ patternlab.watchers[globalPath].close();
+ }
+
+ const globalWatcher = chokidar.watch(
+ path.resolve(globalPath),
+ {
+ ignored: /(^|[\/\\])\../,
+ ignoreInitial: true,
+ awaitWriteFinish : {
+ stabilityThreshold: 200,
+ pollInterval: 100
+ }
+ }
+ );
+
+ //watch for changes and rebuild
+ globalWatcher.on('addDir', (p) => {
+ patternlab.events.emit('patternlab-global-change', {
+ file: p
+ });
+ })
+ .on('add', (p) => {
+ patternlab.events.emit('patternlab-global-change', {
+ file: p
+ });
+ }).on('change', (p) => {
+ patternlab.events.emit('patternlab-global-change', {
+ file: p
+ });
+ });
+
+ patternlab.watchers[globalPath] = globalWatcher;
+
+ });
+
+ // watch patterns
+ const baseFileExtensions = ['.json', '.yml', '.yaml', '.md'];
+ const patternWatches = baseFileExtensions.concat(patternlab.engines.getSupportedFileExtensions()).map(
+ dotExtension => path.join(
+ basePath,
+ assetDirectories.source.patterns,
+ `/**/*${dotExtension}`
+ )
+ );
+ _.each(patternWatches, (patternWatchPath) => {
+ if (patternlab.config.debug) {
+ console.log(`Pattern Lab is watching ${patternWatchPath} for changes`);
+ }
+
+ const patternWatcher = chokidar.watch(
+ path.resolve(patternWatchPath),
+ {
+ ignored: /(^|[\/\\])\../,
+ ignoreInitial: true,
+ awaitWriteFinish : {
+ stabilityThreshold: 200,
+ pollInterval: 100
+ }
+ }
+ );
+
+ //watch for changes and rebuild
+ patternWatcher.on('addDir', (p) => {
+ patternlab.events.emit('patternlab-pattern-change', {
+ file: p
+ });
+ }).on('add', (p) => {
+ patternlab.events.emit('patternlab-pattern-change', {
+ file: p
+ });
+ }).on('change', (p) => {
+ patternlab.events.emit('patternlab-pattern-change', {
+ file: p
+ });
+ });
+ });
+ }
+ };
+
+ return {
+ copyAssets: (assetDirectories, patternlab, options) => {
+ asset_copy(assetDirectories, patternlab, options);
+ },
+ transformConfigPaths: (paths) => {
+ return transform_paths(paths);
+ }
+ };
+
+};
+
+module.exports = asset_copier;
diff --git a/core/lib/changes_hunter.js b/core/lib/changes_hunter.js
index 3b98f9a9c..f92666abd 100644
--- a/core/lib/changes_hunter.js
+++ b/core/lib/changes_hunter.js
@@ -1,12 +1,12 @@
-"use strict";
-const fs = require("fs-extra"),
- CompileState = require('./object_factory').CompileState;
+'use strict';
+const fs = require("fs-extra");
+const CompileState = require('./object_factory').CompileState;
/**
* For detecting changed patterns.
* @constructor
*/
-let ChangesHunter = function () {
+const ChangesHunter = function () {
};
ChangesHunter.prototype = {
@@ -24,11 +24,11 @@ ChangesHunter.prototype = {
checkBuildState: function (pattern, patternlab) {
//write the compiled template to the public patterns directory
- let renderedTemplatePath =
+ const renderedTemplatePath =
patternlab.config.paths.public.patterns + pattern.getPatternLink(patternlab, 'rendered');
//write the compiled template to the public patterns directory
- let markupOnlyPath =
+ const markupOnlyPath =
patternlab.config.paths.public.patterns + pattern.getPatternLink(patternlab, 'markupOnly');
if (!pattern.compileState) {
@@ -45,7 +45,7 @@ ChangesHunter.prototype = {
// Prevent error message if file does not exist
fs.accessSync(renderedFile, fs.F_OK)
);
- let outputLastModified = fs.statSync(renderedTemplatePath).mtime.getTime();
+ const outputLastModified = fs.statSync(renderedTemplatePath).mtime.getTime();
if (pattern.lastModified && outputLastModified > pattern.lastModified) {
pattern.compileState = CompileState.CLEAN;
@@ -55,7 +55,7 @@ ChangesHunter.prototype = {
pattern.compileState = CompileState.NEEDS_REBUILD;
}
- let node = patternlab.graph.node(pattern);
+ const node = patternlab.graph.node(pattern);
// Make the pattern known to the PatternGraph and remember its compileState
if (!node) {
@@ -78,7 +78,7 @@ ChangesHunter.prototype = {
checkLastModified: function (currentPattern, file) {
if (file) {
try {
- let stat = fs.statSync(file);
+ const stat = fs.statSync(file);
// Needs recompile whenever one of the patterns files (template, json, pseudopatterns) changed
currentPattern.lastModified =
diff --git a/core/lib/data_loader.js b/core/lib/data_loader.js
index 84044eefd..2dbf185a2 100644
--- a/core/lib/data_loader.js
+++ b/core/lib/data_loader.js
@@ -39,7 +39,7 @@ function loadDataFromFolder(dataFilesPath, excludeFileNames, fsDep) {
const dataFilesFullPath = dataFilesPath + '*.{json,yml,yaml}',
excludeFullPath = dataFilesPath + excludeFileNames + '.{json,yml,yaml}';
- let globOptions = {};
+ const globOptions = {};
if (excludeFileNames) {
globOptions.ignore = [excludeFullPath];
}
@@ -48,7 +48,7 @@ function loadDataFromFolder(dataFilesPath, excludeFileNames, fsDep) {
let mergeObject = {};
dataFiles.forEach(function (filePath) {
- let jsonData = yaml.safeLoad(fsDep.readFileSync(path.resolve(filePath), 'utf8'));
+ const jsonData = yaml.safeLoad(fsDep.readFileSync(path.resolve(filePath), 'utf8'));
mergeObject = _.merge(mergeObject, jsonData);
});
diff --git a/core/lib/lineage_hunter.js b/core/lib/lineage_hunter.js
index d20db5771..7c61be98d 100644
--- a/core/lib/lineage_hunter.js
+++ b/core/lib/lineage_hunter.js
@@ -1,30 +1,30 @@
-"use strict";
+'use strict';
+const extend = require("util")._extend;
-var extend = require("util")._extend;
+const lineage_hunter = function () {
-var lineage_hunter = function () {
+ function findlineage(pattern, patternlab) {
- var pa = require('./pattern_assembler');
+ const pa = require('./pattern_assembler');
+ const pattern_assembler = new pa();
- function findlineage(pattern, patternlab) {
// As we are adding edges from pattern to ancestor patterns, ensure it is known to the graph
patternlab.graph.add(pattern);
- var pattern_assembler = new pa();
//find the {{> template-name }} within patterns
- var matches = pattern.findPartials();
+ const matches = pattern.findPartials();
if (matches !== null) {
matches.forEach(function (match) {
//get the ancestorPattern
- var ancestorPattern = pattern_assembler.getPartial(pattern.findPartial(match), patternlab);
+ const ancestorPattern = pattern_assembler.getPartial(pattern.findPartial(match), patternlab);
if (ancestorPattern && pattern.lineageIndex.indexOf(ancestorPattern.patternPartial) === -1) {
//add it since it didnt exist
pattern.lineageIndex.push(ancestorPattern.patternPartial);
//create the more complex patternLineage object too
- var l = {
+ const l = {
"lineagePattern": ancestorPattern.patternPartial,
"lineagePath": "../../patterns/" + ancestorPattern.patternLink
};
@@ -44,7 +44,7 @@ var lineage_hunter = function () {
ancestorPattern.lineageRIndex.push(pattern.patternPartial);
//create the more complex patternLineage object in reverse
- var lr = {
+ const lr = {
"lineagePattern": pattern.patternPartial,
"lineagePath": "../../patterns/" + pattern.patternLink
};
@@ -69,7 +69,7 @@ var lineage_hunter = function () {
* @param graph {PatternGraph}
*/
function setPatternState(direction, pattern, targetPattern, graph) {
- var index = null;
+ let index = null;
if (direction === 'fromPast') {
index = graph.lineage(pattern);
} else {
@@ -77,7 +77,7 @@ var lineage_hunter = function () {
}
// if the request came from the past, apply target pattern state to current pattern lineage
- for (var i = 0; i < index.length; i++) {
+ for (let i = 0; i < index.length; i++) {
if (index[i].patternPartial === targetPattern.patternPartial) {
index[i].lineageState = targetPattern.patternState;
}
@@ -87,36 +87,36 @@ var lineage_hunter = function () {
function cascadePatternStates(patternlab) {
- for (var i = 0; i < patternlab.patterns.length; i++) {
- var pattern = patternlab.patterns[i];
+ for (let i = 0; i < patternlab.patterns.length; i++) {
+ const pattern = patternlab.patterns[i];
//for each pattern with a defined state
if (pattern.patternState) {
- var lineage = patternlab.graph.lineage(pattern);
+ const lineage = patternlab.graph.lineage(pattern);
if (lineage && lineage.length > 0) {
//find all lineage - patterns being consumed by this one
- for (var h = 0; h < lineage.length; h++) {
+ for (let h = 0; h < lineage.length; h++) {
// Not needed, the graph already knows the concrete pattern
- // var lineagePattern = pattern_assembler.getPartial(lineageIndex[h], patternlab);
+ // let lineagePattern = pattern_assembler.getPartial(lineageIndex[h], patternlab);
setPatternState('fromFuture', lineage[h], pattern, patternlab.graph);
}
}
- var lineageR = patternlab.graph.lineageR(pattern);
+ const lineageR = patternlab.graph.lineageR(pattern);
if (lineageR && lineageR.length > 0) {
//find all reverse lineage - that is, patterns consuming this one
- for (var j = 0; j < lineageR.length; j++) {
+ for (let j = 0; j < lineageR.length; j++) {
- var lineageRPattern = lineageR[j];
+ const lineageRPattern = lineageR[j];
//only set patternState if pattern.patternState "is less than" the lineageRPattern.patternstate
//or if lineageRPattern.patternstate (the consuming pattern) does not have a state
//this makes patternlab apply the lowest common ancestor denominator
- let patternStateCascade = patternlab.config.patternStateCascade;
- let patternStateIndex = patternStateCascade.indexOf(pattern.patternState);
- let patternReverseStateIndex = patternStateCascade.indexOf(lineageRPattern.patternState);
+ const patternStateCascade = patternlab.config.patternStateCascade;
+ const patternStateIndex = patternStateCascade.indexOf(pattern.patternState);
+ const patternReverseStateIndex = patternStateCascade.indexOf(lineageRPattern.patternState);
if (lineageRPattern.patternState === '' || (patternStateIndex < patternReverseStateIndex)) {
if (patternlab.config.debug) {
diff --git a/core/lib/list_item_hunter.js b/core/lib/list_item_hunter.js
index d04b6d0a7..7ffe450de 100644
--- a/core/lib/list_item_hunter.js
+++ b/core/lib/list_item_hunter.js
@@ -1,21 +1,20 @@
"use strict";
-var list_item_hunter = function () {
-
- var extend = require('util')._extend,
- pa = require('./pattern_assembler'),
- smh = require('./style_modifier_hunter'),
- plutils = require('./utilities'),
- jsonCopy = require('./json_copy'),
- Pattern = require('./object_factory').Pattern;
-
- var pattern_assembler = new pa(),
- style_modifier_hunter = new smh(),
- items = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen', 'twenty'];
+const list_item_hunter = function () {
+ const extend = require('util')._extend;
+ const _ = require('lodash');
+ const pa = require('./pattern_assembler');
+ const smh = require('./style_modifier_hunter');
+ const jsonCopy = require('./json_copy');
+ const Pattern = require('./object_factory').Pattern;
+
+ const pattern_assembler = new pa();
+ const style_modifier_hunter = new smh();
+ const items = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen', 'twenty'];
function processListItemPartials(pattern, patternlab) {
//find any listitem blocks
- var matches = pattern.findListItems();
+ const matches = pattern.findListItems();
if (matches !== null) {
matches.forEach(function (liMatch) {
@@ -25,14 +24,14 @@ var list_item_hunter = function () {
}
//find the boundaries of the block
- var loopNumberString = liMatch.split('.')[1].split('}')[0].trim();
- var end = liMatch.replace('#', '/');
- var patternBlock = pattern.template.substring(pattern.template.indexOf(liMatch) + liMatch.length, pattern.template.indexOf(end)).trim();
+ const loopNumberString = liMatch.split('.')[1].split('}')[0].trim();
+ const end = liMatch.replace('#', '/');
+ const patternBlock = pattern.template.substring(pattern.template.indexOf(liMatch) + liMatch.length, pattern.template.indexOf(end)).trim();
//build arrays that repeat the block, however large we need to
- var repeatedBlockTemplate = [];
- var repeatedBlockHtml = '';
- for (var i = 0; i < items.indexOf(loopNumberString); i++) {
+ const repeatedBlockTemplate = [];
+ let repeatedBlockHtml = '';
+ for (let i = 0; i < items.indexOf(loopNumberString); i++) {
if (patternlab.config.debug) {
console.log('list item(s) in pattern', pattern.patternPartial, 'adding', patternBlock, 'to repeatedBlockTemplate');
}
@@ -40,7 +39,7 @@ var list_item_hunter = function () {
}
//check for a local listitems.json file
- var listData;
+ let listData;
try {
listData = jsonCopy(patternlab.listitems, 'config.paths.source.data listitems');
} catch (err) {
@@ -48,19 +47,19 @@ var list_item_hunter = function () {
console.log(err);
}
- listData = plutils.mergeData(listData, pattern.listitems);
+ listData = _.merge(listData, pattern.listitems);
listData = pattern_assembler.parse_data_links_specific(patternlab, listData, 'listitems.json + any pattern listitems.json');
//iterate over each copied block, rendering its contents along with pattenlab.listitems[i]
- for (var i = 0; i < repeatedBlockTemplate.length; i++) {
+ for (let i = 0; i < repeatedBlockTemplate.length; i++) {
- var thisBlockTemplate = repeatedBlockTemplate[i];
- var thisBlockHTML = "";
+ let thisBlockTemplate = repeatedBlockTemplate[i];
+ let thisBlockHTML = "";
//combine listItem data with pattern data with global data
- var itemData = listData['' + items.indexOf(loopNumberString)]; //this is a property like "2"
- var globalData;
- var localData;
+ const itemData = listData['' + items.indexOf(loopNumberString)]; //this is a property like "2"
+ let globalData;
+ let localData;
try {
globalData = jsonCopy(patternlab.data, 'config.paths.source.data global data');
localData = jsonCopy(pattern.jsonFileData, `${pattern.patternPartial} data`);
@@ -69,23 +68,23 @@ var list_item_hunter = function () {
console.log(err);
}
- var allData = plutils.mergeData(globalData, localData);
- allData = plutils.mergeData(allData, itemData !== undefined ? itemData[i] : {}); //itemData could be undefined if the listblock contains no partial, just markup
+ let allData = _.merge(globalData, localData);
+ allData = _.merge(allData, itemData !== undefined ? itemData[i] : {}); //itemData could be undefined if the listblock contains no partial, just markup
allData.link = extend({}, patternlab.data.link);
//check for partials within the repeated block
- var foundPartials = Pattern.createEmpty({'template': thisBlockTemplate}).findPartials();
+ const foundPartials = Pattern.createEmpty({'template': thisBlockTemplate}).findPartials();
if (foundPartials && foundPartials.length > 0) {
- for (var j = 0; j < foundPartials.length; j++) {
+ for (let j = 0; j < foundPartials.length; j++) {
//get the partial
- var partialName = foundPartials[j].match(/([\w\-\.\/~]+)/g)[0];
- var partialPattern = pattern_assembler.getPartial(partialName, patternlab);
+ const partialName = foundPartials[j].match(/([\w\-\.\/~]+)/g)[0];
+ const partialPattern = pattern_assembler.getPartial(partialName, patternlab);
//create a copy of the partial so as to not pollute it after the get_pattern_by_key call.
- var cleanPartialPattern;
+ let cleanPartialPattern;
try {
cleanPartialPattern = JSON.parse(JSON.stringify(partialPattern));
cleanPartialPattern = jsonCopy(partialPattern, `partial pattern ${partialName}`);
@@ -119,7 +118,7 @@ var list_item_hunter = function () {
}
//replace the block with our generated HTML
- var repeatingBlock = pattern.extendedTemplate.substring(pattern.extendedTemplate.indexOf(liMatch), pattern.extendedTemplate.indexOf(end) + end.length);
+ const repeatingBlock = pattern.extendedTemplate.substring(pattern.extendedTemplate.indexOf(liMatch), pattern.extendedTemplate.indexOf(end) + end.length);
pattern.extendedTemplate = pattern.extendedTemplate.replace(repeatingBlock, repeatedBlockHtml);
//update the extendedTemplate in the partials object in case this pattern is consumed later
diff --git a/core/lib/markdown_parser.js b/core/lib/markdown_parser.js
index 495e0d181..68fcfa68d 100644
--- a/core/lib/markdown_parser.js
+++ b/core/lib/markdown_parser.js
@@ -1,9 +1,8 @@
-"use strict";
+'use strict';
+const md = require('markdown-it')();
+const yaml = require('js-yaml');
-var md = require('markdown-it')();
-var yaml = require('js-yaml');
-
-var markdown_parser = function () {
+const markdown_parser = function () {
/**
* Converts a markdown block with frontmatter (each is optional, technically) to a well-formed object.
@@ -11,18 +10,18 @@ var markdown_parser = function () {
* @returns an object with any frontmatter keys, plus a .markdown key
*/
function parseMarkdownBlock(block) {
- var returnObject = {};
+ let returnObject = {};
try {
//for each block process the yaml frontmatter and markdown
- var frontmatterRE = /---\r?\n{1}([\s\S]*)---\r?\n{1}([\s\S]*)+/gm;
- var chunks = frontmatterRE.exec(block);
+ const frontmatterRE = /---\r?\n{1}([\s\S]*)---\r?\n{1}([\s\S]*)+/gm;
+ const chunks = frontmatterRE.exec(block);
if (chunks) {
//we got some frontmatter
if (chunks && chunks[1]) {
//parse the yaml if we got it
- var frontmatter = chunks[1];
+ const frontmatter = chunks[1];
returnObject = yaml.safeLoad(frontmatter);
}
diff --git a/core/lib/object_factory.js b/core/lib/object_factory.js
index 488b6fa13..78479e0b3 100644
--- a/core/lib/object_factory.js
+++ b/core/lib/object_factory.js
@@ -1,20 +1,27 @@
-"use strict";
-
-var patternEngines = require('./pattern_engines');
-var path = require('path');
-var extend = require('util')._extend;
+'use strict';
+const patternEngines = require('./pattern_engines');
+const path = require('path');
+const extend = require('util')._extend;
// patternPrefixMatcher is intended to match the leading maybe-underscore,
// zero or more digits, and maybe-dash at the beginning of a pattern file name we can hack them
// off and get at the good part.
-var patternPrefixMatcher = /^_?(\d+-)?/;
+const patternPrefixMatcher = /^_?(\d+-)?/;
// Pattern properties
-
-var Pattern = function (relPath, data, patternlab) {
- // We expect relPath to be the path of the pattern template, relative to the
- // root of the pattern tree. Parse out the path parts and save the useful ones.
- var pathObj = path.parse(path.normalize(relPath));
+/**
+ * Pattern constructor
+ * @constructor
+ */
+const Pattern = function (relPath, data, patternlab) {
+ /**
+ * We expect relPath to be the path of the pattern template, relative to the
+ * root of the pattern tree. Parse out the path parts and save the useful ones.
+ * @param {relPath} relative directory
+ * @param {data} The JSON used to render values in the pattern.
+ * @param {patternlab} rendered html files for the pattern
+ */
+ const pathObj = path.parse(path.normalize(relPath));
this.relPath = path.normalize(relPath); // '00-atoms/00-global/00-colors.mustache'
this.fileName = pathObj.name; // '00-colors'
this.subdir = pathObj.dir; // '00-atoms/00-global'
@@ -114,8 +121,8 @@ Pattern.prototype = {
// Should look something like '00-atoms-00-global-00-colors/00-atoms-00-global-00-colors.html'
getPatternLink: function (patternlab, suffixType, customfileExtension) {
// if no suffixType is provided, we default to rendered
- var suffixConfig = patternlab.config.outputFileSuffixes;
- var suffix = suffixType ? suffixConfig[suffixType] : suffixConfig.rendered;
+ const suffixConfig = patternlab.config.outputFileSuffixes;
+ const suffix = suffixType ? suffixConfig[suffixType] : suffixConfig.rendered;
if (suffixType === 'rawTemplate') {
return this.name + path.sep + this.name + suffix + this.fileExtension;
@@ -165,7 +172,7 @@ Pattern.createEmpty = function (customProps, patternlab) {
}
}
- var pattern = new Pattern(relPath, null, patternlab);
+ const pattern = new Pattern(relPath, null, patternlab);
return extend(pattern, customProps);
};
@@ -173,11 +180,11 @@ Pattern.createEmpty = function (customProps, patternlab) {
// parameters that replace the positional parameters that the Pattern
// constructor takes.
Pattern.create = function (relPath, data, customProps, patternlab) {
- var newPattern = new Pattern(relPath || '', data || null, patternlab);
+ const newPattern = new Pattern(relPath || '', data || null, patternlab);
return extend(newPattern, customProps);
};
-var CompileState = {
+const CompileState = {
NEEDS_REBUILD: "needs rebuild",
BUILDING: "building",
CLEAN: "clean"
diff --git a/core/lib/parameter_hunter.js b/core/lib/parameter_hunter.js
index d9c94e597..f236f5e31 100644
--- a/core/lib/parameter_hunter.js
+++ b/core/lib/parameter_hunter.js
@@ -1,14 +1,13 @@
-"use strict";
+'use strict';
-var parameter_hunter = function () {
-
- var extend = require('util')._extend,
- pa = require('./pattern_assembler'),
- smh = require('./style_modifier_hunter'),
- plutils = require('./utilities'),
- style_modifier_hunter = new smh(),
- jsonCopy = require('./json_copy'),
- pattern_assembler = new pa();
+const parameter_hunter = function () {
+ const extend = require('util')._extend;
+ const _ = require('lodash');
+ const jsonCopy = require('./json_copy');
+ const pa = require('./pattern_assembler');
+ const smh = require('./style_modifier_hunter');
+ const style_modifier_hunter = new smh();
+ const pattern_assembler = new pa();
/**
* This function is really to accommodate the lax JSON-like syntax allowed by
@@ -54,14 +53,14 @@ var parameter_hunter = function () {
* @returns {string} paramStringWellFormed
*/
function paramToJson(pString, patternlab) {
- var colonPos = -1;
- var keys = [];
- var paramString = pString; // to not reassign param
- var paramStringWellFormed;
- var quotePos = -1;
- var regex;
- var values = [];
- var wrapper;
+ let colonPos = -1;
+ const keys = [];
+ let paramString = pString; // to not reassign param
+ let paramStringWellFormed;
+ let quotePos = -1;
+ let regex;
+ const values = [];
+ let wrapper;
// attempt to parse the data in case it is already well formed JSON
try {
@@ -181,7 +180,7 @@ var parameter_hunter = function () {
//build paramStringWellFormed string for JSON parsing
paramStringWellFormed = '{';
- for (var i = 0; i < keys.length; i++) {
+ for (let i = 0; i < keys.length; i++) {
//keys
//replace single-quote wrappers with double-quotes
@@ -251,8 +250,8 @@ var parameter_hunter = function () {
//compile this partial immeadiately, essentially consuming it.
pattern.parameteredPartials.forEach(function (pMatch) {
//find the partial's name and retrieve it
- var partialName = pMatch.match(/([\w\-\.\/~]+)/g)[0];
- var partialPattern = pattern_assembler.getPartial(partialName, patternlab);
+ const partialName = pMatch.match(/([\w\-\.\/~]+)/g)[0];
+ const partialPattern = pattern_assembler.getPartial(partialName, patternlab);
//if we retrieved a pattern we should make sure that its extendedTemplate is reset. looks to fix #190
partialPattern.extendedTemplate = partialPattern.template;
@@ -262,14 +261,14 @@ var parameter_hunter = function () {
}
//strip out the additional data, convert string to JSON.
- var leftParen = pMatch.indexOf('(');
- var rightParen = pMatch.lastIndexOf(')');
- var paramString = '{' + pMatch.substring(leftParen + 1, rightParen) + '}';
- var paramStringWellFormed = paramToJson(paramString, patternlab);
+ const leftParen = pMatch.indexOf('(');
+ const rightParen = pMatch.lastIndexOf(')');
+ const paramString = '{' + pMatch.substring(leftParen + 1, rightParen) + '}';
+ const paramStringWellFormed = paramToJson(paramString, patternlab);
- var paramData = {};
- var globalData = {};
- var localData = {};
+ let paramData = {};
+ let globalData = {};
+ let localData = {};
try {
paramData = JSON.parse(paramStringWellFormed);
@@ -280,8 +279,12 @@ var parameter_hunter = function () {
console.log(err);
}
- var allData = plutils.mergeData(globalData, localData);
- allData = plutils.mergeData(allData, paramData);
+ // resolve any pattern links that might be present
+ paramData = pattern_assembler.parse_data_links_specific(patternlab, paramData, pattern.patternPartial);
+
+ //combine all data: GLOBAL DATA => PATTERN.JSON DATA => PARAMETER DATA
+ let allData = _.merge(globalData, localData);
+ allData = _.merge(allData, paramData);
//if the partial has pattern parameters itself, we need to handle those
findparameters(partialPattern, patternlab);
@@ -294,7 +297,7 @@ var parameter_hunter = function () {
//extend pattern data links into link for pattern link shortcuts to work. we do this locally and globally
allData.link = extend({}, patternlab.data.link);
- var renderedPartial = pattern_assembler.renderPattern(partialPattern.extendedTemplate, allData, patternlab.partials);
+ const renderedPartial = pattern_assembler.renderPattern(partialPattern.extendedTemplate, allData, patternlab.partials);
//remove the parameter from the partial and replace it with the rendered partial + paramData
pattern.extendedTemplate = pattern.extendedTemplate.replace(pMatch, renderedPartial);
diff --git a/core/lib/pattern_assembler.js b/core/lib/pattern_assembler.js
index 1015a0d6d..701ef908d 100644
--- a/core/lib/pattern_assembler.js
+++ b/core/lib/pattern_assembler.js
@@ -1,26 +1,28 @@
"use strict";
-var path = require('path'),
- _ = require('lodash'),
- fs = require('fs-extra'),
- Pattern = require('./object_factory').Pattern,
- CompileState = require('./object_factory').CompileState,
- pph = require('./pseudopattern_hunter'),
- mp = require('./markdown_parser'),
- plutils = require('./utilities'),
- dataLoader = require('./data_loader')(),
- patternEngines = require('./pattern_engines'),
- lh = require('./lineage_hunter'),
- lih = require('./list_item_hunter'),
- smh = require('./style_modifier_hunter'),
- ph = require('./parameter_hunter'),
- jsonCopy = require('./json_copy'),
- ch = require('./changes_hunter');
-
+const path = require('path');
+const _ = require('lodash');
+const Pattern = require('./object_factory').Pattern;
+const CompileState = require('./object_factory').CompileState;
+const pph = require('./pseudopattern_hunter');
+const mp = require('./markdown_parser');
+const plutils = require('./utilities');
+const patternEngines = require('./pattern_engines');
+const lh = require('./lineage_hunter');
+const lih = require('./list_item_hunter');
+const smh = require('./style_modifier_hunter');
+const ph = require('./parameter_hunter');
+const ch = require('./changes_hunter');
+const jsonCopy = require('./json_copy');
+const da = require('./data_loader');
const markdown_parser = new mp();
const changes_hunter = new ch();
+const dataLoader = new da();
+
+//this is mocked in unit tests
+let fs = require('fs-extra'); //eslint-disable-line prefer-const
-var pattern_assembler = function () {
+const pattern_assembler = function () {
// HELPER FUNCTIONS
function getPartial(partialName, patternlab) {
@@ -62,7 +64,7 @@ var pattern_assembler = function () {
list.push(container.listitems[item]);
}
}
- container.listItemArray = plutils.shuffle(list);
+ container.listItemArray = _.shuffle(list);
for (var i = 1; i <= container.listItemArray.length; i++) {
var tempItems = [];
@@ -78,21 +80,7 @@ var pattern_assembler = function () {
}
}
- /*
- * Deprecated in favor of .md 'status' frontmatter inside a pattern. Still used for unit tests at this time.
- * Will be removed in future versions
- */
- function setState(pattern, patternlab, displayDeprecatedWarning) {
- if (patternlab.config.patternStates && patternlab.config.patternStates[pattern.patternPartial]) {
-
- if (displayDeprecatedWarning) {
- plutils.error("Deprecation Warning: Using patternlab-config.json patternStates object will be deprecated in favor of the state frontmatter key associated with individual pattern markdown files.");
- console.log("This feature will still work in it's current form this release (but still be overridden by the new parsing method), and will be removed in the future.");
- }
- pattern.patternState = patternlab.config.patternStates[pattern.patternPartial];
- }
- }
function addPattern(pattern, patternlab) {
@@ -128,9 +116,10 @@ var pattern_assembler = function () {
} else {
patternlab.partials[pattern.patternPartial] = pattern.patternDesc;
}
- patternlab.graph.add(pattern);
- patternlab.patterns.push(pattern);
+ //patterns sorted by name so the patterntype and patternsubtype is adhered to for menu building
+ patternlab.patterns.splice(_.sortedIndexBy(patternlab.patterns, pattern, 'name'), 0, pattern);
+ patternlab.graph.add(pattern);
}
}
@@ -162,7 +151,7 @@ var pattern_assembler = function () {
var markdownFileContents = fs.readFileSync(markdownFileName, 'utf8');
var markdownObject = markdown_parser.parse(markdownFileContents);
- if (!plutils.isObjectEmpty(markdownObject)) {
+ if (!_.isEmpty(markdownObject)) {
//set keys and markdown itself
currentPattern.patternDescExists = true;
currentPattern.patternDesc = markdownObject.markdown;
@@ -253,7 +242,9 @@ var pattern_assembler = function () {
addPattern(pattern, patternlab);
}
- function processPatternIterative(relPath, patternlab) {
+ // loads a pattern from disk, creates a Pattern object from it and
+ // all its associated files, and records it in patternlab.patterns[]
+ function loadPatternIterative(relPath, patternlab) {
var relativeDepth = (relPath.match(/\w(?=\\)|\w(?=\/)/g) || []).length;
if (relativeDepth > 2) {
@@ -294,10 +285,8 @@ var pattern_assembler = function () {
console.log(err);
}
}
-
}
- var pseudopattern_hunter = new pph();
//extract some information
var filename = fileObject.base;
@@ -320,13 +309,10 @@ var pattern_assembler = function () {
return currentPattern;
}
- //see if this file has a state
- setState(currentPattern, patternlab, true);
-
//look for a json file for this template
try {
var jsonFilename = path.resolve(patternsPath, currentPattern.subdir, currentPattern.fileName);
- let configData = dataLoader.loadDataFromFile(jsonFilename, fs);
+ const configData = dataLoader.loadDataFromFile(jsonFilename, fs);
if (configData) {
currentPattern.jsonFileData = configData;
@@ -343,7 +329,7 @@ var pattern_assembler = function () {
//look for a listitems.json file for this template
try {
var listJsonFileName = path.resolve(patternsPath, currentPattern.subdir, currentPattern.fileName + ".listitems");
- let listItemsConfig = dataLoader.loadDataFromFile(listJsonFileName, fs);
+ const listItemsConfig = dataLoader.loadDataFromFile(listJsonFileName, fs);
if (listItemsConfig) {
currentPattern.listitems = listItemsConfig;
@@ -381,12 +367,24 @@ var pattern_assembler = function () {
//add currentPattern to patternlab.patterns array
addPattern(currentPattern, patternlab);
- //look for a pseudo pattern by checking if there is a file containing same name, with ~ in it, ending in .json
- pseudopattern_hunter.find_pseudopatterns(currentPattern, patternlab);
-
return currentPattern;
}
+ // This is now solely for analysis; loading of the pattern file is
+ // above, in loadPatternIterative()
+ function processPatternIterative(pattern, patternlab) {
+ //look for a pseudo pattern by checking if there is a file
+ //containing same name, with ~ in it, ending in .json
+ return pph.find_pseudopatterns(pattern, patternlab).then(() => {
+ //find any stylemodifiers that may be in the current pattern
+ pattern.stylePartials = pattern.findPartialsWithStyleModifiers();
+
+ //find any pattern parameters that may be in the current pattern
+ pattern.parameteredPartials = pattern.findPartialsWithPatternParameters();
+ return pattern;
+ }).catch(plutils.reportError('There was an error in processPatternIterative():'));
+ }
+
function processPatternRecursive(file, patternlab) {
//find current pattern in patternlab object using var file as a partial
@@ -572,9 +570,6 @@ var pattern_assembler = function () {
find_list_items: function (pattern) {
return pattern.findListItems();
},
- setPatternState: function (pattern, patternlab, displayDeprecatedWarning) {
- setState(pattern, patternlab, displayDeprecatedWarning);
- },
addPattern: function (pattern, patternlab) {
addPattern(pattern, patternlab);
},
@@ -587,8 +582,11 @@ var pattern_assembler = function () {
renderPattern: function (template, data, partials) {
return renderPattern(template, data, partials);
},
- process_pattern_iterative: function (file, patternlab) {
- return processPatternIterative(file, patternlab);
+ load_pattern_iterative: function (file, patternlab) {
+ return loadPatternIterative(file, patternlab);
+ },
+ process_pattern_iterative: function (pattern, patternlab) {
+ return processPatternIterative(pattern, patternlab);
},
process_pattern_recursive: function (file, patternlab, additionalData) {
processPatternRecursive(file, patternlab, additionalData);
diff --git a/core/lib/pattern_engines.js b/core/lib/pattern_engines.js
index c316cec9d..7582b4ea7 100644
--- a/core/lib/pattern_engines.js
+++ b/core/lib/pattern_engines.js
@@ -1,11 +1,10 @@
// special shoutout to Geoffrey Pursell for single-handedly making Pattern Lab Node Pattern Engines possible!
'use strict';
-
-var path = require('path');
-var diveSync = require('diveSync');
+const path = require('path');
+const diveSync = require('diveSync');
const chalk = require('chalk');
-var engineMatcher = /^patternengine-node-(.*)$/;
-var enginesDirectories = [
+const engineMatcher = /^patternengine-node-(.*)$/;
+const enginesDirectories = [
{
displayName: 'the core',
path: path.resolve(__dirname, '..', '..', 'node_modules')
@@ -15,31 +14,26 @@ var enginesDirectories = [
path: path.join(process.cwd(), 'node_modules')
}
];
-var PatternEngines; // the main export object
-var engineNameForExtension; // generated mapping of extension to engine name
-
-
-// free "private" functions, for internal setup only
// given a path: return the engine name if the path points to a valid engine
// module directory, or false if it doesn't
function isEngineModule(filePath) {
- var baseName = path.basename(filePath);
- var engineMatch = baseName.match(engineMatcher);
+ const baseName = path.basename(filePath);
+ const engineMatch = baseName.match(engineMatcher);
if (engineMatch) { return engineMatch[1]; }
return false;
}
function findEngineModulesInDirectory(dir) {
- var foundEngines = [];
+ const foundEngines = [];
diveSync(dir, {
recursive: false,
directories: true
}, function (err, filePath) {
if (err) { throw err; }
- var foundEngineName = isEngineModule(filePath);
+ const foundEngineName = isEngineModule(filePath);
if (foundEngineName) {
foundEngines.push({
name: foundEngineName,
@@ -51,57 +45,6 @@ function findEngineModulesInDirectory(dir) {
return foundEngines;
}
-// Try to load engines! We scan for engines at each path specified above. This
-// function is kind of a big deal.
-function loadAllEngines(enginesObject) {
- enginesDirectories.forEach(function (engineDirectory) {
- var enginesInThisDir = findEngineModulesInDirectory(engineDirectory.path);
- console.log(chalk.bold(`Loading engines from ${engineDirectory.displayName}...\n`));
-
- // find all engine-named things in this directory and try to load them,
- // unless it's already been loaded.
- enginesInThisDir.forEach(function (engineDiscovery) {
- var errorMessage;
- var successMessage = chalk.green("good to go");
-
- try {
- // give it a try! load 'er up. But not if we already have, of course.
- if (enginesObject[engineDiscovery.name]) {
- throw new Error("already loaded, skipping.");
- }
- enginesObject[engineDiscovery.name] = require(engineDiscovery.modulePath);
- } catch (err) {
- errorMessage = err.message;
- } finally {
- // report on the status of the engine, one way or another!
- console.log(` ${engineDiscovery.name}:`, errorMessage ? chalk.red(errorMessage) : successMessage);
- }
- });
- console.log('');
- });
-
- // Complain if for some reason we haven't loaded any engines.
- if (Object.keys(enginesObject).length === 0) {
- throw new Error('No engines loaded! Something is seriously wrong.');
- }
- console.log(chalk.bold('Done loading engines.\n'));
-}
-
-
-// produce a mapping between file extension and engine name for each of the
-// loaded engines
-function createFileExtensionToEngineNameMap(enginesObject) {
- var mapping = {};
-
- Object.keys(enginesObject).forEach(function (engineName) {
- var extensionForEngine = enginesObject[engineName].engineFileExtension;
- mapping[extensionForEngine] = engineName;
- });
-
- return mapping;
-}
-
-
//
// PatternEngines: the main export of this module
//
@@ -117,13 +60,84 @@ function createFileExtensionToEngineNameMap(enginesObject) {
// only the engine names so we can easily iterate over them; all the handy
// methods and properites below should therefore be on its prototype.
-PatternEngines = Object.create({
+const PatternEngines = Object.create({
+
+ loadAllEngines: function (patternLabConfig) {
+ var self = this;
+
+ // Try to load engines! We scan for engines at each path specified above. This
+ // function is kind of a big deal.
+ enginesDirectories.forEach(function (engineDirectory) {
+ const enginesInThisDir = findEngineModulesInDirectory(engineDirectory.path);
+ if (patternLabConfig.debug) {
+ console.log(chalk.bold(`Loading engines from ${engineDirectory.displayName}...\n`));
+ }
+
+ // find all engine-named things in this directory and try to load them,
+ // unless it's already been loaded.
+ enginesInThisDir.forEach(function (engineDiscovery) {
+ let errorMessage;
+ const successMessage = "good to go";
+ if (patternLabConfig.debug) {
+ chalk.green(successMessage);
+ }
+
+ try {
+ // Give it a try! load 'er up. But not if we already have,
+ // of course. Also pass the pattern lab config object into
+ // the engine's closure scope so it can know things about
+ // things.
+ if (self[engineDiscovery.name]) {
+ throw new Error("already loaded, skipping.");
+ }
+ self[engineDiscovery.name] = require(engineDiscovery.modulePath);
+ if (typeof self[engineDiscovery.name].usePatternLabConfig === 'function') {
+ self[engineDiscovery.name].usePatternLabConfig(patternLabConfig);
+ }
+ if (typeof self[engineDiscovery.name].spawnMeta === 'function') {
+ self[engineDiscovery.name].spawnMeta(patternLabConfig);
+ }
+ } catch (err) {
+ errorMessage = err.message;
+ } finally {
+ // report on the status of the engine, one way or another!
+ if (patternLabConfig.debug) {
+ console.log(` ${engineDiscovery.name}:`, errorMessage ? chalk.red(errorMessage) : successMessage);
+ }
+ }
+ });
+ console.log('');
+ });
+
+ // Complain if for some reason we haven't loaded any engines.
+ if (Object.keys(self).length === 0) {
+ throw new Error('No engines loaded! Something is seriously wrong.');
+ }
+ if (patternLabConfig.debug) {
+ console.log(chalk.bold('Done loading engines.\n'));
+ }
+ },
+
getEngineNameForPattern: function (pattern) {
// avoid circular dependency by putting this in here. TODO: is this slow?
- var of = require('./object_factory');
-
+ const of = require('./object_factory');
if (pattern instanceof of.Pattern && typeof pattern.fileExtension === 'string' && pattern.fileExtension) {
- return engineNameForExtension[pattern.fileExtension];
+ //loop through known engines and find the one that supports the pattern's fileExtension
+ const engineNames = Object.keys(this);
+ for (let i = 0; i < engineNames.length; i++) {
+ const engine = this[engineNames[i]];
+
+ if (Array.isArray(engine.engineFileExtension)) {
+ if (engine.engineFileExtension.includes(pattern.fileExtension)) {
+ return engine.engineName;
+ }
+ } else {
+ //this likely means the users engines are out of date. todo: tell them to upgrade
+ if (engine.engineFileExtension === pattern.fileExtension) {
+ return engine.engineName;
+ }
+ }
+ }
}
// otherwise, assume it's a plain mustache template string and act
@@ -135,27 +149,29 @@ PatternEngines = Object.create({
if (pattern.isPseudoPattern) {
return this.getEngineForPattern(pattern.basePattern);
} else {
- var engineName = this.getEngineNameForPattern(pattern);
+ const engineName = this.getEngineNameForPattern(pattern);
return this[engineName];
}
},
+ // combine all found engines into a single array of supported extensions
getSupportedFileExtensions: function () {
- var engineNames = Object.keys(PatternEngines);
- return engineNames.map(function (engineName) {
+ const engineNames = Object.keys(PatternEngines);
+ const allEnginesExtensions = engineNames.map((engineName) => {
return PatternEngines[engineName].engineFileExtension;
});
+ return [].concat.apply([], allEnginesExtensions);
},
isFileExtensionSupported: function (fileExtension) {
- var supportedExtensions = PatternEngines.getSupportedFileExtensions();
+ const supportedExtensions = PatternEngines.getSupportedFileExtensions();
return (supportedExtensions.lastIndexOf(fileExtension) !== -1);
},
// given a filename, return a boolean: whether or not the filename indicates
// that the file is pseudopattern JSON
isPseudoPatternJSON: function (filename) {
- var extension = path.extname(filename);
+ const extension = path.extname(filename);
return (extension === '.json' && filename.indexOf('~') > -1);
},
@@ -165,24 +181,17 @@ PatternEngines = Object.create({
// pattern files!
isPatternFile: function (filename) {
// skip hidden patterns/files without a second thought
- var extension = path.extname(filename);
+ const extension = path.extname(filename);
if (filename.charAt(0) === '.' ||
(extension === '.json' && !PatternEngines.isPseudoPatternJSON(filename))) {
return false;
}
// not a hidden pattern, let's dig deeper
- var supportedPatternFileExtensions = PatternEngines.getSupportedFileExtensions();
+ const supportedPatternFileExtensions = PatternEngines.getSupportedFileExtensions();
return (supportedPatternFileExtensions.lastIndexOf(extension) !== -1 ||
PatternEngines.isPseudoPatternJSON(filename));
}
});
-
-// load up the engines we found
-loadAllEngines(PatternEngines);
-
-// mapping of file extensions to engine names, for lookup use
-engineNameForExtension = createFileExtensionToEngineNameMap(PatternEngines);
-
module.exports = PatternEngines;
diff --git a/core/lib/pattern_exporter.js b/core/lib/pattern_exporter.js
index 1b899a6a2..3d8d161c1 100644
--- a/core/lib/pattern_exporter.js
+++ b/core/lib/pattern_exporter.js
@@ -1,8 +1,8 @@
"use strict";
-var fs = require('fs-extra');
+const fs = require('fs-extra');
-var pattern_exporter = function () {
+const pattern_exporter = function () {
/**
* Exports all pattern's final HTML as defined in patternlab-config.json to desired location.
@@ -13,11 +13,11 @@ var pattern_exporter = function () {
*/
function exportPatterns(patternlab) {
//read the config export options
- var exportPartials = patternlab.config.patternExportPatternPartials;
+ const exportPartials = patternlab.config.patternExportPatternPartials;
//find the chosen patterns to export
- for (var i = 0; i < exportPartials.length; i++) {
- for (var j = 0; j < patternlab.patterns.length; j++) {
+ for (let i = 0; i < exportPartials.length; i++) {
+ for (let j = 0; j < patternlab.patterns.length; j++) {
if (exportPartials[i] === patternlab.patterns[j].patternPartial) {
//write matches to the desired location
fs.outputFileSync(patternlab.config.patternExportDirectory + patternlab.patterns[j].patternPartial + '.html', patternlab.patterns[j].patternPartialCode);
diff --git a/core/lib/pattern_graph.js b/core/lib/pattern_graph.js
index 5c28d3af1..c509ca406 100644
--- a/core/lib/pattern_graph.js
+++ b/core/lib/pattern_graph.js
@@ -125,9 +125,9 @@ PatternGraph.prototype = {
* @throws {Error} If the pattern is unknown
*/
link: function (patternFrom, patternTo) {
- let nameFrom = nodeName(patternFrom);
- let nameTo = nodeName(patternTo);
- for (let name of [nameFrom, nameTo]) {
+ const nameFrom = nodeName(patternFrom);
+ const nameTo = nodeName(patternTo);
+ for (const name of [nameFrom, nameTo]) {
if (!this.patterns.has(name)) {
throw new Error("Pattern not known: " + name);
}
@@ -144,8 +144,8 @@ PatternGraph.prototype = {
* @return {boolean}
*/
hasLink: function (patternFrom, patternTo) {
- let nameFrom = nodeName(patternFrom);
- let nameTo = nodeName(patternTo);
+ const nameFrom = nodeName(patternFrom);
+ const nameTo = nodeName(patternTo);
return this.graph.hasEdge(nameFrom, nameTo);
},
@@ -170,22 +170,22 @@ PatternGraph.prototype = {
* Edges are added in reverse order for topological sorting(e.g. atom -> molecule -> organism,
* where "->" means "included by").
*/
- let compileGraph = new Graph({
+ const compileGraph = new Graph({
directed: true
});
- let nodes = this.graph.nodes();
- let changedNodes = nodes.filter(n => compileStateFilter(this.patterns, n));
+ const nodes = this.graph.nodes();
+ const changedNodes = nodes.filter(n => compileStateFilter(this.patterns, n));
this.nodes2patterns(changedNodes).forEach(pattern => {
- let patternNode = nodeName(pattern);
+ const patternNode = nodeName(pattern);
if (!compileGraph.hasNode(patternNode)) {
compileGraph.setNode(patternNode);
}
this.applyReverse(pattern, (from, to) => {
from.compileState = CompileState.NEEDS_REBUILD;
- let fromName = nodeName(from);
- let toName = nodeName(to);
- for (let name of [fromName, toName]) {
+ const fromName = nodeName(from);
+ const toName = nodeName(to);
+ for (const name of [fromName, toName]) {
if (!compileGraph.hasNode(name)) {
compileGraph.setNode(name);
}
@@ -212,7 +212,7 @@ PatternGraph.prototype = {
* between patterns and node metadata.
*/
applyReverse: function (pattern, fn) {
- for (let p of this.lineageR(pattern)) {
+ for (const p of this.lineageR(pattern)) {
fn(p, pattern);
this.applyReverse(p, fn);
}
diff --git a/core/lib/pattern_graph_dot.js b/core/lib/pattern_graph_dot.js
index 5d87c383e..1b89060b9 100644
--- a/core/lib/pattern_graph_dot.js
+++ b/core/lib/pattern_graph_dot.js
@@ -88,11 +88,11 @@ const PatternGraphDot = {};
PatternGraphDot.generate = function (patternGraph) {
const g = patternGraph.graph;
const patterns = patternGraph.patterns;
- let buckets = new Map();
+ const buckets = new Map();
const colors = ["darkgreen", "firebrick", "slateblue", "darkgoldenrod", "black"];
const colorMap = new Map();
let colIdx = 0;
- for (let p of patterns.partials.values()) {
+ for (const p of patterns.partials.values()) {
if (p.isPseudoPattern || !p.patternType) {
continue;
}
@@ -117,7 +117,7 @@ PatternGraphDot.generate = function (patternGraph) {
let subGraphLines = [];
- for (let key of sortedKeys) {
+ for (const key of sortedKeys) {
const subPatterns = buckets.get(key);
subGraphLines = subGraphLines.concat(subGraph(key, subPatterns));
}
@@ -125,9 +125,9 @@ PatternGraphDot.generate = function (patternGraph) {
res.push("edge[style=solid];");
- foo: for (let edge of g.edges()) {
- let fromTo = patternGraph.nodes2patterns([edge.v, edge.w]);
- for (let pattern of fromTo) {
+ foo: for (const edge of g.edges()) {
+ const fromTo = patternGraph.nodes2patterns([edge.v, edge.w]);
+ for (const pattern of fromTo) {
if (pattern.isPseudoPattern || !pattern.patternType) {
continue foo;
}
diff --git a/core/lib/pattern_registry.js b/core/lib/pattern_registry.js
index cbd46d82d..6463607ac 100644
--- a/core/lib/pattern_registry.js
+++ b/core/lib/pattern_registry.js
@@ -50,16 +50,16 @@ PatternRegistry.prototype = {
*/
// This previously has been a for loop over an array in pattern_
- let byPartialName = this.partials.get(partialName);
+ const byPartialName = this.partials.get(partialName);
if (this.partials.has(partialName)) {
return byPartialName;
}
- let patterns = this.allPatterns();
+ const patterns = this.allPatterns();
//else look by verbose syntax
- for (let thisPattern of patterns) {
+ for (const thisPattern of patterns) {
switch (partialName) {
case thisPattern.relPath:
case thisPattern.verbosePartial:
@@ -68,7 +68,7 @@ PatternRegistry.prototype = {
}
//return the fuzzy match if all else fails
- for (let thisPattern of patterns) {
+ for (const thisPattern of patterns) {
const partialParts = partialName.split('-'),
partialType = partialParts[0],
partialNameEnd = partialParts.slice(1).join('-');
diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js
index a4f5a8131..c76651bf4 100644
--- a/core/lib/patternlab.js
+++ b/core/lib/patternlab.js
@@ -1,5 +1,5 @@
/*
- * patternlab-node - v2.12.0 - 2017
+ * patternlab-node - v3.0.0-alpha.1 - 2017
*
* Brian Muenzenmeyer, Geoff Pursell, Raphael Okon, tburny and the web community.
* Licensed under the MIT license.
@@ -10,24 +10,36 @@
"use strict";
-var diveSync = require('diveSync'),
- _ = require('lodash'),
- path = require('path'),
- chalk = require('chalk'),
- cleanHtml = require('js-beautify').html,
- inherits = require('util').inherits,
- pm = require('./plugin_manager'),
- fs = require('fs-extra'),
- packageInfo = require('../../package.json'),
- dataLoader = require('./data_loader')(),
- plutils = require('./utilities'),
- jsonCopy = require('./json_copy'),
- ui = require('./ui_builder'),
- ui_builder = new ui(),
- pe = require('./pattern_exporter'),
- pattern_exporter = new pe(),
- PatternGraph = require('./pattern_graph').PatternGraph,
- updateNotifier = require('update-notifier');
+const diveSync = require('diveSync');
+const dive = require('dive');
+const _ = require('lodash');
+const path = require('path');
+const chalk = require('chalk');
+const cleanHtml = require('js-beautify').html;
+const inherits = require('util').inherits;
+const pm = require('./plugin_manager');
+const packageInfo = require('../../package.json');
+const dataLoader = require('./data_loader')();
+const plutils = require('./utilities');
+const jsonCopy = require('./json_copy');
+const PatternGraph = require('./pattern_graph').PatternGraph;
+const pa = require('./pattern_assembler');
+const lh = require('./lineage_hunter');
+const sm = require('./starterkit_manager');
+const pe = require('./pattern_exporter');
+const Pattern = require('./object_factory').Pattern;
+const CompileState = require('./object_factory').CompileState;
+const updateNotifier = require('update-notifier');
+
+//these are mocked in unit tests, so let them be overridden
+let fs = require('fs-extra'); // eslint-disable-line
+let ui_builder = require('./ui_builder'); // eslint-disable-line
+let pattern_exporter = new pe(); // eslint-disable-line
+let assetCopier = require('./asset_copy'); // eslint-disable-line
+let serve = require('./serve'); // eslint-disable-line
+
+const pattern_assembler = new pa();
+const lineage_hunter = new lh();
//register our log events
plutils.log.on('error', msg => console.log(msg));
@@ -35,14 +47,8 @@ plutils.log.on('debug', msg => console.log(msg));
plutils.log.on('warning', msg => console.log(msg));
plutils.log.on('info', msg => console.log(msg));
-console.log(
- chalk.bold('\n====[ Pattern Lab / Node'),
- `- v${packageInfo.version}`,
- chalk.bold(']====\n')
-);
-
-var patternEngines = require('./pattern_engines');
-var EventEmitter = require('events').EventEmitter;
+const patternEngines = require('./pattern_engines');
+const EventEmitter = require('events').EventEmitter;
//bootstrap update notifier
updateNotifier({
@@ -62,21 +68,45 @@ function buildPatternData(dataFilesPath, fsDep) {
// GTP: these two diveSync pattern processors factored out so they can be reused
// from unit tests to reduce code dupe!
-function processAllPatternsIterative(pattern_assembler, patterns_dir, patternlab) {
- diveSync(
- patterns_dir,
- function (err, file) {
- //log any errors
- if (err) {
- console.log(err);
- return;
- }
- pattern_assembler.process_pattern_iterative(path.relative(patterns_dir, file), patternlab);
- }
- );
+function processAllPatternsIterative(patterns_dir, patternlab) {
+
+ const promiseAllPatternFiles = new Promise(function (resolve) {
+ dive(
+ patterns_dir,
+ (err, file) => {
+ //log any errors
+ if (err) {
+ console.log('error in processAllPatternsIterative():', err);
+ return;
+ }
+
+ // We now have the loading and process phases spearated; this
+ // loads all the patterns before beginning any analysis, so we
+ // can load them asynchronously and be sure we know about all
+ // of them before we start lineage hunting, for
+ // example. Incidentally, this should also allow people to do
+ // horrifying things like include a page in a atom. But
+ // please, if you're reading this: don't.
+
+ // NOTE: sync for now
+ pattern_assembler.load_pattern_iterative(path.relative(patterns_dir, file), patternlab);
+ },
+ resolve
+ );
+ });
+ return promiseAllPatternFiles.then(() => {
+ // This is the second phase: once we've loaded all patterns,
+ // start analysis.
+ // patternlab.patterns.forEach((pattern) => {
+ // pattern_assembler.process_pattern_iterative(pattern, patternlab);
+ // });
+ return Promise.all(patternlab.patterns.map((pattern) => {
+ return pattern_assembler.process_pattern_iterative(pattern, patternlab);
+ }));
+ });
}
-function processAllPatternsRecursive(pattern_assembler, patterns_dir, patternlab) {
+function processAllPatternsRecursive(patterns_dir, patternlab) {
diveSync(
patterns_dir,
function (err, file) {
@@ -92,7 +122,7 @@ function processAllPatternsRecursive(pattern_assembler, patterns_dir, patternlab
function checkConfiguration(patternlab) {
//default the output suffixes if not present
- var outputFileSuffixes = {
+ const outputFileSuffixes = {
rendered: '.rendered',
rawTemplate: '',
markupOnly: '.markup-only'
@@ -101,10 +131,16 @@ function checkConfiguration(patternlab) {
if (!patternlab.config.outputFileSuffixes) {
plutils.warning('Configuration Object "outputFileSuffixes" not found, and defaulted to the following:');
console.log(outputFileSuffixes);
- plutils.warning('Since Pattern Lab Core 2.3.0 this configuration option is required. Suggest you add it to your patternlab-config.json file.');
+ plutils.warning('Since Pattern Lab Node Core 2.3.0 this configuration option is required. Suggest you add it to your patternlab-config.json file.');
console.log();
}
patternlab.config.outputFileSuffixes = _.extend(outputFileSuffixes, patternlab.config.outputFileSuffixes);
+
+ if (typeof patternlab.config.paths.source.patternlabFiles === 'string') {
+ plutils.warning(`Configuration key [paths.source.patternlabFiles] inside patternlab-config.json was found as the string '${patternlab.config.paths.source.patternlabFiles}'`);
+ plutils.warning('Since Pattern Lab Node Core 3.0.0 this key is an object. Suggest you update this key following this issue: https://github.com/pattern-lab/patternlab-node/issues/683.');
+ }
+
}
/**
@@ -117,21 +153,21 @@ function initializePlugins(patternlab) {
if (!patternlab.config.plugins) { return; }
- var plugin_manager = new pm(patternlab.config, path.resolve(__dirname, '../../patternlab-config.json'));
- var foundPlugins = plugin_manager.detect_plugins();
+ const plugin_manager = new pm(patternlab.config, path.resolve(__dirname, '../../patternlab-config.json'));
+ const foundPlugins = plugin_manager.detect_plugins();
if (foundPlugins && foundPlugins.length > 0) {
- for (var i = 0; i < foundPlugins.length; i++) {
+ for (let i = 0; i < foundPlugins.length; i++) {
- let pluginKey = foundPlugins[i];
+ const pluginKey = foundPlugins[i];
if (patternlab.config.debug) {
console.log('Found plugin: ', pluginKey);
console.log('Attempting to load and initialize plugin.');
}
- var plugin = plugin_manager.load_plugin(pluginKey);
+ const plugin = plugin_manager.load_plugin(pluginKey);
plugin(patternlab);
}
}
@@ -143,9 +179,9 @@ function initializePlugins(patternlab) {
*/
function installPlugin(pluginName) {
//get the config
- var configPath = path.resolve(process.cwd(), 'patternlab-config.json');
- var config = fs.readJSONSync(path.resolve(configPath), 'utf8');
- var plugin_manager = new pm(config, configPath);
+ const configPath = path.resolve(process.cwd(), 'patternlab-config.json');
+ const config = fs.readJSONSync(path.resolve(configPath), 'utf8');
+ const plugin_manager = new pm(config, configPath);
plugin_manager.install_plugin(pluginName);
}
@@ -155,24 +191,16 @@ function PatternLabEventEmitter() {
}
inherits(PatternLabEventEmitter, EventEmitter);
-var patternlab_engine = function (config) {
- 'use strict';
-
- var pa = require('./pattern_assembler'),
- lh = require('./lineage_hunter'),
- sm = require('./starterkit_manager'),
- Pattern = require('./object_factory').Pattern,
- CompileState = require('./object_factory').CompileState,
- patternlab = {};
+const patternlab_engine = function (config) {
+ const patternlab = {};
patternlab.engines = patternEngines;
-
- var pattern_assembler = new pa(),
- lineage_hunter = new lh();
+ patternlab.engines.loadAllEngines(config);
patternlab.package = fs.readJSONSync(path.resolve(__dirname, '../../package.json'));
patternlab.config = config || fs.readJSONSync(path.resolve(__dirname, '../../patternlab-config.json'));
patternlab.events = new PatternLabEventEmitter();
+ patternlab.watchers = {};
// Initialized when building
patternlab.graph = null;
@@ -182,9 +210,13 @@ var patternlab_engine = function (config) {
//todo: determine if this is the best place to wire up plugins
initializePlugins(patternlab);
- var paths = patternlab.config.paths;
+ const paths = patternlab.config.paths;
function getVersion() {
+ return patternlab.package.version;
+ }
+
+ function logVersion() {
console.log(patternlab.package.version);
}
@@ -277,12 +309,12 @@ var patternlab_engine = function (config) {
}
function listStarterkits() {
- var starterkit_manager = new sm(patternlab.config);
+ const starterkit_manager = new sm(patternlab.config);
return starterkit_manager.list_starterkits();
}
function loadStarterKit(starterkitName, clean) {
- var starterkit_manager = new sm(patternlab.config);
+ const starterkit_manager = new sm(patternlab.config);
starterkit_manager.load_starterkit(starterkitName, clean);
}
@@ -291,8 +323,8 @@ var patternlab_engine = function (config) {
*/
function processHeadPattern() {
try {
- var headPath = path.resolve(paths.source.meta, '_00-head.mustache');
- var headPattern = new Pattern(headPath, null, patternlab);
+ const headPath = path.resolve(paths.source.meta, '_00-head.mustache');
+ const headPattern = new Pattern(headPath, null, patternlab);
headPattern.template = fs.readFileSync(headPath, 'utf8');
headPattern.isPattern = false;
headPattern.isMetaPattern = true;
@@ -311,8 +343,8 @@ var patternlab_engine = function (config) {
*/
function processFootPattern() {
try {
- var footPath = path.resolve(paths.source.meta, '_01-foot.mustache');
- var footPattern = new Pattern(footPath, null, patternlab);
+ const footPath = path.resolve(paths.source.meta, '_01-foot.mustache');
+ const footPattern = new Pattern(footPath, null, patternlab);
footPattern.template = fs.readFileSync(footPath, 'utf8');
footPattern.isPattern = false;
footPattern.isMetaPattern = true;
@@ -376,19 +408,19 @@ var patternlab_engine = function (config) {
patternlab.events.emit('patternlab-pattern-before-data-merge', patternlab, pattern);
//render the pattern, but first consolidate any data we may have
- var allData;
+ let allData;
try {
allData = jsonCopy(patternlab.data, 'config.paths.source.data global data');
} catch (err) {
console.log('There was an error parsing JSON for ' + pattern.relPath);
console.log(err);
}
- allData = plutils.mergeData(allData, pattern.jsonFileData);
+ allData = _.merge(allData, pattern.jsonFileData);
allData.cacheBuster = patternlab.cacheBuster;
//re-rendering the headHTML each time allows pattern-specific data to influence the head of the pattern
pattern.header = head;
- var headHTML = pattern_assembler.renderPattern(pattern.header, allData);
+ const headHTML = pattern_assembler.renderPattern(pattern.header, allData);
//render the extendedTemplate with all data
pattern.patternPartialCode = pattern_assembler.renderPattern(pattern, allData);
@@ -428,23 +460,23 @@ var patternlab_engine = function (config) {
});
//set the pattern-specific footer by compiling the general-footer with data, and then adding it to the meta footer
- var footerPartial = pattern_assembler.renderPattern(patternlab.footer, {
+ const footerPartial = pattern_assembler.renderPattern(patternlab.footer, {
isPattern: pattern.isPattern,
patternData: pattern.patternData,
cacheBuster: patternlab.cacheBuster
});
- var allFooterData;
+ let allFooterData;
try {
allFooterData = jsonCopy(patternlab.data, 'config.paths.source.data global data');
} catch (err) {
console.log('There was an error parsing JSON for ' + pattern.relPath);
console.log(err);
}
- allFooterData = plutils.mergeData(allFooterData, pattern.jsonFileData);
+ allFooterData = _.merge(allFooterData, pattern.jsonFileData);
allFooterData.patternLabFoot = footerPartial;
- var footerHTML = pattern_assembler.renderPattern(patternlab.userFoot, allFooterData);
+ const footerHTML = pattern_assembler.renderPattern(patternlab.userFoot, allFooterData);
patternlab.events.emit('patternlab-pattern-write-begin', patternlab, pattern);
@@ -479,28 +511,35 @@ var patternlab_engine = function (config) {
function buildPatterns(deletePatternDir) {
+ if (patternlab.config.debug) {
+ console.log(
+ chalk.bold('\n====[ Pattern Lab / Node'),
+ `- v${packageInfo.version}`,
+ chalk.bold(']====\n')
+ );
+ }
+
patternlab.events.emit('patternlab-build-pattern-start', patternlab);
- let graph = patternlab.graph = loadPatternGraph(deletePatternDir);
+ const graph = patternlab.graph = loadPatternGraph(deletePatternDir);
- let graphNeedsUpgrade = !PatternGraph.checkVersion(graph);
+ const graphNeedsUpgrade = !PatternGraph.checkVersion(graph);
if (graphNeedsUpgrade) {
plutils.log.info("Due to an upgrade, a complete rebuild is required and the public/patterns directory was deleted. " +
- "Incremental build is available again on the next successful run.");
+ "Incremental build is available again on the next successful run.");
// Ensure that the freshly built graph has the latest version again.
patternlab.graph.upgradeVersion();
}
// Flags
- let incrementalBuildsEnabled = !(deletePatternDir || graphNeedsUpgrade);
+ const incrementalBuildsEnabled = !(deletePatternDir || graphNeedsUpgrade);
if (incrementalBuildsEnabled) {
plutils.log.info("Incremental builds enabled.");
} else {
// needs to be done BEFORE processing patterns
- fs.removeSync(paths.public.patterns);
fs.emptyDirSync(paths.public.patterns);
}
@@ -517,11 +556,11 @@ var patternlab_engine = function (config) {
patternlab.listitems = {};
}
try {
- patternlab.header = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'partials', 'general-header.mustache'), 'utf8');
- patternlab.footer = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'partials', 'general-footer.mustache'), 'utf8');
- patternlab.patternSection = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'partials', 'patternSection.mustache'), 'utf8');
- patternlab.patternSectionSubType = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'partials', 'patternSectionSubtype.mustache'), 'utf8');
- patternlab.viewAll = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'viewall.mustache'), 'utf8');
+ patternlab.header = fs.readFileSync(path.resolve(paths.source.patternlabFiles['general-header']), 'utf8');
+ patternlab.footer = fs.readFileSync(path.resolve(paths.source.patternlabFiles['general-footer']), 'utf8');
+ patternlab.patternSection = fs.readFileSync(path.resolve(paths.source.patternlabFiles.patternSection), 'utf8');
+ patternlab.patternSectionSubType = fs.readFileSync(path.resolve(paths.source.patternlabFiles.patternSectionSubtype), 'utf8');
+ patternlab.viewAll = fs.readFileSync(path.resolve(paths.source.patternlabFiles.viewall), 'utf8');
} catch (ex) {
console.log(ex);
plutils.error('\nERROR: missing an essential file from ' + paths.source.patternlabFiles + '. Pattern Lab won\'t work without this file.\n');
@@ -539,118 +578,224 @@ var patternlab_engine = function (config) {
patternlab.events.emit('patternlab-build-global-data-end', patternlab);
// diveSync once to perform iterative populating of patternlab object
- processAllPatternsIterative(pattern_assembler, paths.source.patterns, patternlab);
+ return processAllPatternsIterative(paths.source.patterns, patternlab).then(() => {
- patternlab.events.emit('patternlab-pattern-iteration-end', patternlab);
+ patternlab.events.emit('patternlab-pattern-iteration-end', patternlab);
- //now that all the main patterns are known, look for any links that might be within data and expand them
- //we need to do this before expanding patterns & partials into extendedTemplates, otherwise we could lose the data -> partial reference
- pattern_assembler.parse_data_links(patternlab);
+ //now that all the main patterns are known, look for any links that might be within data and expand them
+ //we need to do this before expanding patterns & partials into extendedTemplates, otherwise we could lose the data -> partial reference
+ pattern_assembler.parse_data_links(patternlab);
- //diveSync again to recursively include partials, filling out the
- //extendedTemplate property of the patternlab.patterns elements
- // TODO we can reduce the time needed by only processing changed patterns and their partials
- processAllPatternsRecursive(pattern_assembler, paths.source.patterns, patternlab);
+ //diveSync again to recursively include partials, filling out the
+ //extendedTemplate property of the patternlab.patterns elements
+ // TODO we can reduce the time needed by only processing changed patterns and their partials
+ processAllPatternsRecursive(paths.source.patterns, patternlab);
- //take the user defined head and foot and process any data and patterns that apply
- processHeadPattern();
- processFootPattern();
+ //take the user defined head and foot and process any data and patterns that apply
+ processHeadPattern();
+ processFootPattern();
- //cascade any patternStates
- lineage_hunter.cascade_pattern_states(patternlab);
+ //cascade any patternStates
+ lineage_hunter.cascade_pattern_states(patternlab);
- //set pattern-specific header if necessary
- var head;
- if (patternlab.userHead) {
- head = patternlab.userHead;
- } else {
- head = patternlab.header;
- }
-
- //set the pattern-specific header by compiling the general-header with data, and then adding it to the meta header
- patternlab.data.patternLabHead = pattern_assembler.renderPattern(patternlab.header, {
- cacheBuster: patternlab.cacheBuster
- });
-
- // If deletePatternDir == true or graph needs to be updated
- // rebuild all patterns
- let patternsToBuild = null;
+ //set pattern-specific header if necessary
+ let head;
+ if (patternlab.userHead) {
+ head = patternlab.userHead;
+ } else {
+ head = patternlab.header;
+ }
- if (incrementalBuildsEnabled) {
- // When the graph was loaded from file, some patterns might have been moved/deleted between runs
- // so the graph data become out of sync
- patternlab.graph.sync().forEach(n => {
- plutils.log.info("[Deleted/Moved] " + n);
+ //set the pattern-specific header by compiling the general-header with data, and then adding it to the meta header
+ patternlab.data.patternLabHead = pattern_assembler.renderPattern(patternlab.header, {
+ cacheBuster: patternlab.cacheBuster
});
- // TODO Find created or deleted files
- let now = new Date().getTime();
- pattern_assembler.mark_modified_patterns(now, patternlab);
- patternsToBuild = patternlab.graph.compileOrder();
- } else {
- // build all patterns, mark all to be rebuilt
- patternsToBuild = patternlab.patterns;
- for (let p of patternsToBuild) {
- p.compileState = CompileState.NEEDS_REBUILD;
+ // If deletePatternDir == true or graph needs to be updated
+ // rebuild all patterns
+ let patternsToBuild = null;
+
+ // If deletePatternDir == true or graph needs to be updated
+ // rebuild all patterns
+ patternsToBuild = null;
+
+ if (incrementalBuildsEnabled) {
+ // When the graph was loaded from file, some patterns might have been moved/deleted between runs
+ // so the graph data become out of sync
+ patternlab.graph.sync().forEach(n => {
+ plutils.log.info("[Deleted/Moved] " + n);
+ });
+
+ // TODO Find created or deleted files
+ const now = new Date().getTime();
+ pattern_assembler.mark_modified_patterns(now, patternlab);
+ patternsToBuild = patternlab.graph.compileOrder();
+ } else {
+ // build all patterns, mark all to be rebuilt
+ patternsToBuild = patternlab.patterns;
+ for (const p of patternsToBuild) {
+ p.compileState = CompileState.NEEDS_REBUILD;
+ }
}
- }
- //render all patterns last, so lineageR works
- patternsToBuild.forEach(pattern => renderSinglePattern(pattern, head));
+ //render all patterns last, so lineageR works
+ patternsToBuild.forEach(pattern => renderSinglePattern(pattern, head));
- // Saves the pattern graph when all files have been compiled
- PatternGraph.storeToFile(patternlab);
- if (patternlab.config.exportToGraphViz) {
- PatternGraph.exportToDot(patternlab, "dependencyGraph.dot");
- plutils.log.info(`Exported pattern graph to ${path.join(config.paths.public.root, "dependencyGraph.dot")}`);
- }
+ // Saves the pattern graph when all files have been compiled
+ PatternGraph.storeToFile(patternlab);
+ if (patternlab.config.exportToGraphViz) {
+ PatternGraph.exportToDot(patternlab, "dependencyGraph.dot");
+ plutils.log.info(`Exported pattern graph to ${path.join(config.paths.public.root, "dependencyGraph.dot")}`);
+ }
- //export patterns if necessary
- pattern_exporter.export_patterns(patternlab);
+ //export patterns if necessary
+ pattern_exporter.export_patterns(patternlab);
+ }).catch((err) => {
+ console.log('Error in buildPatterns():', err);
+ });
}
return {
+ /**
+ * logs current version
+ *
+ * @returns {void} current patternlab-node version as defined in package.json, as console output
+ */
version: function () {
+ return logVersion();
+ },
+
+ /**
+ * return current version
+ *
+ * @returns {string} current patternlab-node version as defined in package.json, as string
+ */
+ v: function () {
return getVersion();
},
- build: function (callback, deletePatternDir) {
+
+ /**
+ * build patterns, copy assets, and construct ui
+ *
+ * @param {function} callback a function invoked when build is complete
+ * @param {object} options an object used to control build behavior
+ * @returns {Promise} a promise fulfilled when build is complete
+ */
+ build: function (callback, options) {
if (patternlab && patternlab.isBusy) {
console.log('Pattern Lab is busy building a previous run - returning early.');
- return;
+ return Promise.resolve();
}
patternlab.isBusy = true;
- buildPatterns(deletePatternDir);
- ui_builder.buildFrontend(patternlab);
- printDebug();
- patternlab.isBusy = false;
- callback();
+ return buildPatterns(options.cleanPublic).then(() => {
+
+ new ui_builder().buildFrontend(patternlab);
+ assetCopier().copyAssets(patternlab.config.paths, patternlab, options);
+
+ this.events.on('patternlab-pattern-change', () => {
+ if (!patternlab.isBusy) {
+ options.cleanPublic = false;
+ return this.build(callback, options);
+ }
+ return Promise.resolve();
+ });
+
+ this.events.on('patternlab-global-change', () => {
+ if (!patternlab.isBusy) {
+ options.cleanPublic = true; //rebuild everything
+ return this.build(callback, options);
+ }
+ return Promise.resolve();
+ });
+
+ printDebug();
+ patternlab.isBusy = false;
+ callback();
+ });
},
+
+ /**
+ * logs usage
+ *
+ * @returns {void} pattern lab API usage, as console output
+ */
help: function () {
help();
},
- patternsonly: function (callback, deletePatternDir) {
+
+ /**
+ * build patterns only, leaving existing public files intact
+ *
+ * @param {function} callback a function invoked when build is complete
+ * @param {object} options an object used to control build behavior
+ * @returns {Promise} a promise fulfilled when build is complete
+ */
+ patternsonly: function (callback, options) {
if (patternlab && patternlab.isBusy) {
console.log('Pattern Lab is busy building a previous run - returning early.');
- return;
+ return Promise.resolve();
}
patternlab.isBusy = true;
- buildPatterns(deletePatternDir);
- printDebug();
- patternlab.isBusy = false;
- callback();
+ return buildPatterns(options.cleanPublic).then(() => {
+ printDebug();
+ patternlab.isBusy = false;
+ callback();
+ });
},
+
+ /**
+ * fetches starterkit repos from pattern-lab github org that contain 'starterkit' in their name
+ *
+ * @returns {Promise} Returns an Array<{name,url}> for the starterkit repos
+ */
liststarterkits: function () {
return listStarterkits();
},
+
+ /**
+ * load starterkit already available via `node_modules/`
+ *
+ * @param {string} starterkitName name of starterkit
+ * @param {boolean} clean whether or not to delete contents of source/ before load
+ * @returns {void}
+ */
loadstarterkit: function (starterkitName, clean) {
loadStarterKit(starterkitName, clean);
},
+
+
+ /**
+ * install plugin already available via `node_modules/`
+ *
+ * @param {string} pluginName name of plugin
+ * @returns {void}
+ */
installplugin: function (pluginName) {
installPlugin(pluginName);
},
+
+ /**
+ * returns all file extensions supported by installed PatternEngines
+ *
+ * @returns {Array} all supported file extensions
+ */
getSupportedTemplateExtensions: function () {
return getSupportedTemplateExtensions();
- }
+ },
+
+ /**
+ * build patterns, copy assets, and construct ui, watch source files, and serve locally
+ *
+ * @param {object} options an object used to control build, copy, and serve behavior
+ * @returns {Promise} TODO: validate
+ */
+ serve: function (options) {
+ options.watch = true;
+ return this.build(() => {}, options).then(function () {
+ serve(patternlab);
+ });
+ },
+ events: patternlab.events
};
};
diff --git a/core/lib/plugin_manager.js b/core/lib/plugin_manager.js
index 3cac4fd69..e636dd4a5 100644
--- a/core/lib/plugin_manager.js
+++ b/core/lib/plugin_manager.js
@@ -1,9 +1,9 @@
"use strict";
-var plugin_manager = function (config, configPath) {
- var path = require('path'),
- fs = require('fs-extra'),
- util = require('./utilities');
+const plugin_manager = function (config, configPath) {
+ const path = require('path');
+ const fs = require('fs-extra');
+ const util = require('./utilities');
/**
* Loads a plugin
@@ -22,7 +22,7 @@ var plugin_manager = function (config, configPath) {
*/
function installPlugin(pluginName) {
try {
- var pluginPath = path.resolve(
+ const pluginPath = path.resolve(
path.join(process.cwd(), 'node_modules', pluginName)
);
console.log('Attempting to load plugin from', pluginPath);
@@ -33,10 +33,10 @@ var plugin_manager = function (config, configPath) {
util.error(pluginName + ' not loaded.');
return;
}
- var pluginPathDirExists = pluginDirStats.isDirectory();
+ const pluginPathDirExists = pluginDirStats.isDirectory();
if (pluginPathDirExists) {
- var diskConfig = fs.readJSONSync(path.resolve(configPath), 'utf8');
+ const diskConfig = fs.readJSONSync(path.resolve(configPath), 'utf8');
//add the plugin entry to patternlab-config.json
if (!diskConfig.plugins) {
@@ -79,9 +79,9 @@ var plugin_manager = function (config, configPath) {
* @return {array} list of installed plugins
*/
function detectPlugins() {
- var node_modules_path = path.join(process.cwd(), 'node_modules');
+ const node_modules_path = path.join(process.cwd(), 'node_modules');
return fs.readdirSync(node_modules_path).filter(function (dir) {
- var module_path = path.join(process.cwd(), 'node_modules', dir);
+ const module_path = path.join(process.cwd(), 'node_modules', dir);
return fs.statSync(module_path).isDirectory() && dir.indexOf('plugin-node-') === 0;
});
}
diff --git a/core/lib/pseudopattern_hunter.js b/core/lib/pseudopattern_hunter.js
index fbcca89ad..debae2d8c 100644
--- a/core/lib/pseudopattern_hunter.js
+++ b/core/lib/pseudopattern_hunter.js
@@ -1,94 +1,136 @@
"use strict";
-var ch = require('./changes_hunter');
-
-var pseudopattern_hunter = function () {
-
- function findpseudopatterns(currentPattern, patternlab) {
- var glob = require('glob'),
- fs = require('fs-extra'),
- pa = require('./pattern_assembler'),
- lh = require('./lineage_hunter'),
- Pattern = require('./object_factory').Pattern,
- plutils = require('./utilities'),
- path = require('path');
-
-
- var pattern_assembler = new pa();
- var lineage_hunter = new lh();
- var changes_hunter = new ch();
- var paths = patternlab.config.paths;
-
- //look for a pseudo pattern by checking if there is a file containing same
- //name, with ~ in it, ending in .json
- var needle = currentPattern.subdir + '/' + currentPattern.fileName + '~*.json';
- var pseudoPatterns = glob.sync(needle, {
- cwd: paths.source.patterns,
- debug: false,
- nodir: true
- });
-
- if (pseudoPatterns.length > 0) {
- for (var i = 0; i < pseudoPatterns.length; i++) {
- if (patternlab.config.debug) {
- console.log('found pseudoPattern variant of ' + currentPattern.patternPartial);
- }
-
- //we want to do everything we normally would here, except instead read the pseudoPattern data
- try {
- var variantFileFullPath = path.resolve(paths.source.patterns, pseudoPatterns[i]);
- var variantFileData = fs.readJSONSync(variantFileFullPath);
- } catch (err) {
- console.log('There was an error parsing pseudopattern JSON for ' + currentPattern.relPath);
- console.log(err);
- }
-
- //extend any existing data with variant data
- variantFileData = plutils.mergeData(currentPattern.jsonFileData, variantFileData);
-
- var variantName = pseudoPatterns[i].substring(pseudoPatterns[i].indexOf('~') + 1).split('.')[0];
- var variantFilePath = path.join(currentPattern.subdir, currentPattern.fileName + '~' + variantName + '.json');
- var lm = fs.statSync(variantFileFullPath);
- var patternVariant = Pattern.create(variantFilePath, variantFileData, {
- //use the same template as the non-variant
- template: currentPattern.template,
- fileExtension: currentPattern.fileExtension,
- extendedTemplate: currentPattern.extendedTemplate,
- isPseudoPattern: true,
- basePattern: currentPattern,
- stylePartials: currentPattern.stylePartials,
- parameteredPartials: currentPattern.parameteredPartials,
-
- // Only regular patterns are discovered during iterative walks
- // Need to recompile on data change or template change
- lastModified: Math.max(currentPattern.lastModified, lm.mtime),
-
- // use the same template engine as the non-variant
- engine: currentPattern.engine
- }, patternlab);
-
- changes_hunter.checkBuildState(patternVariant, patternlab);
- patternlab.graph.add(patternVariant);
- patternlab.graph.link(patternVariant, currentPattern);
-
- //process the companion markdown file if it exists
- pattern_assembler.parse_pattern_markdown(patternVariant, patternlab);
-
- //find pattern lineage
- lineage_hunter.find_lineage(patternVariant, patternlab);
-
- //add to patternlab object so we can look these up later.
- pattern_assembler.addPattern(patternVariant, patternlab);
+const ch = require('./changes_hunter');
+const glob = require('glob');
+const fs = require('fs-extra');
+const _ = require('lodash');
+const lh = require('./lineage_hunter');
+const Pattern = require('./object_factory').Pattern;
+const path = require('path');
+const lineage_hunter = new lh();
+const changes_hunter = new ch();
+
+const pseudopattern_hunter = function () {};
+
+pseudopattern_hunter.prototype.find_pseudopatterns = function (currentPattern, patternlab) {
+ const pa = require('./pattern_assembler');
+ const pattern_assembler = new pa();
+
+ const paths = patternlab.config.paths;
+
+ //look for a pseudo pattern by checking if there is a file containing same
+ //name, with ~ in it, ending in .json
+ const needle = currentPattern.subdir + '/' + currentPattern.fileName + '~*.json';
+ const pseudoPatterns = glob.sync(needle, {
+ cwd: paths.source.patterns,
+ debug: false,
+ nodir: true
+ });
+
+ if (pseudoPatterns.length > 0) {
+ for (let i = 0; i < pseudoPatterns.length; i++) {
+ if (patternlab.config.debug) {
+ console.log('found pseudoPattern variant of ' + currentPattern.patternPartial);
+ }
+
+ //we want to do everything we normally would here, except instead read the pseudoPattern data
+ try {
+ var variantFileFullPath = path.resolve(paths.source.patterns, pseudoPatterns[i]);
+ var variantFileData = fs.readJSONSync(variantFileFullPath);
+ } catch (err) {
+ console.log('There was an error parsing pseudopattern JSON for ' + currentPattern.relPath);
+ console.log(err);
}
- }
- }
- return {
- find_pseudopatterns: function (pattern, patternlab) {
- findpseudopatterns(pattern, patternlab);
+ //extend any existing data with variant data
+ variantFileData = _.merge(currentPattern.jsonFileData, variantFileData);
+
+ let variantName = pseudoPatterns[i].substring(pseudoPatterns[i].indexOf('~') + 1).split('.')[0];
+ let variantFilePath = path.join(currentPattern.subdir, currentPattern.fileName + '~' + variantName + '.json');
+ let lm = fs.statSync(variantFileFullPath);
+ let patternVariant = Pattern.create(variantFilePath, variantFileData, {
+ //use the same template as the non-variant
+ template: currentPattern.template,
+ fileExtension: currentPattern.fileExtension,
+ extendedTemplate: currentPattern.extendedTemplate,
+ isPseudoPattern: true,
+ basePattern: currentPattern,
+ stylePartials: currentPattern.stylePartials,
+ parameteredPartials: currentPattern.parameteredPartials,
+
+ // Only regular patterns are discovered during iterative walks
+ // Need to recompile on data change or template change
+ lastModified: Math.max(currentPattern.lastModified, lm.mtime),
+
+ // use the same template engine as the non-variant
+ engine: currentPattern.engine
+ }, patternlab);
+
+ changes_hunter.checkBuildState(patternVariant, patternlab);
+ patternlab.graph.add(patternVariant);
+ patternlab.graph.link(patternVariant, currentPattern);
+
+ //process the companion markdown file if it exists
+ pattern_assembler.parse_pattern_markdown(patternVariant, patternlab);
+
+ //find pattern lineage
+ lineage_hunter.find_lineage(patternVariant, patternlab);
+
+ //add to patternlab object so we can look these up later.
+ pattern_assembler.addPattern(patternVariant, patternlab);
+
+ //we want to do everything we normally would here, except instead read the pseudoPattern data
+ try {
+ var variantFileFullPath = path.resolve(paths.source.patterns, pseudoPatterns[i]);
+ var variantFileData = fs.readJSONSync(variantFileFullPath);
+ } catch (err) {
+ console.log('There was an error parsing pseudopattern JSON for ' + currentPattern.relPath);
+ console.log(err);
+ }
+
+ //extend any existing data with variant data
+ variantFileData = _.merge(currentPattern.jsonFileData, variantFileData);
+
+ variantName = pseudoPatterns[i].substring(pseudoPatterns[i].indexOf('~') + 1).split('.')[0];
+ variantFilePath = path.join(currentPattern.subdir, currentPattern.fileName + '~' + variantName + '.json');
+ lm = fs.statSync(variantFileFullPath);
+ patternVariant = Pattern.create(variantFilePath, variantFileData, {
+ //use the same template as the non-variant
+ template: currentPattern.template,
+ fileExtension: currentPattern.fileExtension,
+ extendedTemplate: currentPattern.extendedTemplate,
+ isPseudoPattern: true,
+ basePattern: currentPattern,
+ stylePartials: currentPattern.stylePartials,
+ parameteredPartials: currentPattern.parameteredPartials,
+
+ // Only regular patterns are discovered during iterative walks
+ // Need to recompile on data change or template change
+ lastModified: Math.max(currentPattern.lastModified, lm.mtime),
+
+ // use the same template engine as the non-variant
+ engine: currentPattern.engine
+ }, patternlab);
+
+ changes_hunter.checkBuildState(patternVariant, patternlab);
+ patternlab.graph.add(patternVariant);
+ patternlab.graph.link(patternVariant, currentPattern);
+
+ //process the companion markdown file if it exists
+ pattern_assembler.parse_pattern_markdown(patternVariant, patternlab);
+
+ //find pattern lineage
+ lineage_hunter.find_lineage(patternVariant, patternlab);
+
+ //add to patternlab object so we can look these up later.
+ pattern_assembler.addPattern(patternVariant, patternlab);
}
- };
+ // GTP: this is to emulate the behavior of the stale asynced
+ // version; when we have time, we can make all the FS calls in here
+ // async and see if it helps any, but it didn't when I tried it.
+ }
+ return Promise.resolve();
};
-module.exports = pseudopattern_hunter;
+module.exports = new pseudopattern_hunter();
diff --git a/core/lib/serve.js b/core/lib/serve.js
new file mode 100644
index 000000000..a773acde9
--- /dev/null
+++ b/core/lib/serve.js
@@ -0,0 +1,39 @@
+"use strict";
+const path = require('path');
+const liveServer = require('live-server');
+
+const serve = (patternlab) => {
+
+ // our default liveserver config
+ const defaults = {
+ root: patternlab.config.paths.public.root,
+ open: true,
+ ignore: path.join(path.resolve(patternlab.config.paths.public.root)),
+ file: 'index.html',
+ logLevel: 0, // errors only
+ wait: 1000
+ };
+
+ // allow for overrides should they exist inside patternlab-config.json
+ const liveServerConfig = Object.assign({}, defaults, patternlab.config.serverOptions);
+
+ // watch for asset changes, and reload appropriately
+ patternlab.events.on('patternlab-asset-change', (data) => {
+ if (data.file.indexOf('css') > -1) {
+ liveServer.refreshCSS();
+ } else {
+ liveServer.reload();
+ }
+ });
+
+ //watch for pattern changes, and reload
+ patternlab.events.on('patternlab-pattern-change', () => {
+ liveServer.reload();
+ });
+
+ //start!
+ liveServer.start(liveServerConfig);
+
+};
+
+module.exports = serve;
diff --git a/core/lib/starterkit_manager.js b/core/lib/starterkit_manager.js
index 77fbf91a2..2498580b9 100644
--- a/core/lib/starterkit_manager.js
+++ b/core/lib/starterkit_manager.js
@@ -1,11 +1,11 @@
"use strict";
-var starterkit_manager = function (config) {
- var path = require('path'),
- fetch = require('node-fetch'),
- fs = require('fs-extra'),
- util = require('./utilities'),
- paths = config.paths;
+const starterkit_manager = function (config) {
+ const path = require('path');
+ const fetch = require('node-fetch');
+ const fs = require('fs-extra');
+ const util = require('./utilities');
+ const paths = config.paths;
/**
* Loads npm module identified by the starterkitName parameter.
@@ -15,7 +15,7 @@ var starterkit_manager = function (config) {
*/
function loadStarterKit(starterkitName, clean) {
try {
- var kitPath = path.resolve(
+ const kitPath = path.resolve(
path.join(process.cwd(), 'node_modules', starterkitName, config.starterkitSubDir)
);
console.log('Attempting to load starterkit from', kitPath);
@@ -26,12 +26,12 @@ var starterkit_manager = function (config) {
util.error(starterkitName + ' not loaded.');
return;
}
- var kitPathDirExists = kitDirStats.isDirectory();
+ const kitPathDirExists = kitDirStats.isDirectory();
if (kitPathDirExists) {
if (clean) {
console.log('Deleting contents of', paths.source.root, 'prior to starterkit load.');
- util.emptyDirectory(paths.source.root);
+ fs.emptyDirSync(paths.source.root);
} else {
console.log('Overwriting contents of', paths.source.root, 'during starterkit load.');
}
@@ -61,7 +61,7 @@ var starterkit_manager = function (config) {
'Accept': 'application/json'
}
}).then(function (res) {
- var contentType = res.headers.get('content-type');
+ const contentType = res.headers.get('content-type');
if (contentType && contentType.indexOf('application/json') === -1) {
throw new TypeError("StarterkitManager->listStarterkits: Not valid JSON");
}
@@ -90,9 +90,9 @@ var starterkit_manager = function (config) {
* @return {array} List of starter kits installed
*/
function detectStarterKits() {
- var node_modules_path = path.join(process.cwd(), 'node_modules');
- var npm_modules = fs.readdirSync(node_modules_path).filter(function (dir) {
- var module_path = path.join(process.cwd(), 'node_modules', dir);
+ const node_modules_path = path.join(process.cwd(), 'node_modules');
+ const npm_modules = fs.readdirSync(node_modules_path).filter(function (dir) {
+ const module_path = path.join(process.cwd(), 'node_modules', dir);
return fs.statSync(module_path).isDirectory() && dir.indexOf('starterkit-') === 0;
});
return npm_modules;
diff --git a/core/lib/style_modifier_hunter.js b/core/lib/style_modifier_hunter.js
index f6f9f0596..af50fb155 100644
--- a/core/lib/style_modifier_hunter.js
+++ b/core/lib/style_modifier_hunter.js
@@ -1,6 +1,6 @@
"use strict";
-var style_modifier_hunter = function () {
+const style_modifier_hunter = function () {
/**
* Modifies a patterns partial with any styleModifiers found on the supplied partial
@@ -11,7 +11,7 @@ var style_modifier_hunter = function () {
*/
function consumestylemodifier(pattern, partial, patternlab) {
//extract the classname from the stylemodifier which comes in the format of :className
- var styleModifier = partial.match(/:([\w\-_|])+/g) ? partial.match(/:([\w\-_|])+/g)[0].slice(1) : null;
+ let styleModifier = partial.match(/:([\w\-_|])+/g) ? partial.match(/:([\w\-_|])+/g)[0].slice(1) : null;
if (styleModifier) {
//replace the special character pipe | used to separate multiple classes with a space
diff --git a/core/lib/ui_builder.js b/core/lib/ui_builder.js
index 2df7218f0..6c2807467 100644
--- a/core/lib/ui_builder.js
+++ b/core/lib/ui_builder.js
@@ -1,17 +1,19 @@
"use strict";
-var path = require('path');
-var fs = require('fs-extra');
-var ae = require('./annotation_exporter');
-var of = require('./object_factory');
-var Pattern = of.Pattern;
-var pattern_assembler = require('./pattern_assembler')();
-var plutils = require('./utilities');
-var eol = require('os').EOL;
-var _ = require('lodash');
-var jsonCopy = require('./json_copy');
-
-var ui_builder = function () {
+const path = require('path');
+const jsonCopy = require('./json_copy');
+const ae = require('./annotation_exporter');
+const of = require('./object_factory');
+const Pattern = of.Pattern;
+const plutils = require('./utilities');
+const eol = require('os').EOL;
+const _ = require('lodash');
+
+//these are mocked in unit tests, so let them be overridden
+let fs = require('fs-extra'); //eslint-disable-line prefer-const
+let pattern_assembler = require('./pattern_assembler')(); //eslint-disable-line prefer-const
+
+const ui_builder = function () {
/**
* Registers the pattern to the patternPaths object for the appropriate patternGroup and basename
@@ -60,7 +62,7 @@ var ui_builder = function () {
* @returns boolean - whether or not the pattern is excluded
*/
function isPatternExcluded(pattern, patternlab) {
- var isOmitted;
+ let isOmitted;
// skip underscore-prefixed files
isOmitted = pattern.isPattern && pattern.fileName.charAt(0) === '_';
@@ -112,7 +114,7 @@ var ui_builder = function () {
*/
function injectDocumentationBlock(pattern, patternlab, isSubtypePattern) {
//first see if pattern_assembler processed one already
- var docPattern = patternlab.subtypePatterns[pattern.patternGroup + (isSubtypePattern ? '-' + pattern.patternSubGroup : '')];
+ let docPattern = patternlab.subtypePatterns[pattern.patternGroup + (isSubtypePattern ? '-' + pattern.patternSubGroup : '')];
if (docPattern) {
docPattern.isDocPattern = true;
docPattern.order = -Number.MAX_SAFE_INTEGER;
@@ -164,7 +166,7 @@ var ui_builder = function () {
* @returns the found pattern type object
*/
function getPatternType(patternlab, pattern) {
- var patternType = _.find(patternlab.patternTypes, ['patternType', pattern.patternType]);
+ const patternType = _.find(patternlab.patternTypes, ['patternType', pattern.patternType]);
if (!patternType) {
plutils.error('Could not find patternType' + pattern.patternType + '. This is a critical error.');
@@ -182,8 +184,8 @@ var ui_builder = function () {
* @returns the found patternSubType object
*/
function getPatternSubType(patternlab, pattern) {
- var patternType = getPatternType(patternlab, pattern);
- var patternSubType = _.find(patternType.patternTypeItems, ['patternSubtype', pattern.patternSubType]);
+ const patternType = getPatternType(patternlab, pattern);
+ const patternSubType = _.find(patternType.patternTypeItems, ['patternSubtype', pattern.patternSubType]);
if (!patternSubType) {
plutils.error('Could not find patternType ' + pattern.patternType + '-' + pattern.patternType + '. This is a critical error.');
@@ -201,15 +203,15 @@ var ui_builder = function () {
* @param pattern - the pattern to register
*/
function addPatternSubType(patternlab, pattern) {
- let newSubType = {
+ const newSubType = {
patternSubtypeLC: pattern.patternSubGroup.toLowerCase(),
patternSubtypeUC: pattern.patternSubGroup.charAt(0).toUpperCase() + pattern.patternSubGroup.slice(1),
patternSubtype: pattern.patternSubType,
patternSubtypeDash: pattern.patternSubGroup, //todo verify
patternSubtypeItems: []
};
- var patternType = getPatternType(patternlab, pattern);
- let insertIndex = _.sortedIndexBy(patternType.patternTypeItems, newSubType, 'patternSubtype');
+ const patternType = getPatternType(patternlab, pattern);
+ const insertIndex = _.sortedIndexBy(patternType.patternTypeItems, newSubType, 'patternSubtype');
patternType.patternTypeItems.splice(insertIndex, 0, newSubType);
}
@@ -220,7 +222,7 @@ var ui_builder = function () {
* @returns {{patternPartial: string, patternName: (*|string), patternState: string, patternSrcPath: string, patternPath: string}}
*/
function createPatternSubTypeItem(pattern) {
- var patternPath = '';
+ let patternPath = '';
if (pattern.isFlatPattern) {
patternPath = pattern.flatPatternPath + '-' + pattern.fileName + '/' + pattern.flatPatternPath + '-' + pattern.fileName + '.html';
} else {
@@ -261,7 +263,7 @@ var ui_builder = function () {
newSubTypeItem = createPatternSubTypeItem(pattern);
}
- let patternSubType = getPatternSubType(patternlab, pattern);
+ const patternSubType = getPatternSubType(patternlab, pattern);
patternSubType.patternSubtypeItems.push(newSubTypeItem);
patternSubType.patternSubtypeItems = _.sortBy(patternSubType.patternSubtypeItems, ['order', 'name']);
}
@@ -272,7 +274,7 @@ var ui_builder = function () {
* @param pattern - the pattern to add
*/
function addPatternItem(patternlab, pattern, isViewAllVariant) {
- var patternType = getPatternType(patternlab, pattern);
+ const patternType = getPatternType(patternlab, pattern);
if (!patternType) {
plutils.error('Could not find patternType' + pattern.patternType + '. This is a critical error.');
console.trace();
@@ -317,7 +319,7 @@ var ui_builder = function () {
return patternsArray.sort(function (a, b) {
let aOrder = parseInt(a.order, 10);
- let bOrder = parseInt(b.order, 10);
+ const bOrder = parseInt(b.order, 10);
if (aOrder === NaN) {
aOrder = Number.MAX_SAFE_INTEGER;
@@ -367,7 +369,7 @@ var ui_builder = function () {
* @returns ptterns grouped by type -> subtype like atoms -> global -> pattern, pattern, pattern
*/
function groupPatterns(patternlab) {
- var groupedPatterns = {
+ const groupedPatterns = {
patternGroups: {}
};
@@ -426,14 +428,14 @@ var ui_builder = function () {
*/
function buildFooterHTML(patternlab, patternPartial) {
//first render the general footer
- var footerPartial = pattern_assembler.renderPattern(patternlab.footer, {
+ const footerPartial = pattern_assembler.renderPattern(patternlab.footer, {
patternData: JSON.stringify({
patternPartial: patternPartial,
}),
cacheBuster: patternlab.cacheBuster
});
- var allFooterData;
+ let allFooterData;
try {
allFooterData = jsonCopy(patternlab.data, 'config.paths.source.data plus patterns data');
} catch (err) {
@@ -443,7 +445,7 @@ var ui_builder = function () {
allFooterData.patternLabFoot = footerPartial;
//then add it to the user footer
- var footerHTML = pattern_assembler.renderPattern(patternlab.userFoot, allFooterData);
+ const footerHTML = pattern_assembler.renderPattern(patternlab.userFoot, allFooterData);
return footerHTML;
}
@@ -456,7 +458,7 @@ var ui_builder = function () {
* @returns HTML
*/
function buildViewAllHTML(patternlab, patterns, patternPartial) {
- var viewAllHTML = pattern_assembler.renderPattern(patternlab.viewAll,
+ const viewAllHTML = pattern_assembler.renderPattern(patternlab.viewAll,
{
partials: patterns,
patternPartial: 'viewall-' + patternPartial,
@@ -476,20 +478,21 @@ var ui_builder = function () {
* @returns every built pattern and set of viewall patterns, so the styleguide can use it
*/
function buildViewAllPages(mainPageHeadHtml, patternlab, styleguidePatterns) {
- var paths = patternlab.config.paths;
- var patterns = [];
- var writeViewAllFile = true;
+ const paths = patternlab.config.paths;
+ let patterns = [];
+ let writeViewAllFile = true;
//loop through the grouped styleguide patterns, building at each level
_.forEach(styleguidePatterns.patternGroups, function (patternTypeObj, patternType) {
- var p;
- var typePatterns = [], styleguideTypePatterns = [];
- var styleGuideExcludes = patternlab.config.styleGuideExcludes || patternlab.config.styleguideExcludes;
+ let p;
+ let typePatterns = [];
+ let styleguideTypePatterns = [];
+ const styleGuideExcludes = patternlab.config.styleGuideExcludes || patternlab.config.styleguideExcludes;
_.forOwn(patternTypeObj, function (patternSubtypes, patternSubtype) {
- var patternPartial = patternType + '-' + patternSubtype;
+ const patternPartial = patternType + '-' + patternSubtype;
//do not create a viewall page for flat patterns
if (patternType === patternSubtype) {
@@ -498,10 +501,10 @@ var ui_builder = function () {
}
//render the footer needed for the viewall template
- var footerHTML = buildFooterHTML(patternlab, 'viewall-' + patternPartial);
+ const footerHTML = buildFooterHTML(patternlab, 'viewall-' + patternPartial);
//render the viewall template by finding these smallest subtype-grouped patterns
- var subtypePatterns = sortPatterns(_.values(patternSubtypes));
+ const subtypePatterns = sortPatterns(_.values(patternSubtypes));
//determine if we should write at this time by checking if these are flat patterns or grouped patterns
p = _.find(subtypePatterns, function (pat) {
@@ -523,7 +526,7 @@ var ui_builder = function () {
typePatterns = typePatterns.concat(subtypePatterns);
- var viewAllHTML = buildViewAllHTML(patternlab, subtypePatterns, patternPartial);
+ const viewAllHTML = buildViewAllHTML(patternlab, subtypePatterns, patternPartial);
fs.outputFileSync(paths.public.patterns + p.flatPatternPath + '/index.html', mainPageHeadHtml + viewAllHTML + footerHTML);
});
@@ -533,22 +536,22 @@ var ui_builder = function () {
}
//render the footer needed for the viewall template
- var footerHTML = buildFooterHTML(patternlab, 'viewall-' + patternType + '-all');
+ const footerHTML = buildFooterHTML(patternlab, 'viewall-' + patternType + '-all');
//add any flat patterns
//todo this isn't quite working yet
//typePatterns = typePatterns.concat(getPatternItems(patternlab, patternType));
//get the appropriate patternType
- var anyPatternOfType = _.find(typePatterns, function (pat) {
+ const anyPatternOfType = _.find(typePatterns, function (pat) {
return pat.patternType && pat.patternType !== '';});
//render the viewall template for the type
- var viewAllHTML = buildViewAllHTML(patternlab, typePatterns, patternType);
+ const viewAllHTML = buildViewAllHTML(patternlab, typePatterns, patternType);
fs.outputFileSync(paths.public.patterns + anyPatternOfType.patternType + '/index.html', mainPageHeadHtml + viewAllHTML + footerHTML);
//determine if we should omit this patterntype completely from the viewall page
- var omitPatternType = styleGuideExcludes && styleGuideExcludes.length
+ const omitPatternType = styleGuideExcludes && styleGuideExcludes.length
&& _.some(styleGuideExcludes, function (exclude) {
return exclude === patternType;
});
@@ -568,11 +571,11 @@ var ui_builder = function () {
* @param patternlab - global data store
*/
function exportData(patternlab) {
- var annotation_exporter = new ae(patternlab);
- var paths = patternlab.config.paths;
+ const annotation_exporter = new ae(patternlab);
+ const paths = patternlab.config.paths;
//write out the data
- var output = '';
+ let output = '';
//config
output += 'var config = ' + JSON.stringify(patternlab.config) + ';\n';
@@ -592,9 +595,6 @@ var ui_builder = function () {
//plugins
output += 'var plugins = ' + JSON.stringify(patternlab.plugins || []) + ';' + eol;
- //theme
- output += 'var theme = ' + JSON.stringify(patternlab.config.theme) + ';' + eol;
-
//smaller config elements
output += 'var defaultShowPatternInfo = ' + (patternlab.config.defaultShowPatternInfo ? patternlab.config.defaultShowPatternInfo : 'false') + ';' + eol;
output += 'var defaultPattern = "' + (patternlab.config.defaultPattern ? patternlab.config.defaultPattern : 'all') + '";' + eol;
@@ -603,8 +603,8 @@ var ui_builder = function () {
fs.outputFileSync(path.resolve(paths.public.data, 'patternlab-data.js'), output);
//annotations
- var annotationsJSON = annotation_exporter.gather();
- var annotations = 'var comments = { "comments" : ' + JSON.stringify(annotationsJSON) + '};';
+ const annotationsJSON = annotation_exporter.gather();
+ const annotations = 'var comments = { "comments" : ' + JSON.stringify(annotationsJSON) + '};';
fs.outputFileSync(path.resolve(paths.public.annotations, 'annotations.js'), annotations);
}
@@ -625,31 +625,31 @@ var ui_builder = function () {
resetUIBuilderState(patternlab);
- var paths = patternlab.config.paths;
+ const paths = patternlab.config.paths;
//determine which patterns should be included in the front-end rendering
- var styleguidePatterns = groupPatterns(patternlab);
+ const styleguidePatterns = groupPatterns(patternlab);
//set the pattern-specific header by compiling the general-header with data, and then adding it to the meta header
- var headerPartial = pattern_assembler.renderPattern(patternlab.header, {
+ const headerPartial = pattern_assembler.renderPattern(patternlab.header, {
cacheBuster: patternlab.cacheBuster
});
- var headFootData = patternlab.data;
+ const headFootData = patternlab.data;
headFootData.patternLabHead = headerPartial;
headFootData.cacheBuster = patternlab.cacheBuster;
- var headerHTML = pattern_assembler.renderPattern(patternlab.userHead, headFootData);
+ const headerHTML = pattern_assembler.renderPattern(patternlab.userHead, headFootData);
//set the pattern-specific footer by compiling the general-footer with data, and then adding it to the meta footer
- var footerPartial = pattern_assembler.renderPattern(patternlab.footer, {
+ const footerPartial = pattern_assembler.renderPattern(patternlab.footer, {
patternData: '{}',
cacheBuster: patternlab.cacheBuster
});
headFootData.patternLabFoot = footerPartial;
- var footerHTML = pattern_assembler.renderPattern(patternlab.userFoot, headFootData);
+ const footerHTML = pattern_assembler.renderPattern(patternlab.userFoot, headFootData);
//build the viewall pages
- var allPatterns = buildViewAllPages(headerHTML, patternlab, styleguidePatterns);
+ const allPatterns = buildViewAllPages(headerHTML, patternlab, styleguidePatterns);
//add the defaultPattern if we found one
if (patternlab.defaultPattern) {
@@ -658,7 +658,7 @@ var ui_builder = function () {
}
//build the main styleguide page
- var styleguideHtml = pattern_assembler.renderPattern(patternlab.viewAll,
+ const styleguideHtml = pattern_assembler.renderPattern(patternlab.viewAll,
{
partials: allPatterns
}, {
@@ -668,7 +668,7 @@ var ui_builder = function () {
fs.outputFileSync(path.resolve(paths.public.styleguide, 'html/styleguide.html'), headerHTML + styleguideHtml + footerHTML);
//move the index file from its asset location into public root
- var patternlabSiteHtml;
+ let patternlabSiteHtml;
try {
patternlabSiteHtml = fs.readFileSync(path.resolve(paths.source.styleguide, 'index.html'), 'utf8');
} catch (error) {
diff --git a/core/lib/utilities.js b/core/lib/utilities.js
index 28166a830..6c88dac90 100644
--- a/core/lib/utilities.js
+++ b/core/lib/utilities.js
@@ -1,7 +1,5 @@
"use strict";
-const fs = require('fs-extra');
-const path = require('path');
const chalk = require('chalk');
const EventEmitter = require('events').EventEmitter;
@@ -49,105 +47,23 @@ const warning = log.warning.bind(log);
*/
const error = log.error.bind(log);
- /**
- * Shuffles an array in place.
- * http://stackoverflow.com/questions/6274339/how-can-i-shuffle-an-array-in-javascript
- *
- * @param {Array} o
- * @returns {Array} o
- */
-const shuffle = function (o) {
- /*eslint-disable curly*/
- for (var j, x, i = o.length; i; j = Math.floor(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
- return o;
-};
-
/**
- * Recursively merge properties of two objects.
- *
- * @param {Object} obj1 If obj1 has properties obj2 doesn't, add to obj2.
- * @param {Object} obj2 This object's properties have priority over obj1.
- * @returns {Object} obj2
+ * Useful for reporting errors in .catch() on Promises
+ * @param {string} - a message to report
+ * @returns {function} - a callback to be passed to a Promise's .catch()
*/
-const mergeData = function (obj1, obj2) {
- /*eslint-disable no-param-reassign, guard-for-in*/
- if (typeof obj2 === 'undefined') {
- obj2 = {};
- }
- for (var p in obj1) {
- try {
- // Only recurse if obj1[p] is an object.
- if (obj1[p].constructor === Object) {
- // Requires 2 objects as params; create obj2[p] if undefined.
- if (typeof obj2[p] === 'undefined') {
- obj2[p] = {};
- }
- obj2[p] = mergeData(obj1[p], obj2[p]);
-
- // Pop when recursion meets a non-object. If obj1[p] is a non-object,
- // only copy to undefined obj2[p]. This way, obj2 maintains priority.
- } else if (typeof obj2[p] === 'undefined') {
- obj2[p] = obj1[p];
- }
- } catch (e) {
- // Property in destination object not set; create it and set its value.
- if (typeof obj2[p] === 'undefined') {
- obj2[p] = obj1[p];
- }
- }
- }
- return obj2;
+const reportError = function (message) {
+ return function (err) {
+ console.log(message);
+ console.log(err);
+ };
};
-/**
- * Determines whether or not an object is empty.
- *
- * @param {Object} obj
- * @returns {Boolean}
- */
-const isObjectEmpty = function (obj) {
- for (var prop in obj) {
- if (obj.hasOwnProperty(prop)) { return false; }
- }
- return true;
-};
-
-/**
- * Recursively delete the contents of directory.
- * Adapted from https://gist.github.com/tkihira/2367067
- *
- * @param {string} dir - directory to empty
- * @param {string} cleanDir - already empty directory
- * @returns {undefined}
- */
-const emptyDirectory = function (dir, cleanDir) {
- var list = fs.readdirSync(dir);
- for (var i = 0; i < list.length; i++) {
- var filename = path.join(dir, list[i]);
- var stat = fs.statSync(filename);
-
- if (filename === "." || filename === "..") {
- // pass these files
- } else if (stat.isDirectory()) {
- this.emptyDirectory(filename);
- } else {
- // rm fiilename
- fs.unlinkSync(filename);
- }
- }
- if (cleanDir) {
- fs.rmdirSync(dir);
- }
-};
module.exports = {
debug,
warning,
error,
log,
- shuffle,
- mergeData,
- isObjectEmpty,
- emptyDirectory
+ reportError
};
-
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 000000000..8db5e864b
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,5363 @@
+{
+ "name": "@pattern-lab/patternlab-node",
+ "version": "3.0.0-alpha.1",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "accepts": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.4.tgz",
+ "integrity": "sha1-hiRnWMfdbSGmR0/whKR0DsBesh8=",
+ "requires": {
+ "mime-types": "2.1.17",
+ "negotiator": "0.6.1"
+ }
+ },
+ "any-promise": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
+ "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8="
+ },
+ "anymatch": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz",
+ "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==",
+ "requires": {
+ "micromatch": "2.3.11",
+ "normalize-path": "2.1.1"
+ }
+ },
+ "apache-crypt": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/apache-crypt/-/apache-crypt-1.2.1.tgz",
+ "integrity": "sha1-1vxyqm0n2ZyVqU/RiNcx7v/6Zjw=",
+ "requires": {
+ "unix-crypt-td-js": "1.0.0"
+ }
+ },
+ "apache-md5": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/apache-md5/-/apache-md5-1.1.2.tgz",
+ "integrity": "sha1-7klza2ObTxCLbp5ibG2pkwa0FpI="
+ },
+ "arr-diff": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz",
+ "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=",
+ "requires": {
+ "arr-flatten": "1.1.0"
+ }
+ },
+ "arr-flatten": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
+ "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg=="
+ },
+ "array-differ": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz",
+ "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE="
+ },
+ "array-union": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
+ "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
+ "requires": {
+ "array-uniq": "1.0.3"
+ }
+ },
+ "array-uniq": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
+ "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY="
+ },
+ "array-unique": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz",
+ "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM="
+ },
+ "arrify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
+ "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0="
+ },
+ "asap": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
+ "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
+ },
+ "async": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/async/-/async-2.5.0.tgz",
+ "integrity": "sha512-e+lJAJeNWuPCNyxZKOBdaJGyLGHugXVQtrAwtuAe2vhxTYxFTKE73p8JuTmdH0qdQZtDvI4dhJwjZc5zsfIsYw==",
+ "requires": {
+ "lodash": "4.17.4"
+ },
+ "dependencies": {
+ "lodash": {
+ "version": "4.17.4",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
+ "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
+ }
+ }
+ },
+ "async-each": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz",
+ "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0="
+ },
+ "balanced-match": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
+ },
+ "basic-auth": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.0.tgz",
+ "integrity": "sha1-AV2z81PgLlY3d1X5YnQuiYHnu7o=",
+ "requires": {
+ "safe-buffer": "5.1.1"
+ }
+ },
+ "batch": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz",
+ "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY="
+ },
+ "bcryptjs": {
+ "version": "2.4.3",
+ "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz",
+ "integrity": "sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms="
+ },
+ "binary-extensions": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.10.0.tgz",
+ "integrity": "sha1-muuabF6IY4qtFx4Wf1kAq+JINdA="
+ },
+ "brace-expansion": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
+ "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
+ "requires": {
+ "balanced-match": "1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "braces": {
+ "version": "1.8.5",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz",
+ "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=",
+ "requires": {
+ "expand-range": "1.8.2",
+ "preserve": "0.2.0",
+ "repeat-element": "1.1.2"
+ }
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "requires": {
+ "ansi-styles": "2.2.1",
+ "escape-string-regexp": "1.0.5",
+ "has-ansi": "2.0.0",
+ "strip-ansi": "3.0.1",
+ "supports-color": "2.0.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
+ },
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
+ },
+ "has-ansi": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+ "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
+ "requires": {
+ "ansi-regex": "2.1.1"
+ }
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "requires": {
+ "ansi-regex": "2.1.1"
+ }
+ },
+ "supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
+ }
+ }
+ },
+ "chokidar": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz",
+ "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=",
+ "requires": {
+ "anymatch": "1.3.2",
+ "async-each": "1.0.1",
+ "glob-parent": "2.0.0",
+ "inherits": "2.0.3",
+ "is-binary-path": "1.0.1",
+ "is-glob": "2.0.1",
+ "path-is-absolute": "1.0.1",
+ "readdirp": "2.1.0"
+ }
+ },
+ "colors": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz",
+ "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM="
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
+ },
+ "connect": {
+ "version": "3.5.1",
+ "resolved": "https://registry.npmjs.org/connect/-/connect-3.5.1.tgz",
+ "integrity": "sha1-bTDXpjx/FwhXprOqazY9lz3KWI4=",
+ "requires": {
+ "debug": "2.2.0",
+ "finalhandler": "0.5.1",
+ "parseurl": "1.3.2",
+ "utils-merge": "1.0.0"
+ }
+ },
+ "core-util-is": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
+ },
+ "cors": {
+ "version": "2.8.4",
+ "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.4.tgz",
+ "integrity": "sha1-K9OB8usgECAQXNUOpZ2mMJBpRoY=",
+ "requires": {
+ "object-assign": "4.1.1",
+ "vary": "1.1.2"
+ },
+ "dependencies": {
+ "object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
+ }
+ }
+ },
+ "debug": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
+ "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=",
+ "requires": {
+ "ms": "0.7.1"
+ }
+ },
+ "del": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz",
+ "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=",
+ "requires": {
+ "globby": "5.0.0",
+ "is-path-cwd": "1.0.0",
+ "is-path-in-cwd": "1.0.0",
+ "object-assign": "4.1.1",
+ "pify": "2.3.0",
+ "pinkie-promise": "2.0.1",
+ "rimraf": "2.6.2"
+ },
+ "dependencies": {
+ "object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
+ }
+ }
+ },
+ "depd": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz",
+ "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k="
+ },
+ "destroy": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
+ "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
+ },
+ "dive": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/dive/-/dive-0.5.0.tgz",
+ "integrity": "sha1-BtDgft0l2oSVmLrKtE1R8oCb7Ec="
+ },
+ "diveSync": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/diveSync/-/diveSync-0.3.0.tgz",
+ "integrity": "sha1-2ZgEk64zvuw29P7G8XH/IYEwzBI=",
+ "requires": {
+ "append": "0.1.1"
+ },
+ "dependencies": {
+ "append": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/append/-/append-0.1.1.tgz",
+ "integrity": "sha1-fl3TJ3RweNh3KG+7Yksej00rOWs="
+ }
+ }
+ },
+ "duplexer": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
+ "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E="
+ },
+ "editorconfig": {
+ "version": "0.13.3",
+ "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.13.3.tgz",
+ "integrity": "sha512-WkjsUNVCu+ITKDj73QDvi0trvpdDWdkDyHybDGSXPfekLCqwmpD7CP7iPbvBgosNuLcI96XTDwNa75JyFl7tEQ==",
+ "requires": {
+ "bluebird": "3.5.1",
+ "commander": "2.11.0",
+ "lru-cache": "3.2.0",
+ "semver": "5.4.1",
+ "sigmund": "1.0.1"
+ },
+ "dependencies": {
+ "bluebird": {
+ "version": "3.5.1",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
+ "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA=="
+ },
+ "commander": {
+ "version": "2.11.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz",
+ "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ=="
+ },
+ "semver": {
+ "version": "5.4.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz",
+ "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg=="
+ }
+ }
+ },
+ "ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
+ },
+ "emitter-mixin": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/emitter-mixin/-/emitter-mixin-0.0.3.tgz",
+ "integrity": "sha1-WUjLKG8uSO3DslGnz8H3iDOW1lw="
+ },
+ "encodeurl": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz",
+ "integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA="
+ },
+ "errno": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.4.tgz",
+ "integrity": "sha1-uJbiOp5ei6M4cfyZar02NfyaHH0=",
+ "requires": {
+ "prr": "0.0.0"
+ }
+ },
+ "escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
+ },
+ "eslint": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.5.0.tgz",
+ "integrity": "sha1-IvyfeA6lvKEwb6srbTM2sPpix1Q=",
+ "dev": true,
+ "requires": {
+ "chalk": "1.1.3",
+ "concat-stream": "1.6.0",
+ "debug": "2.6.9",
+ "doctrine": "1.5.0",
+ "escope": "3.6.0",
+ "espree": "3.5.1",
+ "estraverse": "4.2.0",
+ "esutils": "2.0.2",
+ "file-entry-cache": "2.0.0",
+ "glob": "7.1.2",
+ "globals": "9.18.0",
+ "ignore": "3.3.5",
+ "imurmurhash": "0.1.4",
+ "inquirer": "0.12.0",
+ "is-my-json-valid": "2.16.1",
+ "is-resolvable": "1.0.0",
+ "js-yaml": "3.10.0",
+ "json-stable-stringify": "1.0.1",
+ "levn": "0.3.0",
+ "lodash": "4.13.1",
+ "mkdirp": "0.5.1",
+ "natural-compare": "1.4.0",
+ "optionator": "0.8.2",
+ "path-is-inside": "1.0.2",
+ "pluralize": "1.2.1",
+ "progress": "1.1.8",
+ "require-uncached": "1.0.3",
+ "shelljs": "0.6.1",
+ "strip-bom": "3.0.0",
+ "strip-json-comments": "1.0.4",
+ "table": "3.8.3",
+ "text-table": "0.2.0",
+ "user-home": "2.0.0"
+ },
+ "dependencies": {
+ "acorn": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.1.2.tgz",
+ "integrity": "sha512-o96FZLJBPY1lvTuJylGA9Bk3t/GKPPJG8H0ydQQl01crzwJgspa4AEIq/pVTXigmK0PHVQhiAtn8WMBLL9D2WA==",
+ "dev": true
+ },
+ "acorn-jsx": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz",
+ "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=",
+ "dev": true,
+ "requires": {
+ "acorn": "3.3.0"
+ },
+ "dependencies": {
+ "acorn": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz",
+ "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=",
+ "dev": true
+ }
+ }
+ },
+ "ajv": {
+ "version": "4.11.8",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz",
+ "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=",
+ "dev": true,
+ "requires": {
+ "co": "4.6.0",
+ "json-stable-stringify": "1.0.1"
+ }
+ },
+ "ajv-keywords": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz",
+ "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=",
+ "dev": true
+ },
+ "ansi-escapes": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz",
+ "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=",
+ "dev": true
+ },
+ "ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+ "dev": true
+ },
+ "array-union": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
+ "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
+ "dev": true,
+ "requires": {
+ "array-uniq": "1.0.3"
+ }
+ },
+ "array-uniq": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
+ "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
+ "dev": true
+ },
+ "arrify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
+ "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
+ "dev": true
+ },
+ "caller-path": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz",
+ "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=",
+ "dev": true,
+ "requires": {
+ "callsites": "0.2.0"
+ }
+ },
+ "callsites": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz",
+ "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=",
+ "dev": true
+ },
+ "circular-json": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz",
+ "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==",
+ "dev": true
+ },
+ "cli-cursor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz",
+ "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=",
+ "dev": true,
+ "requires": {
+ "restore-cursor": "1.0.1"
+ }
+ },
+ "cli-width": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz",
+ "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=",
+ "dev": true
+ },
+ "co": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+ "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
+ "dev": true
+ },
+ "code-point-at": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
+ "dev": true
+ },
+ "concat-stream": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz",
+ "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=",
+ "dev": true,
+ "requires": {
+ "inherits": "2.0.3",
+ "readable-stream": "2.3.3",
+ "typedarray": "0.0.6"
+ }
+ },
+ "core-util-is": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
+ "dev": true
+ },
+ "d": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz",
+ "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=",
+ "dev": true,
+ "requires": {
+ "es5-ext": "0.10.30"
+ }
+ },
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "deep-is": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
+ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
+ "dev": true
+ },
+ "del": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz",
+ "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=",
+ "dev": true,
+ "requires": {
+ "globby": "5.0.0",
+ "is-path-cwd": "1.0.0",
+ "is-path-in-cwd": "1.0.0",
+ "object-assign": "4.1.1",
+ "pify": "2.3.0",
+ "pinkie-promise": "2.0.1",
+ "rimraf": "2.6.2"
+ }
+ },
+ "doctrine": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz",
+ "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=",
+ "dev": true,
+ "requires": {
+ "esutils": "2.0.2",
+ "isarray": "1.0.0"
+ }
+ },
+ "es5-ext": {
+ "version": "0.10.30",
+ "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.30.tgz",
+ "integrity": "sha1-cUGhaDZpfbq/qq7uQUlc4p9SyTk=",
+ "dev": true,
+ "requires": {
+ "es6-iterator": "2.0.1",
+ "es6-symbol": "3.1.1"
+ }
+ },
+ "es6-iterator": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz",
+ "integrity": "sha1-jjGcnwRTv1ddN0lAplWSDlnKVRI=",
+ "dev": true,
+ "requires": {
+ "d": "1.0.0",
+ "es5-ext": "0.10.30",
+ "es6-symbol": "3.1.1"
+ }
+ },
+ "es6-map": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz",
+ "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=",
+ "dev": true,
+ "requires": {
+ "d": "1.0.0",
+ "es5-ext": "0.10.30",
+ "es6-iterator": "2.0.1",
+ "es6-set": "0.1.5",
+ "es6-symbol": "3.1.1",
+ "event-emitter": "0.3.5"
+ }
+ },
+ "es6-set": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz",
+ "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=",
+ "dev": true,
+ "requires": {
+ "d": "1.0.0",
+ "es5-ext": "0.10.30",
+ "es6-iterator": "2.0.1",
+ "es6-symbol": "3.1.1",
+ "event-emitter": "0.3.5"
+ }
+ },
+ "es6-symbol": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz",
+ "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=",
+ "dev": true,
+ "requires": {
+ "d": "1.0.0",
+ "es5-ext": "0.10.30"
+ }
+ },
+ "es6-weak-map": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz",
+ "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=",
+ "dev": true,
+ "requires": {
+ "d": "1.0.0",
+ "es5-ext": "0.10.30",
+ "es6-iterator": "2.0.1",
+ "es6-symbol": "3.1.1"
+ }
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+ "dev": true
+ },
+ "escope": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz",
+ "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=",
+ "dev": true,
+ "requires": {
+ "es6-map": "0.1.5",
+ "es6-weak-map": "2.0.2",
+ "esrecurse": "4.2.0",
+ "estraverse": "4.2.0"
+ }
+ },
+ "espree": {
+ "version": "3.5.1",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.1.tgz",
+ "integrity": "sha1-DJiLirRttTEAoZVK5LqZXd0n2H4=",
+ "dev": true,
+ "requires": {
+ "acorn": "5.1.2",
+ "acorn-jsx": "3.0.1"
+ }
+ },
+ "esrecurse": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz",
+ "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=",
+ "dev": true,
+ "requires": {
+ "estraverse": "4.2.0",
+ "object-assign": "4.1.1"
+ }
+ },
+ "estraverse": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
+ "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=",
+ "dev": true
+ },
+ "esutils": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
+ "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
+ "dev": true
+ },
+ "event-emitter": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
+ "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=",
+ "dev": true,
+ "requires": {
+ "d": "1.0.0",
+ "es5-ext": "0.10.30"
+ }
+ },
+ "exit-hook": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz",
+ "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=",
+ "dev": true
+ },
+ "fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
+ "dev": true
+ },
+ "figures": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz",
+ "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=",
+ "dev": true,
+ "requires": {
+ "escape-string-regexp": "1.0.5",
+ "object-assign": "4.1.1"
+ }
+ },
+ "file-entry-cache": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz",
+ "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=",
+ "dev": true,
+ "requires": {
+ "flat-cache": "1.3.0",
+ "object-assign": "4.1.1"
+ }
+ },
+ "flat-cache": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz",
+ "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=",
+ "dev": true,
+ "requires": {
+ "circular-json": "0.3.3",
+ "del": "2.2.2",
+ "graceful-fs": "4.1.11",
+ "write": "0.2.1"
+ }
+ },
+ "generate-function": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz",
+ "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=",
+ "dev": true
+ },
+ "generate-object-property": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz",
+ "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=",
+ "dev": true,
+ "requires": {
+ "is-property": "1.0.2"
+ }
+ },
+ "globals": {
+ "version": "9.18.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz",
+ "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==",
+ "dev": true
+ },
+ "globby": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz",
+ "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=",
+ "dev": true,
+ "requires": {
+ "array-union": "1.0.2",
+ "arrify": "1.0.1",
+ "glob": "7.1.2",
+ "object-assign": "4.1.1",
+ "pify": "2.3.0",
+ "pinkie-promise": "2.0.1"
+ }
+ },
+ "graceful-fs": {
+ "version": "4.1.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
+ "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
+ "dev": true
+ },
+ "ignore": {
+ "version": "3.3.5",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.5.tgz",
+ "integrity": "sha512-JLH93mL8amZQhh/p6mfQgVBH3M6epNq3DfsXsTSuSrInVjwyYlFE1nv2AgfRCC8PoOhM0jwQ5v8s9LgbK7yGDw==",
+ "dev": true
+ },
+ "imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+ "dev": true
+ },
+ "inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
+ "dev": true
+ },
+ "inquirer": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz",
+ "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=",
+ "dev": true,
+ "requires": {
+ "ansi-escapes": "1.4.0",
+ "ansi-regex": "2.1.1",
+ "chalk": "1.1.3",
+ "cli-cursor": "1.0.2",
+ "cli-width": "2.2.0",
+ "figures": "1.7.0",
+ "lodash": "4.13.1",
+ "readline2": "1.0.1",
+ "run-async": "0.1.0",
+ "rx-lite": "3.1.2",
+ "string-width": "1.0.2",
+ "strip-ansi": "3.0.1",
+ "through": "2.3.8"
+ }
+ },
+ "is-fullwidth-code-point": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+ "dev": true,
+ "requires": {
+ "number-is-nan": "1.0.1"
+ }
+ },
+ "is-my-json-valid": {
+ "version": "2.16.1",
+ "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz",
+ "integrity": "sha512-ochPsqWS1WXj8ZnMIV0vnNXooaMhp7cyL4FMSIPKTtnV0Ha/T19G2b9kkhcNsabV9bxYkze7/aLZJb/bYuFduQ==",
+ "dev": true,
+ "requires": {
+ "generate-function": "2.0.0",
+ "generate-object-property": "1.2.0",
+ "jsonpointer": "4.0.1",
+ "xtend": "4.0.1"
+ }
+ },
+ "is-path-cwd": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz",
+ "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=",
+ "dev": true
+ },
+ "is-path-in-cwd": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz",
+ "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=",
+ "dev": true,
+ "requires": {
+ "is-path-inside": "1.0.0"
+ }
+ },
+ "is-path-inside": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz",
+ "integrity": "sha1-/AbloWg/vaE95mev9xe7wQpI838=",
+ "dev": true,
+ "requires": {
+ "path-is-inside": "1.0.2"
+ }
+ },
+ "is-property": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
+ "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=",
+ "dev": true
+ },
+ "is-resolvable": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.0.tgz",
+ "integrity": "sha1-jfV8YeouPFAUCNEA+wE8+NbgzGI=",
+ "dev": true,
+ "requires": {
+ "tryit": "1.0.3"
+ }
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+ "dev": true
+ },
+ "json-stable-stringify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz",
+ "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=",
+ "dev": true,
+ "requires": {
+ "jsonify": "0.0.0"
+ }
+ },
+ "jsonify": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
+ "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=",
+ "dev": true
+ },
+ "jsonpointer": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz",
+ "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=",
+ "dev": true
+ },
+ "levn": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
+ "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
+ "dev": true,
+ "requires": {
+ "prelude-ls": "1.1.2",
+ "type-check": "0.3.2"
+ }
+ },
+ "minimist": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+ "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
+ "dev": true
+ },
+ "mkdirp": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+ "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+ "dev": true,
+ "requires": {
+ "minimist": "0.0.8"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ },
+ "mute-stream": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz",
+ "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=",
+ "dev": true
+ },
+ "natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
+ "dev": true
+ },
+ "number-is-nan": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
+ "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
+ "dev": true
+ },
+ "object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
+ "dev": true
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "dev": true,
+ "requires": {
+ "wrappy": "1.0.2"
+ }
+ },
+ "onetime": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz",
+ "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=",
+ "dev": true
+ },
+ "optionator": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
+ "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=",
+ "dev": true,
+ "requires": {
+ "deep-is": "0.1.3",
+ "fast-levenshtein": "2.0.6",
+ "levn": "0.3.0",
+ "prelude-ls": "1.1.2",
+ "type-check": "0.3.2",
+ "wordwrap": "1.0.0"
+ }
+ },
+ "os-homedir": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
+ "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
+ "dev": true
+ },
+ "path-is-inside": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
+ "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=",
+ "dev": true
+ },
+ "pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+ "dev": true
+ },
+ "pinkie": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
+ "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
+ "dev": true
+ },
+ "pinkie-promise": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+ "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
+ "dev": true,
+ "requires": {
+ "pinkie": "2.0.4"
+ }
+ },
+ "pluralize": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz",
+ "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=",
+ "dev": true
+ },
+ "prelude-ls": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
+ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
+ "dev": true
+ },
+ "process-nextick-args": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
+ "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=",
+ "dev": true
+ },
+ "progress": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz",
+ "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=",
+ "dev": true
+ },
+ "readable-stream": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
+ "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
+ "dev": true,
+ "requires": {
+ "core-util-is": "1.0.2",
+ "inherits": "2.0.3",
+ "isarray": "1.0.0",
+ "process-nextick-args": "1.0.7",
+ "safe-buffer": "5.1.1",
+ "string_decoder": "1.0.3",
+ "util-deprecate": "1.0.2"
+ }
+ },
+ "readline2": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz",
+ "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=",
+ "dev": true,
+ "requires": {
+ "code-point-at": "1.1.0",
+ "is-fullwidth-code-point": "1.0.0",
+ "mute-stream": "0.0.5"
+ }
+ },
+ "require-uncached": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz",
+ "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=",
+ "dev": true,
+ "requires": {
+ "caller-path": "0.1.0",
+ "resolve-from": "1.0.1"
+ }
+ },
+ "resolve-from": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz",
+ "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=",
+ "dev": true
+ },
+ "restore-cursor": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz",
+ "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=",
+ "dev": true,
+ "requires": {
+ "exit-hook": "1.1.1",
+ "onetime": "1.1.0"
+ }
+ },
+ "rimraf": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
+ "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
+ "dev": true,
+ "requires": {
+ "glob": "7.1.2"
+ }
+ },
+ "run-async": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz",
+ "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=",
+ "dev": true,
+ "requires": {
+ "once": "1.4.0"
+ }
+ },
+ "rx-lite": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz",
+ "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=",
+ "dev": true
+ },
+ "safe-buffer": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
+ "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==",
+ "dev": true
+ },
+ "shelljs": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.6.1.tgz",
+ "integrity": "sha1-7GIRvtGSBEIIj+D3Cyg3Iy7SyKg=",
+ "dev": true
+ },
+ "slice-ansi": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz",
+ "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=",
+ "dev": true
+ },
+ "string_decoder": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
+ "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "5.1.1"
+ }
+ },
+ "string-width": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+ "dev": true,
+ "requires": {
+ "code-point-at": "1.1.0",
+ "is-fullwidth-code-point": "1.0.0",
+ "strip-ansi": "3.0.1"
+ }
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "2.1.1"
+ }
+ },
+ "strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+ "dev": true
+ },
+ "strip-json-comments": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz",
+ "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=",
+ "dev": true
+ },
+ "table": {
+ "version": "3.8.3",
+ "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz",
+ "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=",
+ "dev": true,
+ "requires": {
+ "ajv": "4.11.8",
+ "ajv-keywords": "1.5.1",
+ "chalk": "1.1.3",
+ "lodash": "4.13.1",
+ "slice-ansi": "0.0.4",
+ "string-width": "2.1.1"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+ "dev": true
+ },
+ "string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "dev": true,
+ "requires": {
+ "is-fullwidth-code-point": "2.0.0",
+ "strip-ansi": "4.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "3.0.0"
+ }
+ }
+ }
+ },
+ "text-table": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
+ "dev": true
+ },
+ "through": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
+ "dev": true
+ },
+ "tryit": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz",
+ "integrity": "sha1-OTvnMKlEb9Hq1tpZoBQwjzbCics=",
+ "dev": true
+ },
+ "type-check": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
+ "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
+ "dev": true,
+ "requires": {
+ "prelude-ls": "1.1.2"
+ }
+ },
+ "typedarray": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
+ "dev": true
+ },
+ "user-home": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz",
+ "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=",
+ "dev": true,
+ "requires": {
+ "os-homedir": "1.0.2"
+ }
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
+ "dev": true
+ },
+ "wordwrap": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+ "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
+ "dev": true
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+ "dev": true
+ },
+ "write": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz",
+ "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=",
+ "dev": true,
+ "requires": {
+ "mkdirp": "0.5.1"
+ }
+ },
+ "xtend": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
+ "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
+ "dev": true
+ }
+ }
+ },
+ "etag": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+ "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
+ },
+ "event-stream": {
+ "version": "3.3.4",
+ "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz",
+ "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=",
+ "requires": {
+ "duplexer": "0.1.1",
+ "from": "0.1.7",
+ "map-stream": "0.1.0",
+ "pause-stream": "0.0.11",
+ "split": "0.3.3",
+ "stream-combiner": "0.0.4",
+ "through": "2.3.8"
+ }
+ },
+ "expand-brackets": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz",
+ "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=",
+ "requires": {
+ "is-posix-bracket": "0.1.1"
+ }
+ },
+ "expand-range": {
+ "version": "1.8.2",
+ "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz",
+ "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=",
+ "requires": {
+ "fill-range": "2.2.3"
+ }
+ },
+ "extglob": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz",
+ "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=",
+ "requires": {
+ "is-extglob": "1.0.0"
+ }
+ },
+ "faye-websocket": {
+ "version": "0.11.1",
+ "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.1.tgz",
+ "integrity": "sha1-8O/hjE9W5PQK/H4Gxxn9XuYYjzg=",
+ "requires": {
+ "websocket-driver": "0.7.0"
+ }
+ },
+ "filename-regex": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz",
+ "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY="
+ },
+ "fill-range": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz",
+ "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=",
+ "requires": {
+ "is-number": "2.1.0",
+ "isobject": "2.1.0",
+ "randomatic": "1.1.7",
+ "repeat-element": "1.1.2",
+ "repeat-string": "1.6.1"
+ }
+ },
+ "finalhandler": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-0.5.1.tgz",
+ "integrity": "sha1-LEANjUUwk1vCMlScX6OF7Afeb80=",
+ "requires": {
+ "debug": "2.2.0",
+ "escape-html": "1.0.3",
+ "on-finished": "2.3.0",
+ "statuses": "1.3.1",
+ "unpipe": "1.0.0"
+ }
+ },
+ "for-in": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
+ "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA="
+ },
+ "for-own": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz",
+ "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=",
+ "requires": {
+ "for-in": "1.0.2"
+ }
+ },
+ "fresh": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+ "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
+ },
+ "from": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz",
+ "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4="
+ },
+ "fs-extra": {
+ "version": "0.30.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz",
+ "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=",
+ "requires": {
+ "graceful-fs": "4.1.11",
+ "jsonfile": "2.4.0",
+ "klaw": "1.3.1",
+ "path-is-absolute": "1.0.1",
+ "rimraf": "2.6.2"
+ },
+ "dependencies": {
+ "graceful-fs": {
+ "version": "4.1.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
+ "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg="
+ },
+ "jsonfile": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
+ "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
+ "requires": {
+ "graceful-fs": "4.1.11"
+ }
+ },
+ "klaw": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz",
+ "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=",
+ "requires": {
+ "graceful-fs": "4.1.11"
+ }
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
+ },
+ "rimraf": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
+ "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
+ "requires": {
+ "glob": "7.1.2"
+ }
+ }
+ }
+ },
+ "fs-promise": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs-promise/-/fs-promise-1.0.0.tgz",
+ "integrity": "sha1-QkakzUVJfS7Vfm5LIhZ9OGSyNnk=",
+ "requires": {
+ "any-promise": "1.3.0",
+ "fs-extra": "1.0.0",
+ "mz": "2.7.0",
+ "thenify-all": "1.6.0"
+ },
+ "dependencies": {
+ "fs-extra": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz",
+ "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=",
+ "requires": {
+ "graceful-fs": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
+ "jsonfile": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
+ "klaw": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz"
+ }
+ }
+ }
+ },
+ "glob": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+ "requires": {
+ "fs.realpath": "1.0.0",
+ "inflight": "1.0.6",
+ "inherits": "2.0.3",
+ "minimatch": "3.0.4",
+ "once": "1.4.0",
+ "path-is-absolute": "1.0.1"
+ },
+ "dependencies": {
+ "balanced-match": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
+ },
+ "brace-expansion": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
+ "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
+ "requires": {
+ "balanced-match": "1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "requires": {
+ "once": "1.4.0",
+ "wrappy": "1.0.2"
+ }
+ },
+ "inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
+ },
+ "minimatch": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "requires": {
+ "brace-expansion": "1.1.8"
+ }
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "requires": {
+ "wrappy": "1.0.2"
+ }
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
+ }
+ }
+ },
+ "glob-base": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz",
+ "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=",
+ "requires": {
+ "glob-parent": "2.0.0",
+ "is-glob": "2.0.1"
+ }
+ },
+ "glob-parent": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz",
+ "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=",
+ "requires": {
+ "is-glob": "2.0.1"
+ }
+ },
+ "globby": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz",
+ "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=",
+ "requires": {
+ "array-union": "1.0.2",
+ "arrify": "1.0.1",
+ "glob": "7.1.2",
+ "object-assign": "4.1.1",
+ "pify": "2.3.0",
+ "pinkie-promise": "2.0.1"
+ },
+ "dependencies": {
+ "object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
+ }
+ }
+ },
+ "graceful-fs": {
+ "version": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
+ "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg="
+ },
+ "graphlib": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/graphlib/-/graphlib-2.1.1.tgz",
+ "integrity": "sha1-QjUsUrovTQNctWbrkfc5X3bryVE=",
+ "requires": {
+ "lodash": "4.13.1"
+ }
+ },
+ "http-auth": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/http-auth/-/http-auth-3.1.3.tgz",
+ "integrity": "sha1-lFz63WZSHq+PfISRPTd9exXyTjE=",
+ "requires": {
+ "apache-crypt": "1.2.1",
+ "apache-md5": "1.1.2",
+ "bcryptjs": "2.4.3",
+ "uuid": "3.1.0"
+ }
+ },
+ "http-errors": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz",
+ "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=",
+ "requires": {
+ "depd": "1.1.1",
+ "inherits": "2.0.3",
+ "setprototypeof": "1.0.3",
+ "statuses": "1.3.1"
+ }
+ },
+ "http-parser-js": {
+ "version": "0.4.9",
+ "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.9.tgz",
+ "integrity": "sha1-6hoE+2St/wJC6ZdPKX3Uw8rSceE="
+ },
+ "inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
+ },
+ "is-binary-path": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
+ "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=",
+ "requires": {
+ "binary-extensions": "1.10.0"
+ }
+ },
+ "is-buffer": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz",
+ "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw="
+ },
+ "is-dotfile": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz",
+ "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE="
+ },
+ "is-equal-shallow": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz",
+ "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=",
+ "requires": {
+ "is-primitive": "2.0.0"
+ }
+ },
+ "is-extendable": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+ "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik="
+ },
+ "is-extglob": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
+ "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA="
+ },
+ "is-glob": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
+ "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
+ "requires": {
+ "is-extglob": "1.0.0"
+ }
+ },
+ "is-number": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz",
+ "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=",
+ "requires": {
+ "kind-of": "3.2.2"
+ }
+ },
+ "is-path-cwd": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz",
+ "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0="
+ },
+ "is-path-in-cwd": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz",
+ "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=",
+ "requires": {
+ "is-path-inside": "1.0.0"
+ }
+ },
+ "is-path-inside": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz",
+ "integrity": "sha1-/AbloWg/vaE95mev9xe7wQpI838=",
+ "requires": {
+ "path-is-inside": "1.0.2"
+ }
+ },
+ "is-posix-bracket": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz",
+ "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q="
+ },
+ "is-primitive": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz",
+ "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU="
+ },
+ "is-wsl": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz",
+ "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0="
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
+ },
+ "isobject": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+ "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+ "requires": {
+ "isarray": "1.0.0"
+ }
+ },
+ "js-beautify": {
+ "version": "1.7.3",
+ "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.7.3.tgz",
+ "integrity": "sha512-mT9skIu0OWfBQPXOGJ4CgpPBgo3tj9gxi7weQdeaxxmpKIADK2g0xS0qCtQml7Ny3Ick5Cno093LKGZTzDd2UQ==",
+ "requires": {
+ "config-chain": "1.1.11",
+ "editorconfig": "0.13.3",
+ "mkdirp": "0.5.1",
+ "nopt": "3.0.6"
+ },
+ "dependencies": {
+ "abbrev": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
+ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
+ },
+ "config-chain": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.11.tgz",
+ "integrity": "sha1-q6CXR9++TD5w52am5BWG4YWfxvI=",
+ "requires": {
+ "ini": "1.3.4",
+ "proto-list": "1.2.4"
+ }
+ },
+ "ini": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz",
+ "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4="
+ },
+ "minimist": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+ "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
+ },
+ "mkdirp": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+ "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+ "requires": {
+ "minimist": "0.0.8"
+ }
+ },
+ "nopt": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
+ "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
+ "requires": {
+ "abbrev": "1.1.1"
+ }
+ },
+ "proto-list": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
+ "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk="
+ }
+ }
+ },
+ "js-yaml": {
+ "version": "3.10.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz",
+ "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==",
+ "requires": {
+ "argparse": "1.0.9",
+ "esprima": "4.0.0"
+ },
+ "dependencies": {
+ "argparse": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz",
+ "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=",
+ "requires": {
+ "sprintf-js": "1.0.3"
+ }
+ },
+ "esprima": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz",
+ "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw=="
+ },
+ "sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
+ }
+ }
+ },
+ "jsonfile": {
+ "version": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
+ "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
+ "requires": {
+ "graceful-fs": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz"
+ }
+ },
+ "junk": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/junk/-/junk-1.0.3.tgz",
+ "integrity": "sha1-h75jSIZJy9ym9Tqzm+yczSNH9ZI="
+ },
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "requires": {
+ "is-buffer": "1.1.5"
+ }
+ },
+ "klaw": {
+ "version": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz",
+ "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=",
+ "requires": {
+ "graceful-fs": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz"
+ }
+ },
+ "live-server": {
+ "version": "github:pattern-lab/live-server#d46ec211455efb0ae2ad140b09e151bc2649c496",
+ "requires": {
+ "chokidar": "1.7.0",
+ "colors": "1.1.2",
+ "connect": "3.5.1",
+ "cors": "2.8.4",
+ "event-stream": "3.3.4",
+ "faye-websocket": "0.11.1",
+ "http-auth": "3.1.3",
+ "morgan": "1.9.0",
+ "object-assign": "4.1.1",
+ "opn": "5.1.0",
+ "proxy-middleware": "0.15.0",
+ "send": "0.16.1",
+ "serve-index": "1.9.1"
+ },
+ "dependencies": {
+ "object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
+ }
+ }
+ },
+ "lodash": {
+ "version": "4.13.1",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.13.1.tgz",
+ "integrity": "sha1-g+SxCRP0hJbU0W/sSlYK8u50S2g="
+ },
+ "lru-cache": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-3.2.0.tgz",
+ "integrity": "sha1-cXibO39Tmb7IVl3aOKow0qCX7+4=",
+ "requires": {
+ "pseudomap": "1.0.2"
+ },
+ "dependencies": {
+ "pseudomap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
+ "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM="
+ }
+ }
+ },
+ "map-stream": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz",
+ "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ="
+ },
+ "markdown-it": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-6.1.1.tgz",
+ "integrity": "sha1-ztA39Ec+6fUVOsQU933IPJG6knw=",
+ "requires": {
+ "argparse": "1.0.9",
+ "entities": "1.1.1",
+ "linkify-it": "1.2.4",
+ "mdurl": "1.0.1",
+ "uc.micro": "1.0.3"
+ },
+ "dependencies": {
+ "argparse": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz",
+ "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=",
+ "requires": {
+ "sprintf-js": "1.0.3"
+ }
+ },
+ "entities": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz",
+ "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA="
+ },
+ "linkify-it": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-1.2.4.tgz",
+ "integrity": "sha1-B3NSbDF8j9E71TTuHRgP+Iq/iBo=",
+ "requires": {
+ "uc.micro": "1.0.3"
+ }
+ },
+ "mdurl": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
+ "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4="
+ },
+ "sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
+ },
+ "uc.micro": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.3.tgz",
+ "integrity": "sha1-ftUNXg+an7ClczeSWfKndFjVAZI="
+ }
+ }
+ },
+ "maximatch": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/maximatch/-/maximatch-0.1.0.tgz",
+ "integrity": "sha1-hs2NawTJ8wfAWmuUGZBtA2D7E6I=",
+ "requires": {
+ "array-differ": "1.0.0",
+ "array-union": "1.0.2",
+ "arrify": "1.0.1",
+ "minimatch": "3.0.4"
+ }
+ },
+ "micromatch": {
+ "version": "2.3.11",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz",
+ "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=",
+ "requires": {
+ "arr-diff": "2.0.0",
+ "array-unique": "0.2.1",
+ "braces": "1.8.5",
+ "expand-brackets": "0.1.5",
+ "extglob": "0.3.2",
+ "filename-regex": "2.0.1",
+ "is-extglob": "1.0.0",
+ "is-glob": "2.0.1",
+ "kind-of": "3.2.2",
+ "normalize-path": "2.1.1",
+ "object.omit": "2.0.1",
+ "parse-glob": "3.0.4",
+ "regex-cache": "0.4.4"
+ }
+ },
+ "mime": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
+ "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ=="
+ },
+ "mime-db": {
+ "version": "1.30.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz",
+ "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE="
+ },
+ "mime-types": {
+ "version": "2.1.17",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz",
+ "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=",
+ "requires": {
+ "mime-db": "1.30.0"
+ }
+ },
+ "minimatch": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "requires": {
+ "brace-expansion": "1.1.8"
+ }
+ },
+ "minimist": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+ "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
+ },
+ "mkdirp": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+ "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+ "requires": {
+ "minimist": "0.0.8"
+ }
+ },
+ "morgan": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.0.tgz",
+ "integrity": "sha1-0B+mxlhZt2/PMbPLU6OCGjEdgFE=",
+ "requires": {
+ "basic-auth": "2.0.0",
+ "debug": "2.6.9",
+ "depd": "1.1.1",
+ "on-finished": "2.3.0",
+ "on-headers": "1.0.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ }
+ }
+ },
+ "ms": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz",
+ "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg="
+ },
+ "mz": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
+ "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
+ "requires": {
+ "any-promise": "1.3.0",
+ "object-assign": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "thenify-all": "1.6.0"
+ }
+ },
+ "negotiator": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
+ "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk="
+ },
+ "node-fetch": {
+ "version": "1.7.3",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
+ "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
+ "requires": {
+ "encoding": "0.1.12",
+ "is-stream": "1.1.0"
+ },
+ "dependencies": {
+ "encoding": {
+ "version": "0.1.12",
+ "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
+ "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=",
+ "requires": {
+ "iconv-lite": "0.4.19"
+ }
+ },
+ "iconv-lite": {
+ "version": "0.4.19",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
+ "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ=="
+ },
+ "is-stream": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+ "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
+ }
+ }
+ },
+ "normalize-path": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
+ "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
+ "requires": {
+ "remove-trailing-separator": "1.1.0"
+ }
+ },
+ "object-assign": {
+ "version": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
+ },
+ "object.omit": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz",
+ "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=",
+ "requires": {
+ "for-own": "0.1.5",
+ "is-extendable": "0.1.1"
+ }
+ },
+ "on-finished": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+ "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
+ "requires": {
+ "ee-first": "1.1.1"
+ }
+ },
+ "on-headers": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz",
+ "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c="
+ },
+ "opn": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/opn/-/opn-5.1.0.tgz",
+ "integrity": "sha512-iPNl7SyM8L30Rm1sjGdLLheyHVw5YXVfi3SKWJzBI7efxRwHojfRFjwE/OLM6qp9xJYMgab8WicTU1cPoY+Hpg==",
+ "requires": {
+ "is-wsl": "1.1.0"
+ }
+ },
+ "parse-glob": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz",
+ "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=",
+ "requires": {
+ "glob-base": "0.3.0",
+ "is-dotfile": "1.0.3",
+ "is-extglob": "1.0.0",
+ "is-glob": "2.0.1"
+ }
+ },
+ "parseurl": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
+ "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M="
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
+ },
+ "path-is-inside": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
+ "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM="
+ },
+ "pause-stream": {
+ "version": "0.0.11",
+ "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz",
+ "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=",
+ "requires": {
+ "through": "2.3.8"
+ }
+ },
+ "pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw="
+ },
+ "pinkie": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
+ "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA="
+ },
+ "pinkie-promise": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+ "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
+ "requires": {
+ "pinkie": "2.0.4"
+ }
+ },
+ "preserve": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz",
+ "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks="
+ },
+ "process-nextick-args": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
+ "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M="
+ },
+ "promise": {
+ "version": "7.3.1",
+ "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
+ "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
+ "requires": {
+ "asap": "2.0.6"
+ }
+ },
+ "proxy-middleware": {
+ "version": "0.15.0",
+ "resolved": "https://registry.npmjs.org/proxy-middleware/-/proxy-middleware-0.15.0.tgz",
+ "integrity": "sha1-o/3xvvtzD5UZZYcqwvYHTGFHelY="
+ },
+ "prr": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/prr/-/prr-0.0.0.tgz",
+ "integrity": "sha1-GoS4WQgyVQFBGFPQCB7j+obikmo="
+ },
+ "randomatic": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz",
+ "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==",
+ "requires": {
+ "is-number": "3.0.0",
+ "kind-of": "4.0.0"
+ },
+ "dependencies": {
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "requires": {
+ "is-buffer": "1.1.5"
+ }
+ }
+ }
+ },
+ "kind-of": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
+ "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
+ "requires": {
+ "is-buffer": "1.1.5"
+ }
+ }
+ }
+ },
+ "range-parser": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
+ "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4="
+ },
+ "readable-stream": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
+ "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
+ "requires": {
+ "core-util-is": "1.0.2",
+ "inherits": "2.0.3",
+ "isarray": "1.0.0",
+ "process-nextick-args": "1.0.7",
+ "safe-buffer": "5.1.1",
+ "string_decoder": "1.0.3",
+ "util-deprecate": "1.0.2"
+ }
+ },
+ "readdirp": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz",
+ "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=",
+ "requires": {
+ "graceful-fs": "4.1.11",
+ "minimatch": "3.0.4",
+ "readable-stream": "2.3.3",
+ "set-immediate-shim": "1.0.1"
+ },
+ "dependencies": {
+ "graceful-fs": {
+ "version": "4.1.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
+ "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg="
+ }
+ }
+ },
+ "recursive-copy": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/recursive-copy/-/recursive-copy-2.0.6.tgz",
+ "integrity": "sha1-1ZD5618WW5ahuAvI+cvLXG+ciek=",
+ "requires": {
+ "del": "2.2.2",
+ "emitter-mixin": "0.0.3",
+ "errno": "0.1.4",
+ "graceful-fs": "4.1.11",
+ "junk": "1.0.3",
+ "maximatch": "0.1.0",
+ "mkdirp": "0.5.1",
+ "pify": "2.3.0",
+ "promise": "7.3.1",
+ "slash": "1.0.0"
+ },
+ "dependencies": {
+ "graceful-fs": {
+ "version": "4.1.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
+ "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg="
+ }
+ }
+ },
+ "regex-cache": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz",
+ "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==",
+ "requires": {
+ "is-equal-shallow": "0.1.3"
+ }
+ },
+ "remove-trailing-separator": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
+ "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8="
+ },
+ "repeat-element": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz",
+ "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo="
+ },
+ "repeat-string": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
+ "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc="
+ },
+ "rewire": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/rewire/-/rewire-2.5.2.tgz",
+ "integrity": "sha1-ZCfee3/u+n02QBUH62SlOFvFjcc=",
+ "dev": true
+ },
+ "rimraf": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
+ "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
+ "requires": {
+ "glob": "7.1.2"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
+ "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
+ },
+ "send": {
+ "version": "0.16.1",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.16.1.tgz",
+ "integrity": "sha512-ElCLJdJIKPk6ux/Hocwhk7NFHpI3pVm/IZOYWqUmoxcgeyM+MpxHHKhb8QmlJDX1pU6WrgaHBkVNm73Sv7uc2A==",
+ "requires": {
+ "debug": "2.6.9",
+ "depd": "1.1.1",
+ "destroy": "1.0.4",
+ "encodeurl": "1.0.1",
+ "escape-html": "1.0.3",
+ "etag": "1.8.1",
+ "fresh": "0.5.2",
+ "http-errors": "1.6.2",
+ "mime": "1.4.1",
+ "ms": "2.0.0",
+ "on-finished": "2.3.0",
+ "range-parser": "1.2.0",
+ "statuses": "1.3.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ }
+ }
+ },
+ "serve-index": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz",
+ "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=",
+ "requires": {
+ "accepts": "1.3.4",
+ "batch": "0.6.1",
+ "debug": "2.6.9",
+ "escape-html": "1.0.3",
+ "http-errors": "1.6.2",
+ "mime-types": "2.1.17",
+ "parseurl": "1.3.2"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ }
+ }
+ },
+ "set-immediate-shim": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz",
+ "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E="
+ },
+ "setprototypeof": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz",
+ "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ="
+ },
+ "sigmund": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz",
+ "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA="
+ },
+ "slash": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz",
+ "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU="
+ },
+ "split": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz",
+ "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=",
+ "requires": {
+ "through": "2.3.8"
+ }
+ },
+ "statuses": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
+ "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4="
+ },
+ "stream-combiner": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz",
+ "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=",
+ "requires": {
+ "duplexer": "0.1.1"
+ }
+ },
+ "string_decoder": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
+ "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
+ "requires": {
+ "safe-buffer": "5.1.1"
+ }
+ },
+ "tap": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/tap/-/tap-7.1.2.tgz",
+ "integrity": "sha1-36w+zxSshUe7rSW70Wzyw3Q/Zc8=",
+ "dev": true,
+ "requires": {
+ "bluebird": "3.5.1",
+ "clean-yaml-object": "0.1.0",
+ "color-support": "1.1.3",
+ "coveralls": "2.13.3",
+ "deeper": "2.1.0",
+ "foreground-child": "1.5.6",
+ "glob": "7.1.2",
+ "isexe": "1.1.2",
+ "js-yaml": "3.10.0",
+ "nyc": "7.1.0",
+ "only-shallow": "1.2.0",
+ "opener": "1.4.3",
+ "os-homedir": "1.0.1",
+ "readable-stream": "2.3.3",
+ "signal-exit": "3.0.2",
+ "stack-utils": "0.4.0",
+ "tap-mocha-reporter": "2.0.1",
+ "tap-parser": "2.2.3",
+ "tmatch": "2.0.1"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+ "dev": true
+ },
+ "argparse": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz",
+ "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=",
+ "dev": true,
+ "requires": {
+ "sprintf-js": "1.0.3"
+ }
+ },
+ "asn1": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
+ "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=",
+ "dev": true
+ },
+ "assert-plus": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz",
+ "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=",
+ "dev": true
+ },
+ "asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
+ "dev": true
+ },
+ "aws-sign2": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz",
+ "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=",
+ "dev": true
+ },
+ "aws4": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
+ "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=",
+ "dev": true
+ },
+ "bcrypt-pbkdf": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
+ "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "tweetnacl": "0.14.5"
+ }
+ },
+ "bluebird": {
+ "version": "3.5.1",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
+ "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==",
+ "dev": true
+ },
+ "boom": {
+ "version": "2.10.1",
+ "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
+ "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=",
+ "dev": true,
+ "requires": {
+ "hoek": "2.16.3"
+ }
+ },
+ "caseless": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz",
+ "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=",
+ "dev": true
+ },
+ "clean-yaml-object": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/clean-yaml-object/-/clean-yaml-object-0.1.0.tgz",
+ "integrity": "sha1-Y/sRDcLOGoTcIfbZM0h20BCui2g=",
+ "dev": true
+ },
+ "color-support": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
+ "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
+ "dev": true
+ },
+ "combined-stream": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz",
+ "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=",
+ "dev": true,
+ "requires": {
+ "delayed-stream": "1.0.0"
+ }
+ },
+ "commander": {
+ "version": "2.11.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz",
+ "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==",
+ "dev": true
+ },
+ "core-util-is": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
+ "dev": true
+ },
+ "coveralls": {
+ "version": "2.13.3",
+ "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-2.13.3.tgz",
+ "integrity": "sha512-iiAmn+l1XqRwNLXhW8Rs5qHZRFMYp9ZIPjEOVRpC/c4so6Y/f4/lFi0FfR5B9cCqgyhkJ5cZmbvcVRfP8MHchw==",
+ "dev": true,
+ "requires": {
+ "js-yaml": "3.6.1",
+ "lcov-parse": "0.0.10",
+ "log-driver": "1.2.5",
+ "minimist": "1.2.0",
+ "request": "2.79.0"
+ },
+ "dependencies": {
+ "js-yaml": {
+ "version": "3.6.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.6.1.tgz",
+ "integrity": "sha1-bl/mfYsgXOTSL60Ft3geja3MSzA=",
+ "dev": true,
+ "requires": {
+ "argparse": "1.0.9",
+ "esprima": "2.7.3"
+ }
+ }
+ }
+ },
+ "cross-spawn": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz",
+ "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=",
+ "dev": true,
+ "requires": {
+ "lru-cache": "4.1.1",
+ "which": "1.3.0"
+ }
+ },
+ "cryptiles": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz",
+ "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=",
+ "dev": true,
+ "requires": {
+ "boom": "2.10.1"
+ }
+ },
+ "dashdash": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+ "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "1.0.0"
+ },
+ "dependencies": {
+ "assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+ "dev": true
+ }
+ }
+ },
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "deeper": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/deeper/-/deeper-2.1.0.tgz",
+ "integrity": "sha1-vFZOX3MXT98gHgiwADDooU2nQ2g=",
+ "dev": true
+ },
+ "delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
+ "dev": true
+ },
+ "diff": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz",
+ "integrity": "sha1-fyjS657nsVqX79ic5j3P2qPMur8=",
+ "dev": true
+ },
+ "ecc-jsbn": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
+ "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "jsbn": "0.1.1"
+ }
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+ "dev": true
+ },
+ "esprima": {
+ "version": "2.7.3",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
+ "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=",
+ "dev": true
+ },
+ "events-to-array": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/events-to-array/-/events-to-array-1.1.2.tgz",
+ "integrity": "sha1-LUH1Y+H+QA7Uli/hpNXGp1Od9/Y=",
+ "dev": true
+ },
+ "extend": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
+ "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=",
+ "dev": true
+ },
+ "extsprintf": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+ "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
+ "dev": true
+ },
+ "foreground-child": {
+ "version": "1.5.6",
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz",
+ "integrity": "sha1-T9ca0t/elnibmApcCilZN8svXOk=",
+ "dev": true,
+ "requires": {
+ "cross-spawn": "4.0.2",
+ "signal-exit": "3.0.2"
+ }
+ },
+ "forever-agent": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+ "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
+ "dev": true
+ },
+ "form-data": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz",
+ "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=",
+ "dev": true,
+ "requires": {
+ "asynckit": "0.4.0",
+ "combined-stream": "1.0.5",
+ "mime-types": "2.1.17"
+ }
+ },
+ "generate-function": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz",
+ "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=",
+ "dev": true
+ },
+ "generate-object-property": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz",
+ "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=",
+ "dev": true,
+ "requires": {
+ "is-property": "1.0.2"
+ }
+ },
+ "getpass": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+ "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "1.0.0"
+ },
+ "dependencies": {
+ "assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+ "dev": true
+ }
+ }
+ },
+ "har-validator": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz",
+ "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=",
+ "dev": true,
+ "requires": {
+ "chalk": "1.1.3",
+ "commander": "2.11.0",
+ "is-my-json-valid": "2.16.1",
+ "pinkie-promise": "2.0.1"
+ }
+ },
+ "hawk": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz",
+ "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=",
+ "dev": true,
+ "requires": {
+ "boom": "2.10.1",
+ "cryptiles": "2.0.5",
+ "hoek": "2.16.3",
+ "sntp": "1.0.9"
+ }
+ },
+ "hoek": {
+ "version": "2.16.3",
+ "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
+ "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=",
+ "dev": true
+ },
+ "http-signature": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz",
+ "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "0.2.0",
+ "jsprim": "1.4.1",
+ "sshpk": "1.13.1"
+ }
+ },
+ "inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
+ "dev": true
+ },
+ "is-my-json-valid": {
+ "version": "2.16.1",
+ "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz",
+ "integrity": "sha512-ochPsqWS1WXj8ZnMIV0vnNXooaMhp7cyL4FMSIPKTtnV0Ha/T19G2b9kkhcNsabV9bxYkze7/aLZJb/bYuFduQ==",
+ "dev": true,
+ "requires": {
+ "generate-function": "2.0.0",
+ "generate-object-property": "1.2.0",
+ "jsonpointer": "4.0.1",
+ "xtend": "4.0.1"
+ }
+ },
+ "is-property": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
+ "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=",
+ "dev": true
+ },
+ "is-typedarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
+ "dev": true
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+ "dev": true
+ },
+ "isexe": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-1.1.2.tgz",
+ "integrity": "sha1-NvPiLmB1CSD15yQaR2qMakInWtA=",
+ "dev": true
+ },
+ "isstream": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
+ "dev": true
+ },
+ "jsbn": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
+ "dev": true,
+ "optional": true
+ },
+ "json-schema": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
+ "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
+ "dev": true
+ },
+ "json-stringify-safe": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
+ "dev": true
+ },
+ "jsonpointer": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz",
+ "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=",
+ "dev": true
+ },
+ "jsprim": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
+ "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "1.0.0",
+ "extsprintf": "1.3.0",
+ "json-schema": "0.2.3",
+ "verror": "1.10.0"
+ },
+ "dependencies": {
+ "assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+ "dev": true
+ }
+ }
+ },
+ "lcov-parse": {
+ "version": "0.0.10",
+ "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-0.0.10.tgz",
+ "integrity": "sha1-GwuP+ayceIklBYK3C3ExXZ2m2aM=",
+ "dev": true
+ },
+ "log-driver": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.5.tgz",
+ "integrity": "sha1-euTsJXMC/XkNVXyxDJcQDYV7AFY=",
+ "dev": true
+ },
+ "lru-cache": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz",
+ "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==",
+ "dev": true,
+ "requires": {
+ "pseudomap": "1.0.2",
+ "yallist": "2.1.2"
+ }
+ },
+ "mime-db": {
+ "version": "1.30.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz",
+ "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=",
+ "dev": true
+ },
+ "mime-types": {
+ "version": "2.1.17",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz",
+ "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=",
+ "dev": true,
+ "requires": {
+ "mime-db": "1.30.0"
+ }
+ },
+ "minimist": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+ "dev": true
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ },
+ "nyc": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/nyc/-/nyc-7.1.0.tgz",
+ "integrity": "sha1-jhSXHzoV0au+x6xhDvVMuInp/7Q=",
+ "dev": true,
+ "requires": {
+ "arrify": "1.0.1",
+ "caching-transform": "1.0.1",
+ "convert-source-map": "1.3.0",
+ "default-require-extensions": "1.0.0",
+ "find-cache-dir": "0.1.1",
+ "find-up": "1.1.2",
+ "foreground-child": "1.5.3",
+ "glob": "7.0.5",
+ "istanbul-lib-coverage": "1.0.0-alpha.4",
+ "istanbul-lib-hook": "1.0.0-alpha.4",
+ "istanbul-lib-instrument": "1.1.0-alpha.4",
+ "istanbul-lib-report": "1.0.0-alpha.3",
+ "istanbul-lib-source-maps": "1.0.0-alpha.10",
+ "istanbul-reports": "1.0.0-alpha.8",
+ "md5-hex": "1.3.0",
+ "micromatch": "2.3.11",
+ "mkdirp": "0.5.1",
+ "pkg-up": "1.0.0",
+ "resolve-from": "2.0.0",
+ "rimraf": "2.5.4",
+ "signal-exit": "3.0.0",
+ "spawn-wrap": "1.2.4",
+ "test-exclude": "1.1.0",
+ "yargs": "4.8.1",
+ "yargs-parser": "2.4.1"
+ },
+ "dependencies": {
+ "align-text": {
+ "version": "0.1.4",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "kind-of": "3.0.3",
+ "longest": "1.0.1",
+ "repeat-string": "1.5.4"
+ }
+ },
+ "amdefine": {
+ "version": "1.0.0",
+ "bundled": true,
+ "dev": true
+ },
+ "ansi-regex": {
+ "version": "2.0.0",
+ "bundled": true,
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "2.2.1",
+ "bundled": true,
+ "dev": true
+ },
+ "append-transform": {
+ "version": "0.3.0",
+ "bundled": true,
+ "dev": true
+ },
+ "arr-diff": {
+ "version": "2.0.0",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "arr-flatten": "1.0.1"
+ }
+ },
+ "arr-flatten": {
+ "version": "1.0.1",
+ "bundled": true,
+ "dev": true
+ },
+ "array-unique": {
+ "version": "0.2.1",
+ "bundled": true,
+ "dev": true
+ },
+ "arrify": {
+ "version": "1.0.1",
+ "bundled": true,
+ "dev": true
+ },
+ "async": {
+ "version": "1.5.2",
+ "bundled": true,
+ "dev": true
+ },
+ "babel-code-frame": {
+ "version": "6.11.0",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "babel-runtime": "6.9.2",
+ "chalk": "1.1.3",
+ "esutils": "2.0.2",
+ "js-tokens": "2.0.0"
+ }
+ },
+ "babel-generator": {
+ "version": "6.11.4",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "babel-messages": "6.8.0",
+ "babel-runtime": "6.9.2",
+ "babel-types": "6.11.1",
+ "detect-indent": "3.0.1",
+ "lodash": "4.13.1",
+ "source-map": "0.5.6"
+ }
+ },
+ "babel-messages": {
+ "version": "6.8.0",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "babel-runtime": "6.9.2"
+ }
+ },
+ "babel-runtime": {
+ "version": "6.9.2",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "core-js": "2.4.1",
+ "regenerator-runtime": "0.9.5"
+ }
+ },
+ "babel-template": {
+ "version": "6.9.0",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "babel-runtime": "6.9.2",
+ "babel-traverse": "6.11.4",
+ "babel-types": "6.11.1",
+ "babylon": "6.8.4",
+ "lodash": "4.13.1"
+ }
+ },
+ "babel-traverse": {
+ "version": "6.11.4",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "babel-code-frame": "6.11.0",
+ "babel-messages": "6.8.0",
+ "babel-runtime": "6.9.2",
+ "babel-types": "6.11.1",
+ "babylon": "6.8.4",
+ "debug": "2.2.0",
+ "globals": "8.18.0",
+ "invariant": "2.2.1",
+ "lodash": "4.13.1"
+ }
+ },
+ "babel-types": {
+ "version": "6.11.1",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "babel-runtime": "6.9.2",
+ "babel-traverse": "6.11.4",
+ "esutils": "2.0.2",
+ "lodash": "4.13.1",
+ "to-fast-properties": "1.0.2"
+ }
+ },
+ "babylon": {
+ "version": "6.8.4",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "babel-runtime": "6.9.2"
+ }
+ },
+ "balanced-match": {
+ "version": "0.4.2",
+ "bundled": true,
+ "dev": true
+ },
+ "brace-expansion": {
+ "version": "1.1.6",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "balanced-match": "0.4.2",
+ "concat-map": "0.0.1"
+ }
+ },
+ "braces": {
+ "version": "1.8.5",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "expand-range": "1.8.2",
+ "preserve": "0.2.0",
+ "repeat-element": "1.1.2"
+ }
+ },
+ "builtin-modules": {
+ "version": "1.1.1",
+ "bundled": true,
+ "dev": true
+ },
+ "caching-transform": {
+ "version": "1.0.1",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "md5-hex": "1.3.0",
+ "mkdirp": "0.5.1",
+ "write-file-atomic": "1.1.4"
+ }
+ },
+ "camelcase": {
+ "version": "1.2.1",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "center-align": {
+ "version": "0.1.3",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "align-text": "0.1.4",
+ "lazy-cache": "1.0.4"
+ }
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "ansi-styles": "2.2.1",
+ "escape-string-regexp": "1.0.5",
+ "has-ansi": "2.0.0",
+ "strip-ansi": "3.0.1",
+ "supports-color": "2.0.0"
+ }
+ },
+ "cliui": {
+ "version": "2.1.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "center-align": "0.1.3",
+ "right-align": "0.1.3",
+ "wordwrap": "0.0.2"
+ },
+ "dependencies": {
+ "wordwrap": {
+ "version": "0.0.2",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "code-point-at": {
+ "version": "1.0.0",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "number-is-nan": "1.0.0"
+ }
+ },
+ "commondir": {
+ "version": "1.0.1",
+ "bundled": true,
+ "dev": true
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "bundled": true,
+ "dev": true
+ },
+ "convert-source-map": {
+ "version": "1.3.0",
+ "bundled": true,
+ "dev": true
+ },
+ "core-js": {
+ "version": "2.4.1",
+ "bundled": true,
+ "dev": true
+ },
+ "cross-spawn": {
+ "version": "4.0.0",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "lru-cache": "4.0.1",
+ "which": "1.2.10"
+ }
+ },
+ "debug": {
+ "version": "2.2.0",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "ms": "0.7.1"
+ }
+ },
+ "decamelize": {
+ "version": "1.2.0",
+ "bundled": true,
+ "dev": true
+ },
+ "default-require-extensions": {
+ "version": "1.0.0",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "strip-bom": "2.0.0"
+ }
+ },
+ "detect-indent": {
+ "version": "3.0.1",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "get-stdin": "4.0.1",
+ "minimist": "1.2.0",
+ "repeating": "1.1.3"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "1.2.0",
+ "bundled": true,
+ "dev": true
+ }
+ }
+ },
+ "error-ex": {
+ "version": "1.3.0",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "is-arrayish": "0.2.1"
+ }
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "bundled": true,
+ "dev": true
+ },
+ "esutils": {
+ "version": "2.0.2",
+ "bundled": true,
+ "dev": true
+ },
+ "expand-brackets": {
+ "version": "0.1.5",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "is-posix-bracket": "0.1.1"
+ }
+ },
+ "expand-range": {
+ "version": "1.8.2",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "fill-range": "2.2.3"
+ }
+ },
+ "extglob": {
+ "version": "0.3.2",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "is-extglob": "1.0.0"
+ }
+ },
+ "filename-regex": {
+ "version": "2.0.0",
+ "bundled": true,
+ "dev": true
+ },
+ "fill-range": {
+ "version": "2.2.3",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "is-number": "2.1.0",
+ "isobject": "2.1.0",
+ "randomatic": "1.1.5",
+ "repeat-element": "1.1.2",
+ "repeat-string": "1.5.4"
+ }
+ },
+ "find-cache-dir": {
+ "version": "0.1.1",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "commondir": "1.0.1",
+ "mkdirp": "0.5.1",
+ "pkg-dir": "1.0.0"
+ }
+ },
+ "find-up": {
+ "version": "1.1.2",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "path-exists": "2.1.0",
+ "pinkie-promise": "2.0.1"
+ }
+ },
+ "for-in": {
+ "version": "0.1.5",
+ "bundled": true,
+ "dev": true
+ },
+ "for-own": {
+ "version": "0.1.4",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "for-in": "0.1.5"
+ }
+ },
+ "foreground-child": {
+ "version": "1.5.3",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "cross-spawn": "4.0.0",
+ "signal-exit": "3.0.0"
+ }
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "bundled": true,
+ "dev": true
+ },
+ "get-caller-file": {
+ "version": "1.0.1",
+ "bundled": true,
+ "dev": true
+ },
+ "get-stdin": {
+ "version": "4.0.1",
+ "bundled": true,
+ "dev": true
+ },
+ "glob": {
+ "version": "7.0.5",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "fs.realpath": "1.0.0",
+ "inflight": "1.0.5",
+ "inherits": "2.0.1",
+ "minimatch": "3.0.2",
+ "once": "1.3.3",
+ "path-is-absolute": "1.0.0"
+ }
+ },
+ "glob-base": {
+ "version": "0.3.0",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "glob-parent": "2.0.0",
+ "is-glob": "2.0.1"
+ }
+ },
+ "glob-parent": {
+ "version": "2.0.0",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "is-glob": "2.0.1"
+ }
+ },
+ "globals": {
+ "version": "8.18.0",
+ "bundled": true,
+ "dev": true
+ },
+ "graceful-fs": {
+ "version": "4.1.4",
+ "bundled": true,
+ "dev": true
+ },
+ "handlebars": {
+ "version": "4.0.5",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "async": "1.5.2",
+ "optimist": "0.6.1",
+ "source-map": "0.4.4",
+ "uglify-js": "2.7.0"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.4.4",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "amdefine": "1.0.0"
+ }
+ }
+ }
+ },
+ "has-ansi": {
+ "version": "2.0.0",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "ansi-regex": "2.0.0"
+ }
+ },
+ "has-flag": {
+ "version": "1.0.0",
+ "bundled": true,
+ "dev": true
+ },
+ "hosted-git-info": {
+ "version": "2.1.5",
+ "bundled": true,
+ "dev": true
+ },
+ "imurmurhash": {
+ "version": "0.1.4",
+ "bundled": true,
+ "dev": true
+ },
+ "inflight": {
+ "version": "1.0.5",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "once": "1.3.3",
+ "wrappy": "1.0.2"
+ }
+ },
+ "inherits": {
+ "version": "2.0.1",
+ "bundled": true,
+ "dev": true
+ },
+ "invariant": {
+ "version": "2.2.1",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "loose-envify": "1.2.0"
+ }
+ },
+ "invert-kv": {
+ "version": "1.0.0",
+ "bundled": true,
+ "dev": true
+ },
+ "is-arrayish": {
+ "version": "0.2.1",
+ "bundled": true,
+ "dev": true
+ },
+ "is-buffer": {
+ "version": "1.1.3",
+ "bundled": true,
+ "dev": true
+ },
+ "is-builtin-module": {
+ "version": "1.0.0",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "builtin-modules": "1.1.1"
+ }
+ },
+ "is-dotfile": {
+ "version": "1.0.2",
+ "bundled": true,
+ "dev": true
+ },
+ "is-equal-shallow": {
+ "version": "0.1.3",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "is-primitive": "2.0.0"
+ }
+ },
+ "is-extendable": {
+ "version": "0.1.1",
+ "bundled": true,
+ "dev": true
+ },
+ "is-extglob": {
+ "version": "1.0.0",
+ "bundled": true,
+ "dev": true
+ },
+ "is-finite": {
+ "version": "1.0.1",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "number-is-nan": "1.0.0"
+ }
+ },
+ "is-fullwidth-code-point": {
+ "version": "1.0.0",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "number-is-nan": "1.0.0"
+ }
+ },
+ "is-glob": {
+ "version": "2.0.1",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "is-extglob": "1.0.0"
+ }
+ },
+ "is-number": {
+ "version": "2.1.0",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "kind-of": "3.0.3"
+ }
+ },
+ "is-posix-bracket": {
+ "version": "0.1.1",
+ "bundled": true,
+ "dev": true
+ },
+ "is-primitive": {
+ "version": "2.0.0",
+ "bundled": true,
+ "dev": true
+ },
+ "is-utf8": {
+ "version": "0.2.1",
+ "bundled": true,
+ "dev": true
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "bundled": true,
+ "dev": true
+ },
+ "isexe": {
+ "version": "1.1.2",
+ "bundled": true,
+ "dev": true
+ },
+ "isobject": {
+ "version": "2.1.0",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "isarray": "1.0.0"
+ }
+ },
+ "istanbul-lib-coverage": {
+ "version": "1.0.0-alpha.4",
+ "bundled": true,
+ "dev": true
+ },
+ "istanbul-lib-hook": {
+ "version": "1.0.0-alpha.4",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "append-transform": "0.3.0"
+ }
+ },
+ "istanbul-lib-instrument": {
+ "version": "1.1.0-alpha.4",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "babel-generator": "6.11.4",
+ "babel-template": "6.9.0",
+ "babel-traverse": "6.11.4",
+ "babel-types": "6.11.1",
+ "babylon": "6.8.4",
+ "istanbul-lib-coverage": "1.0.0-alpha.4"
+ }
+ },
+ "istanbul-lib-report": {
+ "version": "1.0.0-alpha.3",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "async": "1.5.2",
+ "istanbul-lib-coverage": "1.0.0-alpha.4",
+ "mkdirp": "0.5.1",
+ "path-parse": "1.0.5",
+ "rimraf": "2.5.4",
+ "supports-color": "3.1.2"
+ },
+ "dependencies": {
+ "supports-color": {
+ "version": "3.1.2",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "has-flag": "1.0.0"
+ }
+ }
+ }
+ },
+ "istanbul-lib-source-maps": {
+ "version": "1.0.0-alpha.10",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "istanbul-lib-coverage": "1.0.0-alpha.4",
+ "mkdirp": "0.5.1",
+ "rimraf": "2.5.4",
+ "source-map": "0.5.6"
+ }
+ },
+ "istanbul-reports": {
+ "version": "1.0.0-alpha.8",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "handlebars": "4.0.5"
+ }
+ },
+ "js-tokens": {
+ "version": "2.0.0",
+ "bundled": true,
+ "dev": true
+ },
+ "kind-of": {
+ "version": "3.0.3",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.3"
+ }
+ },
+ "lazy-cache": {
+ "version": "1.0.4",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "lcid": {
+ "version": "1.0.0",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "invert-kv": "1.0.0"
+ }
+ },
+ "load-json-file": {
+ "version": "1.1.0",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "graceful-fs": "4.1.4",
+ "parse-json": "2.2.0",
+ "pify": "2.3.0",
+ "pinkie-promise": "2.0.1",
+ "strip-bom": "2.0.0"
+ }
+ },
+ "lodash": {
+ "version": "4.13.1",
+ "bundled": true,
+ "dev": true
+ },
+ "lodash.assign": {
+ "version": "4.0.9",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "lodash.keys": "4.0.7",
+ "lodash.rest": "4.0.3"
+ }
+ },
+ "lodash.keys": {
+ "version": "4.0.7",
+ "bundled": true,
+ "dev": true
+ },
+ "lodash.rest": {
+ "version": "4.0.3",
+ "bundled": true,
+ "dev": true
+ },
+ "longest": {
+ "version": "1.0.1",
+ "bundled": true,
+ "dev": true
+ },
+ "loose-envify": {
+ "version": "1.2.0",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "js-tokens": "1.0.3"
+ },
+ "dependencies": {
+ "js-tokens": {
+ "version": "1.0.3",
+ "bundled": true,
+ "dev": true
+ }
+ }
+ },
+ "lru-cache": {
+ "version": "4.0.1",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "pseudomap": "1.0.2",
+ "yallist": "2.0.0"
+ }
+ },
+ "md5-hex": {
+ "version": "1.3.0",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "md5-o-matic": "0.1.1"
+ }
+ },
+ "md5-o-matic": {
+ "version": "0.1.1",
+ "bundled": true,
+ "dev": true
+ },
+ "micromatch": {
+ "version": "2.3.11",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "arr-diff": "2.0.0",
+ "array-unique": "0.2.1",
+ "braces": "1.8.5",
+ "expand-brackets": "0.1.5",
+ "extglob": "0.3.2",
+ "filename-regex": "2.0.0",
+ "is-extglob": "1.0.0",
+ "is-glob": "2.0.1",
+ "kind-of": "3.0.3",
+ "normalize-path": "2.0.1",
+ "object.omit": "2.0.0",
+ "parse-glob": "3.0.4",
+ "regex-cache": "0.4.3"
+ }
+ },
+ "minimatch": {
+ "version": "3.0.2",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "brace-expansion": "1.1.6"
+ }
+ },
+ "minimist": {
+ "version": "0.0.8",
+ "bundled": true,
+ "dev": true
+ },
+ "mkdirp": {
+ "version": "0.5.1",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "minimist": "0.0.8"
+ }
+ },
+ "ms": {
+ "version": "0.7.1",
+ "bundled": true,
+ "dev": true
+ },
+ "normalize-package-data": {
+ "version": "2.3.5",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "hosted-git-info": "2.1.5",
+ "is-builtin-module": "1.0.0",
+ "semver": "5.3.0",
+ "validate-npm-package-license": "3.0.1"
+ }
+ },
+ "normalize-path": {
+ "version": "2.0.1",
+ "bundled": true,
+ "dev": true
+ },
+ "number-is-nan": {
+ "version": "1.0.0",
+ "bundled": true,
+ "dev": true
+ },
+ "object.omit": {
+ "version": "2.0.0",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "for-own": "0.1.4",
+ "is-extendable": "0.1.1"
+ }
+ },
+ "once": {
+ "version": "1.3.3",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "wrappy": "1.0.2"
+ }
+ },
+ "optimist": {
+ "version": "0.6.1",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "minimist": "0.0.8",
+ "wordwrap": "0.0.3"
+ }
+ },
+ "os-homedir": {
+ "version": "1.0.1",
+ "bundled": true,
+ "dev": true
+ },
+ "os-locale": {
+ "version": "1.4.0",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "lcid": "1.0.0"
+ }
+ },
+ "parse-glob": {
+ "version": "3.0.4",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "glob-base": "0.3.0",
+ "is-dotfile": "1.0.2",
+ "is-extglob": "1.0.0",
+ "is-glob": "2.0.1"
+ }
+ },
+ "parse-json": {
+ "version": "2.2.0",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "error-ex": "1.3.0"
+ }
+ },
+ "path-exists": {
+ "version": "2.1.0",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "pinkie-promise": "2.0.1"
+ }
+ },
+ "path-is-absolute": {
+ "version": "1.0.0",
+ "bundled": true,
+ "dev": true
+ },
+ "path-parse": {
+ "version": "1.0.5",
+ "bundled": true,
+ "dev": true
+ },
+ "path-type": {
+ "version": "1.1.0",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "graceful-fs": "4.1.4",
+ "pify": "2.3.0",
+ "pinkie-promise": "2.0.1"
+ }
+ },
+ "pify": {
+ "version": "2.3.0",
+ "bundled": true,
+ "dev": true
+ },
+ "pinkie": {
+ "version": "2.0.4",
+ "bundled": true,
+ "dev": true
+ },
+ "pinkie-promise": {
+ "version": "2.0.1",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "pinkie": "2.0.4"
+ }
+ },
+ "pkg-dir": {
+ "version": "1.0.0",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "find-up": "1.1.2"
+ }
+ },
+ "pkg-up": {
+ "version": "1.0.0",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "find-up": "1.1.2"
+ }
+ },
+ "preserve": {
+ "version": "0.2.0",
+ "bundled": true,
+ "dev": true
+ },
+ "pseudomap": {
+ "version": "1.0.2",
+ "bundled": true,
+ "dev": true
+ },
+ "randomatic": {
+ "version": "1.1.5",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "is-number": "2.1.0",
+ "kind-of": "3.0.3"
+ }
+ },
+ "read-pkg": {
+ "version": "1.1.0",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "load-json-file": "1.1.0",
+ "normalize-package-data": "2.3.5",
+ "path-type": "1.1.0"
+ }
+ },
+ "read-pkg-up": {
+ "version": "1.0.1",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "find-up": "1.1.2",
+ "read-pkg": "1.1.0"
+ }
+ },
+ "regenerator-runtime": {
+ "version": "0.9.5",
+ "bundled": true,
+ "dev": true
+ },
+ "regex-cache": {
+ "version": "0.4.3",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "is-equal-shallow": "0.1.3",
+ "is-primitive": "2.0.0"
+ }
+ },
+ "repeat-element": {
+ "version": "1.1.2",
+ "bundled": true,
+ "dev": true
+ },
+ "repeat-string": {
+ "version": "1.5.4",
+ "bundled": true,
+ "dev": true
+ },
+ "repeating": {
+ "version": "1.1.3",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "is-finite": "1.0.1"
+ }
+ },
+ "require-directory": {
+ "version": "2.1.1",
+ "bundled": true,
+ "dev": true
+ },
+ "require-main-filename": {
+ "version": "1.0.1",
+ "bundled": true,
+ "dev": true
+ },
+ "resolve-from": {
+ "version": "2.0.0",
+ "bundled": true,
+ "dev": true
+ },
+ "right-align": {
+ "version": "0.1.3",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "align-text": "0.1.4"
+ }
+ },
+ "rimraf": {
+ "version": "2.5.4",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "glob": "7.0.5"
+ }
+ },
+ "semver": {
+ "version": "5.3.0",
+ "bundled": true,
+ "dev": true
+ },
+ "set-blocking": {
+ "version": "2.0.0",
+ "bundled": true,
+ "dev": true
+ },
+ "signal-exit": {
+ "version": "3.0.0",
+ "bundled": true,
+ "dev": true
+ },
+ "slide": {
+ "version": "1.1.6",
+ "bundled": true,
+ "dev": true
+ },
+ "source-map": {
+ "version": "0.5.6",
+ "bundled": true,
+ "dev": true
+ },
+ "spawn-wrap": {
+ "version": "1.2.4",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "foreground-child": "1.5.3",
+ "mkdirp": "0.5.1",
+ "os-homedir": "1.0.1",
+ "rimraf": "2.5.4",
+ "signal-exit": "2.1.2",
+ "which": "1.2.10"
+ },
+ "dependencies": {
+ "signal-exit": {
+ "version": "2.1.2",
+ "bundled": true,
+ "dev": true
+ }
+ }
+ },
+ "spdx-correct": {
+ "version": "1.0.2",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "spdx-license-ids": "1.2.1"
+ }
+ },
+ "spdx-exceptions": {
+ "version": "1.0.5",
+ "bundled": true,
+ "dev": true
+ },
+ "spdx-expression-parse": {
+ "version": "1.0.2",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "spdx-exceptions": "1.0.5",
+ "spdx-license-ids": "1.2.1"
+ }
+ },
+ "spdx-license-ids": {
+ "version": "1.2.1",
+ "bundled": true,
+ "dev": true
+ },
+ "string-width": {
+ "version": "1.0.1",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "code-point-at": "1.0.0",
+ "is-fullwidth-code-point": "1.0.0",
+ "strip-ansi": "3.0.1"
+ }
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "ansi-regex": "2.0.0"
+ }
+ },
+ "strip-bom": {
+ "version": "2.0.0",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "is-utf8": "0.2.1"
+ }
+ },
+ "supports-color": {
+ "version": "2.0.0",
+ "bundled": true,
+ "dev": true
+ },
+ "test-exclude": {
+ "version": "1.1.0",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "arrify": "1.0.1",
+ "lodash.assign": "4.0.9",
+ "micromatch": "2.3.11",
+ "read-pkg-up": "1.0.1",
+ "require-main-filename": "1.0.1"
+ }
+ },
+ "to-fast-properties": {
+ "version": "1.0.2",
+ "bundled": true,
+ "dev": true
+ },
+ "uglify-js": {
+ "version": "2.7.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "async": "0.2.10",
+ "source-map": "0.5.6",
+ "uglify-to-browserify": "1.0.2",
+ "yargs": "3.10.0"
+ },
+ "dependencies": {
+ "async": {
+ "version": "0.2.10",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "yargs": {
+ "version": "3.10.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "camelcase": "1.2.1",
+ "cliui": "2.1.0",
+ "decamelize": "1.2.0",
+ "window-size": "0.1.0"
+ }
+ }
+ }
+ },
+ "uglify-to-browserify": {
+ "version": "1.0.2",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "validate-npm-package-license": {
+ "version": "3.0.1",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "spdx-correct": "1.0.2",
+ "spdx-expression-parse": "1.0.2"
+ }
+ },
+ "which": {
+ "version": "1.2.10",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "isexe": "1.1.2"
+ }
+ },
+ "which-module": {
+ "version": "1.0.0",
+ "bundled": true,
+ "dev": true
+ },
+ "window-size": {
+ "version": "0.1.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "wordwrap": {
+ "version": "0.0.3",
+ "bundled": true,
+ "dev": true
+ },
+ "wrap-ansi": {
+ "version": "2.0.0",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "string-width": "1.0.1"
+ }
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "bundled": true,
+ "dev": true
+ },
+ "write-file-atomic": {
+ "version": "1.1.4",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "graceful-fs": "4.1.4",
+ "imurmurhash": "0.1.4",
+ "slide": "1.1.6"
+ }
+ },
+ "y18n": {
+ "version": "3.2.1",
+ "bundled": true,
+ "dev": true
+ },
+ "yallist": {
+ "version": "2.0.0",
+ "bundled": true,
+ "dev": true
+ },
+ "yargs": {
+ "version": "4.8.1",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "cliui": "3.2.0",
+ "decamelize": "1.2.0",
+ "get-caller-file": "1.0.1",
+ "lodash.assign": "4.0.9",
+ "os-locale": "1.4.0",
+ "read-pkg-up": "1.0.1",
+ "require-directory": "2.1.1",
+ "require-main-filename": "1.0.1",
+ "set-blocking": "2.0.0",
+ "string-width": "1.0.1",
+ "which-module": "1.0.0",
+ "window-size": "0.2.0",
+ "y18n": "3.2.1",
+ "yargs-parser": "2.4.1"
+ },
+ "dependencies": {
+ "cliui": {
+ "version": "3.2.0",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "string-width": "1.0.1",
+ "strip-ansi": "3.0.1",
+ "wrap-ansi": "2.0.0"
+ }
+ },
+ "window-size": {
+ "version": "0.2.0",
+ "bundled": true,
+ "dev": true
+ }
+ }
+ },
+ "yargs-parser": {
+ "version": "2.4.1",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "camelcase": "3.0.0",
+ "lodash.assign": "4.0.9"
+ },
+ "dependencies": {
+ "camelcase": {
+ "version": "3.0.0",
+ "bundled": true,
+ "dev": true
+ }
+ }
+ }
+ }
+ },
+ "oauth-sign": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
+ "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=",
+ "dev": true
+ },
+ "only-shallow": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/only-shallow/-/only-shallow-1.2.0.tgz",
+ "integrity": "sha1-cc7O26kyS8BRiu8Q7AgNMkncJGU=",
+ "dev": true
+ },
+ "opener": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/opener/-/opener-1.4.3.tgz",
+ "integrity": "sha1-XG2ixdflgx6P+jlklQ+NZnSskLg=",
+ "dev": true
+ },
+ "os-homedir": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.1.tgz",
+ "integrity": "sha1-DWK99EuRb9O73PLKsZGUj7CU8Ac=",
+ "dev": true
+ },
+ "pinkie": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
+ "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
+ "dev": true
+ },
+ "pinkie-promise": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+ "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
+ "dev": true,
+ "requires": {
+ "pinkie": "2.0.4"
+ }
+ },
+ "process-nextick-args": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
+ "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=",
+ "dev": true
+ },
+ "pseudomap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
+ "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
+ "dev": true
+ },
+ "punycode": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+ "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
+ "dev": true
+ },
+ "qs": {
+ "version": "6.3.2",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.3.2.tgz",
+ "integrity": "sha1-51vV9uJoEioqDgvaYwslUMFmUCw=",
+ "dev": true
+ },
+ "readable-stream": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
+ "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
+ "dev": true,
+ "requires": {
+ "core-util-is": "1.0.2",
+ "inherits": "2.0.3",
+ "isarray": "1.0.0",
+ "process-nextick-args": "1.0.7",
+ "safe-buffer": "5.1.1",
+ "string_decoder": "1.0.3",
+ "util-deprecate": "1.0.2"
+ }
+ },
+ "request": {
+ "version": "2.79.0",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.79.0.tgz",
+ "integrity": "sha1-Tf5b9r6LjNw3/Pk+BLZVd3InEN4=",
+ "dev": true,
+ "requires": {
+ "aws-sign2": "0.6.0",
+ "aws4": "1.6.0",
+ "caseless": "0.11.0",
+ "combined-stream": "1.0.5",
+ "extend": "3.0.1",
+ "forever-agent": "0.6.1",
+ "form-data": "2.1.4",
+ "har-validator": "2.0.6",
+ "hawk": "3.1.3",
+ "http-signature": "1.1.1",
+ "is-typedarray": "1.0.0",
+ "isstream": "0.1.2",
+ "json-stringify-safe": "5.0.1",
+ "mime-types": "2.1.17",
+ "oauth-sign": "0.8.2",
+ "qs": "6.3.2",
+ "stringstream": "0.0.5",
+ "tough-cookie": "2.3.3",
+ "tunnel-agent": "0.4.3",
+ "uuid": "3.1.0"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
+ "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==",
+ "dev": true
+ },
+ "signal-exit": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
+ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
+ "dev": true
+ },
+ "sntp": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz",
+ "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=",
+ "dev": true,
+ "requires": {
+ "hoek": "2.16.3"
+ }
+ },
+ "sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+ "dev": true
+ },
+ "sshpk": {
+ "version": "1.13.1",
+ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz",
+ "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=",
+ "dev": true,
+ "requires": {
+ "asn1": "0.2.3",
+ "assert-plus": "1.0.0",
+ "bcrypt-pbkdf": "1.0.1",
+ "dashdash": "1.14.1",
+ "ecc-jsbn": "0.1.1",
+ "getpass": "0.1.7",
+ "jsbn": "0.1.1",
+ "tweetnacl": "0.14.5"
+ },
+ "dependencies": {
+ "assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+ "dev": true
+ }
+ }
+ },
+ "stack-utils": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-0.4.0.tgz",
+ "integrity": "sha1-lAy4L8z6hOj/Lz/fKT/ngBa+zNE=",
+ "dev": true
+ },
+ "string_decoder": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
+ "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "5.1.1"
+ }
+ },
+ "stringstream": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
+ "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=",
+ "dev": true
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "2.1.1"
+ }
+ },
+ "tap-mocha-reporter": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/tap-mocha-reporter/-/tap-mocha-reporter-2.0.1.tgz",
+ "integrity": "sha1-xwMWFz1uOhbFjhupLV1s2N5YoS4=",
+ "dev": true,
+ "requires": {
+ "color-support": "1.1.3",
+ "debug": "2.6.9",
+ "diff": "1.4.0",
+ "escape-string-regexp": "1.0.5",
+ "glob": "7.1.2",
+ "js-yaml": "3.10.0",
+ "readable-stream": "2.3.3",
+ "tap-parser": "2.2.3",
+ "unicode-length": "1.0.3"
+ }
+ },
+ "tap-parser": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-2.2.3.tgz",
+ "integrity": "sha1-rebpbje/04zg8WLaBn80A08GiwE=",
+ "dev": true,
+ "requires": {
+ "events-to-array": "1.1.2",
+ "js-yaml": "3.10.0",
+ "readable-stream": "2.3.3"
+ }
+ },
+ "tmatch": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/tmatch/-/tmatch-2.0.1.tgz",
+ "integrity": "sha1-DFYkbzPzDaG409colauvFmYPOM8=",
+ "dev": true
+ },
+ "tough-cookie": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz",
+ "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=",
+ "dev": true,
+ "requires": {
+ "punycode": "1.4.1"
+ }
+ },
+ "tunnel-agent": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz",
+ "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=",
+ "dev": true
+ },
+ "tweetnacl": {
+ "version": "0.14.5",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+ "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
+ "dev": true,
+ "optional": true
+ },
+ "unicode-length": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/unicode-length/-/unicode-length-1.0.3.tgz",
+ "integrity": "sha1-Wtp6f+1RhBpBijKM8UlHisg1irs=",
+ "dev": true,
+ "requires": {
+ "punycode": "1.4.1",
+ "strip-ansi": "3.0.1"
+ }
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
+ "dev": true
+ },
+ "uuid": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz",
+ "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==",
+ "dev": true
+ },
+ "verror": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+ "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "1.0.0",
+ "core-util-is": "1.0.2",
+ "extsprintf": "1.3.0"
+ },
+ "dependencies": {
+ "assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+ "dev": true
+ }
+ }
+ },
+ "which": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz",
+ "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==",
+ "dev": true,
+ "requires": {
+ "isexe": "2.0.0"
+ },
+ "dependencies": {
+ "isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+ "dev": true
+ }
+ }
+ },
+ "xtend": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
+ "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
+ "dev": true
+ },
+ "yallist": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+ "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
+ "dev": true
+ }
+ }
+ },
+ "thenify": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.0.tgz",
+ "integrity": "sha1-5p44obq+lpsBCCB5eLn2K4hgSDk=",
+ "requires": {
+ "any-promise": "1.3.0"
+ }
+ },
+ "thenify-all": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
+ "integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=",
+ "requires": {
+ "thenify": "3.3.0"
+ }
+ },
+ "through": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
+ },
+ "unix-crypt-td-js": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unix-crypt-td-js/-/unix-crypt-td-js-1.0.0.tgz",
+ "integrity": "sha1-HAgkFQSBvHoB1J6Y8exmjYJBLzs="
+ },
+ "unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
+ },
+ "update-notifier": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.2.0.tgz",
+ "integrity": "sha1-G1g3z5DAc22IYncytmHBOPht5y8=",
+ "requires": {
+ "boxen": "1.2.1",
+ "chalk": "1.1.3",
+ "configstore": "3.1.1",
+ "import-lazy": "2.1.0",
+ "is-npm": "1.0.0",
+ "latest-version": "3.1.0",
+ "semver-diff": "2.1.0",
+ "xdg-basedir": "3.0.0"
+ },
+ "dependencies": {
+ "ansi-align": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz",
+ "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=",
+ "requires": {
+ "string-width": "2.1.1"
+ }
+ },
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="
+ },
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "requires": {
+ "color-convert": "1.9.0"
+ }
+ },
+ "boxen": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.2.1.tgz",
+ "integrity": "sha1-DxHn/jRO25OXl3/BPt5/ZNlWSB0=",
+ "requires": {
+ "ansi-align": "2.0.0",
+ "camelcase": "4.1.0",
+ "chalk": "2.1.0",
+ "cli-boxes": "1.0.0",
+ "string-width": "2.1.1",
+ "term-size": "1.2.0",
+ "widest-line": "1.0.0"
+ },
+ "dependencies": {
+ "chalk": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+ "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.4.0"
+ }
+ }
+ }
+ },
+ "camelcase": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
+ "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0="
+ },
+ "capture-stack-trace": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz",
+ "integrity": "sha1-Sm+gc5nCa7pH8LJJa00PtAjFVQ0="
+ },
+ "cli-boxes": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz",
+ "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM="
+ },
+ "code-point-at": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
+ },
+ "color-convert": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.0.tgz",
+ "integrity": "sha1-Gsz5fdc5uYO/mU1W/sj5WFNkG3o=",
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
+ },
+ "configstore": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.1.tgz",
+ "integrity": "sha512-5oNkD/L++l0O6xGXxb1EWS7SivtjfGQlRyxJsYgE0Z495/L81e2h4/d3r969hoPXuFItzNOKMtsXgYG4c7dYvw==",
+ "requires": {
+ "dot-prop": "4.2.0",
+ "graceful-fs": "4.1.11",
+ "make-dir": "1.0.0",
+ "unique-string": "1.0.0",
+ "write-file-atomic": "2.3.0",
+ "xdg-basedir": "3.0.0"
+ }
+ },
+ "create-error-class": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz",
+ "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=",
+ "requires": {
+ "capture-stack-trace": "1.0.0"
+ }
+ },
+ "cross-spawn": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
+ "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
+ "requires": {
+ "lru-cache": "4.1.1",
+ "shebang-command": "1.2.0",
+ "which": "1.3.0"
+ }
+ },
+ "crypto-random-string": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz",
+ "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4="
+ },
+ "deep-extend": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz",
+ "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8="
+ },
+ "dot-prop": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz",
+ "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==",
+ "requires": {
+ "is-obj": "1.0.1"
+ }
+ },
+ "duplexer3": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
+ "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI="
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
+ },
+ "execa": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz",
+ "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=",
+ "requires": {
+ "cross-spawn": "5.1.0",
+ "get-stream": "3.0.0",
+ "is-stream": "1.1.0",
+ "npm-run-path": "2.0.2",
+ "p-finally": "1.0.0",
+ "signal-exit": "3.0.2",
+ "strip-eof": "1.0.0"
+ }
+ },
+ "get-stream": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
+ "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ="
+ },
+ "got": {
+ "version": "6.7.1",
+ "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz",
+ "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=",
+ "requires": {
+ "create-error-class": "3.0.2",
+ "duplexer3": "0.1.4",
+ "get-stream": "3.0.0",
+ "is-redirect": "1.0.0",
+ "is-retry-allowed": "1.1.0",
+ "is-stream": "1.1.0",
+ "lowercase-keys": "1.0.0",
+ "safe-buffer": "5.1.1",
+ "timed-out": "4.0.1",
+ "unzip-response": "2.0.1",
+ "url-parse-lax": "1.0.0"
+ }
+ },
+ "graceful-fs": {
+ "version": "4.1.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
+ "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg="
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE="
+ },
+ "import-lazy": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz",
+ "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM="
+ },
+ "imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o="
+ },
+ "ini": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz",
+ "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4="
+ },
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="
+ },
+ "is-npm": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz",
+ "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ="
+ },
+ "is-obj": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
+ "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8="
+ },
+ "is-redirect": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz",
+ "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ="
+ },
+ "is-retry-allowed": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz",
+ "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ="
+ },
+ "is-stream": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+ "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
+ },
+ "isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
+ },
+ "latest-version": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz",
+ "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=",
+ "requires": {
+ "package-json": "4.0.1"
+ }
+ },
+ "lowercase-keys": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz",
+ "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY="
+ },
+ "lru-cache": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz",
+ "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==",
+ "requires": {
+ "pseudomap": "1.0.2",
+ "yallist": "2.1.2"
+ }
+ },
+ "make-dir": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.0.0.tgz",
+ "integrity": "sha1-l6ARdR6R3YfPre9Ygy67BJNt6Xg=",
+ "requires": {
+ "pify": "2.3.0"
+ }
+ },
+ "minimist": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
+ },
+ "npm-run-path": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
+ "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
+ "requires": {
+ "path-key": "2.0.1"
+ }
+ },
+ "number-is-nan": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
+ "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
+ },
+ "p-finally": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
+ "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4="
+ },
+ "package-json": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz",
+ "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=",
+ "requires": {
+ "got": "6.7.1",
+ "registry-auth-token": "3.3.1",
+ "registry-url": "3.1.0",
+ "semver": "5.4.1"
+ }
+ },
+ "path-key": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+ "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A="
+ },
+ "pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw="
+ },
+ "prepend-http": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
+ "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw="
+ },
+ "pseudomap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
+ "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM="
+ },
+ "rc": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.1.tgz",
+ "integrity": "sha1-LgPo5C7kULjLPc5lvhv4l04d/ZU=",
+ "requires": {
+ "deep-extend": "0.4.2",
+ "ini": "1.3.4",
+ "minimist": "1.2.0",
+ "strip-json-comments": "2.0.1"
+ }
+ },
+ "registry-auth-token": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.1.tgz",
+ "integrity": "sha1-+w0yie4Nmtosu1KvXf5mywcNMAY=",
+ "requires": {
+ "rc": "1.2.1",
+ "safe-buffer": "5.1.1"
+ }
+ },
+ "registry-url": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz",
+ "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=",
+ "requires": {
+ "rc": "1.2.1"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
+ "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
+ },
+ "semver": {
+ "version": "5.4.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz",
+ "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg=="
+ },
+ "semver-diff": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz",
+ "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=",
+ "requires": {
+ "semver": "5.4.1"
+ }
+ },
+ "shebang-command": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+ "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+ "requires": {
+ "shebang-regex": "1.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+ "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM="
+ },
+ "signal-exit": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
+ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0="
+ },
+ "string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "requires": {
+ "is-fullwidth-code-point": "2.0.0",
+ "strip-ansi": "4.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "requires": {
+ "ansi-regex": "3.0.0"
+ }
+ },
+ "strip-eof": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
+ "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8="
+ },
+ "strip-json-comments": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+ "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo="
+ },
+ "supports-color": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+ "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ },
+ "term-size": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz",
+ "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=",
+ "requires": {
+ "execa": "0.7.0"
+ }
+ },
+ "timed-out": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz",
+ "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8="
+ },
+ "unique-string": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz",
+ "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=",
+ "requires": {
+ "crypto-random-string": "1.0.0"
+ }
+ },
+ "unzip-response": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz",
+ "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c="
+ },
+ "url-parse-lax": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz",
+ "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=",
+ "requires": {
+ "prepend-http": "1.0.4"
+ }
+ },
+ "which": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz",
+ "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==",
+ "requires": {
+ "isexe": "2.0.0"
+ }
+ },
+ "widest-line": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-1.0.0.tgz",
+ "integrity": "sha1-DAnIXCqUaD0Nfq+O4JfVZL8OEFw=",
+ "requires": {
+ "string-width": "1.0.2"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
+ },
+ "is-fullwidth-code-point": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+ "requires": {
+ "number-is-nan": "1.0.1"
+ }
+ },
+ "string-width": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+ "requires": {
+ "code-point-at": "1.1.0",
+ "is-fullwidth-code-point": "1.0.0",
+ "strip-ansi": "3.0.1"
+ }
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "requires": {
+ "ansi-regex": "2.1.1"
+ }
+ }
+ }
+ },
+ "write-file-atomic": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.3.0.tgz",
+ "integrity": "sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA==",
+ "requires": {
+ "graceful-fs": "4.1.11",
+ "imurmurhash": "0.1.4",
+ "signal-exit": "3.0.2"
+ }
+ },
+ "xdg-basedir": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz",
+ "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ="
+ },
+ "yallist": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+ "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI="
+ }
+ }
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
+ },
+ "utils-merge": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz",
+ "integrity": "sha1-ApT7kiu5N1FTVBxPcJYjHyh8ivg="
+ },
+ "uuid": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz",
+ "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g=="
+ },
+ "vary": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+ "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
+ },
+ "websocket-driver": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.0.tgz",
+ "integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=",
+ "requires": {
+ "http-parser-js": "0.4.9",
+ "websocket-extensions": "0.1.2"
+ }
+ },
+ "websocket-extensions": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.2.tgz",
+ "integrity": "sha1-Dhh4HeYpoYMIzhSBZQ9n/6JpOl0="
+ }
+ }
+}
diff --git a/package.json b/package.json
index 36871314c..d9aab8d89 100644
--- a/package.json
+++ b/package.json
@@ -1,26 +1,31 @@
{
- "name": "patternlab-node",
+ "name": "@pattern-lab/patternlab-node",
"description": "Pattern Lab is a collection of tools to help you create atomic design systems. This is the node command line interface (CLI).",
- "version": "2.12.0",
+ "version": "3.0.0-alpha.1",
"main": "./core/lib/patternlab.js",
"dependencies": {
+ "async": "^2.1.2",
"chalk": "^1.1.3",
+ "chokidar": "^1.7.0",
+ "dive": "^0.5.0",
"diveSync": "^0.3.0",
"fs-extra": "^0.30.0",
+ "fs-promise": "^1.0.0",
"glob": "^7.0.0",
"graphlib": "^2.1.1",
"js-beautify": "^1.6.3",
"js-yaml": "^3.6.1",
+ "live-server": "github:pattern-lab/live-server#d46ec21",
"lodash": "~4.13.1",
"markdown-it": "^6.0.1",
"node-fetch": "^1.6.0",
- "patternengine-node-mustache": "^1.0.0",
+ "recursive-copy": "^2.0.6",
"update-notifier": "^2.2.0"
},
"devDependencies": {
- "eslint": "^3.5.0",
- "rewire": "^2.5.2",
- "tap": "^7.1.2"
+ "eslint": "3.5.0",
+ "rewire": "2.5.2",
+ "tap": "7.1.2"
},
"keywords": [
"Pattern Lab",
@@ -51,10 +56,11 @@
],
"license": "MIT",
"scripts": {
- "test": "eslint core/**/*.js && tap test/*_tests.js --reporter spec",
- "lint": "eslint core/**/*.js"
+ "lint": "eslint core/**/*.js",
+ "pretest": "npm run lint",
+ "test": "tap test/*_tests.js --reporter spec --coverage"
},
"engines": {
- "node": ">=4.0"
+ "node": ">=6.0"
}
}
diff --git a/pattern_exports/test-paramParent.html b/pattern_exports/test-paramParent.html
new file mode 100644
index 000000000..2c75ed8b1
--- /dev/null
+++ b/pattern_exports/test-paramParent.html
@@ -0,0 +1,4 @@
+
+
diff --git a/patternlab-config.json b/patternlab-config.json
index 70ff944c7..dc3021cc6 100644
--- a/patternlab-config.json
+++ b/patternlab-config.json
@@ -47,11 +47,12 @@
"tools-all": false,
"tools-docs": false
},
- "ishMinimum": "240",
- "ishMaximum": "2600",
- "patternStateCascade": ["inprogress", "inreview", "complete"],
- "patternStates": {
+ "ishViewportRange": {
+ "s": [240, 500],
+ "m": [500, 800],
+ "l": [800, 2600]
},
+ "patternStateCascade": ["inprogress", "inreview", "complete"],
"patternExportPatternPartials": [],
"patternExportDirectory": "./pattern_exports/",
"cacheBust": true,
@@ -61,5 +62,10 @@
"markupOnly": ".markup-only"
},
"cleanOutputHtml": true,
- "exportToGraphViz": false
+ "exportToGraphViz": false,
+ "theme": {
+ "color": "dark",
+ "density": "compact",
+ "layout": "horizontal"
+ }
}
diff --git a/test/asset_copy_tests.js b/test/asset_copy_tests.js
new file mode 100644
index 000000000..9d2346912
--- /dev/null
+++ b/test/asset_copy_tests.js
@@ -0,0 +1,66 @@
+"use strict";
+
+var tap = require('tap');
+var rewire = require("rewire");
+var _ = require('lodash');
+var eol = require('os').EOL;
+var Pattern = require('../core/lib/object_factory').Pattern;
+var extend = require('util')._extend;
+var ac = rewire('../core/lib/asset_copy');
+var path = require('path');
+var config = require('./util/patternlab-config.json');
+
+var engineLoader = require('../core/lib/pattern_engines');
+engineLoader.loadAllEngines(config);
+
+//set up a global mocks - we don't want to be writing/rendering any files right now
+// var chokidarMock = {
+// watch: function (path, data, cb) { }
+// };
+
+// ac.__set__({
+// 'chokidar': chokidarMock,
+// });
+
+const assetCopier = ac();
+
+function createFakePatternLab(customProps) {
+ var pl = {
+ config: {
+ paths: {
+ source: {
+ img: './test/img',
+ css: './test/css'
+ },
+ public: {
+ img: './test/output/img',
+ css: './test/output/css'
+ }
+ },
+ styleGuideExcludes: [ ],
+ debug: false,
+ outputFileSuffixes: {
+ rendered: '.rendered',
+ rawTemplate: '',
+ markupOnly: '.markup-only'
+ }
+ },
+ data: {}
+ };
+ return extend(pl, customProps);
+}
+
+tap.test('transformConfigPaths takes configuration.paths() and maps to a better key store', function (test) {
+ //arrange
+ var patternlab = createFakePatternLab({});
+
+ //act
+ var result = assetCopier.transformConfigPaths(patternlab.config.paths);
+
+ //assert
+ test.equals(result.img.source, './test/img');
+ test.equals(result.img.public, './test/output/img');
+ test.equals(result.css.source, './test/css');
+ test.equals(result.css.public, './test/output/css');
+ test.end();
+});
diff --git a/test/engine_handlebars_tests.js b/test/engine_handlebars_tests.js
index 58a7085f6..53a2453e5 100644
--- a/test/engine_handlebars_tests.js
+++ b/test/engine_handlebars_tests.js
@@ -8,14 +8,16 @@ var Pattern = require('../core/lib/object_factory').Pattern;
var PatternGraph = require('../core/lib/pattern_graph').PatternGraph;
var testPatternsPath = path.resolve(__dirname, 'files', '_handlebars-test-patterns');
var eol = require('os').EOL;
+var config = require('./util/patternlab-config.json');
+var engineLoader = require('../core/lib/pattern_engines');
+engineLoader.loadAllEngines(config);
// don't run these tests unless handlebars is installed
-var engineLoader = require('../core/lib/pattern_engines');
if (!engineLoader.handlebars) {
tap.test('Handlebars engine not installed, skipping tests.', function (test) {
- test.end()
- })
- return
+ test.end();
+ });
+ return;
}
// fake pattern lab constructor:
@@ -81,11 +83,14 @@ tap.test('hello world handlebars pattern renders', function (test) {
// do all the normal processing of the pattern
var patternlab = new fakePatternLab();
var assembler = new pa();
- var helloWorldPattern = assembler.process_pattern_iterative(patternPath, patternlab);
- assembler.process_pattern_recursive(patternPath, patternlab);
+ var helloWorldPattern = assembler.load_pattern_iterative(patternPath, patternlab);
- test.equals(helloWorldPattern.render(), 'Hello world!' + eol);
- test.end();
+ return assembler.process_pattern_iterative(helloWorldPattern, patternlab)
+ .then((helloWorldPattern) => {
+ assembler.process_pattern_recursive(patternPath, patternlab);
+
+ test.equals(helloWorldPattern.render(), 'Hello world!' + eol);
+ });
});
tap.test('hello worlds handlebars pattern can see the atoms-helloworld partial and renders it twice', function (test) {
@@ -99,15 +104,20 @@ tap.test('hello worlds handlebars pattern can see the atoms-helloworld partial a
var patternlab = new fakePatternLab(); // environment
var assembler = new pa();
- // do all the normal processing of the pattern
- assembler.process_pattern_iterative(pattern1Path, patternlab);
- var helloWorldsPattern = assembler.process_pattern_iterative(pattern2Path, patternlab);
- assembler.process_pattern_recursive(pattern1Path, patternlab);
- assembler.process_pattern_recursive(pattern2Path, patternlab);
+ // do all the normal loading and processing of the pattern
+ const pattern1 = assembler.load_pattern_iterative(pattern1Path, patternlab);
+ const pattern2 = assembler.load_pattern_iterative(pattern2Path, patternlab);
- // test
- test.equals(helloWorldsPattern.render(), 'Hello world!' + eol + ' and Hello world!' + eol + eol);
- test.end();
+ return Promise.all([
+ assembler.process_pattern_iterative(pattern1, patternlab),
+ assembler.process_pattern_iterative(pattern2, patternlab)
+ ]).then(() => {
+ assembler.process_pattern_recursive(pattern1Path, patternlab);
+ assembler.process_pattern_recursive(pattern2Path, patternlab);
+
+ // test
+ test.equals(pattern2.render(), 'Hello world!' + eol + ' and Hello world!' + eol + eol);
+ });
});
tap.test('handlebars partials can render JSON values', function (test) {
@@ -121,12 +131,14 @@ tap.test('handlebars partials can render JSON values', function (test) {
var assembler = new pa();
// do all the normal processing of the pattern
- var helloWorldWithData = assembler.process_pattern_iterative(pattern1Path, patternlab);
- assembler.process_pattern_recursive(pattern1Path, patternlab);
+ var helloWorldWithData = assembler.load_pattern_iterative(pattern1Path, patternlab);
- // test
- test.equals(helloWorldWithData.render(), 'Hello world!' + eol + 'Yeah, we got the subtitle from the JSON.' + eol);
- test.end();
+ return assembler.process_pattern_iterative(helloWorldWithData, patternlab).then(() => {
+ assembler.process_pattern_recursive(pattern1Path, patternlab);
+
+ // test
+ test.equals(helloWorldWithData.render(), 'Hello world!' + eol + 'Yeah, we got the subtitle from the JSON.' + eol);
+ });
});
tap.test('handlebars partials use the JSON environment from the calling pattern and can accept passed parameters', function (test) {
@@ -141,14 +153,19 @@ tap.test('handlebars partials use the JSON environment from the calling pattern
var assembler = new pa();
// do all the normal processing of the pattern
- assembler.process_pattern_iterative(atomPath, patternlab);
- var mol = assembler.process_pattern_iterative(molPath, patternlab);
- assembler.process_pattern_recursive(atomPath, patternlab);
- assembler.process_pattern_recursive(molPath, patternlab);
-
- // test
- test.equals(mol.render(), 'Call with default JSON environment: ' + eol + 'This is Hello world!' + eol + 'from the default JSON.' + eol + eol + eol +'Call with passed parameter: ' + eol + 'However, this is Hello world!' + eol + 'from a totally different blob.' + eol + eol);
- test.end();
+ const atom = assembler.load_pattern_iterative(atomPath, patternlab);
+ const mol = assembler.load_pattern_iterative(molPath, patternlab);
+
+ return Promise.all([
+ assembler.process_pattern_iterative(atom, patternlab),
+ assembler.process_pattern_iterative(mol, patternlab)
+ ]).then(() => {
+ assembler.process_pattern_recursive(atomPath, patternlab);
+ assembler.process_pattern_recursive(molPath, patternlab);
+
+ // test
+ test.equals(mol.render(), 'Call with default JSON environment: ' + eol + 'This is Hello world!' + eol + 'from the default JSON.' + eol + eol + eol +'Call with passed parameter: ' + eol + 'However, this is Hello world!' + eol + 'from a totally different blob.' + eol + eol);
+ });
});
tap.test('find_pattern_partials finds partials', function (test) {
@@ -213,16 +230,21 @@ tap.test('hidden handlebars patterns can be called by their nice names', functio
var pattern_assembler = new pa();
var hiddenPatternPath = path.join('00-atoms', '00-global', '_00-hidden.hbs');
- var hiddenPattern = pattern_assembler.process_pattern_iterative(hiddenPatternPath, pl);
- pattern_assembler.process_pattern_recursive(hiddenPatternPath, pl);
-
var testPatternPath = path.join('00-molecules', '00-global', '00-hidden-pattern-tester.hbs');
- var testPattern = pattern_assembler.process_pattern_iterative(testPatternPath, pl);
- pattern_assembler.process_pattern_recursive(testPatternPath, pl);
- //act
- test.equals(util.sanitized(testPattern.render()), util.sanitized('Here\'s the hidden atom: [I\'m the hidden atom\n]\n'));
- test.end();
+ var hiddenPattern = pattern_assembler.load_pattern_iterative(hiddenPatternPath, pl);
+ var testPattern = pattern_assembler.load_pattern_iterative(testPatternPath, pl);
+
+ return Promise.all([
+ pattern_assembler.process_pattern_iterative(hiddenPattern, pl),
+ pattern_assembler.process_pattern_iterative(testPattern, pl)
+ ]).then(() => {
+ pattern_assembler.process_pattern_recursive(hiddenPatternPath, pl);
+ pattern_assembler.process_pattern_recursive(testPatternPath, pl);
+
+ //act
+ test.equals(util.sanitized(testPattern.render()), util.sanitized('Here\'s the hidden atom: [I\'m the hidden atom\n]\n'));
+ });
});
tap.test('@partial-block template should render without throwing (@geoffp repo issue #3)', function(test) {
@@ -233,13 +255,15 @@ tap.test('@partial-block template should render without throwing (@geoffp repo i
// do all the normal processing of the pattern
var patternlab = new fakePatternLab();
var assembler = new pa();
- var atPartialBlockPattern = assembler.process_pattern_iterative(patternPath, patternlab);
- assembler.process_pattern_recursive(patternPath, patternlab);
+ var atPartialBlockPattern = assembler.load_pattern_iterative(patternPath, patternlab);
- var results = '{{> @partial-block }}' + eol + 'It worked!' + eol;
- test.equal(atPartialBlockPattern.render(), results);
- test.end();
-})
+ return assembler.process_pattern_iterative(atPartialBlockPattern, patternlab).then(() => {
+ assembler.process_pattern_recursive(patternPath, patternlab);
+
+ var results = '{{> @partial-block }}' + eol + 'It worked!' + eol;
+ test.equal(atPartialBlockPattern.render(), results);
+ });
+});
tap.test('A template calling a @partial-block template should render correctly', function(test) {
test.plan(1);
@@ -253,13 +277,19 @@ tap.test('A template calling a @partial-block template should render correctly',
var assembler = new pa();
// do all the normal processing of the pattern
- assembler.process_pattern_iterative(pattern1Path, patternlab);
- var callAtPartialBlockPattern = assembler.process_pattern_iterative(pattern2Path, patternlab);
- assembler.process_pattern_recursive(pattern1Path, patternlab);
- assembler.process_pattern_recursive(pattern2Path, patternlab);
-
- // test
- var results = 'Hello World!' + eol + 'It worked!' + eol;
- test.equals(callAtPartialBlockPattern.render(), results);
- test.end();
-})
+ const pattern1 = assembler.load_pattern_iterative(pattern1Path, patternlab);
+ const callAtPartialBlockPattern = assembler.load_pattern_iterative(pattern2Path, patternlab);
+
+ return Promise.all([
+ assembler.process_pattern_iterative(pattern1, patternlab),
+ assembler.process_pattern_iterative(callAtPartialBlockPattern, patternlab)
+ ]).then(() => {
+ assembler.process_pattern_recursive(pattern1Path, patternlab);
+ assembler.process_pattern_recursive(pattern2Path, patternlab);
+
+ // test
+ var results = 'Hello World!' + eol + 'It worked!' + eol;
+ test.equals(callAtPartialBlockPattern.render(), results);
+ });
+
+});
diff --git a/test/engine_mustache_tests.js b/test/engine_mustache_tests.js
index 30d2c3048..77330ec8a 100644
--- a/test/engine_mustache_tests.js
+++ b/test/engine_mustache_tests.js
@@ -7,9 +7,11 @@ var Pattern = require('../core/lib/object_factory').Pattern;
var PatternGraph = require('../core/lib/pattern_graph').PatternGraph;
var testPatternsPath = path.resolve(__dirname, 'files', '_patterns');
var eol = require('os').EOL;
+var config = require('./util/patternlab-config.json');
// don't run these tests unless mustache is installed
var engineLoader = require('../core/lib/pattern_engines');
+engineLoader.loadAllEngines(config);
if (!engineLoader.mustache) {
tap.test('Mustache engine not installed, skipping tests.', function (test) {
test.end();
@@ -32,7 +34,7 @@ function fakePatternLab() {
data: {
link: {}
},
- config: require('../patternlab-config.json'),
+ config: config,
package: {}
};
diff --git a/test/engine_twig_tests.js b/test/engine_twig_tests.js
index d41b70901..713071462 100644
--- a/test/engine_twig_tests.js
+++ b/test/engine_twig_tests.js
@@ -81,11 +81,13 @@ tap.test('button twig pattern renders', function (test) {
// do all the normal processing of the pattern
var patternlab = new fakePatternLab();
var assembler = new pa();
- var helloWorldPattern = assembler.process_pattern_iterative(patternPath, patternlab);
- assembler.process_pattern_recursive(patternPath, patternlab);
+ var helloWorldPattern = assembler.load_pattern_iterative(patternPath, patternlab);
- test.equals(helloWorldPattern.render(), expectedValue);
- test.end();
+ return assembler.process_pattern_iterative(helloWorldPattern, patternlab).then(() => {
+ assembler.process_pattern_recursive(patternPath, patternlab);
+
+ test.equals(helloWorldPattern.render(), expectedValue);
+ });
});
tap.test('media object twig pattern can see the atoms-button and atoms-image partials and renders them', function (test) {
@@ -103,17 +105,23 @@ tap.test('media object twig pattern can see the atoms-button and atoms-image par
var assembler = new pa();
// do all the normal processing of the pattern
- assembler.process_pattern_iterative(buttonPatternPath, patternlab);
- assembler.process_pattern_iterative(imagePatternPath, patternlab);
- var mediaObjectPattern = assembler.process_pattern_iterative(mediaObjectPatternPath, patternlab);
- assembler.process_pattern_recursive(buttonPatternPath, patternlab);
- assembler.process_pattern_recursive(imagePatternPath, patternlab);
- assembler.process_pattern_recursive(mediaObjectPatternPath, patternlab);
-
- // test
- // this pattern is too long - so just remove line endings on both sides and compare output
- test.equals(mediaObjectPattern.render().replace(/\r?\n|\r/gm, ""), expectedValue.replace(/\r?\n|\r/gm, ""));
- test.end();
+ const buttonPattern = assembler.load_pattern_iterative(buttonPatternPath, patternlab);
+ const imagePattern = assembler.load_pattern_iterative(imagePatternPath, patternlab);
+ const mediaObjectPattern = assembler.load_pattern_iterative(mediaObjectPatternPath, patternlab);
+
+ return Promise.all([
+ assembler.process_pattern_iterative(buttonPattern, patternlab),
+ assembler.process_pattern_iterative(imagePattern, patternlab),
+ assembler.process_pattern_iterative(mediaObjectPattern, patternlab)
+ ]).then(() => {
+ assembler.process_pattern_recursive(buttonPatternPath, patternlab);
+ assembler.process_pattern_recursive(imagePatternPath, patternlab);
+ assembler.process_pattern_recursive(mediaObjectPatternPath, patternlab);
+
+ // test
+ // this pattern is too long - so just remove line endings on both sides and compare output
+ test.equals(mediaObjectPattern.render().replace(/\r?\n|\r/gm, ""), expectedValue.replace(/\r?\n|\r/gm, ""));
+ });
});
tap.test('twig partials can render JSON values', {skip: true}, function (test) {
@@ -198,4 +206,3 @@ tap.test('find_pattern_partials finds partials with twig parameters', function (
"{% include 'organisms-sidebar' ignore missing with {'foo': 'bar'} %}"
]);
});
-
diff --git a/test/engine_underscore_tests.js b/test/engine_underscore_tests.js
index 7e2342449..db5854c72 100644
--- a/test/engine_underscore_tests.js
+++ b/test/engine_underscore_tests.js
@@ -55,12 +55,13 @@ tap.test('hello world underscore pattern renders', function (test) {
// do all the normal processing of the pattern
var patternlab = new fakePatternLab();
var assembler = new pa();
- var helloWorldPattern = assembler.process_pattern_iterative(patternPath, patternlab);
- assembler.process_pattern_recursive(patternPath, patternlab);
+ const helloWorldPattern = assembler.load_pattern_iterative(patternPath, patternlab);
- test.equals(helloWorldPattern.render(), 'Hello world!' + eol);
- test.end();
+ return assembler.process_pattern_iterative(helloWorldPattern, patternlab).then(() => {
+ assembler.process_pattern_recursive(patternPath, patternlab);
+ test.equals(helloWorldPattern.render(), 'Hello world!' + eol);
+ });
});
tap.test('underscore partials can render JSON values', function (test) {
@@ -80,13 +81,13 @@ tap.test('underscore partials can render JSON values', function (test) {
var assembler = new pa();
// do all the normal processing of the pattern
- var helloWorldWithData = assembler.process_pattern_iterative(pattern1Path, patternlab);
- assembler.process_pattern_recursive(pattern1Path, patternlab);
-
- // test
- test.equals(helloWorldWithData.render(), 'Hello world!' + eol + 'Yeah, we got the subtitle from the JSON.' + eol);
- test.end();
+ const helloWorldWithData = assembler.load_pattern_iterative(pattern1Path, patternlab);
+ return assembler.process_pattern_iterative(helloWorldWithData, patternlab).then(() => {
+ assembler.process_pattern_recursive(pattern1Path, patternlab);
+ // test
+ test.equals(helloWorldWithData.render(), 'Hello world!' + eol + 'Yeah, we got the subtitle from the JSON.' + eol);
+ });
});
tap.test('findPartial return the ID of the partial, given a whole partial call', function (test) {
@@ -103,22 +104,28 @@ tap.test('findPartial return the ID of the partial, given a whole partial call',
});
tap.test('hidden underscore patterns can be called by their nice names', function(test){
- const util = require('./util/test_utils.js');
+ const util = require('./util/test_utils.js');
- //arrange
- const testPatternsPath = path.resolve(__dirname, 'files', '_underscore-test-patterns');
- const pl = util.fakePatternLab(testPatternsPath);
- var pattern_assembler = new pa();
+ //arrange
+ const testPatternsPath = path.resolve(__dirname, 'files', '_underscore-test-patterns');
+ const pl = util.fakePatternLab(testPatternsPath);
+ var pattern_assembler = new pa();
- var hiddenPatternPath = path.join('00-atoms', '00-global', '_00-hidden.html');
- var hiddenPattern = pattern_assembler.process_pattern_iterative(hiddenPatternPath, pl);
- pattern_assembler.process_pattern_recursive(hiddenPatternPath, pl);
+ var hiddenPatternPath = path.join('00-atoms', '00-global', '_00-hidden.html');
+ var testPatternPath = path.join('00-molecules', '00-global', '00-hidden-pattern-tester.html');
+
+ var hiddenPattern = pattern_assembler.load_pattern_iterative(hiddenPatternPath, pl);
+ var testPattern = pattern_assembler.load_pattern_iterative(testPatternPath, pl);
- var testPatternPath = path.join('00-molecules', '00-global', '00-hidden-pattern-tester.html');
- var testPattern = pattern_assembler.process_pattern_iterative(testPatternPath, pl);
+ return Promise.all([
+ pattern_assembler.process_pattern_iterative(hiddenPattern, pl),
+ pattern_assembler.process_pattern_iterative(testPattern, pl)
+ ]).then(() => {
+ pattern_assembler.process_pattern_recursive(hiddenPatternPath, pl);
pattern_assembler.process_pattern_recursive(testPatternPath, pl);
//act
test.equals(util.sanitized(testPattern.render()), util.sanitized('Here\'s the hidden atom: [I\'m the hidden atom\n]\n'));
test.end();
});
+});
diff --git a/test/files/_patterns/00-test/00-foo.md b/test/files/_patterns/00-test/00-foo.md
index 4c8bbf296..b284e8103 100644
--- a/test/files/_patterns/00-test/00-foo.md
+++ b/test/files/_patterns/00-test/00-foo.md
@@ -1,3 +1,6 @@
+---
+state: inreview
+---
## A Simple Include
This pattern contains an include of `test-bar`. It also has this markdown file, which does not have frontmatter.
diff --git a/test/files/_patterns/00-test/01-bar.md b/test/files/_patterns/00-test/01-bar.md
index 755aa5799..a811dacd7 100644
--- a/test/files/_patterns/00-test/01-bar.md
+++ b/test/files/_patterns/00-test/01-bar.md
@@ -1,5 +1,5 @@
---
-status: complete
+state: complete
title: An Atom Walks Into a Bar
joke: bad
---
diff --git a/test/files/_patterns/00-test/02-baz.md b/test/files/_patterns/00-test/02-baz.md
new file mode 100644
index 000000000..f6f78b399
--- /dev/null
+++ b/test/files/_patterns/00-test/02-baz.md
@@ -0,0 +1 @@
+### Only baz
\ No newline at end of file
diff --git a/test/files/_patterns/00-test/02-baz.mustache b/test/files/_patterns/00-test/02-baz.mustache
new file mode 100644
index 000000000..3f9538666
--- /dev/null
+++ b/test/files/_patterns/00-test/02-baz.mustache
@@ -0,0 +1 @@
+baz
\ No newline at end of file
diff --git a/test/files/_patterns/00-test/03-styled-atom.md b/test/files/_patterns/00-test/03-styled-atom.md
index 23371c488..58c494066 100644
--- a/test/files/_patterns/00-test/03-styled-atom.md
+++ b/test/files/_patterns/00-test/03-styled-atom.md
@@ -1,3 +1,3 @@
---
-status: inprogress
+state: inprogress
---
diff --git a/test/lineage_hunter_tests.js b/test/lineage_hunter_tests.js
index d1206c1e1..58d7892c6 100644
--- a/test/lineage_hunter_tests.js
+++ b/test/lineage_hunter_tests.js
@@ -7,6 +7,10 @@ var pa = require('../core/lib/pattern_assembler');
var of = require('../core/lib/object_factory');
var Pattern = require('../core/lib/object_factory').Pattern;
var PatternGraph = require('../core/lib/pattern_graph').PatternGraph;
+var config = require('./util/patternlab-config.json');
+
+var engineLoader = require('../core/lib/pattern_engines');
+engineLoader.loadAllEngines(config);
var fs = require('fs-extra');
var path = require('path');
@@ -31,6 +35,9 @@ function createBasePatternLabObject() {
paths: {
source: {
patterns: patterns_dir
+ },
+ public: {
+ patterns: './test/public/_patterns'
}
},
outputFileSuffixes: {
@@ -45,6 +52,8 @@ function createBasePatternLabObject() {
pl.config.debug = false;
pl.patterns = [];
pl.partials = {};
+ pl.patternGroups = {};
+ pl.subtypePatterns = {};
return pl;
}
@@ -263,17 +272,8 @@ tap.test('cascade_pattern_states sets the pattern state on any lineage patterns
//arrange
var pl = createBasePatternLabObject();
- var atomPattern = new of.Pattern('00-test/01-bar.mustache');
- atomPattern.template = fs.readFileSync(pl.config.paths.source.patterns + '00-test/01-bar.mustache', 'utf8');
- atomPattern.extendedTemplate = atomPattern.template;
- atomPattern.patternState = "inreview";
- pattern_assembler.addPattern(atomPattern, pl);
-
- var consumerPattern = new of.Pattern('00-test/00-foo.mustache');
- consumerPattern.template = fs.readFileSync(pl.config.paths.source.patterns + '00-test/00-foo.mustache', 'utf8');
- consumerPattern.extendedTemplate = consumerPattern.template;
- consumerPattern.patternState = "complete";
- pattern_assembler.addPattern(consumerPattern, pl);
+ var atomPattern = pattern_assembler.load_pattern_iterative('00-test/01-bar.mustache', pl);
+ var consumerPattern = pattern_assembler.load_pattern_iterative('00-test/00-foo.mustache', pl);
lineage_hunter.find_lineage(consumerPattern, pl);
diff --git a/test/list_item_hunter_tests.js b/test/list_item_hunter_tests.js
index 74b21cd74..ff7dae374 100644
--- a/test/list_item_hunter_tests.js
+++ b/test/list_item_hunter_tests.js
@@ -8,6 +8,9 @@ var PatternGraph = require('../core/lib/pattern_graph').PatternGraph;
var extend = require('util')._extend;
var pa = require('../core/lib/pattern_assembler');
var pattern_assembler = new pa();
+var config = require('./util/patternlab-config.json');
+var engineLoader = require('../core/lib/pattern_engines');
+engineLoader.loadAllEngines(config);
// fake pattern creators
function createFakeListPattern(customProps) {
@@ -421,5 +424,3 @@ tap.test('process_list_item_partials - correctly ignores already processed parti
test.equals(listPattern.extendedTemplate.replace(/\s\s+/g, ' ').replace(/\n/g, ' ').trim(), expectedValue.trim());
test.end();
});
-
-
diff --git a/test/markdown_parser_tests.js b/test/markdown_parser_tests.js
index 5931dd832..63f541ab8 100644
--- a/test/markdown_parser_tests.js
+++ b/test/markdown_parser_tests.js
@@ -10,14 +10,14 @@ var markdown_parser = new mp();
tap.test('parses pattern description block correctly when frontmatter not present', function(test) {
//arrange
- var markdownFileName = path.resolve("./test/files/_patterns/00-test/00-foo.md");
+ var markdownFileName = path.resolve("./test/files/_patterns/00-test/02-baz.md");
var markdownFileContents = fs.readFileSync(markdownFileName, 'utf8');
//act
var returnObject = markdown_parser.parse(markdownFileContents);
//assert
- test.equals(returnObject.markdown, 'A Simple Include \nThis pattern contains an include of test-bar
. It also has this markdown file, which does not have frontmatter.
\n');
+ test.equals(returnObject.markdown, 'Only baz \n');
test.end();
});
@@ -31,7 +31,7 @@ tap.test('parses pattern description block correctly when frontmatter present',
//assert
test.equals(returnObject.markdown, 'A Simple Bit of Markup \nFoo cannot get simpler than bar, amiright?
\n');
- test.equals(returnObject.status, 'complete');
+ test.equals(returnObject.state, 'complete');
test.end();
});
@@ -45,6 +45,6 @@ tap.test('parses frontmatter only when no markdown present', function (test) {
//assert
test.equals(returnObject.markdown, '');
- test.equals(returnObject.status, 'inprogress');
+ test.equals(returnObject.state, 'inprogress');
test.end();
});
diff --git a/test/object_factory_tests.js b/test/object_factory_tests.js
index f20034f61..0b8512ce8 100644
--- a/test/object_factory_tests.js
+++ b/test/object_factory_tests.js
@@ -1,6 +1,7 @@
"use strict";
var tap = require('tap');
+var config = require('./util/patternlab-config.json');
// fake pattern lab constructor:
// sets up a fake patternlab object, which is needed by the pattern processing
@@ -16,7 +17,7 @@ function fakePatternLab() {
data: {
link: {}
},
- config: require('../patternlab-config.json'),
+ config: config,
package: {}
};
@@ -27,6 +28,8 @@ var of = require('../core/lib/object_factory');
var Pattern = require('../core/lib/object_factory').Pattern;
var path = require('path');
var pl = fakePatternLab();
+var engineLoader = require('../core/lib/pattern_engines');
+engineLoader.loadAllEngines(config);
tap.test('test Pattern initializes correctly', function (test) {
var p = new Pattern('00-atoms/00-global/00-colors.mustache', { d: 123});
diff --git a/test/parameter_hunter_tests.js b/test/parameter_hunter_tests.js
index 5393c077f..05823fd30 100644
--- a/test/parameter_hunter_tests.js
+++ b/test/parameter_hunter_tests.js
@@ -3,14 +3,15 @@
var tap = require('tap');
var pa = require('../core/lib/pattern_assembler');
var Pattern = require('../core/lib/object_factory').Pattern;
-var CompileState = require('../core/lib/object_factory').CompileState;
var PatternGraph = require('../core/lib/pattern_graph').PatternGraph;
var fs = require('fs-extra');
var util = require('./util/test_utils.js');
var ph = require('../core/lib/parameter_hunter');
-
+var config = require('./util/patternlab-config.json');
+var engineLoader = require('../core/lib/pattern_engines');
+engineLoader.loadAllEngines(config);
//setup current pattern from what we would have during execution
function currentPatternClosure() {
@@ -59,12 +60,14 @@ function patternlabClosure() {
},
data: {
description: 'Not a quote from a smart man',
- link: {}
+ link: {
+ "molecules-single-comment": "01-molecules-06-components-02-single-comment/01-molecules-06-components-02-single-comment.html"
+ }
},
partials: {},
graph: PatternGraph.empty()
- }
-};
+ };
+}
tap.test('parameter hunter finds and extends templates', function(test) {
var currentPattern = currentPatternClosure();
@@ -402,3 +405,21 @@ tap.test('parameter hunter parses parameters containing html tags', function(tes
test.end();
});
+
+tap.test('parameter hunter expands links inside parameters', function (test) {
+ var currentPattern = currentPatternClosure();
+ var patternlab = patternlabClosure();
+ var parameter_hunter = new ph();
+
+ patternlab.patterns[0].template = '{{ description }} ';
+ patternlab.patterns[0].extendedTemplate = patternlab.patterns[0].template;
+
+ currentPattern.template = "{{> molecules-single-comment(url: 'link.molecules-single-comment', description: 'Link to single comment') }}";
+ currentPattern.extendedTemplate = currentPattern.template;
+ currentPattern.parameteredPartials[0] = currentPattern.template;
+
+ parameter_hunter.find_parameters(currentPattern, patternlab);
+ test.equals(currentPattern.extendedTemplate, 'Link to single comment ');
+
+ test.end();
+});
diff --git a/test/pattern_assembler_tests.js b/test/pattern_assembler_tests.js
index 5d4e02a45..fe35e6fb6 100644
--- a/test/pattern_assembler_tests.js
+++ b/test/pattern_assembler_tests.js
@@ -7,6 +7,9 @@ var Pattern = require('../core/lib/object_factory').Pattern;
var CompileState = require('../core/lib/object_factory').CompileState;
var PatternGraph = require('../core/lib/pattern_graph').PatternGraph;
var path = require('path');
+var config = require('./util/patternlab-config.json');
+var engineLoader = require('../core/lib/pattern_engines');
+engineLoader.loadAllEngines(config);
function emptyPatternLab() {
return {
@@ -32,45 +35,43 @@ tap.test('process_pattern_recursive recursively includes partials', function(tes
patternlab.config.paths.public = public_dir;
patternlab.config.outputFileSuffixes = {rendered: ''};
- //patternlab.data = fs.readJSONSync(path.resolve(patternlab.config.paths.source.data, 'data.json'));
patternlab.data = {};
- //patternlab.listitems = fs.readJSONSync(path.resolve(patternlab.config.paths.source.data, 'listitems.json'));
patternlab.listitems = {};
- //patternlab.header = fs.readFileSync(path.resolve(patternlab.config.paths.source.patternlabFiles, 'templates/pattern-header-footer/header.html'), 'utf8');
patternlab.header = '';
- //patternlab.footer = fs.readFileSync(path.resolve(patternlab.config.paths.source.patternlabFiles, 'templates/pattern-header-footer/footer.html'), 'utf8');
patternlab.footer = '';
patternlab.patterns = [];
patternlab.data.link = {};
patternlab.partials = {};
//diveSync once to perform iterative populating of patternlab object
- plMain.process_all_patterns_iterative(pattern_assembler, patterns_dir, patternlab);
-
- //diveSync again to recursively include partials, filling out the
- //extendedTemplate property of the patternlab.patterns elements
- plMain.process_all_patterns_recursive(pattern_assembler, patterns_dir, patternlab);
-
- //get test output for comparison
- var foo = fs.readFileSync(patterns_dir + '/00-test/00-foo.mustache', 'utf8').trim();
- var bar = fs.readFileSync(patterns_dir + '/00-test/01-bar.mustache', 'utf8').trim();
- var fooExtended;
-
- //get extended pattern
- for (var i = 0; i < patternlab.patterns.length; i++) {
- if (patternlab.patterns[i].fileName === '00-foo') {
- fooExtended = patternlab.patterns[i].extendedTemplate.trim();
- break;
- }
- }
+ plMain.process_all_patterns_iterative(patterns_dir, patternlab)
+ .then(() => {
+ //diveSync again to recursively include partials, filling out the
+ //extendedTemplate property of the patternlab.patterns elements
+ plMain.process_all_patterns_recursive(patterns_dir, patternlab);
+
+ //get test output for comparison
+ var foo = fs.readFileSync(patterns_dir + '/00-test/00-foo.mustache', 'utf8').trim();
+ var bar = fs.readFileSync(patterns_dir + '/00-test/01-bar.mustache', 'utf8').trim();
+ var fooExtended;
+
+ //get extended pattern
+ for (var i = 0; i < patternlab.patterns.length; i++) {
+ if (patternlab.patterns[i].fileName === '00-foo') {
+ fooExtended = patternlab.patterns[i].extendedTemplate.trim();
+ break;
+ }
+ }
- //check initial values
- test.equals(foo, '{{> test-bar }}', 'foo template not as expected');
- test.equals(bar, 'bar', 'bar template not as expected');
- //test that 00-foo.mustache included partial 01-bar.mustache
- test.equals(fooExtended, 'bar', 'foo includes bar');
+ //check initial values
+ test.equals(foo, '{{> test-bar }}', 'foo template not as expected');
+ test.equals(bar, 'bar', 'bar template not as expected');
+ //test that 00-foo.mustache included partial 01-bar.mustache
+ test.equals(fooExtended, 'bar', 'foo includes bar');
- test.end();
+ test.end();
+ })
+ .catch(test.threw);
});
tap.test('processPatternRecursive - correctly replaces all stylemodifiers when multiple duplicate patterns with different stylemodifiers found', function(test) {
@@ -478,59 +479,21 @@ tap.test('processPatternRecursive - 685 ensure listitems data is used', function
pattern_assembler.combine_listItems(pl);
var listPatternPath = path.join('00-test', '685-list.mustache');
- var listPattern = pattern_assembler.process_pattern_iterative(listPatternPath, pl);
+ var listPattern = pattern_assembler.load_pattern_iterative(listPatternPath, pl);
- //act
- pattern_assembler.process_pattern_recursive(listPatternPath, pl);
+ return Promise.all([
+ pattern_assembler.process_pattern_iterative(listPattern, pl)
+ ]).then((results) => {
- //assert
- test.true(listPattern.extendedTemplate.indexOf(1) > -1);
- test.true(listPattern.extendedTemplate.indexOf(2) > -1);
- test.true(listPattern.extendedTemplate.indexOf(3) > -1);
- test.end();
-});
+ //act
+ pattern_assembler.process_pattern_recursive(listPatternPath, pl);
-tap.test('setState - applies any patternState matching the pattern', function(test) {
- //arrange
- var pa = require('../core/lib/pattern_assembler');
- var pattern_assembler = new pa();
- var patternlab = {};
- patternlab.config = {};
- patternlab.config.patternStates = {};
- patternlab.config.patternStates["pages-homepage-emergency"] = "inprogress";
-
- var pattern = {
- patternPartial: "pages-homepage-emergency"
- };
-
- //act
- pattern_assembler.setPatternState(pattern, patternlab);
-
- //assert
- test.equals(pattern.patternState, "inprogress");
- test.end();
-});
-
-tap.test('setState - does not apply any patternState if nothing matches the pattern', function(test) {
- //arrange
- var pa = require('../core/lib/pattern_assembler');
- var pattern_assembler = new pa();
- var patternlab = {};
- patternlab.config = {};
- patternlab.config.patternStates = {};
- patternlab.config.patternStates["pages-homepage-emergency"] = "inprogress";
-
- var pattern = {
- key: "pages-homepage",
- patternState: ""
- };
-
- //act
- pattern_assembler.setPatternState(pattern, patternlab);
-
- //assert
- test.equals(pattern.patternState, "");
- test.end();
+ //assert
+ test.true(results[0].extendedTemplate.indexOf(1) > -1);
+ test.true(results[0].extendedTemplate.indexOf(2) > -1);
+ test.true(results[0].extendedTemplate.indexOf(3) > -1);
+ test.end();
+ }).catch(test.threw);
});
tap.test('parseDataLinks - replaces found link.* data for their expanded links', function(test) {
@@ -550,61 +513,53 @@ tap.test('parseDataLinks - replaces found link.* data for their expanded links',
patternlab.listitems = {};
patternlab.header = {};
patternlab.footer = {};
- //patternlab.data = fs.readJSONSync(path.resolve(patternlab.config.paths.source.data, 'data.json'));
- //patternlab.listitems = fs.readJSONSync(path.resolve(patternlab.config.paths.source.data, 'listitems.json'));
- //patternlab.header = fs.readFileSync(path.resolve(patternlab.config.paths.source.patternlabFiles, 'templates/pattern-header-footer/header.html'), 'utf8');
- //patternlab.footer = fs.readFileSync(path.resolve(patternlab.config.paths.source.patternlabFiles, 'templates/pattern-header-footer/footer.html'), 'utf8');
patternlab.patterns = [
- {
- patternPartial: 'twitter-brad'
- },
- {
- patternPartial: 'twitter-dave'
- },
- {
- patternPartial: 'twitter-brian'
- }
+ Pattern.createEmpty({ patternPartial: 'twitter-brad' }, patternlab),
+ Pattern.createEmpty({ patternPartial: 'twitter-dave' }, patternlab),
+ Pattern.createEmpty({ patternPartial: 'twitter-brian' }, patternlab)
];
patternlab.data.link = {};
patternlab.partials = {};
//diveSync once to perform iterative populating of patternlab object
- plMain.process_all_patterns_iterative(pattern_assembler, patterns_dir, patternlab);
-
- //for the sake of the test, also imagining I have the following pages...
- patternlab.data.link['twitter-brad'] = 'https://twitter.com/brad_frost';
- patternlab.data.link['twitter-dave'] = 'https://twitter.com/dmolsen';
- patternlab.data.link['twitter-brian'] = 'https://twitter.com/bmuenzenmeyer';
-
- patternlab.data.brad = {url: "link.twitter-brad"};
- patternlab.data.dave = {url: "link.twitter-dave"};
- patternlab.data.brian = {url: "link.twitter-brian"};
-
-
- var pattern;
- for (var i = 0; i < patternlab.patterns.length; i++) {
- if (patternlab.patterns[i].patternPartial === 'test-nav') {
- pattern = patternlab.patterns[i];
- }
- }
-
- //assert before
- test.equals(pattern.jsonFileData.brad.url, "link.twitter-brad", "brad pattern data should be found");
- test.equals(pattern.jsonFileData.dave.url, "link.twitter-dave", "dave pattern data should be found");
- test.equals(pattern.jsonFileData.brian.url, "link.twitter-brian", "brian pattern data should be found");
-
- //act
- pattern_assembler.parse_data_links(patternlab);
-
- //assert after
- test.equals(pattern.jsonFileData.brad.url, "https://twitter.com/brad_frost", "brad pattern data should be replaced");
- test.equals(pattern.jsonFileData.dave.url, "https://twitter.com/dmolsen", "dave pattern data should be replaced");
- test.equals(pattern.jsonFileData.brian.url, "https://twitter.com/bmuenzenmeyer", "brian pattern data should be replaced");
+ plMain.process_all_patterns_iterative( patterns_dir, patternlab)
+ .then(() => {
+ //for the sake of the test, also imagining I have the following pages...
+ patternlab.data.link['twitter-brad'] = 'https://twitter.com/brad_frost';
+ patternlab.data.link['twitter-dave'] = 'https://twitter.com/dmolsen';
+ patternlab.data.link['twitter-brian'] = 'https://twitter.com/bmuenzenmeyer';
+
+ patternlab.data.brad = {url: "link.twitter-brad"};
+ patternlab.data.dave = {url: "link.twitter-dave"};
+ patternlab.data.brian = {url: "link.twitter-brian"};
+
+
+ var pattern;
+ for (var i = 0; i < patternlab.patterns.length; i++) {
+ if (patternlab.patterns[i].patternPartial === 'test-nav') {
+ pattern = patternlab.patterns[i];
+ }
+ }
- test.equals(patternlab.data.brad.url, "https://twitter.com/brad_frost", "global brad data should be replaced");
- test.equals(patternlab.data.dave.url, "https://twitter.com/dmolsen", "global dave data should be replaced");
- test.equals(patternlab.data.brian.url, "https://twitter.com/bmuenzenmeyer", "global brian data should be replaced");
- test.end();
+ //assert before
+ test.equals(pattern.jsonFileData.brad.url, "link.twitter-brad", "brad pattern data should be found");
+ test.equals(pattern.jsonFileData.dave.url, "link.twitter-dave", "dave pattern data should be found");
+ test.equals(pattern.jsonFileData.brian.url, "link.twitter-brian", "brian pattern data should be found");
+
+ //act
+ pattern_assembler.parse_data_links(patternlab);
+
+ //assert after
+ test.equals(pattern.jsonFileData.brad.url, "https://twitter.com/brad_frost", "brad pattern data should be replaced");
+ test.equals(pattern.jsonFileData.dave.url, "https://twitter.com/dmolsen", "dave pattern data should be replaced");
+ test.equals(pattern.jsonFileData.brian.url, "https://twitter.com/bmuenzenmeyer", "brian pattern data should be replaced");
+
+ test.equals(patternlab.data.brad.url, "https://twitter.com/brad_frost", "global brad data should be replaced");
+ test.equals(patternlab.data.dave.url, "https://twitter.com/dmolsen", "global dave data should be replaced");
+ test.equals(patternlab.data.brian.url, "https://twitter.com/bmuenzenmeyer", "global brian data should be replaced");
+ test.end();
+ })
+ .catch(test.threw);
});
tap.test('get_pattern_by_key - returns the fuzzy result when no others found', function(test) {
@@ -791,16 +746,21 @@ tap.test('hidden patterns can be called by their nice names', function(test){
//act
var hiddenPatternPath = path.join('00-test', '_00-hidden-pattern.mustache');
- var hiddenPattern = pattern_assembler.process_pattern_iterative(hiddenPatternPath, pl);
- pattern_assembler.process_pattern_recursive(hiddenPatternPath, pl);
-
var testPatternPath = path.join('00-test', '15-hidden-pattern-tester.mustache');
- var testPattern = pattern_assembler.process_pattern_iterative(testPatternPath, pl);
- pattern_assembler.process_pattern_recursive(testPatternPath, pl);
- //assert
- test.equals(util.sanitized(testPattern.render()), util.sanitized('Hello there! Here\'s the hidden atom: [This is the hidden atom]'), 'hidden pattern rendered output not as expected');
- test.end();
+ var hiddenPattern = pattern_assembler.load_pattern_iterative(hiddenPatternPath, pl);
+ var testPattern = pattern_assembler.load_pattern_iterative(testPatternPath, pl);
+
+ return Promise.all([
+ pattern_assembler.process_pattern_iterative(hiddenPattern, pl),
+ pattern_assembler.process_pattern_iterative(testPattern, pl)
+ ]).then((results) => {
+ pattern_assembler.process_pattern_recursive(hiddenPatternPath, pl);
+ pattern_assembler.process_pattern_recursive(testPatternPath, pl);
+
+ //assert
+ test.equals(util.sanitized(results[1].render()), util.sanitized('Hello there! Here\'s the hidden atom: [This is the hidden atom]'), 'hidden pattern rendered output not as expected');
+ }).catch(test.threw);
});
tap.test('parses pattern title correctly when frontmatter present', function(test){
@@ -811,14 +771,17 @@ tap.test('parses pattern title correctly when frontmatter present', function(tes
var pl = util.fakePatternLab(testPatternsPath);
var pattern_assembler = new pa();
- //act
var testPatternPath = path.join('00-test', '01-bar.mustache');
- var testPattern = pattern_assembler.process_pattern_iterative(testPatternPath, pl);
- pattern_assembler.process_pattern_recursive(testPatternPath, pl);
+ var testPattern = pattern_assembler.load_pattern_iterative(testPatternPath, pl);
- //assert
- test.equals(testPattern.patternName, 'An Atom Walks Into a Bar','patternName not overridden');
- test.end();
+ //act
+ return Promise.all([
+ pattern_assembler.process_pattern_iterative(testPattern, pl),
+ pattern_assembler.process_pattern_recursive(testPatternPath, pl)
+ ]).then((results) => {
+ //assert
+ test.equals(results[0].patternName, 'An Atom Walks Into a Bar','patternName not overridden');
+ }).catch(test.threw);
});
tap.test('parses pattern extra frontmatter correctly when frontmatter present', function(test){
@@ -829,12 +792,16 @@ tap.test('parses pattern extra frontmatter correctly when frontmatter present',
var pl = util.fakePatternLab(testPatternsPath);
var pattern_assembler = new pa();
- //act
var testPatternPath = path.join('00-test', '01-bar.mustache');
- var testPattern = pattern_assembler.process_pattern_iterative(testPatternPath, pl);
- pattern_assembler.process_pattern_recursive(testPatternPath, pl);
+ var testPattern = pattern_assembler.load_pattern_iterative(testPatternPath, pl);
- //assert
- test.equals(testPattern.allMarkdown.joke, 'bad','extra key not added');
- test.end();
+ //act
+ return Promise.all([
+ pattern_assembler.process_pattern_iterative(testPattern, pl),
+ pattern_assembler.process_pattern_recursive(testPatternPath, pl)
+ ]).then((results) => {
+ //assert
+ test.equals(results[0].allMarkdown.joke, 'bad','extra key not added');
+
+ }).catch(test.threw);
});
diff --git a/test/pattern_engines_tests.js b/test/pattern_engines_tests.js
index dc55b6cf0..0d20e73ad 100644
--- a/test/pattern_engines_tests.js
+++ b/test/pattern_engines_tests.js
@@ -4,6 +4,9 @@ var tap = require('tap');
var patternEngines = require('../core/lib/pattern_engines');
var Pattern = require('../core/lib/object_factory').Pattern;
+var config = require('./util/patternlab-config.json');
+
+patternEngines.loadAllEngines(config);
// the mustache test pattern, stolen from object_factory unit tests
var mustacheTestPattern = new Pattern('source/_patterns/00-atoms/00-global/00-colors-alt.mustache', {d: 123});
@@ -122,7 +125,7 @@ function testProps(object, propTests, test) {
});
test.ok(object.hasOwnProperty(propName), '"' + propName + '" prop should be present');
- test.ok(isOneOfTheseTypes, '"' + propName + '" prop should be one of types ' + possibleTypes);
+ test.ok(isOneOfTheseTypes, '"' + propName + '" prop should be one of types ' + possibleTypes + ' but was instead ' + typeof propName);
}
// go over each property test and run it
@@ -151,7 +154,7 @@ engineNames.forEach(function (engineName) {
var propertyTests = {
'engine': ['object', 'function'],
'engineName': 'string',
- 'engineFileExtension': 'string',
+ 'engineFileExtension': ['string', 'object'],
'renderPattern': 'function',
'findPartials': 'function'
};
@@ -162,3 +165,23 @@ engineNames.forEach(function (engineName) {
});
});
+tap.test('patternEngines getSupportedFileExtensions flattens known engine extensions into a single array', function (test) {
+
+ //arrange
+ patternEngines.fooEngine = {
+ engineFileExtension : ['.foo1', '.foo2']
+ };
+ patternEngines.barEngine = {
+ engineFileExtension : '.bar'
+ };
+
+ const exts = patternEngines.getSupportedFileExtensions();
+ test.ok(exts.includes('.foo1'));
+ test.ok(exts.includes('.foo2'));
+ test.ok(exts.includes('.bar'));
+
+ delete patternEngines.fooEngine;
+ delete patternEngines.barEngine;
+
+ test.end();
+});
diff --git a/test/pattern_graph_tests.js b/test/pattern_graph_tests.js
index 78980422b..b09a2c4b2 100644
--- a/test/pattern_graph_tests.js
+++ b/test/pattern_graph_tests.js
@@ -7,6 +7,9 @@ var Pattern = require('../core/lib/object_factory').Pattern;
var CompileState = require('../core/lib/object_factory').CompileState;
var tap = require('tap');
const posixPath = require('./util/test_utils.js').posixPath;
+var config = require('./util/patternlab-config.json');
+var engineLoader = require('../core/lib/pattern_engines');
+engineLoader.loadAllEngines(config);
var patternlab = {
config: {
diff --git a/test/patternlab_tests.js b/test/patternlab_tests.js
index 52456e187..c680058ba 100644
--- a/test/patternlab_tests.js
+++ b/test/patternlab_tests.js
@@ -9,8 +9,10 @@ var config = require('./util/patternlab-config.json');
var plEngineModule = rewire('../core/lib/patternlab');
//set up a global mocks - we don't want to be writing/rendering any files right now
-const uiBuilderMock = {
- buildFrontend: function (patternlab) { }
+const uiBuilderMock = function(){
+ return {
+ buildFrontend: function () { }
+ };
};
const fsMock = {
diff --git a/test/pseudopattern_hunter_tests.js b/test/pseudopattern_hunter_tests.js
index 007138475..57becf357 100644
--- a/test/pseudopattern_hunter_tests.js
+++ b/test/pseudopattern_hunter_tests.js
@@ -3,14 +3,18 @@
var tap = require('tap');
var path = require('path');
-var pha = require('../core/lib/pseudopattern_hunter');
+var pph = require('../core/lib/pseudopattern_hunter');
+
var pa = require('../core/lib/pattern_assembler');
var Pattern = require('../core/lib/object_factory').Pattern;
var PatternGraph = require('../core/lib/pattern_graph').PatternGraph;
+var config = require('./util/patternlab-config.json');
+var engineLoader = require('../core/lib/pattern_engines');
+engineLoader.loadAllEngines(config);
+
var fs = require('fs-extra');
var pattern_assembler = new pa();
-var pseudopattern_hunter = new pha();
var patterns_dir = './test/files/_patterns/';
var public_patterns_dir = './test/public/patterns';
@@ -51,16 +55,14 @@ tap.test('pseudpattern found and added as a pattern', function (test) {
//act
var patternCountBefore = pl.patterns.length;
- pseudopattern_hunter.find_pseudopatterns(atomPattern, pl);
-
- //assert
- test.equals(patternCountBefore + 1, pl.patterns.length);
- test.equals(pl.patterns[1].patternPartial, 'test-styled-atom-alt');
- test.equals(pl.patterns[1].extendedTemplate.replace(/\s\s+/g, ' ').replace(/\n/g, ' ').trim(), ' {{message}} ');
- test.equals(JSON.stringify(pl.patterns[1].jsonFileData), JSON.stringify({"message": "alternateMessage"}));
- test.equals(pl.patterns[1].patternLink, '00-test-03-styled-atom-alt' + path.sep + '00-test-03-styled-atom-alt.html');
-
- test.end();
+ return pph.find_pseudopatterns(atomPattern, pl).then(() => {
+ //assert
+ test.equals(patternCountBefore + 1, pl.patterns.length);
+ test.equals(pl.patterns[1].patternPartial, 'test-styled-atom-alt');
+ test.equals(pl.patterns[1].extendedTemplate.replace(/\s\s+/g, ' ').replace(/\n/g, ' ').trim(), ' {{message}} ');
+ test.equals(JSON.stringify(pl.patterns[1].jsonFileData), JSON.stringify({"message": "alternateMessage"}));
+ test.equals(pl.patterns[1].patternLink, '00-test-03-styled-atom-alt' + path.sep + '00-test-03-styled-atom-alt.html');
+ });
});
tap.test('pseudpattern variant includes stylePartials and parameteredPartials', function (test) {
@@ -83,12 +85,10 @@ tap.test('pseudpattern variant includes stylePartials and parameteredPartials',
pattern_assembler.addPattern(pseudoPattern, pl);
//act
- pseudopattern_hunter.find_pseudopatterns(pseudoPattern, pl);
-
- //assert
- test.equals(pl.patterns[2].patternPartial, 'test-pseudomodifier-test');
- test.equals(pl.patterns[2].stylePartials, pseudoPattern.stylePartials);
- test.equals(pl.patterns[2].parameteredPartials, pseudoPattern.parameteredPartials);
-
- test.end();
+ return pph.find_pseudopatterns(pseudoPattern, pl).then(() => {
+ //assert
+ test.equals(pl.patterns[2].patternPartial, 'test-pseudomodifier-test');
+ test.equals(pl.patterns[2].stylePartials, pseudoPattern.stylePartials);
+ test.equals(pl.patterns[2].parameteredPartials, pseudoPattern.parameteredPartials);
+ });
});
diff --git a/test/ui_builder_tests.js b/test/ui_builder_tests.js
index 5bf8af416..6dc5bf308 100644
--- a/test/ui_builder_tests.js
+++ b/test/ui_builder_tests.js
@@ -8,6 +8,10 @@ var Pattern = require('../core/lib/object_factory').Pattern;
var extend = require('util')._extend;
var uiModule = rewire('../core/lib/ui_builder');
var path = require('path');
+var config = require('./util/patternlab-config.json');
+
+var engineLoader = require('../core/lib/pattern_engines');
+engineLoader.loadAllEngines(config);
//set up a global mocks - we don't want to be writing/rendering any files right now
var fsMock = {
diff --git a/test/util/patternlab-config.json b/test/util/patternlab-config.json
index d13f33508..720975302 100644
--- a/test/util/patternlab-config.json
+++ b/test/util/patternlab-config.json
@@ -6,7 +6,13 @@
"data" : "./test/files/_data/",
"meta": "./test/files/_meta/",
"styleguide" : "./test/files/styleguide/",
- "patternlabFiles" : "./test/files/",
+ "patternlabFiles" : {
+ "general-header": "./test/files/partials/general-header.mustache",
+ "general-footer": "./test/files/partials/general-footer.mustache",
+ "patternSection": "./test/files/partials/patternSection.mustache",
+ "patternSectionSubtype": "./test/files/partials/patternSectionSubtype.mustache",
+ "viewall": "./test/files/viewall.mustache"
+ },
"js" : "./test/files/js",
"images" : "./test/files/images",
"fonts" : "./test/files/fonts",
@@ -63,5 +69,10 @@
},
"cleanOutputHtml": true,
"exportToGraphViz": false,
- "cleanPublic": true
+ "cleanPublic": true,
+ "theme": {
+ "color": "dark",
+ "density": "compact",
+ "layout": "horizontal"
+ }
}