├── .github
└── workflows
│ └── nodejs.yml
├── .gitignore
├── docs
├── api.md
├── basics.md
├── core.md
├── index.md
├── logo.png
└── recipes
│ ├── guarding-middleware-authentication-and-permissions.md
│ └── integrating-with-an-existing-express-app.md
├── package-lock.json
├── package.json
├── readme.md
├── src
├── config.js
├── ctx.js
├── index.d.ts
├── index.js
└── symbols.js
└── test
└── index.js
/.github/workflows/nodejs.yml:
--------------------------------------------------------------------------------
1 | name: Node CI
2 |
3 | on: [push]
4 |
5 | jobs:
6 | build:
7 |
8 | runs-on: ubuntu-latest
9 |
10 | strategy:
11 | matrix:
12 | node-version: [10.x, 12.x, 14.x]
13 |
14 | steps:
15 | - uses: actions/checkout@v1
16 | - name: Use Node.js ${{ matrix.node-version }}
17 | uses: actions/setup-node@v1
18 | with:
19 | node-version: ${{ matrix.node-version }}
20 | - name: npm install and test
21 | run: |
22 | npm ci
23 | npm test
24 | env:
25 | CI: true
26 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | .sketchpad/
3 | /index.js
4 | coverage/
5 | .vscode
6 | .nyc_output
--------------------------------------------------------------------------------
/docs/api.md:
--------------------------------------------------------------------------------
1 | # HexNut Docs - API
2 |
3 | ## HexNut Server
4 | HexNut server instance
5 |
6 | **Kind**: global class
7 |
8 | * [HexNut](#HexNut)
9 | * [new HexNut(wsConfig)](#new_HexNut_new)
10 | * [.use(middleware)](#HexNut+use)
11 | * [.start()](#HexNut+start)
12 |
13 |
14 |
15 | ### new HexNut(wsConfig)
16 | Create a new HexNut instance
17 |
18 |
19 | | Param | Type | Description |
20 | | --- | --- | --- |
21 | | wsConfig | object
| Config object, mixed with defaults, passed to Websocket.Server constructor |
22 |
23 | #### Primary useful options for wsConfig
24 |
25 | * **port**: The port number of the server
26 | * **server**: A [http](https://nodejs.org/api/http.html)/[https](https://nodejs.org/api/https.html) node server instance. If passed, the websocket will use this server to accept connections. This option allows for interop with other frameworks like koa and express.
27 |
28 |
29 |
30 | ### app.use(middleware)
31 | Adds a middleware function to the HexNut instance
32 |
33 | **Kind**: instance method of [HexNut
](#HexNut)
34 |
35 | | Param | Type |
36 | | --- | --- |
37 | | middleware | [middleware
](#middleware) |
38 |
39 |
40 |
41 | ### app.start()
42 | Start the HexNut Websocket Server
43 |
44 | **Kind**: instance method of [HexNut
](#HexNut)
45 |
46 | ### app.stop()
47 | Stop the HexNut Websocket Server
48 |
49 | **Kind**: instance method of [HexNut
](#HexNut)
50 |
51 |
52 |
53 | ## middleware : function
54 | **Kind**: global typedef
55 |
56 | | Param | Type | Description |
57 | | --- | --- | --- |
58 | | ctx | ctx
| Context object for the connection |
59 | | next | NextMiddlewareFn
| Callback function that triggers the next middleware |
60 |
61 |
62 |
63 | ## ctx
64 | Context object representing a HexNut connection
65 |
66 | **Kind**: global class
67 |
68 | - [HexNut Docs - API](#hexnut-docs---api)
69 | - [HexNut Server](#hexnut-server)
70 | - [new HexNut(wsConfig)](#new-hexnutwsconfig)
71 | - [app.use(middleware)](#appusemiddleware)
72 | - [app.start()](#appstart)
73 | - [app.stop()](#appstop)
74 | - [middleware : function
](#middleware--codefunctioncode)
75 | - [ctx](#ctx)
76 | - [ctx.message](#ctxmessage)
77 | - [ctx.isConnection](#ctxisconnection)
78 | - [ctx.isMessage](#ctxismessage)
79 | - [ctx.isClosing](#ctxisclosing)
80 | - [ctx.requestHeaders](#ctxrequestheaders)
81 | - [ctx.ip](#ctxip)
82 | - [ctx.path](#ctxpath)
83 | - [ctx.method](#ctxmethod)
84 | - [ctx.send(data)](#ctxsenddata)
85 | - [ctx.sendToAll(data)](#ctxsendtoalldata)
86 | - [ctx.done()](#ctxdone)
87 | - [ctx.throw(err)](#ctxthrowerr)
88 | - [ctx.app](#ctxapp)
89 |
90 |
91 |
92 | ### ctx.message
93 | The message recieved. Equal to `null` if `ctx.isConnection === true`
94 |
95 | ### ctx.isConnection
96 | True if this activation of the middlware chain is a new connection
97 |
98 |
99 |
100 | ### ctx.isMessage
101 | True if this activation of the middlware chain is a new message
102 |
103 |
104 |
105 | ### ctx.isClosing
106 | True if this activation of the middlware chain is a connection closing
107 |
108 |
109 |
110 | ### ctx.requestHeaders
111 | Object representing the http(s) headers that began this connection
112 |
113 |
114 |
115 | ### ctx.ip
116 | IP Address of the client
117 |
118 |
119 |
120 | ### ctx.path
121 | String URL path that began the connection
122 |
123 |
124 |
125 | ### ctx.method
126 | HTTP method used to begin the connection
127 |
128 |
129 |
130 | ### ctx.send(data)
131 | Send a message to the client
132 |
133 |
134 | | Param | Type |
135 | | --- | --- |
136 | | data | \*
|
137 |
138 |
139 |
140 | ### ctx.sendToAll(data)
141 | Send a message to all connected clients
142 |
143 |
144 | | Param | Type |
145 | | --- | --- |
146 | | data | \*
|
147 |
148 |
149 |
150 | ### ctx.done()
151 | Short circuit all remaining middleware
152 |
153 |
154 |
155 | ### ctx.throw(err)
156 | Throw an error
157 |
158 | | Param | Type |
159 | | --- | --- |
160 | | err | Error
|
161 |
162 | ### ctx.app
163 | Reference to the HexNut app.
--------------------------------------------------------------------------------
/docs/basics.md:
--------------------------------------------------------------------------------
1 | # HexNut Docs - Basics
2 |
3 | Back to main docs page
4 |
5 | ## Installing HexNut
6 |
7 | ```bash
8 | npm i hexnut
9 | ```
10 |
11 | ## Creating a server
12 |
13 | ```javascript
14 | const HexNut = require('hexnut');
15 | const app = new HexNut({ port: 8080 });
16 |
17 | // This server will never do anything, but the logic code would go here
18 |
19 | app.start();
20 | ```
21 |
22 | ## Using middleware
23 |
24 | To illustrate basic middleware usage, the `hexnut-handle` package will be used
25 |
26 | ```javascript
27 | const HexNut = require('hexnut');
28 | const handle = require('hexnut-handle');
29 | const app = new HexNut({ port: 8080 });
30 |
31 | app.use(handle.connect(ctx => {
32 | ctx.send('Connected!');
33 | ctx.state = {
34 | messagesReceived: 0
35 | };
36 | }));
37 |
38 | app.use(handle.matchMessage(msg => msg === 'A', ctx => {
39 | ctx.state.messagesReceived += 1;
40 | ctx.send(`It was an 'A' message. Received ${ctx.state.messagesReceived} messages.`);
41 | }));
42 |
43 | app.use(handle.matchMessage(msg => msg === 'B', ctx => {
44 | ctx.state.messagesReceived += 1;
45 | ctx.send(`It was an 'B' message. Received ${ctx.state.messagesReceived} messages.`);
46 | }));
47 |
48 | app.use(handle.message(ctx => {
49 | ctx.state.messagesReceived += 1;
50 | ctx.send(`Any other kind of message will go here. Received ${ctx.state.messagesReceived} messages.`);
51 | }));
52 |
53 | app.start();
54 | ```
55 |
56 | Back to main docs page
--------------------------------------------------------------------------------
/docs/core.md:
--------------------------------------------------------------------------------
1 | # HexNut Docs - Core Concepts
2 |
3 | Back to main docs page
4 |
5 | HexNut was designed to be instantly usable by anyone who was familiar with existing node web frameworks like koa and express.
6 |
7 | There are 2 core concepts at work in HexNut, and both are fairly simple:
8 |
9 | - client websocket connection are abstracted into a `ctx` object, which lasts for the lifetime of the connection
10 | - a _middleware_ chain is used to process the ctx object, and add functionality to HexNut
11 |
12 | The main _difference_ between HexNut and web frameworks like koa and express is that web socket connections are **persistent** and **stateful**. Every _http request_ that comes into a web framework is standalone - it carries no state and is not intrinsically related to any connections that came in before or after. The moment the request is finalised, the objects associated with that request (`ctx` in koa, `req/res` in express) cease to exist. Now, contrasting to that, every _message_ that comes through a websocket is intrinsically tied to the connection as a whole, so in HexNut, the same `ctx` is passed to every message associcated with a particular client, and is only destroyed when the connection itself is destroyed.
13 |
14 | ## The ctx object
15 |
16 | (To see the full docs for the `ctx` object, check out the API documentation)
17 |
18 | The `ctx` object is created when a connection is received, and lasts for the lifetime of the connection.
19 |
20 | - You can send messages to the client using `ctx.send(data)`.
21 | - You can get the data of a message using `ctx.message`.
22 | - You can find out the the _type_ of message that was received using `ctx.isMessage`, `ctx.isConnection`, or `ctx.isClosing`, since middleware functions fire on new connections, when a message is received, and when the connection is closing.
23 |
24 | An important note is that any middleware you write can add properties/functions to the `ctx` object, and they will be accessible to every middleware for lifetime of the connection. This makes writing protocols and other stateful exchanges far easier.
25 |
26 | ## Middleware
27 |
28 | Middleware are special functions that run when a connection is established and when messages are received. Middleware functions have a signature of:
29 |
30 | ```javascript
31 | async function myMiddleware(ctx, next) {
32 | // - code -
33 | }
34 | ```
35 |
36 | Where `ctx` is the context described above, and `next` is a function that can be used to trigger the next middleware in the chain. Middleware functions are asynchronous (they return Promises), which means you can easily use `async/await` syntax to connect with data sources or API.
37 |
38 | Middleware should (most of the time) be thought of as a _lower level construct_, which basically means you should write or use higher level abstractions. For example, here is how you would handle a new connection and message in "pure" middleware form:
39 |
40 | ```javascript
41 | app.use((ctx, next) => {
42 | if (ctx.isConnection) {
43 | ctx.send('Howdy partner!');
44 | } else {
45 | // It wasn't a connection, so trigger the next middleware in the chain
46 | return next();
47 | }
48 | });
49 |
50 |
51 | app.use((ctx, next) => {
52 | if (ctx.isMessage && ctx.message === 'Hello') {
53 | ctx.send('You said "Hello"!');
54 | } else {
55 | // It wasn't a message or the message was not correct, so trigger the next middleware in the chain
56 | return next();
57 | }
58 | });
59 |
60 | app.use((ctx, next) => {
61 | if (ctx.isMessage) {
62 | ctx.send('You said anything else, except "Hello"!');
63 | } else {
64 | // It wasn't a message or the message was not correct, so trigger the next middleware in the chain
65 | return next();
66 | }
67 | });
68 | ```
69 |
70 | Writing these `if/else` statements and returning `next()` is going to get tedious and error prone and some point, so it's better to create an abstraction. A very simple one exists for this very purpose called `hexnut-handle`. This is how it simplifies and makes the code more readable:
71 |
72 | ```javascript
73 | const handle = require('hexnut-handle');
74 |
75 | app.use(handle.connect(
76 | ctx => ctx.send(`You said: ${ctx.message}!`)
77 | ));
78 |
79 | app.use(handle.matchMessage(
80 | msg => msg === 'Hello', // Only run our handler if the message === 'Hello'
81 | ctx => ctx.send('You said "Hello"!')
82 | ));
83 |
84 | app.use(handle.message(ctx => {
85 | ctx.send('You said anything else, except "Hello"!')
86 | }));
87 | ```
88 |
89 | Because middleware functions can be `async`, they can actually run code even after they have passed on to the next middleware by calling `next()`.
90 |
91 | ```javascript
92 | app.use(async (ctx, next) => {
93 | // Record when we started running
94 | const startTime = Date.now();
95 |
96 | // Await the next middleware in the chain
97 | await next();
98 |
99 | // After the next middleware has run, we can continue to run more code
100 | const endTime = Date.now();
101 |
102 | console.log(`This middleware ran for ${endTime - startTime} milliseconds`);
103 | });
104 | ```
105 |
106 | Back to main docs page
107 |
--------------------------------------------------------------------------------
/docs/index.md:
--------------------------------------------------------------------------------
1 | # HexNut Docs
2 |
3 | ## Core
4 |
5 | HexNut is a framework based on middleware that makes it easier to work with websockets.
6 |
7 | The core documentation for `HexNut` is split into 3 parts:
8 |
9 | 1. Basics: Installing and setting up a server
10 | 2. Core concepts: Understanding the ctx object and how middleware works
11 | 3. API Docs: Detailed API documentation
12 |
13 | ## Recipes
14 |
15 | The recipes section documents some of the common practical uses of hexnut.
16 |
17 | 1. Integrating with an existing express app
18 | 1. Guarding middleware: Authentication and Permissions
--------------------------------------------------------------------------------
/docs/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/francisrstokes/hexnut/7f00dc93cc19521def113f016b8d7e2644da9a03/docs/logo.png
--------------------------------------------------------------------------------
/docs/recipes/guarding-middleware-authentication-and-permissions.md:
--------------------------------------------------------------------------------
1 | # Guarding middleware: Authentication and Permissions
2 |
3 |
4 | Just like in a REST app, it's common want to mark some of your middleware as requiring authentication, permissions, or some other kind of condition.
5 |
6 | ## Protecting middleware until a token is provided and validated
7 |
8 | In this app, JSON is used to transfer data between client and server. If the app receives message in the format
9 |
10 | ```
11 | { "type": "auth", "token": "556da09a7c06c41a0c107bd6218d509b" }
12 | ```
13 |
14 | it should validate the token, and record the user as being logged in. In reality, a more robust token mechanism - with features like revocation, expiry time, refresh mechanism etc - should be employed on a production app.
15 |
16 | ```javascript
17 | const Hexnut = require('hexnut');
18 | const handle = require('hexnut-handle');
19 | const bodyparser = require('hexnut-bodyparser');
20 | const db = require('./some-db-layer');
21 |
22 | const app = new Hexnut({ port: 8080 });
23 |
24 | // Automatically parse json messages
25 | app.use(bodyparser.json());
26 |
27 | // This middleware checks for incoming auth messages. When it gets one, it checks
28 | // the token with the database layer. If it's valid, this state and the user are
29 | // associated with the ctx object. If not, an error message is sent, and any
30 | // previously associated token information is removed from ctx.
31 | app.use(async (ctx, next) => {
32 | if (ctx.isMessage() && ctx.message.type && ctx.message.type === 'auth') {
33 | // Communicate with the database layer and validate the token
34 | const {isValid, user} = await db.checkToken(ctx.message.token);
35 | if (isValid) {
36 | ctx.user = user;
37 | ctx.hasValidToken = true;
38 | } else {
39 | ctx.hasValidToken = false;
40 | ctx.user = null;
41 | ctx.send(JSON.stringify({ type: 'error', message: 'bad token' }));
42 | }
43 | } else {
44 | return next();
45 | }
46 | });
47 |
48 | // The protected middleware wraps a user provided middlware.
49 | // When it runs, it only allows the the user provided middleware to run
50 | // if the context has already validated a token.
51 | const protected = mw => (ctx, next) => {
52 | if (ctx.hasValidToken) {
53 | return mw(ctx, next);
54 | } else {
55 | ctx.send(JSON.stringify({ type: 'error', message: 'unauthorized' }));
56 | }
57 | };
58 |
59 | const sensitiveMessageHandler = protected(handle.matchMessage(
60 | msg => msg.type === 'secret stuff',
61 | ctx => {
62 | console.log(ctx.message.secrets);
63 | }
64 | ));
65 |
66 | app.use(sensitiveMessageHandler);
67 |
68 | app.start();
69 | ```
70 |
71 | ## Protecting middleware unless a user has permission
72 |
73 | In the example above, middleware can be protected - only running when the user has been properly validated. Protecting middleware based on user roles/permissions is a very similar idea.
74 |
75 | ```javascript
76 |
77 | // After a user has been validated, the user object and hasValidToken properties are added
78 | // to ctx. Assuming that the user object has a list of string permissions on it, we can build
79 | // an application specific middleware for protecting based on permissions.
80 |
81 | const permit = (requiredPermissions, mw) => (ctx, next) => {
82 | const hasAllPermissions = requiredPermissions.every(perm => ctx.user.permissions.includes(perm));
83 | if (hasAllPermissions) {
84 | return mw(ctx, next);
85 | } else {
86 | ctx.send(JSON.stringify({ type: 'error', message: 'not permitted' }));
87 | }
88 | };
89 |
90 | // Using the permit middleware is as simple as:
91 | app.use(permit(['manager', 'district coach'], ctx => {
92 | console.log('This user was allowed');
93 | }));
94 |
95 | ```
--------------------------------------------------------------------------------
/docs/recipes/integrating-with-an-existing-express-app.md:
--------------------------------------------------------------------------------
1 | # Integrating with an existing express app
2 |
3 | A hexnut app can share the same underlying server as an express app, and thus easily incorporated into an existing backend.
4 |
5 | ```javascript
6 | const Hexnut = require('hexnut');
7 | const handle = require('hexnut-handle');
8 | const cors = require('cors');
9 | const expressApp = require('App')();
10 | const http = require('http');
11 | const https = require('https');
12 |
13 |
14 | // Add express middle to the express app
15 | expressApp.use(cors());
16 |
17 | // Configure http/https server for express
18 | let withSSL = true;
19 | const server = withSSL
20 | ? new https.createServer({ cert, key }, expressApp)
21 | : new http.createServer(expressApp);
22 |
23 | // Create a hexnut app using the server
24 | const app = new Hexnut({ port: 8080, server });
25 |
26 | // Add hexnut middleware to hexnut app
27 | app.use(handle.message(ctx => {
28 | ctx.send(`You sent: ${ctx.message}`);
29 | }));
30 |
31 | // Start the app
32 | app.start();
33 | ```
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "hexnut",
3 | "version": "0.5.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "@babel/code-frame": {
8 | "version": "7.5.5",
9 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz",
10 | "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==",
11 | "dev": true,
12 | "requires": {
13 | "@babel/highlight": "^7.0.0"
14 | }
15 | },
16 | "@babel/generator": {
17 | "version": "7.7.4",
18 | "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.4.tgz",
19 | "integrity": "sha512-m5qo2WgdOJeyYngKImbkyQrnUN1mPceaG5BV+G0E3gWsa4l/jCSryWJdM2x8OuGAOyh+3d5pVYfZWCiNFtynxg==",
20 | "dev": true,
21 | "requires": {
22 | "@babel/types": "^7.7.4",
23 | "jsesc": "^2.5.1",
24 | "lodash": "^4.17.13",
25 | "source-map": "^0.5.0"
26 | },
27 | "dependencies": {
28 | "source-map": {
29 | "version": "0.5.7",
30 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
31 | "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
32 | "dev": true
33 | }
34 | }
35 | },
36 | "@babel/helper-function-name": {
37 | "version": "7.7.4",
38 | "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.4.tgz",
39 | "integrity": "sha512-AnkGIdiBhEuiwdoMnKm7jfPfqItZhgRaZfMg1XX3bS25INOnLPjPG1Ppnajh8eqgt5kPJnfqrRHqFqmjKDZLzQ==",
40 | "dev": true,
41 | "requires": {
42 | "@babel/helper-get-function-arity": "^7.7.4",
43 | "@babel/template": "^7.7.4",
44 | "@babel/types": "^7.7.4"
45 | }
46 | },
47 | "@babel/helper-get-function-arity": {
48 | "version": "7.7.4",
49 | "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.4.tgz",
50 | "integrity": "sha512-QTGKEdCkjgzgfJ3bAyRwF4yyT3pg+vDgan8DSivq1eS0gwi+KGKE5x8kRcbeFTb/673mkO5SN1IZfmCfA5o+EA==",
51 | "dev": true,
52 | "requires": {
53 | "@babel/types": "^7.7.4"
54 | }
55 | },
56 | "@babel/helper-split-export-declaration": {
57 | "version": "7.7.4",
58 | "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.4.tgz",
59 | "integrity": "sha512-guAg1SXFcVr04Guk9eq0S4/rWS++sbmyqosJzVs8+1fH5NI+ZcmkaSkc7dmtAFbHFva6yRJnjW3yAcGxjueDug==",
60 | "dev": true,
61 | "requires": {
62 | "@babel/types": "^7.7.4"
63 | }
64 | },
65 | "@babel/highlight": {
66 | "version": "7.5.0",
67 | "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz",
68 | "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==",
69 | "dev": true,
70 | "requires": {
71 | "chalk": "^2.0.0",
72 | "esutils": "^2.0.2",
73 | "js-tokens": "^4.0.0"
74 | }
75 | },
76 | "@babel/parser": {
77 | "version": "7.7.4",
78 | "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.4.tgz",
79 | "integrity": "sha512-jIwvLO0zCL+O/LmEJQjWA75MQTWwx3c3u2JOTDK5D3/9egrWRRA0/0hk9XXywYnXZVVpzrBYeIQTmhwUaePI9g==",
80 | "dev": true
81 | },
82 | "@babel/template": {
83 | "version": "7.7.4",
84 | "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.4.tgz",
85 | "integrity": "sha512-qUzihgVPguAzXCK7WXw8pqs6cEwi54s3E+HrejlkuWO6ivMKx9hZl3Y2fSXp9i5HgyWmj7RKP+ulaYnKM4yYxw==",
86 | "dev": true,
87 | "requires": {
88 | "@babel/code-frame": "^7.0.0",
89 | "@babel/parser": "^7.7.4",
90 | "@babel/types": "^7.7.4"
91 | }
92 | },
93 | "@babel/traverse": {
94 | "version": "7.7.4",
95 | "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.7.4.tgz",
96 | "integrity": "sha512-P1L58hQyupn8+ezVA2z5KBm4/Zr4lCC8dwKCMYzsa5jFMDMQAzaBNy9W5VjB+KAmBjb40U7a/H6ao+Xo+9saIw==",
97 | "dev": true,
98 | "requires": {
99 | "@babel/code-frame": "^7.5.5",
100 | "@babel/generator": "^7.7.4",
101 | "@babel/helper-function-name": "^7.7.4",
102 | "@babel/helper-split-export-declaration": "^7.7.4",
103 | "@babel/parser": "^7.7.4",
104 | "@babel/types": "^7.7.4",
105 | "debug": "^4.1.0",
106 | "globals": "^11.1.0",
107 | "lodash": "^4.17.13"
108 | },
109 | "dependencies": {
110 | "debug": {
111 | "version": "4.1.1",
112 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
113 | "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
114 | "dev": true,
115 | "requires": {
116 | "ms": "^2.1.1"
117 | }
118 | }
119 | }
120 | },
121 | "@babel/types": {
122 | "version": "7.7.4",
123 | "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.4.tgz",
124 | "integrity": "sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA==",
125 | "dev": true,
126 | "requires": {
127 | "esutils": "^2.0.2",
128 | "lodash": "^4.17.13",
129 | "to-fast-properties": "^2.0.0"
130 | }
131 | },
132 | "@types/node": {
133 | "version": "15.12.4",
134 | "resolved": "https://registry.npmjs.org/@types/node/-/node-15.12.4.tgz",
135 | "integrity": "sha512-zrNj1+yqYF4WskCMOHwN+w9iuD12+dGm0rQ35HLl9/Ouuq52cEtd0CH9qMgrdNmi5ejC1/V7vKEXYubB+65DkA=="
136 | },
137 | "@types/ws": {
138 | "version": "7.4.5",
139 | "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.5.tgz",
140 | "integrity": "sha512-8mbDgtc8xpxDDem5Gwj76stBDJX35KQ3YBoayxlqUQcL5BZUthiqP/VQ4PQnLHqM4PmlbyO74t98eJpURO+gPA==",
141 | "requires": {
142 | "@types/node": "*"
143 | }
144 | },
145 | "ansi-colors": {
146 | "version": "4.1.1",
147 | "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
148 | "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
149 | "dev": true
150 | },
151 | "ansi-escape-sequences": {
152 | "version": "4.1.0",
153 | "resolved": "https://registry.npmjs.org/ansi-escape-sequences/-/ansi-escape-sequences-4.1.0.tgz",
154 | "integrity": "sha512-dzW9kHxH011uBsidTXd14JXgzye/YLb2LzeKZ4bsgl/Knwx8AtbSFkkGxagdNOoh0DlqHCmfiEjWKBaqjOanVw==",
155 | "dev": true,
156 | "requires": {
157 | "array-back": "^3.0.1"
158 | },
159 | "dependencies": {
160 | "array-back": {
161 | "version": "3.1.0",
162 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz",
163 | "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==",
164 | "dev": true
165 | }
166 | }
167 | },
168 | "ansi-regex": {
169 | "version": "3.0.0",
170 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
171 | "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
172 | "dev": true
173 | },
174 | "ansi-styles": {
175 | "version": "3.2.1",
176 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
177 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
178 | "dev": true,
179 | "requires": {
180 | "color-convert": "^1.9.0"
181 | }
182 | },
183 | "anymatch": {
184 | "version": "3.1.1",
185 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
186 | "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
187 | "dev": true,
188 | "requires": {
189 | "normalize-path": "^3.0.0",
190 | "picomatch": "^2.0.4"
191 | }
192 | },
193 | "append-transform": {
194 | "version": "1.0.0",
195 | "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-1.0.0.tgz",
196 | "integrity": "sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==",
197 | "dev": true,
198 | "requires": {
199 | "default-require-extensions": "^2.0.0"
200 | }
201 | },
202 | "archy": {
203 | "version": "1.0.0",
204 | "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz",
205 | "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=",
206 | "dev": true
207 | },
208 | "argparse": {
209 | "version": "1.0.10",
210 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
211 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
212 | "dev": true,
213 | "requires": {
214 | "sprintf-js": "~1.0.2"
215 | }
216 | },
217 | "array-back": {
218 | "version": "4.0.1",
219 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.1.tgz",
220 | "integrity": "sha512-Z/JnaVEXv+A9xabHzN43FiiiWEE7gPCRXMrVmRm00tWbjZRul1iHm7ECzlyNq1p4a4ATXz+G9FJ3GqGOkOV3fg==",
221 | "dev": true
222 | },
223 | "array.prototype.map": {
224 | "version": "1.0.2",
225 | "resolved": "https://registry.npmjs.org/array.prototype.map/-/array.prototype.map-1.0.2.tgz",
226 | "integrity": "sha512-Az3OYxgsa1g7xDYp86l0nnN4bcmuEITGe1rbdEBVkrqkzMgDcbdQ2R7r41pNzti+4NMces3H8gMmuioZUilLgw==",
227 | "dev": true,
228 | "requires": {
229 | "define-properties": "^1.1.3",
230 | "es-abstract": "^1.17.0-next.1",
231 | "es-array-method-boxes-properly": "^1.0.0",
232 | "is-string": "^1.0.4"
233 | }
234 | },
235 | "assertion-error": {
236 | "version": "1.1.0",
237 | "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
238 | "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
239 | "dev": true
240 | },
241 | "balanced-match": {
242 | "version": "1.0.0",
243 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
244 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
245 | "dev": true
246 | },
247 | "binary-extensions": {
248 | "version": "2.1.0",
249 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz",
250 | "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==",
251 | "dev": true
252 | },
253 | "bluebird": {
254 | "version": "3.7.2",
255 | "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
256 | "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
257 | "dev": true
258 | },
259 | "brace-expansion": {
260 | "version": "1.1.11",
261 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
262 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
263 | "dev": true,
264 | "requires": {
265 | "balanced-match": "^1.0.0",
266 | "concat-map": "0.0.1"
267 | }
268 | },
269 | "braces": {
270 | "version": "3.0.2",
271 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
272 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
273 | "dev": true,
274 | "requires": {
275 | "fill-range": "^7.0.1"
276 | }
277 | },
278 | "browser-stdout": {
279 | "version": "1.3.1",
280 | "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
281 | "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
282 | "dev": true
283 | },
284 | "cache-point": {
285 | "version": "1.0.0",
286 | "resolved": "https://registry.npmjs.org/cache-point/-/cache-point-1.0.0.tgz",
287 | "integrity": "sha512-ZqrZp9Hi5Uq7vfSGmNP2bUT/9DzZC2Y/GXjHB8rUJN1a+KLmbV05+vxHipNsg8+CSVgjcVVzLV8VZms6w8ZeRw==",
288 | "dev": true,
289 | "requires": {
290 | "array-back": "^4.0.0",
291 | "fs-then-native": "^2.0.0",
292 | "mkdirp2": "^1.0.4"
293 | }
294 | },
295 | "caching-transform": {
296 | "version": "3.0.2",
297 | "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-3.0.2.tgz",
298 | "integrity": "sha512-Mtgcv3lh3U0zRii/6qVgQODdPA4G3zhG+jtbCWj39RXuUFTMzH0vcdMtaJS1jPowd+It2Pqr6y3NJMQqOqCE2w==",
299 | "dev": true,
300 | "requires": {
301 | "hasha": "^3.0.0",
302 | "make-dir": "^2.0.0",
303 | "package-hash": "^3.0.0",
304 | "write-file-atomic": "^2.4.2"
305 | }
306 | },
307 | "camelcase": {
308 | "version": "5.3.1",
309 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
310 | "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
311 | "dev": true
312 | },
313 | "catharsis": {
314 | "version": "0.8.11",
315 | "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.8.11.tgz",
316 | "integrity": "sha512-a+xUyMV7hD1BrDQA/3iPV7oc+6W26BgVJO05PGEoatMyIuPScQKsde6i3YorWX1qs+AZjnJ18NqdKoCtKiNh1g==",
317 | "dev": true,
318 | "requires": {
319 | "lodash": "^4.17.14"
320 | }
321 | },
322 | "chai": {
323 | "version": "4.2.0",
324 | "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz",
325 | "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==",
326 | "dev": true,
327 | "requires": {
328 | "assertion-error": "^1.1.0",
329 | "check-error": "^1.0.2",
330 | "deep-eql": "^3.0.1",
331 | "get-func-name": "^2.0.0",
332 | "pathval": "^1.1.0",
333 | "type-detect": "^4.0.5"
334 | }
335 | },
336 | "chalk": {
337 | "version": "2.4.2",
338 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
339 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
340 | "dev": true,
341 | "requires": {
342 | "ansi-styles": "^3.2.1",
343 | "escape-string-regexp": "^1.0.5",
344 | "supports-color": "^5.3.0"
345 | },
346 | "dependencies": {
347 | "supports-color": {
348 | "version": "5.5.0",
349 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
350 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
351 | "dev": true,
352 | "requires": {
353 | "has-flag": "^3.0.0"
354 | }
355 | }
356 | }
357 | },
358 | "check-error": {
359 | "version": "1.0.2",
360 | "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
361 | "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=",
362 | "dev": true
363 | },
364 | "chokidar": {
365 | "version": "3.3.1",
366 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.1.tgz",
367 | "integrity": "sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg==",
368 | "dev": true,
369 | "requires": {
370 | "anymatch": "~3.1.1",
371 | "braces": "~3.0.2",
372 | "fsevents": "~2.1.2",
373 | "glob-parent": "~5.1.0",
374 | "is-binary-path": "~2.1.0",
375 | "is-glob": "~4.0.1",
376 | "normalize-path": "~3.0.0",
377 | "readdirp": "~3.3.0"
378 | }
379 | },
380 | "cliui": {
381 | "version": "5.0.0",
382 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
383 | "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
384 | "dev": true,
385 | "requires": {
386 | "string-width": "^3.1.0",
387 | "strip-ansi": "^5.2.0",
388 | "wrap-ansi": "^5.1.0"
389 | },
390 | "dependencies": {
391 | "ansi-regex": {
392 | "version": "4.1.0",
393 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
394 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
395 | "dev": true
396 | },
397 | "string-width": {
398 | "version": "3.1.0",
399 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
400 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
401 | "dev": true,
402 | "requires": {
403 | "emoji-regex": "^7.0.1",
404 | "is-fullwidth-code-point": "^2.0.0",
405 | "strip-ansi": "^5.1.0"
406 | }
407 | },
408 | "strip-ansi": {
409 | "version": "5.2.0",
410 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
411 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
412 | "dev": true,
413 | "requires": {
414 | "ansi-regex": "^4.1.0"
415 | }
416 | }
417 | }
418 | },
419 | "collect-all": {
420 | "version": "1.0.3",
421 | "resolved": "https://registry.npmjs.org/collect-all/-/collect-all-1.0.3.tgz",
422 | "integrity": "sha512-0y0rBgoX8IzIjBAUnO73SEtSb4Mhk3IoceWJq5zZSxb9mWORhWH8xLYo4EDSOE1jRBk1LhmfjqWFFt10h/+MEA==",
423 | "dev": true,
424 | "requires": {
425 | "stream-connect": "^1.0.2",
426 | "stream-via": "^1.0.4"
427 | }
428 | },
429 | "color-convert": {
430 | "version": "1.9.3",
431 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
432 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
433 | "dev": true,
434 | "requires": {
435 | "color-name": "1.1.3"
436 | }
437 | },
438 | "color-name": {
439 | "version": "1.1.3",
440 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
441 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
442 | "dev": true
443 | },
444 | "command-line-args": {
445 | "version": "5.1.1",
446 | "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.1.1.tgz",
447 | "integrity": "sha512-hL/eG8lrll1Qy1ezvkant+trihbGnaKaeEjj6Scyr3DN+RC7iQ5Rz84IeLERfAWDGo0HBSNAakczwgCilDXnWg==",
448 | "dev": true,
449 | "requires": {
450 | "array-back": "^3.0.1",
451 | "find-replace": "^3.0.0",
452 | "lodash.camelcase": "^4.3.0",
453 | "typical": "^4.0.0"
454 | },
455 | "dependencies": {
456 | "array-back": {
457 | "version": "3.1.0",
458 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz",
459 | "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==",
460 | "dev": true
461 | },
462 | "typical": {
463 | "version": "4.0.0",
464 | "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz",
465 | "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==",
466 | "dev": true
467 | }
468 | }
469 | },
470 | "command-line-tool": {
471 | "version": "0.8.0",
472 | "resolved": "https://registry.npmjs.org/command-line-tool/-/command-line-tool-0.8.0.tgz",
473 | "integrity": "sha512-Xw18HVx/QzQV3Sc5k1vy3kgtOeGmsKIqwtFFoyjI4bbcpSgnw2CWVULvtakyw4s6fhyAdI6soQQhXc2OzJy62g==",
474 | "dev": true,
475 | "requires": {
476 | "ansi-escape-sequences": "^4.0.0",
477 | "array-back": "^2.0.0",
478 | "command-line-args": "^5.0.0",
479 | "command-line-usage": "^4.1.0",
480 | "typical": "^2.6.1"
481 | },
482 | "dependencies": {
483 | "array-back": {
484 | "version": "2.0.0",
485 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz",
486 | "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==",
487 | "dev": true,
488 | "requires": {
489 | "typical": "^2.6.1"
490 | }
491 | }
492 | }
493 | },
494 | "command-line-usage": {
495 | "version": "4.1.0",
496 | "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-4.1.0.tgz",
497 | "integrity": "sha512-MxS8Ad995KpdAC0Jopo/ovGIroV/m0KHwzKfXxKag6FHOkGsH8/lv5yjgablcRxCJJC0oJeUMuO/gmaq+Wq46g==",
498 | "dev": true,
499 | "requires": {
500 | "ansi-escape-sequences": "^4.0.0",
501 | "array-back": "^2.0.0",
502 | "table-layout": "^0.4.2",
503 | "typical": "^2.6.1"
504 | },
505 | "dependencies": {
506 | "array-back": {
507 | "version": "2.0.0",
508 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz",
509 | "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==",
510 | "dev": true,
511 | "requires": {
512 | "typical": "^2.6.1"
513 | }
514 | }
515 | }
516 | },
517 | "commander": {
518 | "version": "2.20.3",
519 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
520 | "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
521 | "dev": true,
522 | "optional": true
523 | },
524 | "common-sequence": {
525 | "version": "2.0.0",
526 | "resolved": "https://registry.npmjs.org/common-sequence/-/common-sequence-2.0.0.tgz",
527 | "integrity": "sha512-f0QqPLpRTgMQn/pQIynf+SdE73Lw5Q1jn4hjirHLgH/NJ71TiHjXusV16BmOyuK5rRQ1W2f++II+TFZbQOh4hA==",
528 | "dev": true
529 | },
530 | "commondir": {
531 | "version": "1.0.1",
532 | "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
533 | "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
534 | "dev": true
535 | },
536 | "concat-map": {
537 | "version": "0.0.1",
538 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
539 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
540 | "dev": true
541 | },
542 | "config-master": {
543 | "version": "3.1.0",
544 | "resolved": "https://registry.npmjs.org/config-master/-/config-master-3.1.0.tgz",
545 | "integrity": "sha1-ZnZjWQUFooO/JqSE1oSJ10xUhdo=",
546 | "dev": true,
547 | "requires": {
548 | "walk-back": "^2.0.1"
549 | },
550 | "dependencies": {
551 | "walk-back": {
552 | "version": "2.0.1",
553 | "resolved": "https://registry.npmjs.org/walk-back/-/walk-back-2.0.1.tgz",
554 | "integrity": "sha1-VU4qnYdPrEeoywBr9EwvDEmYoKQ=",
555 | "dev": true
556 | }
557 | }
558 | },
559 | "convert-source-map": {
560 | "version": "1.7.0",
561 | "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz",
562 | "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==",
563 | "dev": true,
564 | "requires": {
565 | "safe-buffer": "~5.1.1"
566 | }
567 | },
568 | "cp-file": {
569 | "version": "6.2.0",
570 | "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-6.2.0.tgz",
571 | "integrity": "sha512-fmvV4caBnofhPe8kOcitBwSn2f39QLjnAnGq3gO9dfd75mUytzKNZB1hde6QHunW2Rt+OwuBOMc3i1tNElbszA==",
572 | "dev": true,
573 | "requires": {
574 | "graceful-fs": "^4.1.2",
575 | "make-dir": "^2.0.0",
576 | "nested-error-stacks": "^2.0.0",
577 | "pify": "^4.0.1",
578 | "safe-buffer": "^5.0.1"
579 | }
580 | },
581 | "cross-spawn": {
582 | "version": "4.0.2",
583 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz",
584 | "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=",
585 | "dev": true,
586 | "requires": {
587 | "lru-cache": "^4.0.1",
588 | "which": "^1.2.9"
589 | }
590 | },
591 | "debug": {
592 | "version": "3.2.6",
593 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
594 | "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
595 | "dev": true,
596 | "requires": {
597 | "ms": "^2.1.1"
598 | }
599 | },
600 | "decamelize": {
601 | "version": "1.2.0",
602 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
603 | "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
604 | "dev": true
605 | },
606 | "deep-eql": {
607 | "version": "3.0.1",
608 | "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz",
609 | "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==",
610 | "dev": true,
611 | "requires": {
612 | "type-detect": "^4.0.0"
613 | }
614 | },
615 | "deep-extend": {
616 | "version": "0.6.0",
617 | "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
618 | "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
619 | "dev": true
620 | },
621 | "default-require-extensions": {
622 | "version": "2.0.0",
623 | "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz",
624 | "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=",
625 | "dev": true,
626 | "requires": {
627 | "strip-bom": "^3.0.0"
628 | }
629 | },
630 | "define-properties": {
631 | "version": "1.1.3",
632 | "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
633 | "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
634 | "dev": true,
635 | "requires": {
636 | "object-keys": "^1.0.12"
637 | }
638 | },
639 | "diff": {
640 | "version": "4.0.2",
641 | "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
642 | "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
643 | "dev": true
644 | },
645 | "dmd": {
646 | "version": "4.0.6",
647 | "resolved": "https://registry.npmjs.org/dmd/-/dmd-4.0.6.tgz",
648 | "integrity": "sha512-7ZYAnFQ6jGm4SICArwqNPylJ83PaOdPTAkds3Z/s1ueFqSc5ilJ2F0b7uP+35W1PUbemH++gn5/VlC3KwEgiHQ==",
649 | "dev": true,
650 | "requires": {
651 | "array-back": "^4.0.1",
652 | "cache-point": "^1.0.0",
653 | "common-sequence": "^2.0.0",
654 | "file-set": "^3.0.0",
655 | "handlebars": "^4.5.3",
656 | "marked": "^0.7.0",
657 | "object-get": "^2.1.0",
658 | "reduce-flatten": "^3.0.0",
659 | "reduce-unique": "^2.0.1",
660 | "reduce-without": "^1.0.1",
661 | "test-value": "^3.0.0",
662 | "walk-back": "^4.0.0"
663 | },
664 | "dependencies": {
665 | "reduce-flatten": {
666 | "version": "3.0.0",
667 | "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-3.0.0.tgz",
668 | "integrity": "sha512-eczl8wAYBxJ6Egl6I1ECIF+8z6sHu+KE7BzaEDZTpPXKXfy9SUDQlVYwkRcNTjJLC3Iakxbhss50KuT/R6SYfg==",
669 | "dev": true
670 | }
671 | }
672 | },
673 | "emoji-regex": {
674 | "version": "7.0.3",
675 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
676 | "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
677 | "dev": true
678 | },
679 | "entities": {
680 | "version": "2.0.3",
681 | "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz",
682 | "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==",
683 | "dev": true
684 | },
685 | "error-ex": {
686 | "version": "1.3.2",
687 | "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
688 | "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
689 | "dev": true,
690 | "requires": {
691 | "is-arrayish": "^0.2.1"
692 | }
693 | },
694 | "es-abstract": {
695 | "version": "1.17.6",
696 | "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz",
697 | "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==",
698 | "dev": true,
699 | "requires": {
700 | "es-to-primitive": "^1.2.1",
701 | "function-bind": "^1.1.1",
702 | "has": "^1.0.3",
703 | "has-symbols": "^1.0.1",
704 | "is-callable": "^1.2.0",
705 | "is-regex": "^1.1.0",
706 | "object-inspect": "^1.7.0",
707 | "object-keys": "^1.1.1",
708 | "object.assign": "^4.1.0",
709 | "string.prototype.trimend": "^1.0.1",
710 | "string.prototype.trimstart": "^1.0.1"
711 | }
712 | },
713 | "es-array-method-boxes-properly": {
714 | "version": "1.0.0",
715 | "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz",
716 | "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==",
717 | "dev": true
718 | },
719 | "es-get-iterator": {
720 | "version": "1.1.0",
721 | "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.0.tgz",
722 | "integrity": "sha512-UfrmHuWQlNMTs35e1ypnvikg6jCz3SK8v8ImvmDsh36fCVUR1MqoFDiyn0/k52C8NqO3YsO8Oe0azeesNuqSsQ==",
723 | "dev": true,
724 | "requires": {
725 | "es-abstract": "^1.17.4",
726 | "has-symbols": "^1.0.1",
727 | "is-arguments": "^1.0.4",
728 | "is-map": "^2.0.1",
729 | "is-set": "^2.0.1",
730 | "is-string": "^1.0.5",
731 | "isarray": "^2.0.5"
732 | }
733 | },
734 | "es-to-primitive": {
735 | "version": "1.2.1",
736 | "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
737 | "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
738 | "dev": true,
739 | "requires": {
740 | "is-callable": "^1.1.4",
741 | "is-date-object": "^1.0.1",
742 | "is-symbol": "^1.0.2"
743 | }
744 | },
745 | "es6-error": {
746 | "version": "4.1.1",
747 | "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz",
748 | "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==",
749 | "dev": true
750 | },
751 | "escape-string-regexp": {
752 | "version": "1.0.5",
753 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
754 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
755 | "dev": true
756 | },
757 | "esprima": {
758 | "version": "4.0.1",
759 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
760 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
761 | "dev": true
762 | },
763 | "esutils": {
764 | "version": "2.0.3",
765 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
766 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
767 | "dev": true
768 | },
769 | "file-set": {
770 | "version": "3.0.0",
771 | "resolved": "https://registry.npmjs.org/file-set/-/file-set-3.0.0.tgz",
772 | "integrity": "sha512-B/SdeSIeRv7VlOgIjtH3dkxMI+tEy5m+OeCXfAUsirBoVoY+bGtsmvmmTFPm/G23TBY4RiTtjpcgePCfwXRjqA==",
773 | "dev": true,
774 | "requires": {
775 | "array-back": "^4.0.0",
776 | "glob": "^7.1.5"
777 | },
778 | "dependencies": {
779 | "glob": {
780 | "version": "7.1.6",
781 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
782 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
783 | "dev": true,
784 | "requires": {
785 | "fs.realpath": "^1.0.0",
786 | "inflight": "^1.0.4",
787 | "inherits": "2",
788 | "minimatch": "^3.0.4",
789 | "once": "^1.3.0",
790 | "path-is-absolute": "^1.0.0"
791 | }
792 | }
793 | }
794 | },
795 | "fill-range": {
796 | "version": "7.0.1",
797 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
798 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
799 | "dev": true,
800 | "requires": {
801 | "to-regex-range": "^5.0.1"
802 | }
803 | },
804 | "find-cache-dir": {
805 | "version": "2.1.0",
806 | "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz",
807 | "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==",
808 | "dev": true,
809 | "requires": {
810 | "commondir": "^1.0.1",
811 | "make-dir": "^2.0.0",
812 | "pkg-dir": "^3.0.0"
813 | }
814 | },
815 | "find-replace": {
816 | "version": "3.0.0",
817 | "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz",
818 | "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==",
819 | "dev": true,
820 | "requires": {
821 | "array-back": "^3.0.1"
822 | },
823 | "dependencies": {
824 | "array-back": {
825 | "version": "3.1.0",
826 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz",
827 | "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==",
828 | "dev": true
829 | }
830 | }
831 | },
832 | "find-up": {
833 | "version": "3.0.0",
834 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
835 | "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
836 | "dev": true,
837 | "requires": {
838 | "locate-path": "^3.0.0"
839 | }
840 | },
841 | "flat": {
842 | "version": "4.1.0",
843 | "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz",
844 | "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==",
845 | "dev": true,
846 | "requires": {
847 | "is-buffer": "~2.0.3"
848 | }
849 | },
850 | "foreground-child": {
851 | "version": "1.5.6",
852 | "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz",
853 | "integrity": "sha1-T9ca0t/elnibmApcCilZN8svXOk=",
854 | "dev": true,
855 | "requires": {
856 | "cross-spawn": "^4",
857 | "signal-exit": "^3.0.0"
858 | }
859 | },
860 | "fs-then-native": {
861 | "version": "2.0.0",
862 | "resolved": "https://registry.npmjs.org/fs-then-native/-/fs-then-native-2.0.0.tgz",
863 | "integrity": "sha1-GaEk2U2QwiyOBF8ujdbr6jbUjGc=",
864 | "dev": true
865 | },
866 | "fs.realpath": {
867 | "version": "1.0.0",
868 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
869 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
870 | "dev": true
871 | },
872 | "fsevents": {
873 | "version": "2.1.3",
874 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz",
875 | "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==",
876 | "dev": true,
877 | "optional": true
878 | },
879 | "function-bind": {
880 | "version": "1.1.1",
881 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
882 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
883 | "dev": true
884 | },
885 | "get-caller-file": {
886 | "version": "2.0.5",
887 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
888 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
889 | "dev": true
890 | },
891 | "get-func-name": {
892 | "version": "2.0.0",
893 | "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz",
894 | "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=",
895 | "dev": true
896 | },
897 | "glob": {
898 | "version": "7.1.3",
899 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
900 | "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
901 | "dev": true,
902 | "requires": {
903 | "fs.realpath": "^1.0.0",
904 | "inflight": "^1.0.4",
905 | "inherits": "2",
906 | "minimatch": "^3.0.4",
907 | "once": "^1.3.0",
908 | "path-is-absolute": "^1.0.0"
909 | }
910 | },
911 | "glob-parent": {
912 | "version": "5.1.2",
913 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
914 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
915 | "dev": true,
916 | "requires": {
917 | "is-glob": "^4.0.1"
918 | }
919 | },
920 | "globals": {
921 | "version": "11.12.0",
922 | "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
923 | "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
924 | "dev": true
925 | },
926 | "graceful-fs": {
927 | "version": "4.2.3",
928 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
929 | "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==",
930 | "dev": true
931 | },
932 | "growl": {
933 | "version": "1.10.5",
934 | "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
935 | "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
936 | "dev": true
937 | },
938 | "handlebars": {
939 | "version": "4.7.7",
940 | "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz",
941 | "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==",
942 | "dev": true,
943 | "requires": {
944 | "minimist": "^1.2.5",
945 | "neo-async": "^2.6.0",
946 | "source-map": "^0.6.1",
947 | "uglify-js": "^3.1.4",
948 | "wordwrap": "^1.0.0"
949 | },
950 | "dependencies": {
951 | "minimist": {
952 | "version": "1.2.5",
953 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
954 | "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
955 | "dev": true
956 | },
957 | "wordwrap": {
958 | "version": "1.0.0",
959 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
960 | "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
961 | "dev": true
962 | }
963 | }
964 | },
965 | "has": {
966 | "version": "1.0.3",
967 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
968 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
969 | "dev": true,
970 | "requires": {
971 | "function-bind": "^1.1.1"
972 | }
973 | },
974 | "has-flag": {
975 | "version": "3.0.0",
976 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
977 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
978 | "dev": true
979 | },
980 | "has-symbols": {
981 | "version": "1.0.1",
982 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
983 | "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==",
984 | "dev": true
985 | },
986 | "hasha": {
987 | "version": "3.0.0",
988 | "resolved": "https://registry.npmjs.org/hasha/-/hasha-3.0.0.tgz",
989 | "integrity": "sha1-UqMvq4Vp1BymmmH/GiFPjrfIvTk=",
990 | "dev": true,
991 | "requires": {
992 | "is-stream": "^1.0.1"
993 | }
994 | },
995 | "he": {
996 | "version": "1.2.0",
997 | "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
998 | "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
999 | "dev": true
1000 | },
1001 | "hosted-git-info": {
1002 | "version": "2.8.9",
1003 | "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
1004 | "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
1005 | "dev": true
1006 | },
1007 | "html-escaper": {
1008 | "version": "2.0.2",
1009 | "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
1010 | "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
1011 | "dev": true
1012 | },
1013 | "imurmurhash": {
1014 | "version": "0.1.4",
1015 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
1016 | "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
1017 | "dev": true
1018 | },
1019 | "inflight": {
1020 | "version": "1.0.6",
1021 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
1022 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
1023 | "dev": true,
1024 | "requires": {
1025 | "once": "^1.3.0",
1026 | "wrappy": "1"
1027 | }
1028 | },
1029 | "inherits": {
1030 | "version": "2.0.3",
1031 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
1032 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
1033 | "dev": true
1034 | },
1035 | "is-arguments": {
1036 | "version": "1.0.4",
1037 | "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz",
1038 | "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==",
1039 | "dev": true
1040 | },
1041 | "is-arrayish": {
1042 | "version": "0.2.1",
1043 | "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
1044 | "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
1045 | "dev": true
1046 | },
1047 | "is-binary-path": {
1048 | "version": "2.1.0",
1049 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
1050 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
1051 | "dev": true,
1052 | "requires": {
1053 | "binary-extensions": "^2.0.0"
1054 | }
1055 | },
1056 | "is-buffer": {
1057 | "version": "2.0.4",
1058 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz",
1059 | "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==",
1060 | "dev": true
1061 | },
1062 | "is-callable": {
1063 | "version": "1.2.0",
1064 | "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz",
1065 | "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==",
1066 | "dev": true
1067 | },
1068 | "is-date-object": {
1069 | "version": "1.0.2",
1070 | "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz",
1071 | "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==",
1072 | "dev": true
1073 | },
1074 | "is-extglob": {
1075 | "version": "2.1.1",
1076 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
1077 | "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
1078 | "dev": true
1079 | },
1080 | "is-fullwidth-code-point": {
1081 | "version": "2.0.0",
1082 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
1083 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
1084 | "dev": true
1085 | },
1086 | "is-glob": {
1087 | "version": "4.0.1",
1088 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
1089 | "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
1090 | "dev": true,
1091 | "requires": {
1092 | "is-extglob": "^2.1.1"
1093 | }
1094 | },
1095 | "is-map": {
1096 | "version": "2.0.1",
1097 | "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.1.tgz",
1098 | "integrity": "sha512-T/S49scO8plUiAOA2DBTBG3JHpn1yiw0kRp6dgiZ0v2/6twi5eiB0rHtHFH9ZIrvlWc6+4O+m4zg5+Z833aXgw==",
1099 | "dev": true
1100 | },
1101 | "is-number": {
1102 | "version": "7.0.0",
1103 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
1104 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
1105 | "dev": true
1106 | },
1107 | "is-regex": {
1108 | "version": "1.1.0",
1109 | "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz",
1110 | "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==",
1111 | "dev": true,
1112 | "requires": {
1113 | "has-symbols": "^1.0.1"
1114 | }
1115 | },
1116 | "is-set": {
1117 | "version": "2.0.1",
1118 | "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.1.tgz",
1119 | "integrity": "sha512-eJEzOtVyenDs1TMzSQ3kU3K+E0GUS9sno+F0OBT97xsgcJsF9nXMBtkT9/kut5JEpM7oL7X/0qxR17K3mcwIAA==",
1120 | "dev": true
1121 | },
1122 | "is-stream": {
1123 | "version": "1.1.0",
1124 | "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
1125 | "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
1126 | "dev": true
1127 | },
1128 | "is-string": {
1129 | "version": "1.0.5",
1130 | "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz",
1131 | "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==",
1132 | "dev": true
1133 | },
1134 | "is-symbol": {
1135 | "version": "1.0.3",
1136 | "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz",
1137 | "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==",
1138 | "dev": true,
1139 | "requires": {
1140 | "has-symbols": "^1.0.1"
1141 | }
1142 | },
1143 | "isarray": {
1144 | "version": "2.0.5",
1145 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
1146 | "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
1147 | "dev": true
1148 | },
1149 | "isexe": {
1150 | "version": "2.0.0",
1151 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
1152 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
1153 | "dev": true
1154 | },
1155 | "istanbul-lib-coverage": {
1156 | "version": "2.0.5",
1157 | "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz",
1158 | "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==",
1159 | "dev": true
1160 | },
1161 | "istanbul-lib-hook": {
1162 | "version": "2.0.7",
1163 | "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-2.0.7.tgz",
1164 | "integrity": "sha512-vrRztU9VRRFDyC+aklfLoeXyNdTfga2EI3udDGn4cZ6fpSXpHLV9X6CHvfoMCPtggg8zvDDmC4b9xfu0z6/llA==",
1165 | "dev": true,
1166 | "requires": {
1167 | "append-transform": "^1.0.0"
1168 | }
1169 | },
1170 | "istanbul-lib-instrument": {
1171 | "version": "3.3.0",
1172 | "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz",
1173 | "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==",
1174 | "dev": true,
1175 | "requires": {
1176 | "@babel/generator": "^7.4.0",
1177 | "@babel/parser": "^7.4.3",
1178 | "@babel/template": "^7.4.0",
1179 | "@babel/traverse": "^7.4.3",
1180 | "@babel/types": "^7.4.0",
1181 | "istanbul-lib-coverage": "^2.0.5",
1182 | "semver": "^6.0.0"
1183 | },
1184 | "dependencies": {
1185 | "semver": {
1186 | "version": "6.3.0",
1187 | "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
1188 | "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
1189 | "dev": true
1190 | }
1191 | }
1192 | },
1193 | "istanbul-lib-report": {
1194 | "version": "2.0.8",
1195 | "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz",
1196 | "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==",
1197 | "dev": true,
1198 | "requires": {
1199 | "istanbul-lib-coverage": "^2.0.5",
1200 | "make-dir": "^2.1.0",
1201 | "supports-color": "^6.1.0"
1202 | },
1203 | "dependencies": {
1204 | "supports-color": {
1205 | "version": "6.1.0",
1206 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
1207 | "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
1208 | "dev": true,
1209 | "requires": {
1210 | "has-flag": "^3.0.0"
1211 | }
1212 | }
1213 | }
1214 | },
1215 | "istanbul-lib-source-maps": {
1216 | "version": "3.0.6",
1217 | "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz",
1218 | "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==",
1219 | "dev": true,
1220 | "requires": {
1221 | "debug": "^4.1.1",
1222 | "istanbul-lib-coverage": "^2.0.5",
1223 | "make-dir": "^2.1.0",
1224 | "rimraf": "^2.6.3",
1225 | "source-map": "^0.6.1"
1226 | },
1227 | "dependencies": {
1228 | "debug": {
1229 | "version": "4.1.1",
1230 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
1231 | "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
1232 | "dev": true,
1233 | "requires": {
1234 | "ms": "^2.1.1"
1235 | }
1236 | }
1237 | }
1238 | },
1239 | "istanbul-reports": {
1240 | "version": "2.2.7",
1241 | "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.7.tgz",
1242 | "integrity": "sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg==",
1243 | "dev": true,
1244 | "requires": {
1245 | "html-escaper": "^2.0.0"
1246 | }
1247 | },
1248 | "iterate-iterator": {
1249 | "version": "1.0.1",
1250 | "resolved": "https://registry.npmjs.org/iterate-iterator/-/iterate-iterator-1.0.1.tgz",
1251 | "integrity": "sha512-3Q6tudGN05kbkDQDI4CqjaBf4qf85w6W6GnuZDtUVYwKgtC1q8yxYX7CZed7N+tLzQqS6roujWvszf13T+n9aw==",
1252 | "dev": true
1253 | },
1254 | "iterate-value": {
1255 | "version": "1.0.2",
1256 | "resolved": "https://registry.npmjs.org/iterate-value/-/iterate-value-1.0.2.tgz",
1257 | "integrity": "sha512-A6fMAio4D2ot2r/TYzr4yUWrmwNdsN5xL7+HUiyACE4DXm+q8HtPcnFTp+NnW3k4N05tZ7FVYFFb2CR13NxyHQ==",
1258 | "dev": true,
1259 | "requires": {
1260 | "es-get-iterator": "^1.0.2",
1261 | "iterate-iterator": "^1.0.1"
1262 | }
1263 | },
1264 | "js-tokens": {
1265 | "version": "4.0.0",
1266 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
1267 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
1268 | "dev": true
1269 | },
1270 | "js-yaml": {
1271 | "version": "3.13.1",
1272 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
1273 | "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
1274 | "dev": true,
1275 | "requires": {
1276 | "argparse": "^1.0.7",
1277 | "esprima": "^4.0.0"
1278 | }
1279 | },
1280 | "js2xmlparser": {
1281 | "version": "4.0.1",
1282 | "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.1.tgz",
1283 | "integrity": "sha512-KrPTolcw6RocpYjdC7pL7v62e55q7qOMHvLX1UCLc5AAS8qeJ6nukarEJAF2KL2PZxlbGueEbINqZR2bDe/gUw==",
1284 | "dev": true,
1285 | "requires": {
1286 | "xmlcreate": "^2.0.3"
1287 | }
1288 | },
1289 | "jsdoc": {
1290 | "version": "3.6.4",
1291 | "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.4.tgz",
1292 | "integrity": "sha512-3G9d37VHv7MFdheviDCjUfQoIjdv4TC5zTTf5G9VODLtOnVS6La1eoYBDlbWfsRT3/Xo+j2MIqki2EV12BZfwA==",
1293 | "dev": true,
1294 | "requires": {
1295 | "@babel/parser": "^7.9.4",
1296 | "bluebird": "^3.7.2",
1297 | "catharsis": "^0.8.11",
1298 | "escape-string-regexp": "^2.0.0",
1299 | "js2xmlparser": "^4.0.1",
1300 | "klaw": "^3.0.0",
1301 | "markdown-it": "^10.0.0",
1302 | "markdown-it-anchor": "^5.2.7",
1303 | "marked": "^0.8.2",
1304 | "mkdirp": "^1.0.4",
1305 | "requizzle": "^0.2.3",
1306 | "strip-json-comments": "^3.1.0",
1307 | "taffydb": "2.6.2",
1308 | "underscore": "~1.10.2"
1309 | },
1310 | "dependencies": {
1311 | "@babel/parser": {
1312 | "version": "7.10.5",
1313 | "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.5.tgz",
1314 | "integrity": "sha512-wfryxy4bE1UivvQKSQDU4/X6dr+i8bctjUjj8Zyt3DQy7NtPizJXT8M52nqpNKL+nq2PW8lxk4ZqLj0fD4B4hQ==",
1315 | "dev": true
1316 | },
1317 | "escape-string-regexp": {
1318 | "version": "2.0.0",
1319 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
1320 | "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
1321 | "dev": true
1322 | },
1323 | "marked": {
1324 | "version": "0.8.2",
1325 | "resolved": "https://registry.npmjs.org/marked/-/marked-0.8.2.tgz",
1326 | "integrity": "sha512-EGwzEeCcLniFX51DhTpmTom+dSA/MG/OBUDjnWtHbEnjAH180VzUeAw+oE4+Zv+CoYBWyRlYOTR0N8SO9R1PVw==",
1327 | "dev": true
1328 | },
1329 | "mkdirp": {
1330 | "version": "1.0.4",
1331 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
1332 | "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
1333 | "dev": true
1334 | },
1335 | "strip-json-comments": {
1336 | "version": "3.1.1",
1337 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
1338 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
1339 | "dev": true
1340 | }
1341 | }
1342 | },
1343 | "jsdoc-api": {
1344 | "version": "5.0.4",
1345 | "resolved": "https://registry.npmjs.org/jsdoc-api/-/jsdoc-api-5.0.4.tgz",
1346 | "integrity": "sha512-1KMwLnfo0FyhF06TQKzqIm8BiY1yoMIGICxRdJHUjzskaHMzHMmpLlmNFgzoa4pAC8t1CDPK5jWuQTvv1pBsEQ==",
1347 | "dev": true,
1348 | "requires": {
1349 | "array-back": "^4.0.0",
1350 | "cache-point": "^1.0.0",
1351 | "collect-all": "^1.0.3",
1352 | "file-set": "^2.0.1",
1353 | "fs-then-native": "^2.0.0",
1354 | "jsdoc": "^3.6.3",
1355 | "object-to-spawn-args": "^1.1.1",
1356 | "temp-path": "^1.0.0",
1357 | "walk-back": "^3.0.1"
1358 | },
1359 | "dependencies": {
1360 | "file-set": {
1361 | "version": "2.0.1",
1362 | "resolved": "https://registry.npmjs.org/file-set/-/file-set-2.0.1.tgz",
1363 | "integrity": "sha512-XgOUUpgR6FbbfYcniLw0qm1Am7PnNYIAkd+eXxRt42LiYhjaso0WiuQ+VmrNdtwotyM+cLCfZ56AZrySP3QnKA==",
1364 | "dev": true,
1365 | "requires": {
1366 | "array-back": "^2.0.0",
1367 | "glob": "^7.1.3"
1368 | },
1369 | "dependencies": {
1370 | "array-back": {
1371 | "version": "2.0.0",
1372 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz",
1373 | "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==",
1374 | "dev": true,
1375 | "requires": {
1376 | "typical": "^2.6.1"
1377 | }
1378 | }
1379 | }
1380 | },
1381 | "walk-back": {
1382 | "version": "3.0.1",
1383 | "resolved": "https://registry.npmjs.org/walk-back/-/walk-back-3.0.1.tgz",
1384 | "integrity": "sha512-umiNB2qLO731Sxbp6cfZ9pwURJzTnftxE4Gc7hq8n/ehkuXC//s9F65IEIJA2ZytQZ1ZOsm/Fju4IWx0bivkUQ==",
1385 | "dev": true
1386 | }
1387 | }
1388 | },
1389 | "jsdoc-parse": {
1390 | "version": "4.0.1",
1391 | "resolved": "https://registry.npmjs.org/jsdoc-parse/-/jsdoc-parse-4.0.1.tgz",
1392 | "integrity": "sha512-qIObw8yqYZjrP2qxWROB5eLQFLTUX2jRGLhW9hjo2CC2fQVlskidCIzjCoctwsDvauBp2a/lR31jkSleczSo8Q==",
1393 | "dev": true,
1394 | "requires": {
1395 | "array-back": "^4.0.0",
1396 | "lodash.omit": "^4.5.0",
1397 | "lodash.pick": "^4.4.0",
1398 | "reduce-extract": "^1.0.0",
1399 | "sort-array": "^2.0.0",
1400 | "test-value": "^3.0.0"
1401 | }
1402 | },
1403 | "jsdoc-to-markdown": {
1404 | "version": "5.0.3",
1405 | "resolved": "https://registry.npmjs.org/jsdoc-to-markdown/-/jsdoc-to-markdown-5.0.3.tgz",
1406 | "integrity": "sha512-tQv5tBV0fTYidRQtE60lJKxE98mmuLcYuITFDKQiDPE9hGccpeEGUNFcVkInq1vigyuPnZmt79bQ8wv2GKjY0Q==",
1407 | "dev": true,
1408 | "requires": {
1409 | "array-back": "^4.0.1",
1410 | "command-line-tool": "^0.8.0",
1411 | "config-master": "^3.1.0",
1412 | "dmd": "^4.0.5",
1413 | "jsdoc-api": "^5.0.4",
1414 | "jsdoc-parse": "^4.0.1",
1415 | "walk-back": "^4.0.0"
1416 | }
1417 | },
1418 | "jsesc": {
1419 | "version": "2.5.2",
1420 | "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
1421 | "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
1422 | "dev": true
1423 | },
1424 | "json-parse-better-errors": {
1425 | "version": "1.0.2",
1426 | "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
1427 | "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
1428 | "dev": true
1429 | },
1430 | "klaw": {
1431 | "version": "3.0.0",
1432 | "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz",
1433 | "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==",
1434 | "dev": true,
1435 | "requires": {
1436 | "graceful-fs": "^4.1.9"
1437 | }
1438 | },
1439 | "linkify-it": {
1440 | "version": "2.2.0",
1441 | "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz",
1442 | "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==",
1443 | "dev": true,
1444 | "requires": {
1445 | "uc.micro": "^1.0.1"
1446 | }
1447 | },
1448 | "load-json-file": {
1449 | "version": "4.0.0",
1450 | "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz",
1451 | "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=",
1452 | "dev": true,
1453 | "requires": {
1454 | "graceful-fs": "^4.1.2",
1455 | "parse-json": "^4.0.0",
1456 | "pify": "^3.0.0",
1457 | "strip-bom": "^3.0.0"
1458 | },
1459 | "dependencies": {
1460 | "pify": {
1461 | "version": "3.0.0",
1462 | "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
1463 | "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
1464 | "dev": true
1465 | }
1466 | }
1467 | },
1468 | "locate-path": {
1469 | "version": "3.0.0",
1470 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
1471 | "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
1472 | "dev": true,
1473 | "requires": {
1474 | "p-locate": "^3.0.0",
1475 | "path-exists": "^3.0.0"
1476 | }
1477 | },
1478 | "lodash": {
1479 | "version": "4.17.21",
1480 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
1481 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
1482 | "dev": true
1483 | },
1484 | "lodash.camelcase": {
1485 | "version": "4.3.0",
1486 | "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
1487 | "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=",
1488 | "dev": true
1489 | },
1490 | "lodash.flattendeep": {
1491 | "version": "4.4.0",
1492 | "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz",
1493 | "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=",
1494 | "dev": true
1495 | },
1496 | "lodash.omit": {
1497 | "version": "4.5.0",
1498 | "resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz",
1499 | "integrity": "sha1-brGa5aHuHdnfC5aeZs4Lf6MLXmA=",
1500 | "dev": true
1501 | },
1502 | "lodash.padend": {
1503 | "version": "4.6.1",
1504 | "resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.6.1.tgz",
1505 | "integrity": "sha1-U8y6BH0G4VjTEfRdpiX05J5vFm4=",
1506 | "dev": true
1507 | },
1508 | "lodash.pick": {
1509 | "version": "4.4.0",
1510 | "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz",
1511 | "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=",
1512 | "dev": true
1513 | },
1514 | "log-symbols": {
1515 | "version": "3.0.0",
1516 | "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz",
1517 | "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==",
1518 | "dev": true,
1519 | "requires": {
1520 | "chalk": "^2.4.2"
1521 | }
1522 | },
1523 | "lru-cache": {
1524 | "version": "4.1.5",
1525 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
1526 | "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
1527 | "dev": true,
1528 | "requires": {
1529 | "pseudomap": "^1.0.2",
1530 | "yallist": "^2.1.2"
1531 | }
1532 | },
1533 | "make-dir": {
1534 | "version": "2.1.0",
1535 | "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
1536 | "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
1537 | "dev": true,
1538 | "requires": {
1539 | "pify": "^4.0.1",
1540 | "semver": "^5.6.0"
1541 | }
1542 | },
1543 | "markdown-it": {
1544 | "version": "10.0.0",
1545 | "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz",
1546 | "integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==",
1547 | "dev": true,
1548 | "requires": {
1549 | "argparse": "^1.0.7",
1550 | "entities": "~2.0.0",
1551 | "linkify-it": "^2.0.0",
1552 | "mdurl": "^1.0.1",
1553 | "uc.micro": "^1.0.5"
1554 | }
1555 | },
1556 | "markdown-it-anchor": {
1557 | "version": "5.3.0",
1558 | "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.3.0.tgz",
1559 | "integrity": "sha512-/V1MnLL/rgJ3jkMWo84UR+K+jF1cxNG1a+KwqeXqTIJ+jtA8aWSHuigx8lTzauiIjBDbwF3NcWQMotd0Dm39jA==",
1560 | "dev": true
1561 | },
1562 | "marked": {
1563 | "version": "0.7.0",
1564 | "resolved": "https://registry.npmjs.org/marked/-/marked-0.7.0.tgz",
1565 | "integrity": "sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg==",
1566 | "dev": true
1567 | },
1568 | "mdurl": {
1569 | "version": "1.0.1",
1570 | "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
1571 | "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=",
1572 | "dev": true
1573 | },
1574 | "merge-source-map": {
1575 | "version": "1.1.0",
1576 | "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz",
1577 | "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==",
1578 | "dev": true,
1579 | "requires": {
1580 | "source-map": "^0.6.1"
1581 | }
1582 | },
1583 | "minimatch": {
1584 | "version": "3.0.4",
1585 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
1586 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
1587 | "dev": true,
1588 | "requires": {
1589 | "brace-expansion": "^1.1.7"
1590 | }
1591 | },
1592 | "mkdirp": {
1593 | "version": "0.5.5",
1594 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
1595 | "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
1596 | "dev": true,
1597 | "requires": {
1598 | "minimist": "^1.2.5"
1599 | },
1600 | "dependencies": {
1601 | "minimist": {
1602 | "version": "1.2.5",
1603 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
1604 | "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
1605 | "dev": true
1606 | }
1607 | }
1608 | },
1609 | "mkdirp2": {
1610 | "version": "1.0.4",
1611 | "resolved": "https://registry.npmjs.org/mkdirp2/-/mkdirp2-1.0.4.tgz",
1612 | "integrity": "sha512-Q2PKB4ZR4UPtjLl76JfzlgSCUZhSV1AXQgAZa1qt5RiaALFjP/CDrGvFBrOz7Ck6McPcwMAxTsJvWOUjOU8XMw==",
1613 | "dev": true
1614 | },
1615 | "mocha": {
1616 | "version": "8.0.1",
1617 | "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.0.1.tgz",
1618 | "integrity": "sha512-vefaXfdYI8+Yo8nPZQQi0QO2o+5q9UIMX1jZ1XMmK3+4+CQjc7+B0hPdUeglXiTlr8IHMVRo63IhO9Mzt6fxOg==",
1619 | "dev": true,
1620 | "requires": {
1621 | "ansi-colors": "4.1.1",
1622 | "browser-stdout": "1.3.1",
1623 | "chokidar": "3.3.1",
1624 | "debug": "3.2.6",
1625 | "diff": "4.0.2",
1626 | "escape-string-regexp": "1.0.5",
1627 | "find-up": "4.1.0",
1628 | "glob": "7.1.6",
1629 | "growl": "1.10.5",
1630 | "he": "1.2.0",
1631 | "js-yaml": "3.13.1",
1632 | "log-symbols": "3.0.0",
1633 | "minimatch": "3.0.4",
1634 | "ms": "2.1.2",
1635 | "object.assign": "4.1.0",
1636 | "promise.allsettled": "1.0.2",
1637 | "serialize-javascript": "3.0.0",
1638 | "strip-json-comments": "3.0.1",
1639 | "supports-color": "7.1.0",
1640 | "which": "2.0.2",
1641 | "wide-align": "1.1.3",
1642 | "workerpool": "6.0.0",
1643 | "yargs": "13.3.2",
1644 | "yargs-parser": "13.1.2",
1645 | "yargs-unparser": "1.6.0"
1646 | },
1647 | "dependencies": {
1648 | "ansi-regex": {
1649 | "version": "4.1.0",
1650 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
1651 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
1652 | "dev": true
1653 | },
1654 | "find-up": {
1655 | "version": "4.1.0",
1656 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
1657 | "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
1658 | "dev": true,
1659 | "requires": {
1660 | "locate-path": "^5.0.0",
1661 | "path-exists": "^4.0.0"
1662 | }
1663 | },
1664 | "glob": {
1665 | "version": "7.1.6",
1666 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
1667 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
1668 | "dev": true,
1669 | "requires": {
1670 | "fs.realpath": "^1.0.0",
1671 | "inflight": "^1.0.4",
1672 | "inherits": "2",
1673 | "minimatch": "^3.0.4",
1674 | "once": "^1.3.0",
1675 | "path-is-absolute": "^1.0.0"
1676 | }
1677 | },
1678 | "locate-path": {
1679 | "version": "5.0.0",
1680 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
1681 | "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
1682 | "dev": true,
1683 | "requires": {
1684 | "p-locate": "^4.1.0"
1685 | }
1686 | },
1687 | "ms": {
1688 | "version": "2.1.2",
1689 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
1690 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
1691 | "dev": true
1692 | },
1693 | "p-locate": {
1694 | "version": "4.1.0",
1695 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
1696 | "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
1697 | "dev": true,
1698 | "requires": {
1699 | "p-limit": "^2.2.0"
1700 | }
1701 | },
1702 | "path-exists": {
1703 | "version": "4.0.0",
1704 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
1705 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
1706 | "dev": true
1707 | },
1708 | "string-width": {
1709 | "version": "3.1.0",
1710 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
1711 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
1712 | "dev": true,
1713 | "requires": {
1714 | "emoji-regex": "^7.0.1",
1715 | "is-fullwidth-code-point": "^2.0.0",
1716 | "strip-ansi": "^5.1.0"
1717 | }
1718 | },
1719 | "strip-ansi": {
1720 | "version": "5.2.0",
1721 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
1722 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
1723 | "dev": true,
1724 | "requires": {
1725 | "ansi-regex": "^4.1.0"
1726 | }
1727 | },
1728 | "which": {
1729 | "version": "2.0.2",
1730 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
1731 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
1732 | "dev": true,
1733 | "requires": {
1734 | "isexe": "^2.0.0"
1735 | }
1736 | },
1737 | "yargs": {
1738 | "version": "13.3.2",
1739 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz",
1740 | "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==",
1741 | "dev": true,
1742 | "requires": {
1743 | "cliui": "^5.0.0",
1744 | "find-up": "^3.0.0",
1745 | "get-caller-file": "^2.0.1",
1746 | "require-directory": "^2.1.1",
1747 | "require-main-filename": "^2.0.0",
1748 | "set-blocking": "^2.0.0",
1749 | "string-width": "^3.0.0",
1750 | "which-module": "^2.0.0",
1751 | "y18n": "^4.0.0",
1752 | "yargs-parser": "^13.1.2"
1753 | },
1754 | "dependencies": {
1755 | "find-up": {
1756 | "version": "3.0.0",
1757 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
1758 | "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
1759 | "dev": true,
1760 | "requires": {
1761 | "locate-path": "^3.0.0"
1762 | }
1763 | },
1764 | "locate-path": {
1765 | "version": "3.0.0",
1766 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
1767 | "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
1768 | "dev": true,
1769 | "requires": {
1770 | "p-locate": "^3.0.0",
1771 | "path-exists": "^3.0.0"
1772 | }
1773 | },
1774 | "p-locate": {
1775 | "version": "3.0.0",
1776 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
1777 | "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
1778 | "dev": true,
1779 | "requires": {
1780 | "p-limit": "^2.0.0"
1781 | }
1782 | },
1783 | "path-exists": {
1784 | "version": "3.0.0",
1785 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
1786 | "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
1787 | "dev": true
1788 | }
1789 | }
1790 | },
1791 | "yargs-parser": {
1792 | "version": "13.1.2",
1793 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz",
1794 | "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==",
1795 | "dev": true,
1796 | "requires": {
1797 | "camelcase": "^5.0.0",
1798 | "decamelize": "^1.2.0"
1799 | }
1800 | }
1801 | }
1802 | },
1803 | "ms": {
1804 | "version": "2.1.1",
1805 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
1806 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
1807 | "dev": true
1808 | },
1809 | "neo-async": {
1810 | "version": "2.6.1",
1811 | "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz",
1812 | "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==",
1813 | "dev": true
1814 | },
1815 | "nested-error-stacks": {
1816 | "version": "2.1.0",
1817 | "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz",
1818 | "integrity": "sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug==",
1819 | "dev": true
1820 | },
1821 | "normalize-package-data": {
1822 | "version": "2.5.0",
1823 | "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
1824 | "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
1825 | "dev": true,
1826 | "requires": {
1827 | "hosted-git-info": "^2.1.4",
1828 | "resolve": "^1.10.0",
1829 | "semver": "2 || 3 || 4 || 5",
1830 | "validate-npm-package-license": "^3.0.1"
1831 | }
1832 | },
1833 | "normalize-path": {
1834 | "version": "3.0.0",
1835 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
1836 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
1837 | "dev": true
1838 | },
1839 | "nyc": {
1840 | "version": "14.1.1",
1841 | "resolved": "https://registry.npmjs.org/nyc/-/nyc-14.1.1.tgz",
1842 | "integrity": "sha512-OI0vm6ZGUnoGZv/tLdZ2esSVzDwUC88SNs+6JoSOMVxA+gKMB8Tk7jBwgemLx4O40lhhvZCVw1C+OYLOBOPXWw==",
1843 | "dev": true,
1844 | "requires": {
1845 | "archy": "^1.0.0",
1846 | "caching-transform": "^3.0.2",
1847 | "convert-source-map": "^1.6.0",
1848 | "cp-file": "^6.2.0",
1849 | "find-cache-dir": "^2.1.0",
1850 | "find-up": "^3.0.0",
1851 | "foreground-child": "^1.5.6",
1852 | "glob": "^7.1.3",
1853 | "istanbul-lib-coverage": "^2.0.5",
1854 | "istanbul-lib-hook": "^2.0.7",
1855 | "istanbul-lib-instrument": "^3.3.0",
1856 | "istanbul-lib-report": "^2.0.8",
1857 | "istanbul-lib-source-maps": "^3.0.6",
1858 | "istanbul-reports": "^2.2.4",
1859 | "js-yaml": "^3.13.1",
1860 | "make-dir": "^2.1.0",
1861 | "merge-source-map": "^1.1.0",
1862 | "resolve-from": "^4.0.0",
1863 | "rimraf": "^2.6.3",
1864 | "signal-exit": "^3.0.2",
1865 | "spawn-wrap": "^1.4.2",
1866 | "test-exclude": "^5.2.3",
1867 | "uuid": "^3.3.2",
1868 | "yargs": "^13.2.2",
1869 | "yargs-parser": "^13.0.0"
1870 | }
1871 | },
1872 | "object-get": {
1873 | "version": "2.1.0",
1874 | "resolved": "https://registry.npmjs.org/object-get/-/object-get-2.1.0.tgz",
1875 | "integrity": "sha1-ciu9tgA576R8rTxtws5RqFwCxa4=",
1876 | "dev": true
1877 | },
1878 | "object-inspect": {
1879 | "version": "1.8.0",
1880 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz",
1881 | "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==",
1882 | "dev": true
1883 | },
1884 | "object-keys": {
1885 | "version": "1.1.1",
1886 | "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
1887 | "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
1888 | "dev": true
1889 | },
1890 | "object-to-spawn-args": {
1891 | "version": "1.1.1",
1892 | "resolved": "https://registry.npmjs.org/object-to-spawn-args/-/object-to-spawn-args-1.1.1.tgz",
1893 | "integrity": "sha1-d9qIJ/Bz0BHJ4bFz+JV4FHAkZ4U=",
1894 | "dev": true
1895 | },
1896 | "object.assign": {
1897 | "version": "4.1.0",
1898 | "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
1899 | "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
1900 | "dev": true,
1901 | "requires": {
1902 | "define-properties": "^1.1.2",
1903 | "function-bind": "^1.1.1",
1904 | "has-symbols": "^1.0.0",
1905 | "object-keys": "^1.0.11"
1906 | }
1907 | },
1908 | "once": {
1909 | "version": "1.4.0",
1910 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
1911 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
1912 | "dev": true,
1913 | "requires": {
1914 | "wrappy": "1"
1915 | }
1916 | },
1917 | "os-homedir": {
1918 | "version": "1.0.2",
1919 | "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
1920 | "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
1921 | "dev": true
1922 | },
1923 | "p-limit": {
1924 | "version": "2.2.1",
1925 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz",
1926 | "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==",
1927 | "dev": true,
1928 | "requires": {
1929 | "p-try": "^2.0.0"
1930 | }
1931 | },
1932 | "p-locate": {
1933 | "version": "3.0.0",
1934 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
1935 | "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
1936 | "dev": true,
1937 | "requires": {
1938 | "p-limit": "^2.0.0"
1939 | }
1940 | },
1941 | "p-try": {
1942 | "version": "2.2.0",
1943 | "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
1944 | "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
1945 | "dev": true
1946 | },
1947 | "package-hash": {
1948 | "version": "3.0.0",
1949 | "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-3.0.0.tgz",
1950 | "integrity": "sha512-lOtmukMDVvtkL84rJHI7dpTYq+0rli8N2wlnqUcBuDWCfVhRUfOmnR9SsoHFMLpACvEV60dX7rd0rFaYDZI+FA==",
1951 | "dev": true,
1952 | "requires": {
1953 | "graceful-fs": "^4.1.15",
1954 | "hasha": "^3.0.0",
1955 | "lodash.flattendeep": "^4.4.0",
1956 | "release-zalgo": "^1.0.0"
1957 | }
1958 | },
1959 | "parse-json": {
1960 | "version": "4.0.0",
1961 | "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
1962 | "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
1963 | "dev": true,
1964 | "requires": {
1965 | "error-ex": "^1.3.1",
1966 | "json-parse-better-errors": "^1.0.1"
1967 | }
1968 | },
1969 | "path-exists": {
1970 | "version": "3.0.0",
1971 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
1972 | "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
1973 | "dev": true
1974 | },
1975 | "path-is-absolute": {
1976 | "version": "1.0.1",
1977 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
1978 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
1979 | "dev": true
1980 | },
1981 | "path-parse": {
1982 | "version": "1.0.6",
1983 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
1984 | "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
1985 | "dev": true
1986 | },
1987 | "path-type": {
1988 | "version": "3.0.0",
1989 | "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
1990 | "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
1991 | "dev": true,
1992 | "requires": {
1993 | "pify": "^3.0.0"
1994 | },
1995 | "dependencies": {
1996 | "pify": {
1997 | "version": "3.0.0",
1998 | "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
1999 | "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
2000 | "dev": true
2001 | }
2002 | }
2003 | },
2004 | "pathval": {
2005 | "version": "1.1.0",
2006 | "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz",
2007 | "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=",
2008 | "dev": true
2009 | },
2010 | "picomatch": {
2011 | "version": "2.2.2",
2012 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
2013 | "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==",
2014 | "dev": true
2015 | },
2016 | "pify": {
2017 | "version": "4.0.1",
2018 | "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
2019 | "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
2020 | "dev": true
2021 | },
2022 | "pkg-dir": {
2023 | "version": "3.0.0",
2024 | "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz",
2025 | "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==",
2026 | "dev": true,
2027 | "requires": {
2028 | "find-up": "^3.0.0"
2029 | }
2030 | },
2031 | "promise.allsettled": {
2032 | "version": "1.0.2",
2033 | "resolved": "https://registry.npmjs.org/promise.allsettled/-/promise.allsettled-1.0.2.tgz",
2034 | "integrity": "sha512-UpcYW5S1RaNKT6pd+s9jp9K9rlQge1UXKskec0j6Mmuq7UJCvlS2J2/s/yuPN8ehftf9HXMxWlKiPbGGUzpoRg==",
2035 | "dev": true,
2036 | "requires": {
2037 | "array.prototype.map": "^1.0.1",
2038 | "define-properties": "^1.1.3",
2039 | "es-abstract": "^1.17.0-next.1",
2040 | "function-bind": "^1.1.1",
2041 | "iterate-value": "^1.0.0"
2042 | }
2043 | },
2044 | "pseudomap": {
2045 | "version": "1.0.2",
2046 | "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
2047 | "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
2048 | "dev": true
2049 | },
2050 | "read-pkg": {
2051 | "version": "3.0.0",
2052 | "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
2053 | "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=",
2054 | "dev": true,
2055 | "requires": {
2056 | "load-json-file": "^4.0.0",
2057 | "normalize-package-data": "^2.3.2",
2058 | "path-type": "^3.0.0"
2059 | }
2060 | },
2061 | "read-pkg-up": {
2062 | "version": "4.0.0",
2063 | "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz",
2064 | "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==",
2065 | "dev": true,
2066 | "requires": {
2067 | "find-up": "^3.0.0",
2068 | "read-pkg": "^3.0.0"
2069 | }
2070 | },
2071 | "readdirp": {
2072 | "version": "3.3.0",
2073 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.3.0.tgz",
2074 | "integrity": "sha512-zz0pAkSPOXXm1viEwygWIPSPkcBYjW1xU5j/JBh5t9bGCJwa6f9+BJa6VaB2g+b55yVrmXzqkyLf4xaWYM0IkQ==",
2075 | "dev": true,
2076 | "requires": {
2077 | "picomatch": "^2.0.7"
2078 | }
2079 | },
2080 | "reduce-extract": {
2081 | "version": "1.0.0",
2082 | "resolved": "https://registry.npmjs.org/reduce-extract/-/reduce-extract-1.0.0.tgz",
2083 | "integrity": "sha1-Z/I4W+2mUGG19fQxJmLosIDKFSU=",
2084 | "dev": true,
2085 | "requires": {
2086 | "test-value": "^1.0.1"
2087 | },
2088 | "dependencies": {
2089 | "array-back": {
2090 | "version": "1.0.4",
2091 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz",
2092 | "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=",
2093 | "dev": true,
2094 | "requires": {
2095 | "typical": "^2.6.0"
2096 | }
2097 | },
2098 | "test-value": {
2099 | "version": "1.1.0",
2100 | "resolved": "https://registry.npmjs.org/test-value/-/test-value-1.1.0.tgz",
2101 | "integrity": "sha1-oJE29y7AQ9J8iTcHwrFZv6196T8=",
2102 | "dev": true,
2103 | "requires": {
2104 | "array-back": "^1.0.2",
2105 | "typical": "^2.4.2"
2106 | }
2107 | }
2108 | }
2109 | },
2110 | "reduce-flatten": {
2111 | "version": "1.0.1",
2112 | "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-1.0.1.tgz",
2113 | "integrity": "sha1-JYx479FT3fk8tWEjf2EYTzaW4yc=",
2114 | "dev": true
2115 | },
2116 | "reduce-unique": {
2117 | "version": "2.0.1",
2118 | "resolved": "https://registry.npmjs.org/reduce-unique/-/reduce-unique-2.0.1.tgz",
2119 | "integrity": "sha512-x4jH/8L1eyZGR785WY+ePtyMNhycl1N2XOLxhCbzZFaqF4AXjLzqSxa2UHgJ2ZVR/HHyPOvl1L7xRnW8ye5MdA==",
2120 | "dev": true
2121 | },
2122 | "reduce-without": {
2123 | "version": "1.0.1",
2124 | "resolved": "https://registry.npmjs.org/reduce-without/-/reduce-without-1.0.1.tgz",
2125 | "integrity": "sha1-aK0OrRGFXJo31OglbBW7+Hly/Iw=",
2126 | "dev": true,
2127 | "requires": {
2128 | "test-value": "^2.0.0"
2129 | },
2130 | "dependencies": {
2131 | "array-back": {
2132 | "version": "1.0.4",
2133 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz",
2134 | "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=",
2135 | "dev": true,
2136 | "requires": {
2137 | "typical": "^2.6.0"
2138 | }
2139 | },
2140 | "test-value": {
2141 | "version": "2.1.0",
2142 | "resolved": "https://registry.npmjs.org/test-value/-/test-value-2.1.0.tgz",
2143 | "integrity": "sha1-Edpv9nDzRxpztiXKTz/c97t0gpE=",
2144 | "dev": true,
2145 | "requires": {
2146 | "array-back": "^1.0.3",
2147 | "typical": "^2.6.0"
2148 | }
2149 | }
2150 | }
2151 | },
2152 | "release-zalgo": {
2153 | "version": "1.0.0",
2154 | "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz",
2155 | "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=",
2156 | "dev": true,
2157 | "requires": {
2158 | "es6-error": "^4.0.1"
2159 | }
2160 | },
2161 | "require-directory": {
2162 | "version": "2.1.1",
2163 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
2164 | "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
2165 | "dev": true
2166 | },
2167 | "require-main-filename": {
2168 | "version": "2.0.0",
2169 | "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
2170 | "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
2171 | "dev": true
2172 | },
2173 | "requizzle": {
2174 | "version": "0.2.3",
2175 | "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.3.tgz",
2176 | "integrity": "sha512-YanoyJjykPxGHii0fZP0uUPEXpvqfBDxWV7s6GKAiiOsiqhX6vHNyW3Qzdmqp/iq/ExbhaGbVrjB4ruEVSM4GQ==",
2177 | "dev": true,
2178 | "requires": {
2179 | "lodash": "^4.17.14"
2180 | }
2181 | },
2182 | "resolve": {
2183 | "version": "1.13.1",
2184 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.13.1.tgz",
2185 | "integrity": "sha512-CxqObCX8K8YtAhOBRg+lrcdn+LK+WYOS8tSjqSFbjtrI5PnS63QPhZl4+yKfrU9tdsbMu9Anr/amegT87M9Z6w==",
2186 | "dev": true,
2187 | "requires": {
2188 | "path-parse": "^1.0.6"
2189 | }
2190 | },
2191 | "resolve-from": {
2192 | "version": "4.0.0",
2193 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
2194 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
2195 | "dev": true
2196 | },
2197 | "rimraf": {
2198 | "version": "2.7.1",
2199 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
2200 | "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
2201 | "dev": true,
2202 | "requires": {
2203 | "glob": "^7.1.3"
2204 | }
2205 | },
2206 | "safe-buffer": {
2207 | "version": "5.1.2",
2208 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
2209 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
2210 | "dev": true
2211 | },
2212 | "semver": {
2213 | "version": "5.7.1",
2214 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
2215 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
2216 | "dev": true
2217 | },
2218 | "serialize-javascript": {
2219 | "version": "3.0.0",
2220 | "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.0.0.tgz",
2221 | "integrity": "sha512-skZcHYw2vEX4bw90nAr2iTTsz6x2SrHEnfxgKYmZlvJYBEZrvbKtobJWlQ20zczKb3bsHHXXTYt48zBA7ni9cw==",
2222 | "dev": true
2223 | },
2224 | "set-blocking": {
2225 | "version": "2.0.0",
2226 | "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
2227 | "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
2228 | "dev": true
2229 | },
2230 | "signal-exit": {
2231 | "version": "3.0.2",
2232 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
2233 | "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
2234 | "dev": true
2235 | },
2236 | "sort-array": {
2237 | "version": "2.0.0",
2238 | "resolved": "https://registry.npmjs.org/sort-array/-/sort-array-2.0.0.tgz",
2239 | "integrity": "sha1-OKnG2if9fRR7QuYFVPKBGHtN9HI=",
2240 | "dev": true,
2241 | "requires": {
2242 | "array-back": "^1.0.4",
2243 | "object-get": "^2.1.0",
2244 | "typical": "^2.6.0"
2245 | },
2246 | "dependencies": {
2247 | "array-back": {
2248 | "version": "1.0.4",
2249 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz",
2250 | "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=",
2251 | "dev": true,
2252 | "requires": {
2253 | "typical": "^2.6.0"
2254 | }
2255 | }
2256 | }
2257 | },
2258 | "source-map": {
2259 | "version": "0.6.1",
2260 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
2261 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
2262 | "dev": true
2263 | },
2264 | "spawn-wrap": {
2265 | "version": "1.4.3",
2266 | "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-1.4.3.tgz",
2267 | "integrity": "sha512-IgB8md0QW/+tWqcavuFgKYR/qIRvJkRLPJDFaoXtLLUaVcCDK0+HeFTkmQHj3eprcYhc+gOl0aEA1w7qZlYezw==",
2268 | "dev": true,
2269 | "requires": {
2270 | "foreground-child": "^1.5.6",
2271 | "mkdirp": "^0.5.0",
2272 | "os-homedir": "^1.0.1",
2273 | "rimraf": "^2.6.2",
2274 | "signal-exit": "^3.0.2",
2275 | "which": "^1.3.0"
2276 | }
2277 | },
2278 | "spdx-correct": {
2279 | "version": "3.1.0",
2280 | "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz",
2281 | "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==",
2282 | "dev": true,
2283 | "requires": {
2284 | "spdx-expression-parse": "^3.0.0",
2285 | "spdx-license-ids": "^3.0.0"
2286 | }
2287 | },
2288 | "spdx-exceptions": {
2289 | "version": "2.2.0",
2290 | "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz",
2291 | "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==",
2292 | "dev": true
2293 | },
2294 | "spdx-expression-parse": {
2295 | "version": "3.0.0",
2296 | "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz",
2297 | "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==",
2298 | "dev": true,
2299 | "requires": {
2300 | "spdx-exceptions": "^2.1.0",
2301 | "spdx-license-ids": "^3.0.0"
2302 | }
2303 | },
2304 | "spdx-license-ids": {
2305 | "version": "3.0.5",
2306 | "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz",
2307 | "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==",
2308 | "dev": true
2309 | },
2310 | "sprintf-js": {
2311 | "version": "1.0.3",
2312 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
2313 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
2314 | "dev": true
2315 | },
2316 | "stream-connect": {
2317 | "version": "1.0.2",
2318 | "resolved": "https://registry.npmjs.org/stream-connect/-/stream-connect-1.0.2.tgz",
2319 | "integrity": "sha1-GLyB8u2zW4tdmoAJIAqYUxRCipc=",
2320 | "dev": true,
2321 | "requires": {
2322 | "array-back": "^1.0.2"
2323 | },
2324 | "dependencies": {
2325 | "array-back": {
2326 | "version": "1.0.4",
2327 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz",
2328 | "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=",
2329 | "dev": true,
2330 | "requires": {
2331 | "typical": "^2.6.0"
2332 | }
2333 | }
2334 | }
2335 | },
2336 | "stream-via": {
2337 | "version": "1.0.4",
2338 | "resolved": "https://registry.npmjs.org/stream-via/-/stream-via-1.0.4.tgz",
2339 | "integrity": "sha512-DBp0lSvX5G9KGRDTkR/R+a29H+Wk2xItOF+MpZLLNDWbEV9tGPnqLPxHEYjmiz8xGtJHRIqmI+hCjmNzqoA4nQ==",
2340 | "dev": true
2341 | },
2342 | "string-width": {
2343 | "version": "2.1.1",
2344 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
2345 | "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
2346 | "dev": true,
2347 | "requires": {
2348 | "is-fullwidth-code-point": "^2.0.0",
2349 | "strip-ansi": "^4.0.0"
2350 | }
2351 | },
2352 | "string.prototype.trimend": {
2353 | "version": "1.0.1",
2354 | "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz",
2355 | "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==",
2356 | "dev": true,
2357 | "requires": {
2358 | "define-properties": "^1.1.3",
2359 | "es-abstract": "^1.17.5"
2360 | }
2361 | },
2362 | "string.prototype.trimstart": {
2363 | "version": "1.0.1",
2364 | "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz",
2365 | "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==",
2366 | "dev": true,
2367 | "requires": {
2368 | "define-properties": "^1.1.3",
2369 | "es-abstract": "^1.17.5"
2370 | }
2371 | },
2372 | "strip-ansi": {
2373 | "version": "4.0.0",
2374 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
2375 | "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
2376 | "dev": true,
2377 | "requires": {
2378 | "ansi-regex": "^3.0.0"
2379 | }
2380 | },
2381 | "strip-bom": {
2382 | "version": "3.0.0",
2383 | "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
2384 | "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
2385 | "dev": true
2386 | },
2387 | "strip-json-comments": {
2388 | "version": "3.0.1",
2389 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz",
2390 | "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==",
2391 | "dev": true
2392 | },
2393 | "supports-color": {
2394 | "version": "7.1.0",
2395 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
2396 | "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
2397 | "dev": true,
2398 | "requires": {
2399 | "has-flag": "^4.0.0"
2400 | },
2401 | "dependencies": {
2402 | "has-flag": {
2403 | "version": "4.0.0",
2404 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
2405 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
2406 | "dev": true
2407 | }
2408 | }
2409 | },
2410 | "table-layout": {
2411 | "version": "0.4.5",
2412 | "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-0.4.5.tgz",
2413 | "integrity": "sha512-zTvf0mcggrGeTe/2jJ6ECkJHAQPIYEwDoqsiqBjI24mvRmQbInK5jq33fyypaCBxX08hMkfmdOqj6haT33EqWw==",
2414 | "dev": true,
2415 | "requires": {
2416 | "array-back": "^2.0.0",
2417 | "deep-extend": "~0.6.0",
2418 | "lodash.padend": "^4.6.1",
2419 | "typical": "^2.6.1",
2420 | "wordwrapjs": "^3.0.0"
2421 | },
2422 | "dependencies": {
2423 | "array-back": {
2424 | "version": "2.0.0",
2425 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz",
2426 | "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==",
2427 | "dev": true,
2428 | "requires": {
2429 | "typical": "^2.6.1"
2430 | }
2431 | }
2432 | }
2433 | },
2434 | "taffydb": {
2435 | "version": "2.6.2",
2436 | "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.6.2.tgz",
2437 | "integrity": "sha1-fLy2S1oUG2ou/CxdLGe04VCyomg=",
2438 | "dev": true
2439 | },
2440 | "temp-path": {
2441 | "version": "1.0.0",
2442 | "resolved": "https://registry.npmjs.org/temp-path/-/temp-path-1.0.0.tgz",
2443 | "integrity": "sha1-JLFUOXOrRCiW2a02fdnL2/r+kYs=",
2444 | "dev": true
2445 | },
2446 | "test-exclude": {
2447 | "version": "5.2.3",
2448 | "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz",
2449 | "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==",
2450 | "dev": true,
2451 | "requires": {
2452 | "glob": "^7.1.3",
2453 | "minimatch": "^3.0.4",
2454 | "read-pkg-up": "^4.0.0",
2455 | "require-main-filename": "^2.0.0"
2456 | }
2457 | },
2458 | "test-value": {
2459 | "version": "3.0.0",
2460 | "resolved": "https://registry.npmjs.org/test-value/-/test-value-3.0.0.tgz",
2461 | "integrity": "sha512-sVACdAWcZkSU9x7AOmJo5TqE+GyNJknHaHsMrR6ZnhjVlVN9Yx6FjHrsKZ3BjIpPCT68zYesPWkakrNupwfOTQ==",
2462 | "dev": true,
2463 | "requires": {
2464 | "array-back": "^2.0.0",
2465 | "typical": "^2.6.1"
2466 | },
2467 | "dependencies": {
2468 | "array-back": {
2469 | "version": "2.0.0",
2470 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz",
2471 | "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==",
2472 | "dev": true,
2473 | "requires": {
2474 | "typical": "^2.6.1"
2475 | }
2476 | }
2477 | }
2478 | },
2479 | "to-fast-properties": {
2480 | "version": "2.0.0",
2481 | "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
2482 | "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=",
2483 | "dev": true
2484 | },
2485 | "to-regex-range": {
2486 | "version": "5.0.1",
2487 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
2488 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
2489 | "dev": true,
2490 | "requires": {
2491 | "is-number": "^7.0.0"
2492 | }
2493 | },
2494 | "type-detect": {
2495 | "version": "4.0.8",
2496 | "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
2497 | "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
2498 | "dev": true
2499 | },
2500 | "typical": {
2501 | "version": "2.6.1",
2502 | "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz",
2503 | "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=",
2504 | "dev": true
2505 | },
2506 | "uc.micro": {
2507 | "version": "1.0.6",
2508 | "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
2509 | "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==",
2510 | "dev": true
2511 | },
2512 | "uglify-js": {
2513 | "version": "3.7.1",
2514 | "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.7.1.tgz",
2515 | "integrity": "sha512-pnOF7jY82wdIhATVn87uUY/FHU+MDUdPLkmGFvGoclQmeu229eTkbG5gjGGBi3R7UuYYSEeYXY/TTY5j2aym2g==",
2516 | "dev": true,
2517 | "optional": true,
2518 | "requires": {
2519 | "commander": "~2.20.3",
2520 | "source-map": "~0.6.1"
2521 | }
2522 | },
2523 | "underscore": {
2524 | "version": "1.10.2",
2525 | "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.10.2.tgz",
2526 | "integrity": "sha512-N4P+Q/BuyuEKFJ43B9gYuOj4TQUHXX+j2FqguVOpjkssLUUrnJofCcBccJSCoeturDoZU6GorDTHSvUDlSQbTg==",
2527 | "dev": true
2528 | },
2529 | "uuid": {
2530 | "version": "3.3.2",
2531 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
2532 | "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA=="
2533 | },
2534 | "validate-npm-package-license": {
2535 | "version": "3.0.4",
2536 | "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
2537 | "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
2538 | "dev": true,
2539 | "requires": {
2540 | "spdx-correct": "^3.0.0",
2541 | "spdx-expression-parse": "^3.0.0"
2542 | }
2543 | },
2544 | "walk-back": {
2545 | "version": "4.0.0",
2546 | "resolved": "https://registry.npmjs.org/walk-back/-/walk-back-4.0.0.tgz",
2547 | "integrity": "sha512-kudCA8PXVQfrqv2mFTG72vDBRi8BKWxGgFLwPpzHcpZnSwZk93WMwUDVcLHWNsnm+Y0AC4Vb6MUNRgaHfyV2DQ==",
2548 | "dev": true
2549 | },
2550 | "which": {
2551 | "version": "1.3.1",
2552 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
2553 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
2554 | "dev": true,
2555 | "requires": {
2556 | "isexe": "^2.0.0"
2557 | }
2558 | },
2559 | "which-module": {
2560 | "version": "2.0.0",
2561 | "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
2562 | "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
2563 | "dev": true
2564 | },
2565 | "wide-align": {
2566 | "version": "1.1.3",
2567 | "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
2568 | "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
2569 | "dev": true,
2570 | "requires": {
2571 | "string-width": "^1.0.2 || 2"
2572 | }
2573 | },
2574 | "wordwrapjs": {
2575 | "version": "3.0.0",
2576 | "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-3.0.0.tgz",
2577 | "integrity": "sha512-mO8XtqyPvykVCsrwj5MlOVWvSnCdT+C+QVbm6blradR7JExAhbkZ7hZ9A+9NUtwzSqrlUo9a67ws0EiILrvRpw==",
2578 | "dev": true,
2579 | "requires": {
2580 | "reduce-flatten": "^1.0.1",
2581 | "typical": "^2.6.1"
2582 | }
2583 | },
2584 | "workerpool": {
2585 | "version": "6.0.0",
2586 | "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.0.0.tgz",
2587 | "integrity": "sha512-fU2OcNA/GVAJLLyKUoHkAgIhKb0JoCpSjLC/G2vYKxUjVmQwGbRVeoPJ1a8U4pnVofz4AQV5Y/NEw8oKqxEBtA==",
2588 | "dev": true
2589 | },
2590 | "wrap-ansi": {
2591 | "version": "5.1.0",
2592 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
2593 | "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
2594 | "dev": true,
2595 | "requires": {
2596 | "ansi-styles": "^3.2.0",
2597 | "string-width": "^3.0.0",
2598 | "strip-ansi": "^5.0.0"
2599 | },
2600 | "dependencies": {
2601 | "ansi-regex": {
2602 | "version": "4.1.0",
2603 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
2604 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
2605 | "dev": true
2606 | },
2607 | "string-width": {
2608 | "version": "3.1.0",
2609 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
2610 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
2611 | "dev": true,
2612 | "requires": {
2613 | "emoji-regex": "^7.0.1",
2614 | "is-fullwidth-code-point": "^2.0.0",
2615 | "strip-ansi": "^5.1.0"
2616 | }
2617 | },
2618 | "strip-ansi": {
2619 | "version": "5.2.0",
2620 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
2621 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
2622 | "dev": true,
2623 | "requires": {
2624 | "ansi-regex": "^4.1.0"
2625 | }
2626 | }
2627 | }
2628 | },
2629 | "wrappy": {
2630 | "version": "1.0.2",
2631 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
2632 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
2633 | "dev": true
2634 | },
2635 | "write-file-atomic": {
2636 | "version": "2.4.3",
2637 | "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz",
2638 | "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==",
2639 | "dev": true,
2640 | "requires": {
2641 | "graceful-fs": "^4.1.11",
2642 | "imurmurhash": "^0.1.4",
2643 | "signal-exit": "^3.0.2"
2644 | }
2645 | },
2646 | "ws": {
2647 | "version": "7.4.6",
2648 | "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz",
2649 | "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A=="
2650 | },
2651 | "xmlcreate": {
2652 | "version": "2.0.3",
2653 | "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.3.tgz",
2654 | "integrity": "sha512-HgS+X6zAztGa9zIK3Y3LXuJes33Lz9x+YyTxgrkIdabu2vqcGOWwdfCpf1hWLRrd553wd4QCDf6BBO6FfdsRiQ==",
2655 | "dev": true
2656 | },
2657 | "y18n": {
2658 | "version": "4.0.1",
2659 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz",
2660 | "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==",
2661 | "dev": true
2662 | },
2663 | "yallist": {
2664 | "version": "2.1.2",
2665 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
2666 | "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
2667 | "dev": true
2668 | },
2669 | "yargs": {
2670 | "version": "13.3.0",
2671 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz",
2672 | "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==",
2673 | "dev": true,
2674 | "requires": {
2675 | "cliui": "^5.0.0",
2676 | "find-up": "^3.0.0",
2677 | "get-caller-file": "^2.0.1",
2678 | "require-directory": "^2.1.1",
2679 | "require-main-filename": "^2.0.0",
2680 | "set-blocking": "^2.0.0",
2681 | "string-width": "^3.0.0",
2682 | "which-module": "^2.0.0",
2683 | "y18n": "^4.0.0",
2684 | "yargs-parser": "^13.1.1"
2685 | },
2686 | "dependencies": {
2687 | "ansi-regex": {
2688 | "version": "4.1.0",
2689 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
2690 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
2691 | "dev": true
2692 | },
2693 | "string-width": {
2694 | "version": "3.1.0",
2695 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
2696 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
2697 | "dev": true,
2698 | "requires": {
2699 | "emoji-regex": "^7.0.1",
2700 | "is-fullwidth-code-point": "^2.0.0",
2701 | "strip-ansi": "^5.1.0"
2702 | }
2703 | },
2704 | "strip-ansi": {
2705 | "version": "5.2.0",
2706 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
2707 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
2708 | "dev": true,
2709 | "requires": {
2710 | "ansi-regex": "^4.1.0"
2711 | }
2712 | }
2713 | }
2714 | },
2715 | "yargs-parser": {
2716 | "version": "13.1.2",
2717 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz",
2718 | "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==",
2719 | "dev": true,
2720 | "requires": {
2721 | "camelcase": "^5.0.0",
2722 | "decamelize": "^1.2.0"
2723 | }
2724 | },
2725 | "yargs-unparser": {
2726 | "version": "1.6.0",
2727 | "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz",
2728 | "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==",
2729 | "dev": true,
2730 | "requires": {
2731 | "flat": "^4.1.0",
2732 | "lodash": "^4.17.15",
2733 | "yargs": "^13.3.0"
2734 | }
2735 | }
2736 | }
2737 | }
2738 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "hexnut",
3 | "version": "0.5.0",
4 | "description": "A middleware based framework for web sockets",
5 | "main": "src/index.js",
6 | "scripts": {
7 | "test": "mocha test/",
8 | "coverage": "nyc --reporter=html mocha test/",
9 | "generate_docs": "jsdoc2md src/index.js > docs.md && jsdoc2md src/ctx.js >> docs.md"
10 | },
11 | "keywords": [
12 | "websockets",
13 | "middleware",
14 | "hexnut",
15 | "express",
16 | "koa"
17 | ],
18 | "author": "Francis Stokes ",
19 | "license": "ISC",
20 | "devDependencies": {
21 | "chai": "^4.2.0",
22 | "jsdoc-to-markdown": "^5.0.3",
23 | "mocha": "^8.0.1",
24 | "nyc": "^14.1.1"
25 | },
26 | "dependencies": {
27 | "@types/ws": "^7.4.5",
28 | "uuid": "^3.3.2",
29 | "ws": "^7.4.6"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # Hexnut
2 |
3 |
4 |
5 | Hexnut is a middleware based, express/koa like framework for web sockets.
6 |
7 | []()
8 | []()
9 | [](https://circleci.com/gh/francisrstokes/hexnut/tree/master)
10 |
11 | For an introduction, and API documentation, please check out the docs.
12 |
13 | ## Middleware
14 |
15 | * hexnut-handle: Basic middleware abstraction for handling connections and messages
16 | * hexnut-bodyparser: Automatically parse JSON messages
17 | * hexnut-sequence: Create sequenced conversations between client and server
18 | * hexnut-with-observable: Integration with `rxjs`
19 | * hexnut-restore-connection: Allow the client to restore a connection state if connectivity is lost
20 | * hexnut-router: Respond differently when sockets connect and communicate on different URLs. Great for versioning!
21 |
22 | ## Client side
23 |
24 | You can use hexnut as a client in the frontend with `hexnut-client`. It is also middleware based and can use many of the server middlewares directly, such as `hexnut-bodyparser` and `hexnut-sequence`.
25 |
26 | ## Examples
27 |
28 | ### Trivial Example
29 |
30 | ```javascript
31 | const Hexnut = require('hexnut');
32 | const errorService = require(/* some error logging service */);
33 | const app = new Hexnut({ port: 8080 });
34 |
35 | app.onerror = async (err, ctx) => {
36 | await errorService(err);
37 | ctx.send(`Error! ${err.message}`);
38 | };
39 |
40 | app.use(ctx => {
41 | if (ctx.isConnection) {
42 | ctx.state = { count: 0 };
43 | return ctx.send('Hello, and welcome to the socket!');
44 | }
45 |
46 | ctx.state.count++;
47 | ctx.send(`Message No. ${ctx.state.count}: ${ctx.message}`);
48 | });
49 |
50 | app.start();
51 | ```
52 |
53 | ### Parsing JSON automatically
54 |
55 | ```javascript
56 | const Hexnut = require('hexnut');
57 | const bodyParser = require('hexnut-bodyparser');
58 | const app = new Hexnut({ port: 8080 });
59 |
60 | app.use(bodyParser.json());
61 |
62 | app.use(ctx => {
63 | if (ctx.isConnection) {
64 | ctx.state = { count: 0 };
65 | return ctx.send('Hello, and welcome to the socket!');
66 | }
67 |
68 | if (ctx.message.type) {
69 | ctx.state.count++;
70 | ctx.send(`Message No. ${ctx.state.count}: ${ctx.message.type}`);
71 | } else {
72 | ctx.send(`Invalid message format, expecting JSON with a "type" key`);
73 | }
74 | });
75 |
76 | app.start();
77 | ```
78 |
79 | ### Handling messages by type
80 |
81 | ```javascript
82 | const Hexnut = require('hexnut');
83 | const handle = require('hexnut-handle');
84 | const app = new Hexnut({ port: 8080 });
85 |
86 | app.use(handle.connect(ctx => {
87 | ctx.count = 0;
88 | }));
89 |
90 | app.use(handle.matchMessage(
91 | msg => msg === 'incCount',
92 | ctx => ctx.count++
93 | ));
94 |
95 | app.use(handle.matchMessage(
96 | msg => msg === 'decCount',
97 | ctx => ctx.count--
98 | ));
99 |
100 | app.use(handle.matchMessage(
101 | msg => msg === 'getCount',
102 | ctx => ctx.send(ctx.count)
103 | ));
104 |
105 | app.start();
106 | ```
107 |
108 |
109 | ### Sequencing Interactions
110 |
111 | ```javascript
112 | const Hexnut = require('hexnut');
113 | const bodyParser = require('hexnut-bodyparser');
114 | const sequence = require('hexnut-sequence');
115 | const app = new Hexnut({ port: 8080 });
116 |
117 | app.use(bodyParser.json());
118 |
119 | // This sequence happens when the user connects
120 | app.use(sequence.onConnect(function* (ctx) {
121 | ctx.send(`Welcome, ${ctx.ip}`);
122 | const name = yield sequence.getMessage();
123 | ctx.clientName = name;
124 | return;
125 | }));
126 |
127 | app.use(sequence.interruptible(function* (ctx) {
128 | // In order to use this sequence, we assert that we must have a clientName on the ctx
129 | yield sequence.assert(() => 'clientName' in ctx);
130 |
131 | // We first expect a message with type == greeting
132 | const greeting = yield sequence.matchMessage(msg => msg.type === 'greeting');
133 |
134 | // Then a message that has type == timeOfDay
135 | const timeOfDay = yield sequence.matchMessage(msg => msg.type === 'timeOfDay');
136 |
137 | return ctx
138 | .send(`And a ${greeting.value} to you too, ${ctx.clientName} on this fine ${timeOfDay.value}`);
139 | }));
140 |
141 | app.start();
142 | ```
143 |
144 | ### Integrating with rxjs
145 |
146 | ```javascript
147 | const Hexnut = require('hexnut');
148 | const { withObservable, filterMessages } = require('hexnut-with-observable');
149 |
150 | const { tap, filter } = require('rxjs/operators');
151 | const { pipe } = require('rxjs');
152 |
153 | const app = new Hexnut({ port: 8181 });
154 |
155 | app.use(withObservable(pipe(
156 | // Do setup operations here...
157 | tap(({ctx}) => {
158 | if (ctx.isConnection) {
159 | console.log(`[${ctx.ip}] Connection started`);
160 | }
161 | }),
162 |
163 | // Filter to only messages
164 | filterMessages(msg => msg !== 'skip'),
165 |
166 | // Process messages
167 | tap(({ctx, next}) => {
168 | ctx.send(`You sent: ${ctx.message}`);
169 | })
170 | )));
171 |
172 |
173 | app.start();
174 | ```
--------------------------------------------------------------------------------
/src/config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | port: 8080
3 | };
4 |
--------------------------------------------------------------------------------
/src/ctx.js:
--------------------------------------------------------------------------------
1 | const {
2 | SOCKET_SYMBOL,
3 | REQUEST_SYMBOL
4 | } = require('./symbols');
5 |
6 | /**
7 | * @class
8 | * Context object representing a HexNut connection
9 | */
10 | const ctx = {
11 | /**
12 | * @private
13 | */
14 | _reset(message) {
15 | this.type = 'message';
16 | this.isComplete = false;
17 | this.message = message;
18 | },
19 |
20 | /**
21 | * Send a message to the client
22 | * @param {*} data
23 | * @method
24 | */
25 | send(...args) {
26 | this[SOCKET_SYMBOL].send(...args);
27 | return this;
28 | },
29 |
30 | /**
31 | * Send a message to all connected clients
32 | * @param {*} data
33 | */
34 | sendToAll(...args) {
35 | this.app.send(...args);
36 | return this;
37 | },
38 |
39 | /**
40 | * Short circuit all remaining middleware
41 | */
42 | done() {
43 | this.isComplete = true;
44 | return this;
45 | },
46 |
47 | /**
48 | * Throw an error
49 | * @param {Error} err
50 | */
51 | throw(err) {
52 | throw err;
53 | },
54 |
55 | /**
56 | * True if this activation of the middlware chain is a new connection
57 | */
58 | get isConnection() {
59 | return this.type === 'connection';
60 | },
61 |
62 | /**
63 | * True if this activation of the middlware chain is a new message
64 | */
65 | get isMessage() {
66 | return this.type === 'message';
67 | },
68 |
69 | /**
70 | * True if this activation of the middlware chain is a closing connection
71 | */
72 | get isClosing() {
73 | return this.type === 'closing';
74 | },
75 |
76 | /**
77 | * Object representing the http(s) headers that began this connection
78 | */
79 | get requestHeaders() {
80 | return this[REQUEST_SYMBOL].headers;
81 | },
82 |
83 | /**
84 | * IP Address of the client
85 | */
86 | get ip() {
87 | return this[REQUEST_SYMBOL].connection.remoteAddress;
88 | },
89 |
90 | /**
91 | * String URL path that began the connection
92 | */
93 | get path() {
94 | return this[REQUEST_SYMBOL].url;
95 | },
96 |
97 | /**
98 | * HTTP method used to begin the connection
99 | */
100 | get method() {
101 | return this[REQUEST_SYMBOL].method;
102 | }
103 | };
104 |
105 | /**
106 | * @private
107 | */
108 | module.exports = (ws, req, app) => Object.assign(Object.create(ctx), {
109 | app,
110 | type: 'connection',
111 | message: null,
112 | [SOCKET_SYMBOL]: ws,
113 | [REQUEST_SYMBOL]: req,
114 | });
--------------------------------------------------------------------------------
/src/index.d.ts:
--------------------------------------------------------------------------------
1 | // Type definitions for Hexnut
2 | // Project: https://github.com/francisrstokes/hexnut/
3 | // Definitions by:
4 | // - Francis Stokes = CtxExtensions & {
24 | send(...args: Array): void;
25 | sendToAll(...args: Array): void;
26 | done(): void;
27 | throw(err): void;
28 | isConnection: boolean;
29 | isMessage: boolean;
30 | isClosing: boolean;
31 | requestHeaders: IncomingHttpHeaders;
32 | ip: string;
33 | path: string;
34 | method: HTTPMethod;
35 | app: HexNut;
36 | message: any;
37 | type: MessageType;
38 | };
39 |
40 | export declare type MiddlewareFunction = (ctx: Ctx, next: () => any) => Promise | any;
41 |
42 | declare class HexNut {
43 | constructor(wsConfig?: ServerOptions, WebsocketClientImpl?: any);
44 | use(middleware: MiddlewareFunction);
45 | start(): void;
46 | stop(): void;
47 | send(...args: Array): void;
48 | isReady(): boolean;
49 | }
50 |
51 | export default HexNut;
52 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | const WebSocket = require('ws');
2 | const uuid = require('uuid/v4');
3 | const config = require('./config');
4 | const createCtx = require('./ctx');
5 | const {SOCKET_SYMBOL} = require('./symbols');
6 |
7 | /**
8 | * @typedef {function(ctx, NextMiddlewareFn)} middleware
9 | * @callback middleware
10 | * @param {ctx} ctx Context object for the connection
11 | * @param {NextMiddlewareFn} next Callback function that triggers the next middleware
12 | */
13 |
14 | /**
15 | * HexNut server instance
16 | */
17 | class HexNut {
18 |
19 | /**
20 | * Create a new HexNut instance
21 | * @param {object} wsConfig - Config object, mixed with defaults, passed to Websocket.Server constructor
22 | */
23 | constructor(wsConfig = config) {
24 | this.config = {
25 | ...wsConfig
26 | };
27 | this.server = null;
28 | this.isRunning = false;
29 | this.middleware = [];
30 | this.connections = {};
31 | this.runSequencer = Promise.resolve();
32 | }
33 |
34 | /**
35 | * Adds a middleware function to the HexNut instance
36 | * @method
37 | * @param {middleware} middleware
38 | */
39 | use(middleware) {
40 | this.middleware.push(middleware);
41 | }
42 |
43 | /**
44 | * Start the HexNut Websocket Server
45 | */
46 | start() {
47 | this.server = new WebSocket.Server(this.config);
48 | this.isRunning = true;
49 |
50 | this.server.on('connection', (ws, req) => {
51 | const id = uuid();
52 | const ctx = createCtx(ws, req, this);
53 | this.connections[id] = ctx;
54 |
55 | this.runSequencer = this.runSequencer.then(() => this.runMiddleware(ctx));
56 |
57 | ws.on('message', message => {
58 | this.runSequencer = this.runSequencer.then(() => {
59 | ctx.message = message;
60 | ctx.type = 'message';
61 | return this.runMiddleware(ctx);
62 | });
63 | });
64 |
65 | ws.on('close', () => {
66 | this.runSequencer = this.runSequencer.then(() => {
67 | ctx.message = null;
68 | ctx.type = 'closing';
69 | return this.runMiddleware(ctx).then(() => {
70 | delete this.connections[id];
71 | });
72 | });
73 | });
74 | });
75 | }
76 |
77 | send(...args) {
78 | Object.values(this.connections).forEach(ctx =>
79 | ctx[SOCKET_SYMBOL].send(...args)
80 | );
81 | }
82 |
83 | /**
84 | * Stop the HexNut Websocket Server
85 | */
86 | stop() {
87 | if (this.isRunning) {
88 | this.isRunning = false;
89 | Object.entries(this.connections).forEach(([id, connection]) => {
90 | connection[SOCKET_SYMBOL].close();
91 | delete this.connections[id];
92 | });
93 | this.server.close();
94 | }
95 | }
96 |
97 | /**
98 | * @private
99 | * @param {Error} err
100 | * @param {Context} ctx
101 | */
102 | onError(err, ctx) {
103 | if (typeof this.onerror === 'function') {
104 | return this.onerror(err, ctx);
105 | }
106 | }
107 |
108 | /**
109 | * @private
110 | * @param {Context} ctx
111 | */
112 | runMiddleware(ctx) {
113 | let i = 0;
114 | const run = async idx => {
115 | if (!ctx.isComplete && typeof this.middleware[idx] === 'function') {
116 | return await this.middleware[idx](ctx, () => run(idx+1));
117 | }
118 | };
119 |
120 | return run(i).catch(err => this.onError(err, ctx));
121 | }
122 | }
123 |
124 | module.exports = HexNut;
--------------------------------------------------------------------------------
/src/symbols.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | SOCKET_SYMBOL: '@@WebsocketConnection',
3 | REQUEST_SYMBOL: '@@WebsocketRequest',
4 | }
--------------------------------------------------------------------------------
/test/index.js:
--------------------------------------------------------------------------------
1 | const {expect} = require('chai');
2 | const Websocket = require('ws');
3 | const HexNut = require('../src');
4 | const defaultConfig = require('../src/config');
5 |
6 | const PORT = process.env.PORT || 8181;
7 | const serverAddress = `ws://localhost:${PORT}`;
8 | const wait = ms => new Promise(resolve => setTimeout(resolve, ms, 42));
9 |
10 | describe('HexNut App', () => {
11 | it('should create a app with no config opts', () => {
12 | expect(() => new HexNut()).to.not.throw();
13 | });
14 |
15 | it('should create a app with empty config opts', () => {
16 | expect(() => new HexNut({})).to.not.throw();
17 | });
18 |
19 | it('should have the default config when no opts are passed', () => {
20 | expect((new HexNut()).config).to.deep.equal(defaultConfig);
21 | expect((new HexNut({})).config).to.not.deep.equal(defaultConfig);
22 | });
23 |
24 | it('should add middleware', () => {
25 | const app = new HexNut();
26 | expect(app.middleware.length).to.equal(0);
27 |
28 | app.use(() => {});
29 | expect(app.middleware.length).to.equal(1);
30 | });
31 |
32 | it('should start the server successfully', done => {
33 | const app = new HexNut();
34 | expect(() => {
35 | app.start();
36 | setTimeout(() => {
37 | app.stop();
38 | done();
39 | }, 10);
40 | }).to.not.throw();
41 | });
42 |
43 | it('should fail to start on bad port', done => {
44 | const app = new HexNut({port:-1});
45 | expect(() => {
46 | app.start();
47 | }).to.throw();
48 | done();
49 | });
50 |
51 | it('should run middleware when a connection occurs', done => {
52 | const app = new HexNut({port: PORT});
53 | app.start();
54 |
55 | let ran = false;
56 | app.use(() => ran = true);
57 |
58 | expect(ran).to.be.false;
59 |
60 | const client = new Websocket(serverAddress);
61 |
62 | client.on('open', ws => {
63 | client.send(1);
64 | setTimeout(() => {
65 | expect(ran).to.be.true;
66 | app.stop();
67 | done();
68 | }, 10);
69 | });
70 | });
71 |
72 | it('should delay messages handling after connection handling', done => {
73 | const app = new HexNut({port: PORT});
74 |
75 | app.start();
76 |
77 | let messageHandled = false;
78 | let connectionHandled = false;
79 |
80 | app.use(async (ctx, next) => {
81 | if (ctx.isConnection) {
82 | await wait(10);
83 | expect(connectionHandled).to.be.false;
84 | expect(messageHandled).to.be.false;
85 | connectionHandled = true;
86 | }
87 | return next();
88 | });
89 |
90 | app.use((ctx, next) => {
91 | if (ctx.isMessage) {
92 | expect(connectionHandled).to.be.true;
93 | messageHandled = true;
94 | }
95 | return next();
96 | });
97 |
98 | expect(messageHandled).to.be.false;
99 | expect(connectionHandled).to.be.false;
100 |
101 | const client = new Websocket(serverAddress);
102 |
103 | client.on('open', ws => {
104 | client.send(1);
105 | setTimeout(() => {
106 | expect(connectionHandled).to.be.true;
107 | expect(messageHandled).to.be.true;
108 | app.stop();
109 | done();
110 | }, 20);
111 | });
112 | });
113 |
114 | it('should run middleware when a connection occurs', done => {
115 | const app = new HexNut({port: PORT});
116 | app.start();
117 |
118 | let ran = false;
119 | app.use(() => ran = true);
120 |
121 | expect(ran).to.be.false;
122 |
123 | const client = new Websocket(serverAddress);
124 |
125 | client.on('open', () => {
126 | client.send(1);
127 | setTimeout(() => {
128 | expect(ran).to.be.true;
129 | app.stop();
130 | done();
131 | }, 10);
132 | });
133 | });
134 |
135 | it('should run the next middleware in the chain when next is called', done => {
136 | const app = new HexNut({port: PORT});
137 | app.start();
138 |
139 | let ran = false;
140 | app.use((_, next) => {
141 | ran = true;
142 | return next();
143 | });
144 |
145 | let ran2 = false;
146 | app.use(() => {
147 | ran2 = true;
148 | });
149 |
150 | let ran3 = false;
151 | app.use(() => {
152 | ran3 = true;
153 | });
154 |
155 | expect(ran).to.be.false;
156 | expect(ran2).to.be.false;
157 | expect(ran3).to.be.false;
158 |
159 | const client = new Websocket(serverAddress);
160 |
161 | client.on('open', ws => {
162 | client.send(1);
163 | setTimeout(() => {
164 | expect(ran).to.be.true;
165 | expect(ran2).to.be.true;
166 | expect(ran3).to.be.false;
167 | app.stop();
168 | done();
169 | }, 10);
170 | });
171 | });
172 |
173 | it('should middleware asyncronously', done => {
174 | const app = new HexNut({port: PORT});
175 | app.start();
176 |
177 | let ran = false;
178 | let ran3 = false;
179 | app.use(async (_, next) => {
180 | ran = true;
181 | await next();
182 | ran3 = true;
183 | });
184 |
185 | let ran2 = false;
186 | app.use(() => {
187 | ran2 = true;
188 | expect(ran3).to.be.false;
189 | });
190 |
191 | expect(ran).to.be.false;
192 | expect(ran2).to.be.false;
193 | expect(ran3).to.be.false;
194 |
195 | const client = new Websocket(serverAddress);
196 |
197 | client.on('open', () => {
198 | client.send(1);
199 | setTimeout(() => {
200 | expect(ran).to.be.true;
201 | expect(ran2).to.be.true;
202 | expect(ran3).to.be.true;
203 | app.stop();
204 | done();
205 | }, 10);
206 | });
207 | });
208 |
209 | it('should run the onerror function when errors occur', done => {
210 | const app = new HexNut({port: PORT});
211 | app.start();
212 |
213 | const err = new Error('yes');
214 |
215 | let ran = false;
216 | app.onerror = (e) => {
217 | ran = true;
218 | expect(e).to.be.equal(err);
219 | }
220 |
221 | app.use(() => {
222 | throw err;
223 | })
224 |
225 | const client = new Websocket(serverAddress);
226 |
227 | client.on('open', () => {
228 | client.send(1);
229 | setTimeout(() => {
230 | expect(ran).to.be.true;
231 | app.stop();
232 | done();
233 | }, 10);
234 | });
235 | });
236 |
237 | it('should not run the next middleware is ctx.done() is called', done => {
238 | const app = new HexNut({port: PORT});
239 | app.start();
240 |
241 | let ran = false;
242 | app.use((ctx, next) => {
243 | ran = true;
244 | ctx.done();
245 | return next();
246 | });
247 |
248 | let ran2 = false;
249 | app.use(() => {
250 | ran2 = true;
251 | });
252 |
253 | const client = new Websocket(serverAddress);
254 |
255 | client.on('open', () => {
256 | client.send(1);
257 | setTimeout(() => {
258 | app.stop();
259 | expect(ran).to.be.true;
260 | expect(ran2).to.be.false;
261 | done();
262 | }, 10);
263 | });
264 | });
265 |
266 | it('should send a message to the client', done => {
267 | const app = new HexNut({port: PORT});
268 | app.start();
269 | app.use(ctx => ctx.send('yes'));
270 |
271 | const client = new Websocket(serverAddress);
272 |
273 | let ran = false;
274 | client.on('message', () => ran = true);
275 |
276 | client.on('open', () => {
277 | setTimeout(() => {
278 | app.stop();
279 | expect(ran).to.be.true;
280 | done();
281 | }, 10);
282 | });
283 | });
284 |
285 | it('should send a message to all clients with sendToAll', done => {
286 | const app = new HexNut({port: PORT});
287 | app.start();
288 | app.use(ctx => ctx.sendToAll('yes'));
289 |
290 | const clients = Array.from({length: 3}, () => new Websocket(serverAddress));
291 |
292 | let ran = clients.map(() => false);
293 | clients.forEach((client, i) => client.on('message', () => ran[i] = true));
294 |
295 | setTimeout(() => {
296 | app.stop();
297 | expect(ran).to.deep.equal(ran.map(() => true));
298 | done();
299 | }, 10);
300 | });
301 |
302 | it('should set isClosing when a connection is closing', done => {
303 | const app = new HexNut({port: PORT});
304 | app.start();
305 |
306 | let wasClosing = false;
307 | app.use(ctx => {
308 | if (ctx.isClosing) {
309 | wasClosing = true;
310 | }
311 | });
312 |
313 | const client = new Websocket(serverAddress);
314 |
315 | client.on('open', () => {
316 | client.close();
317 | setTimeout(() => {
318 | app.stop();
319 | expect(wasClosing).to.be.true;
320 | done();
321 | }, 10);
322 | });
323 | });
324 | });
325 |
326 | describe('ctx', () => {
327 | it('should get info about the request info', done => {
328 | const app = new HexNut({port: PORT});
329 | app.start();
330 |
331 | const path = '/something/anything/235.whatever';
332 |
333 | app.use(ctx => {
334 | expect(ctx.requestHeaders).to.be.an('object');
335 | expect(ctx.ip).to.be.a('string');
336 | expect(ctx.path).to.equal(path);
337 | expect(ctx.method).to.equal('GET');
338 |
339 | expect(ctx.isConnection).to.be.a('boolean');
340 | expect(ctx.isMessage).to.be.a('boolean');
341 | expect(ctx.send).to.be.a('function');
342 | expect(ctx.sendToAll).to.be.a('function');
343 | expect(ctx._reset).to.be.a('function');
344 |
345 | expect(() => {
346 | ctx.throw('xyz')
347 | }).to.throw('xyz');
348 | });
349 |
350 | const client = new Websocket(serverAddress + path);
351 |
352 | client.on('open', () => {
353 | client.send(1);
354 | setTimeout(() => {
355 | app.stop();
356 | done();
357 | }, 10);
358 | });
359 | });
360 | });
--------------------------------------------------------------------------------