Adapter
call
Given a key and a set of arguments, call them when given a context. Primarily useful in composition.
Use a closure to call a stored key with stored arguments.
const call = (key, ...args) => context => context[key](...args);
+ }
30 seconds of code Curated collection of useful JavaScript snippets that you can understand in 30 seconds or less.
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 07f08ceb1..2cd489a62 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1421,6 +1421,12 @@
"esutils": "2.0.2"
}
},
+ "duplexer": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
+ "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=",
+ "dev": true
+ },
"ecc-jsbn": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
@@ -3092,6 +3098,12 @@
"error-ex": "1.3.1"
}
},
+ "parse-ms": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-1.0.1.tgz",
+ "integrity": "sha1-VjRtR0nXjyNDDKDHE4UK75GqNh0=",
+ "dev": true
+ },
"path-exists": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
@@ -3190,6 +3202,12 @@
"find-up": "1.1.2"
}
},
+ "plur": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/plur/-/plur-1.0.0.tgz",
+ "integrity": "sha1-24XGgU9eXlo7Se/CjWBP7GKXUVY=",
+ "dev": true
+ },
"pluralize": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz",
@@ -3235,6 +3253,12 @@
"resolved": "https://registry.npmjs.org/qs/-/qs-6.3.2.tgz",
"integrity": "sha1-51vV9uJoEioqDgvaYwslUMFmUCw="
},
+ "re-emitter": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/re-emitter/-/re-emitter-1.1.3.tgz",
+ "integrity": "sha1-+p4xn/3u6zWycpbvDz03TawvUqc=",
+ "dev": true
+ },
"read-pkg": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
@@ -3387,6 +3411,12 @@
"resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz",
"integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk="
},
+ "repeat-string": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
+ "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
+ "dev": true
+ },
"repeating": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
@@ -3655,6 +3685,15 @@
"resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz",
"integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc="
},
+ "split": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz",
+ "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==",
+ "dev": true,
+ "requires": {
+ "through": "2.3.8"
+ }
+ },
"sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
@@ -3831,6 +3870,55 @@
}
}
},
+ "tap-out": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/tap-out/-/tap-out-1.4.2.tgz",
+ "integrity": "sha1-yQfsG/lAURHQiCY+kvVgi4jLs3o=",
+ "dev": true,
+ "requires": {
+ "re-emitter": "1.1.3",
+ "readable-stream": "2.3.3",
+ "split": "1.0.1",
+ "trim": "0.0.1"
+ }
+ },
+ "tap-spec": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/tap-spec/-/tap-spec-4.1.1.tgz",
+ "integrity": "sha1-4unyb1IIIysfViKIyXYk1YqI8Fo=",
+ "dev": true,
+ "requires": {
+ "chalk": "1.1.3",
+ "duplexer": "0.1.1",
+ "figures": "1.7.0",
+ "lodash": "3.10.1",
+ "pretty-ms": "2.1.0",
+ "repeat-string": "1.6.1",
+ "tap-out": "1.4.2",
+ "through2": "2.0.3"
+ },
+ "dependencies": {
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "2.2.1",
+ "escape-string-regexp": "1.0.5",
+ "has-ansi": "2.0.0",
+ "strip-ansi": "3.0.1",
+ "supports-color": "2.0.0"
+ }
+ },
+ "lodash": {
+ "version": "3.10.1",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
+ "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=",
+ "dev": true
+ }
+ }
+ },
"tape": {
"version": "4.8.0",
"resolved": "https://registry.npmjs.org/tape/-/tape-4.8.0.tgz",
@@ -3894,6 +3982,12 @@
"punycode": "1.4.1"
}
},
+ "trim": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz",
+ "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=",
+ "dev": true
+ },
"trim-newlines": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
diff --git a/package.json b/package.json
index 0d0c380c0..1d58fac2b 100644
--- a/package.json
+++ b/package.json
@@ -11,7 +11,8 @@
"rollup-plugin-babel": "^3.0.3",
"rollup-plugin-babel-minify": "^3.1.2",
"semistandard": "^11.0.0",
- "tape": "^4.8.0"
+ "tape": "^4.8.0",
+ "tap-spec": "^4.1.1"
},
"name": "30-seconds-of-code",
"description": "A collection of useful JavaScript snippets.",
@@ -24,7 +25,8 @@
"tagger": "node ./scripts/tag.js",
"webber": "node ./scripts/web.js",
"tdd": "node ./scripts/tdd.js",
- "module": "node ./scripts/module.js"
+ "module": "node ./scripts/module.js",
+ "test": "tape test/**/*.test.js | tap-spec"
},
"repository": {
"type": "git",
diff --git a/scripts/tdd.js b/scripts/tdd.js
index d67396d7b..92cadd062 100644
--- a/scripts/tdd.js
+++ b/scripts/tdd.js
@@ -1,50 +1,84 @@
-const fs = require('fs-extra');
+/*
+ This is the tdd script that creates & updates your TDD environment .
+ Run using `npm run tagger`.
+*/
+// Load modules
+const fs = require('fs-extra');
+const chalk = require('chalk');
+// Load helper functions (these are from existing snippets in 30 seconds of code!)
+const isTravisCI = () => 'TRAVIS' in process.env && 'CI' in process.env;
+if(isTravisCI() && process.env['TRAVIS_EVENT_TYPE'] !== 'cron' && process.env['TRAVIS_EVENT_TYPE'] !== 'api') {
+ console.log(`${chalk.green('NOBUILD')} Testing terminated, not a cron job or a custom build!`);
+ process.exit(0);
+}
+// Declare paths
const SNIPPETS_PATH = './snippets';
const TEST_PATH = './test';
+// Array of snippet names
const snippetFiles = fs.readdirSync(SNIPPETS_PATH, 'utf8').map(fileName => fileName.slice(0, -3));
-fs.removeSync(TEST_PATH);
+// Current Snippet that depend on node_modules
+const errSnippets = ['JSONToFile', 'readFileLines', 'UUIDGeneratorNode'];
snippetFiles
+ .filter(fileName => !errSnippets.includes(fileName))
.map(fileName => {
+ // Check if fileName for snippet exist in test/ dir, if doesnt create
fs.ensureDirSync(`${TEST_PATH}/${fileName}`);
+
+ // return fileName for later use
return fileName;
})
.map(fileName => {
+ // Grab snippetData
const fileData = fs.readFileSync(`${SNIPPETS_PATH}/${fileName}.md`, 'utf8');
+ // Grab snippet Code blocks
const fileCode = fileData.slice(fileData.indexOf('```js'), fileData.lastIndexOf('```') + 3);
+ // Split code based on code markers
const blockMarkers = fileCode
.split('\n')
.map((line, lineIndex) => (line.slice(0, 3) === '```' ? lineIndex : '//CLEAR//'))
.filter(x => !(x === '//CLEAR//'));
+ // Grab snippet function based on code markers
const fileFunction = fileCode
.split('\n')
.map(line => line.trim())
.filter((_, i) => blockMarkers[0] < i && i < blockMarkers[1]);
+ // Grab snippet example based on code markers
const fileExample = fileCode
.split('\n')
.map(line => line.trim())
.filter((_, i) => blockMarkers[2] < i && i < blockMarkers[3]);
- const exportFile = `module.exports = ${fileFunction.join('\n').slice(17)}`;
+ // Export template for snippetName.js which takes into account snippet name.length when generating snippetName.js file
+ const exportFile = `module.exports = ${fileFunction.join('\n').slice(9 + fileName.length)}`;
+
+ // Export template for snippetName.test.js which generates a example test & other information
const exportTest = [
`const test = require('tape');`,
`const ${fileName} = require('./${fileName}.js');`,
- `test('Testing ${fileName}', (t) => {`,
- `//For more information on all the methods supported by tape\n//Please go to https://github.com/substack/tape`,
- `//t.deepEqual(${fileName}(args..), 'Expected');`,
- `//t.equal(${fileName}(args..), 'Expected');`,
- `//t.false(${fileName}(args..), 'Expected');`,
- `//t.true(${fileName}(args..), 'Expected');`,
- `//t.throws(${fileName}(args..), 'Expected');`,
- `t.end();`,
+ `\ntest('Testing ${fileName}', (t) => {`,
+ `\t//For more information on all the methods supported by tape\n\t//Please go to https://github.com/substack/tape`,
+ `\tt.true(typeof ${fileName} === 'function', '${fileName} is a Function');`,
+ `\t//t.deepEqual(${fileName}(args..), 'Expected');`,
+ `\t//t.equal(${fileName}(args..), 'Expected');`,
+ `\t//t.false(${fileName}(args..), 'Expected');`,
+ `\t//t.throws(${fileName}(args..), 'Expected');`,
+ `\tt.end();`,
`});`
].join('\n');
+ // Write/Update exportFile which is snippetName.js in respective dir
fs.writeFileSync(`${TEST_PATH}/${fileName}/${fileName}.js`, exportFile);
- fs.writeFileSync(`${TEST_PATH}/${fileName}/${fileName}.test.js`, exportTest);
+ if ( !fs.existsSync(`${TEST_PATH}/${fileName}/${fileName}.test.js`) ) {
+ // if snippetName.test.js doesn't exist inrespective dir exportTest
+ fs.writeFileSync(`${TEST_PATH}/${fileName}/${fileName}.test.js`, exportTest);
+ }
+
+ // return fileName for later use
return fileName;
});
+
diff --git a/snippets/factors.md b/snippets/factors.md
new file mode 100644
index 000000000..0e31b5dd5
--- /dev/null
+++ b/snippets/factors.md
@@ -0,0 +1,42 @@
+### factors
+
+Returns the array of factors of the given `num`.
+If the second argument is set to `true` returns only the prime factors of `num`.
+If `num` is `1` or `0` returns an empty array.
+If `num` is less than `0` returns all the factors of `-int` together with their additive inverses.
+
+Use `Array.from()`, `Array.map()` and `Array.filter()` to find all the factors of `num`.
+If given `num` is negative, use `Array.reduce()` to add the additive inverses to the array.
+Return all results if `primes` is `false`, else determine and return only the prime factors using `isPrime` and `Array.filter()`.
+Omit the second argument, `primes`, to return prime and non-prime factors by default.
+
+**Note**:- _Negative numbers are not considered prime._
+
+```js
+const factors = (num, primes = false) => {
+ const isPrime = num => {
+ const boundary = Math.floor(Math.sqrt(num));
+ for (var i = 2; i <= boundary; i++) if (num % i === 0) return false;
+ return num >= 2;
+ };
+ const isNeg = num < 0;
+ num = isNeg ? -num : num;
+ let array = Array.from({ length: num - 1 })
+ .map((val, i) => (num % (i + 2) === 0 ? i + 2 : false))
+ .filter(val => val);
+ if (isNeg)
+ array = array.reduce((acc, val) => {
+ acc.push(val);
+ acc.push(-val);
+ return acc;
+ }, []);
+ return primes ? array.filter(isPrime) : array;
+};
+```
+
+```js
+factors(12); // [2,3,4,6,12]
+factors(12, true); // [2,3]
+factors(-12); // [2, -2, 3, -3, 4, -4, 6, -6, 12, -12]
+factors(-12, true); // [2,3]
+```
diff --git a/snippets/howManyTimes.md b/snippets/howManyTimes.md
new file mode 100644
index 000000000..add649172
--- /dev/null
+++ b/snippets/howManyTimes.md
@@ -0,0 +1,32 @@
+### howManyTimes
+
+Returns the number of times `num` can be divided by `divisor` (integer or fractional) without getting a fractional answer.
+Works for both negative and positive integers.
+
+If `divisor` is `-1` or `1` return `Infinity`.
+If `divisor` is `-0` or `0` return `0`.
+Otherwise, keep dividing `num` with `divisor` and incrementing `i`, while the result is an integer.
+Return the number of times the loop was executed, `i`.
+
+```js
+const howManyTimes = (num, divisor) => {
+ if (divisor === 1 || divisor === -1) return Infinity;
+ if (divisor === 0) return 0;
+ let i = 0;
+ while (Number.isInteger(num / divisor)) {
+ i++;
+ num = num / divisor;
+ }
+ return i;
+};
+```
+
+```js
+howManyTimes(100, 2); //2
+howManyTimes(100, -2); //2
+howManyTimes(100, 2.5); //2
+howManyTimes(100, 3); //0
+howManyTimes(100, 0); //0
+howManyTimes(100, 1); //Infinity
+howManyTimes(100, -1); //Infinity
+```
diff --git a/snippets/maxN.md b/snippets/maxN.md
index efc9e5052..87ee686fd 100644
--- a/snippets/maxN.md
+++ b/snippets/maxN.md
@@ -1,10 +1,11 @@
### maxN
-Returns the `n` maximum elements from the provided array. If `n` is greater than or equal to the provided array's length than return the original array(sorted in descending order).
+Returns the `n` maximum elements from the provided array. If `n` is greater than or equal to the provided array's length, then return the original array(sorted in descending order).
-Sort's the array's shallow copy in descending order and returns the first n elements
+Use `Array.sort()` combined with the spread operator (`...`) to create a shallow clone of the array and sort it in descending order.
+Use `Array.slice()` to get the specified number of elements.
+Omit the second argument, `n`, to get a one-element array.
-Skip the second argument to get a single element(in the form of a array)
```js
const maxN = (arr, n = 1) => [...arr].sort((a, b) => b - a).slice(0, n);
```
diff --git a/snippets/minN.md b/snippets/minN.md
index 2cee5b091..a97c5e1f7 100644
--- a/snippets/minN.md
+++ b/snippets/minN.md
@@ -1,10 +1,11 @@
### minN
-Returns the `n` minimum elements from the provided array. If `n` is greater than or equal to the provided array's length than return the original array(sorted in ascending order).
+Returns the `n` minimum elements from the provided array. If `n` is greater than or equal to the provided array's length, then return the original array(sorted in ascending order).
-Sort's the array's shallow copy in ascending order and returns the first n elements
+Use `Array.sort()` combined with the spread operator (`...`) to create a shallow clone of the array and sort it in ascending order.
+Use `Array.slice()` to get the specified number of elements.
+Omit the second argument, `n`, to get a one-element array.
-Skip the second argument to get a single element(in the form of a array)
```js
const minN = (arr, n = 1) => [...arr].sort((a, b) => a - b).slice(0, n);
```
diff --git a/snippets/pluralize.md b/snippets/pluralize.md
new file mode 100644
index 000000000..decf1c2ef
--- /dev/null
+++ b/snippets/pluralize.md
@@ -0,0 +1,23 @@
+# pluralize
+
+If `num` is greater than `1` returns the plural form of the given string, else return the singular form.
+
+Check if `num` is greater than `0`. Throw an appropriate `Error` if not, return the appropriate string otherwise.
+Omit the third argument, `items`, to use a default plural form same as `item` suffixed with a single `'s'`.
+
+```js
+const pluralize = (num, item, items = item + 's') =>
+ num <= 0
+ ? (() => {
+ throw new Error(`'num' should be >= 1. Value povided was ${num}.`);
+ })()
+ : num === 1 ? item : items;
+```
+
+```js
+pluralize(1, 'apple', 'apples'); // 'apple'
+pluralize(3, 'apple', 'apples'); // 'apples'
+pluralize(2, 'apple'); // 'apples'
+pluralize(0, 'apple', 'apples'); // Gives error
+pluralize(-3, 'apple', 'apples'); // Gives error
+```
diff --git a/static-parts/README-start.md b/static-parts/README-start.md
index a3a94d299..34775afdc 100644
--- a/static-parts/README-start.md
+++ b/static-parts/README-start.md
@@ -5,7 +5,7 @@
[](https://github.com/Chalarangelo/30-seconds-of-code/blob/master/LICENSE) [](https://gitter.im/30-seconds-of-code/Lobby) [](http://makeapullrequest.com) [](https://travis-ci.org/Chalarangelo/30-seconds-of-code) [](https://insight.io/github.com/Chalarangelo/30-seconds-of-code/tree/master/?source=0) [](https://github.com/Flet/semistandard) [](https://www.producthunt.com/posts/30-seconds-of-code)
-> Curated collection of useful Javascript snippets that you can understand in 30 seconds or less.
+> Curated collection of useful JavaScript snippets that you can understand in 30 seconds or less.
- Use Ctrl + F or command + F to search for a snippet.
@@ -13,6 +13,57 @@
- Snippets are written in ES6, use the [Babel transpiler](https://babeljs.io/) to ensure backwards-compatibility.
- You can import these snippets into your text editor of choice (VSCode, Atom, Sublime) using the files found in [this repo](https://github.com/Rob-Rychs/30-seconds-of-code-texteditorsnippets).
- You can import these snippets into Alfred 3, using [this file](https://github.com/lslvxy/30-seconds-of-code-alfredsnippets).
-- You can find a package with all the snippets on [npm](https://www.npmjs.com/package/30-seconds-of-code). Bear in mind that most of these snippets are not production-ready.
+
+#### Package
+
+⚠️ **WARNING:** Snippets are not production ready.
+
+You can find a package with all the snippets on [npm](https://www.npmjs.com/package/30-seconds-of-code).
+
+```
+npm install 30-seconds-of-code
+```
+
+CDN links
+- [ES2017 Full (UMD)](https://unpkg.com/30-seconds-of-code)
+- [ES5 Minified (UMD)](https://unpkg.com/30-seconds-of-code/dist/_30s.es5.min.js)
+
+
+
+**Browser**
+
+> IMPORTANT: replace the `src` with the full version link and desired target spec (such as ES5 minified)):
+
+```html
+
+
+```
+
+**Node**
+
+```js
+// CommonJS
+const _30s = require('30-seconds-of-code');
+_30s.average(1, 2, 3);
+
+// ES Modules
+import _30s from '30-seconds-of-code';
+_30s.average(1, 2, 3);
+```
+
+To import snippets directly:
+
+```js
+// CommonJS
+const { average } = require('30-seconds-of-code');
+average(1, 2, 3);
+
+// ES Modules
+import { average } from '30-seconds-of-code';
+average(1, 2, 3);
+```
+
## Table of Contents
diff --git a/tag_database b/tag_database
index 7b4e92890..5ef49198b 100644
--- a/tag_database
+++ b/tag_database
@@ -39,6 +39,7 @@ escapeRegExp:string
everyNth:array
extendHex:utility
factorial:math
+factors:math
fibonacci:math
fibonacciCountUntilNum:math
fibonacciUntilNum:math
@@ -49,7 +50,7 @@ flip:adapter
fromCamelCase:string
functionName:function
gcd:math
-geometricProgression:uncategorized
+geometricProgression:math
getDaysDiffBetweenDates:date
getScrollPosition:browser
getStyle:browser
@@ -62,6 +63,7 @@ hasFlags:node
head:array
hexToRGB:utility
hide:browser
+howManyTimes:math
httpsRedirect:browser
initial:array
initialize2DArray:array
@@ -96,10 +98,10 @@ lcm:math
lowercaseKeys:object
mapObject:array
mask:string
-maxN:math
+maxN:array
median:math
memoize:function
-minN:math
+minN:array
negate:logic
nthElement:array
objectFromPairs:object
@@ -111,6 +113,7 @@ palindrome:string
percentile:math
pick:array
pipeFunctions:adapter
+pluralize:string
powerset:math
prettyBytes:utility
primes:math
diff --git a/yarn.lock b/yarn.lock
index c7dec9cb4..98cfbe791 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1093,6 +1093,10 @@ doctrine@^2.0.0:
dependencies:
esutils "^2.0.2"
+duplexer@^0.1.1:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1"
+
ecc-jsbn@~0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505"
@@ -1379,7 +1383,7 @@ fast-levenshtein@~2.0.4:
version "2.0.6"
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
-figures@^1.3.5:
+figures@^1.3.5, figures@^1.4.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e"
dependencies:
@@ -1758,7 +1762,7 @@ is-date-object@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16"
-is-finite@^1.0.0:
+is-finite@^1.0.0, is-finite@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa"
dependencies:
@@ -1995,6 +1999,10 @@ lodash.some@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d"
+lodash@^3.6.0:
+ version "3.10.1"
+ resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6"
+
lodash@^4.0.0, lodash@^4.17.4, lodash@^4.3.0, lodash@~4.17.4:
version "4.17.4"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
@@ -2272,6 +2280,10 @@ parse-json@^2.2.0:
dependencies:
error-ex "^1.2.0"
+parse-ms@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/parse-ms/-/parse-ms-1.0.1.tgz#56346d4749d78f23430ca0c713850aef91aa361d"
+
path-exists@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b"
@@ -2347,6 +2359,10 @@ pkg-up@^1.0.0:
dependencies:
find-up "^1.0.0"
+plur@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/plur/-/plur-1.0.0.tgz#db85c6814f5e5e5a3b49efc28d604fec62975156"
+
pluralize@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45"
@@ -2359,6 +2375,14 @@ prettier@^1.9.2:
version "1.9.2"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.9.2.tgz#96bc2132f7a32338e6078aeb29727178c6335827"
+pretty-ms@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/pretty-ms/-/pretty-ms-2.1.0.tgz#4257c256df3fb0b451d6affaab021884126981dc"
+ dependencies:
+ is-finite "^1.0.1"
+ parse-ms "^1.0.0"
+ plur "^1.0.0"
+
private@^0.1.6, private@^0.1.7:
version "0.1.8"
resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff"
@@ -2387,6 +2411,10 @@ qs@~6.5.1:
version "6.5.1"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8"
+re-emitter@^1.0.0:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/re-emitter/-/re-emitter-1.1.3.tgz#fa9e319ffdeeeb35b27296ef0f3d374dac2f52a7"
+
read-pkg-up@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02"
@@ -2402,7 +2430,7 @@ read-pkg@^1.0.0:
normalize-package-data "^2.3.2"
path-type "^1.0.0"
-readable-stream@^2.0.1, readable-stream@^2.0.6, readable-stream@^2.2.2:
+readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2:
version "2.3.3"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c"
dependencies:
@@ -2473,6 +2501,10 @@ relateurl@0.2.x:
version "0.2.7"
resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9"
+repeat-string@^1.5.2:
+ version "1.6.1"
+ resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637"
+
repeating@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda"
@@ -2733,6 +2765,12 @@ spdx-license-ids@^1.0.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57"
+split@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9"
+ dependencies:
+ through "2"
+
sprintf-js@~1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
@@ -2852,6 +2890,28 @@ table@^3.7.8:
slice-ansi "0.0.4"
string-width "^2.0.0"
+tap-out@^1.4.1:
+ version "1.4.2"
+ resolved "https://registry.yarnpkg.com/tap-out/-/tap-out-1.4.2.tgz#c907ec1bf9405111d088263e92f5608b88cbb37a"
+ dependencies:
+ re-emitter "^1.0.0"
+ readable-stream "^2.0.0"
+ split "^1.0.0"
+ trim "0.0.1"
+
+tap-spec@^4.1.1:
+ version "4.1.1"
+ resolved "https://registry.yarnpkg.com/tap-spec/-/tap-spec-4.1.1.tgz#e2e9f26f5208232b1f562288c97624d58a88f05a"
+ dependencies:
+ chalk "^1.0.0"
+ duplexer "^0.1.1"
+ figures "^1.4.0"
+ lodash "^3.6.0"
+ pretty-ms "^2.1.0"
+ repeat-string "^1.5.2"
+ tap-out "^1.4.1"
+ through2 "^2.0.0"
+
tape@^4.8.0:
version "4.8.0"
resolved "https://registry.yarnpkg.com/tape/-/tape-4.8.0.tgz#f6a9fec41cc50a1de50fa33603ab580991f6068e"
@@ -2882,7 +2942,14 @@ text-table@~0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
-through@^2.3.6, through@~2.3.4, through@~2.3.8:
+through2@^2.0.0:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be"
+ dependencies:
+ readable-stream "^2.1.5"
+ xtend "~4.0.1"
+
+through@2, through@^2.3.6, through@~2.3.4, through@~2.3.8:
version "2.3.8"
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
@@ -2904,6 +2971,10 @@ trim-right@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003"
+trim@0.0.1:
+ version "0.0.1"
+ resolved "https://registry.yarnpkg.com/trim/-/trim-0.0.1.tgz#5858547f6b290757ee95cccc666fb50084c460dd"
+
"true-case-path@^1.0.2":
version "1.0.2"
resolved "https://registry.yarnpkg.com/true-case-path/-/true-case-path-1.0.2.tgz#7ec91130924766c7f573be3020c34f8fdfd00d62"
@@ -3027,7 +3098,7 @@ xml-char-classes@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/xml-char-classes/-/xml-char-classes-1.0.0.tgz#64657848a20ffc5df583a42ad8a277b4512bbc4d"
-xtend@^4.0.0, xtend@^4.0.1:
+xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"