From c8142c3a2814159bcd7bc094acfebe100a8d9393 Mon Sep 17 00:00:00 2001 From: atomiks Date: Sun, 31 Dec 2017 00:42:36 +1100 Subject: [PATCH 01/61] resolve conflicts --- package.json | 3 ++- scripts/module.js | 69 +++++++++++++++++++++++++++++++++++++++++++++++ scripts/rollup.js | 19 +++++++++++++ 3 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 scripts/module.js create mode 100644 scripts/rollup.js diff --git a/package.json b/package.json index 366cba720..e0912f2e3 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,8 @@ "linter": "node ./scripts/lint.js", "tagger": "node ./scripts/tag.js", "webber": "node ./scripts/web.js", - "tdd": "node ./scripts/tdd.js" + "tdd": "node ./scripts/tdd.js", + "module": "node .scripts/module.js" }, "repository": { "type": "git", diff --git a/scripts/module.js b/scripts/module.js new file mode 100644 index 000000000..db55708b3 --- /dev/null +++ b/scripts/module.js @@ -0,0 +1,69 @@ +/* + Builds the `Snippet` module. +*/ +const fs = require('fs-extra'); +const cp = require('child_process'); +const path = require('path'); +const chalk = require('chalk'); + +const SNIPPETS_PATH = './snippets'; +const TEMP_PATH = './temp'; +const IMPORTS = './imports.js'; + +const codeRE = /```\s*js([\s\S]*?)```/; + +const tagDatabase = fs.readFileSync('tag_database', 'utf8'); + +console.time('Module'); + +try { + const snippets = fs.readdirSync(SNIPPETS_PATH); + + if (!fs.existsSync(TEMP_PATH)) { + fs.mkdirSync(TEMP_PATH); + } + + fs.writeFileSync(IMPORTS, ''); + + let exportStr = 'export default {'; + + for (const snippet of snippets) { + const snippetData = fs.readFileSync(path.join(SNIPPETS_PATH, snippet), 'utf8'); + const snippetName = snippet.replace('.md', ''); + + const isNodeSnippet = tagDatabase + .slice(tagDatabase.indexOf(snippetName) + snippetName.length + 1) + .split('\n')[0] + .includes('node'); + + if (!isNodeSnippet) { + const importData = fs.readFileSync(IMPORTS); + fs.writeFileSync( + IMPORTS, + importData + `\nimport { ${snippetName} } from './temp/${snippetName}.js'` + ); + exportStr += `${snippetName},`; + + fs.writeFileSync( + `${TEMP_PATH}/${snippetName}.js`, + 'export ' + snippetData.match(codeRE)[1].replace('\n', '') + ); + } + } + + exportStr += '}'; + + const importData = fs.readFileSync(IMPORTS); + fs.writeFileSync(IMPORTS, importData + `\n${exportStr}`); + + cp.execSync('rollup -c scripts/rollup.js'); + + fs.removeSync(TEMP_PATH); + fs.unlink(IMPORTS); + + console.log(`${chalk.green('SUCCESS!')} Snippet module built!`); + console.timeEnd('Module'); +} catch (err) { + console.log(`${chalk.red('ERROR!')} During module creation: ${err}`); + process.exit(1); +} diff --git a/scripts/rollup.js b/scripts/rollup.js new file mode 100644 index 000000000..5a16ef58a --- /dev/null +++ b/scripts/rollup.js @@ -0,0 +1,19 @@ +import babel from 'rollup-plugin-babel'; +import minify from 'rollup-plugin-babel-minify'; + +export default { + input: './imports.js', + output: { + file: './lib/TSOC.js', + format: 'umd', + name: 'TSOC' + }, + externalHelpers: true, + plugins: [ + babel({ + presets: ['es2015-rollup'], + plugins: ['transform-object-assign', 'transform-object-rest-spread'] + }), + minify({ comments: false }) + ] +}; From b7b35c4af4f6b6f6a19d4f6db56c1d9ca12feea8 Mon Sep 17 00:00:00 2001 From: atomiks Date: Sun, 31 Dec 2017 00:45:18 +1100 Subject: [PATCH 02/61] fix typos --- package.json | 2 +- scripts/module.js | 3 +-- scripts/rollup.js | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index e0912f2e3..6d4b549fd 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "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" }, "repository": { "type": "git", diff --git a/scripts/module.js b/scripts/module.js index db55708b3..f6753b11b 100644 --- a/scripts/module.js +++ b/scripts/module.js @@ -12,11 +12,10 @@ const IMPORTS = './imports.js'; const codeRE = /```\s*js([\s\S]*?)```/; -const tagDatabase = fs.readFileSync('tag_database', 'utf8'); - console.time('Module'); try { + const tagDatabase = fs.readFileSync('tag_database', 'utf8'); const snippets = fs.readdirSync(SNIPPETS_PATH); if (!fs.existsSync(TEMP_PATH)) { diff --git a/scripts/rollup.js b/scripts/rollup.js index 5a16ef58a..963eccb4f 100644 --- a/scripts/rollup.js +++ b/scripts/rollup.js @@ -4,7 +4,7 @@ import minify from 'rollup-plugin-babel-minify'; export default { input: './imports.js', output: { - file: './lib/TSOC.js', + file: './module/TSOC.js', format: 'umd', name: 'TSOC' }, From 5dce7c771cf68725c46c497c1a3bb5262810a9c7 Mon Sep 17 00:00:00 2001 From: atomiks Date: Tue, 2 Jan 2018 01:02:57 +1100 Subject: [PATCH 03/61] Add more package types, allow for node snippets --- .gitignore | 1 - package-lock.json | 1060 +++++++++++++++++++++++++++++++++++++++++++-- package.json | 17 +- scripts/module.js | 40 +- scripts/rollup.js | 75 +++- 5 files changed, 1113 insertions(+), 80 deletions(-) diff --git a/.gitignore b/.gitignore index 6f177e3db..1672226d8 100644 --- a/.gitignore +++ b/.gitignore @@ -3,5 +3,4 @@ currentSnippet\.js *.md.temp.js .idea test.sh -dist/ test/ diff --git a/package-lock.json b/package-lock.json index f06436ab6..07f08ceb1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,9 +1,14 @@ { "name": "30-seconds-of-code", - "version": "1.0.0", + "version": "0.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { + "@comandeer/babel-plugin-banner": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@comandeer/babel-plugin-banner/-/babel-plugin-banner-1.0.0.tgz", + "integrity": "sha1-QLzOC77ghLWwJUWjNjXQU8JINW8=" + }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -53,16 +58,6 @@ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=" }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" - }, "aproba": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", @@ -202,6 +197,808 @@ } } }, + "babel-core": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.0.tgz", + "integrity": "sha1-rzL3izGm/O8RnIew/Y2XU/A6C7g=", + "requires": { + "babel-code-frame": "6.26.0", + "babel-generator": "6.26.0", + "babel-helpers": "6.24.1", + "babel-messages": "6.23.0", + "babel-register": "6.26.0", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0", + "babylon": "6.18.0", + "convert-source-map": "1.5.1", + "debug": "2.6.9", + "json5": "0.5.1", + "lodash": "4.17.4", + "minimatch": "3.0.4", + "path-is-absolute": "1.0.1", + "private": "0.1.8", + "slash": "1.0.0", + "source-map": "0.5.7" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, + "babel-generator": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.0.tgz", + "integrity": "sha1-rBriAHC3n248odMmlhMFN3TyDcU=", + "requires": { + "babel-messages": "6.23.0", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "detect-indent": "4.0.0", + "jsesc": "1.3.0", + "lodash": "4.17.4", + "source-map": "0.5.7", + "trim-right": "1.0.1" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, + "babel-helper-builder-binary-assignment-operator-visitor": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", + "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=", + "requires": { + "babel-helper-explode-assignable-expression": "6.24.1", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helper-call-delegate": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", + "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", + "requires": { + "babel-helper-hoist-variables": "6.24.1", + "babel-runtime": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helper-define-map": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz", + "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=", + "requires": { + "babel-helper-function-name": "6.24.1", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "lodash": "4.17.4" + } + }, + "babel-helper-evaluate-path": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-helper-evaluate-path/-/babel-helper-evaluate-path-0.2.0.tgz", + "integrity": "sha512-0EK9TUKMxHL549hWDPkQoS7R0Ozg1CDLheVBHYds2B2qoAvmr9ejY3zOXFsrICK73TN7bPhU14PBeKc8jcBTwg==" + }, + "babel-helper-explode-assignable-expression": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", + "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=", + "requires": { + "babel-runtime": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helper-flip-expressions": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-helper-flip-expressions/-/babel-helper-flip-expressions-0.2.0.tgz", + "integrity": "sha512-rAsPA1pWBc7e2E6HepkP2e1sXugT+Oq/VCqhyuHJ8aJ2d/ifwnJfd4Qxjm21qlW43AN8tqaeByagKK6wECFMSw==" + }, + "babel-helper-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", + "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", + "requires": { + "babel-helper-get-function-arity": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helper-get-function-arity": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", + "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helper-hoist-variables": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", + "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helper-is-nodes-equiv": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/babel-helper-is-nodes-equiv/-/babel-helper-is-nodes-equiv-0.0.1.tgz", + "integrity": "sha1-NOmzALFHnd2Y7HfqC76TQt/jloQ=" + }, + "babel-helper-is-void-0": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-helper-is-void-0/-/babel-helper-is-void-0-0.2.0.tgz", + "integrity": "sha512-Axj1AYuD0E3Dl7nT3KxROP7VekEofz3XtEljzURf3fABalLpr8PamtgLFt+zuxtaCxRf9iuZmbAMMYWri5Bazw==" + }, + "babel-helper-mark-eval-scopes": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-helper-mark-eval-scopes/-/babel-helper-mark-eval-scopes-0.2.0.tgz", + "integrity": "sha512-KJuwrOUcHbvbh6he4xRXZFLaivK9DF9o3CrvpWnK1Wp0B+1ANYABXBMgwrnNFIDK/AvicxQ9CNr8wsgivlp4Aw==" + }, + "babel-helper-optimise-call-expression": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", + "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helper-regex": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz", + "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=", + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "lodash": "4.17.4" + } + }, + "babel-helper-remap-async-to-generator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", + "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=", + "requires": { + "babel-helper-function-name": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helper-remove-or-void": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-helper-remove-or-void/-/babel-helper-remove-or-void-0.2.0.tgz", + "integrity": "sha512-1Z41upf/XR+PwY7Nd+F15Jo5BiQi5205ZXUuKed3yoyQgDkMyoM7vAdjEJS/T+M6jy32sXjskMUgms4zeiVtRA==" + }, + "babel-helper-replace-supers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", + "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", + "requires": { + "babel-helper-optimise-call-expression": "6.24.1", + "babel-messages": "6.23.0", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helper-to-multiple-sequence-expressions": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-helper-to-multiple-sequence-expressions/-/babel-helper-to-multiple-sequence-expressions-0.2.0.tgz", + "integrity": "sha512-ij9lpfdP3+Zc/7kNwa+NXbTrUlsYEWPwt/ugmQO0qflzLrveTIkbfOqQztvitk81aG5NblYDQXDlRohzu3oa8Q==" + }, + "babel-helpers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", + "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", + "requires": { + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" + } + }, + "babel-messages": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", + "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-check-es2015-constants": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", + "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-minify-builtins": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-builtins/-/babel-plugin-minify-builtins-0.2.0.tgz", + "integrity": "sha512-4i+8ntaS8gwVUcOz5y+zE+55OVOl2nTbmHV51D4wAIiKcRI8U5K//ip1GHfhsgk/NJrrHK7h97Oy5jpqt0Iixg==", + "requires": { + "babel-helper-evaluate-path": "0.2.0" + } + }, + "babel-plugin-minify-constant-folding": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-constant-folding/-/babel-plugin-minify-constant-folding-0.2.0.tgz", + "integrity": "sha512-B3ffQBEUQ8ydlIkYv2MkZtTCbV7FAkWAV7NkyhcXlGpD10PaCxNGQ/B9oguXGowR1m16Q5nGhvNn8Pkn1MO6Hw==", + "requires": { + "babel-helper-evaluate-path": "0.2.0" + } + }, + "babel-plugin-minify-dead-code-elimination": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-dead-code-elimination/-/babel-plugin-minify-dead-code-elimination-0.2.0.tgz", + "integrity": "sha512-zE7y3pRyzA4zK5nBou0kTcwUTSQ/AiFrynt1cIEYN7vcO2gS9ZFZoI0aO9JYLUdct5fsC1vfB35408yrzTyVfg==", + "requires": { + "babel-helper-evaluate-path": "0.2.0", + "babel-helper-mark-eval-scopes": "0.2.0", + "babel-helper-remove-or-void": "0.2.0", + "lodash.some": "4.6.0" + } + }, + "babel-plugin-minify-flip-comparisons": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-flip-comparisons/-/babel-plugin-minify-flip-comparisons-0.2.0.tgz", + "integrity": "sha512-QOqXSEmD/LhT3LpM1WCyzAGcQZYYKJF7oOHvS6QbpomHenydrV53DMdPX2mK01icBExKZcJAHF209wvDBa+CSg==", + "requires": { + "babel-helper-is-void-0": "0.2.0" + } + }, + "babel-plugin-minify-guarded-expressions": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-guarded-expressions/-/babel-plugin-minify-guarded-expressions-0.2.0.tgz", + "integrity": "sha512-5+NSPdRQ9mnrHaA+zFj+D5OzmSiv90EX5zGH6cWQgR/OUqmCHSDqgTRPFvOctgpo8MJyO7Rt7ajs2UfLnlAwYg==", + "requires": { + "babel-helper-flip-expressions": "0.2.0" + } + }, + "babel-plugin-minify-infinity": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-infinity/-/babel-plugin-minify-infinity-0.2.0.tgz", + "integrity": "sha512-U694vrla1lN6vDHWGrR832t3a/A2eh+kyl019LxEE2+sS4VTydyOPRsAOIYAdJegWRA4cMX1lm9azAN0cLIr8g==" + }, + "babel-plugin-minify-mangle-names": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-mangle-names/-/babel-plugin-minify-mangle-names-0.2.0.tgz", + "integrity": "sha512-Gixuak1/CO7VCdjn15/8Bxe/QsAtDG4zPbnsNoe1mIJGCIH/kcmSjFhMlGJtXDQZd6EKzeMfA5WmX9+jvGRefw==", + "requires": { + "babel-helper-mark-eval-scopes": "0.2.0" + } + }, + "babel-plugin-minify-numeric-literals": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-numeric-literals/-/babel-plugin-minify-numeric-literals-0.2.0.tgz", + "integrity": "sha512-VcLpb+r1YS7+RIOXdRsFVLLqoh22177USpHf+JM/g1nZbzdqENmfd5v534MLAbRErhbz6SyK+NQViVzVtBxu8g==" + }, + "babel-plugin-minify-replace": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-replace/-/babel-plugin-minify-replace-0.2.0.tgz", + "integrity": "sha512-SEW6zoSVxh3OH6E1LCgyhhTWMnCv+JIRu5h5IlJDA11tU4ZeSF7uPQcO4vN/o52+FssRB26dmzJ/8D+z0QPg5Q==" + }, + "babel-plugin-minify-simplify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-simplify/-/babel-plugin-minify-simplify-0.2.0.tgz", + "integrity": "sha512-Mj3Mwy2zVosMfXDWXZrQH5/uMAyfJdmDQ1NVqit+ArbHC3LlXVzptuyC1JxTyai/wgFvjLaichm/7vSUshkWqw==", + "requires": { + "babel-helper-flip-expressions": "0.2.0", + "babel-helper-is-nodes-equiv": "0.0.1", + "babel-helper-to-multiple-sequence-expressions": "0.2.0" + } + }, + "babel-plugin-minify-type-constructors": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-type-constructors/-/babel-plugin-minify-type-constructors-0.2.0.tgz", + "integrity": "sha512-NiOvvA9Pq6bki6nP4BayXwT5GZadw7DJFDDzHmkpnOQpENWe8RtHtKZM44MG1R6EQ5XxgbLdsdhswIzTkFlO5g==", + "requires": { + "babel-helper-is-void-0": "0.2.0" + } + }, + "babel-plugin-syntax-async-functions": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", + "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=" + }, + "babel-plugin-syntax-exponentiation-operator": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", + "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=" + }, + "babel-plugin-syntax-trailing-function-commas": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", + "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=" + }, + "babel-plugin-transform-async-to-generator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", + "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=", + "requires": { + "babel-helper-remap-async-to-generator": "6.24.1", + "babel-plugin-syntax-async-functions": "6.13.0", + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-arrow-functions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", + "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-block-scoped-functions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", + "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-block-scoping": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", + "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=", + "requires": { + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0", + "lodash": "4.17.4" + } + }, + "babel-plugin-transform-es2015-classes": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", + "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", + "requires": { + "babel-helper-define-map": "6.26.0", + "babel-helper-function-name": "6.24.1", + "babel-helper-optimise-call-expression": "6.24.1", + "babel-helper-replace-supers": "6.24.1", + "babel-messages": "6.23.0", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-plugin-transform-es2015-computed-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", + "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", + "requires": { + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" + } + }, + "babel-plugin-transform-es2015-destructuring": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", + "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-duplicate-keys": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", + "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-plugin-transform-es2015-for-of": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", + "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", + "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", + "requires": { + "babel-helper-function-name": "6.24.1", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-plugin-transform-es2015-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", + "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-modules-amd": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", + "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", + "requires": { + "babel-plugin-transform-es2015-modules-commonjs": "6.26.0", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" + } + }, + "babel-plugin-transform-es2015-modules-commonjs": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz", + "integrity": "sha1-DYOUApt9xqvhqX7xgeAHWN0uXYo=", + "requires": { + "babel-plugin-transform-strict-mode": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-plugin-transform-es2015-modules-systemjs": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", + "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", + "requires": { + "babel-helper-hoist-variables": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" + } + }, + "babel-plugin-transform-es2015-modules-umd": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", + "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", + "requires": { + "babel-plugin-transform-es2015-modules-amd": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" + } + }, + "babel-plugin-transform-es2015-object-super": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", + "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", + "requires": { + "babel-helper-replace-supers": "6.24.1", + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-parameters": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", + "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", + "requires": { + "babel-helper-call-delegate": "6.24.1", + "babel-helper-get-function-arity": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-plugin-transform-es2015-shorthand-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", + "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-plugin-transform-es2015-spread": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", + "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-sticky-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", + "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", + "requires": { + "babel-helper-regex": "6.26.0", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-plugin-transform-es2015-template-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", + "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-typeof-symbol": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", + "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-unicode-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", + "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", + "requires": { + "babel-helper-regex": "6.26.0", + "babel-runtime": "6.26.0", + "regexpu-core": "2.0.0" + } + }, + "babel-plugin-transform-exponentiation-operator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", + "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", + "requires": { + "babel-helper-builder-binary-assignment-operator-visitor": "6.24.1", + "babel-plugin-syntax-exponentiation-operator": "6.13.0", + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-inline-consecutive-adds": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-inline-consecutive-adds/-/babel-plugin-transform-inline-consecutive-adds-0.2.0.tgz", + "integrity": "sha512-GlhOuLOQ28ua9prg0hT33HslCrEmz9xWXy9ZNZSACppCyRxxRW+haYtRgm7uYXCcd0q8ggCWD2pfWEJp5iiZfQ==" + }, + "babel-plugin-transform-member-expression-literals": { + "version": "6.8.5", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-member-expression-literals/-/babel-plugin-transform-member-expression-literals-6.8.5.tgz", + "integrity": "sha512-Ux3ligf+ukzWaCbBYOstDuFBhRgMiJHlpJBKV4P47qtzVkd0lg1ddPj9fqIJqAM0n+CvxipyrZrnNnw3CdtQCg==" + }, + "babel-plugin-transform-merge-sibling-variables": { + "version": "6.8.6", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-merge-sibling-variables/-/babel-plugin-transform-merge-sibling-variables-6.8.6.tgz", + "integrity": "sha512-o5Jioq553HtEAUN5uty7ELJMenXIxHI3PIs1yLqYWYQwP6mg6IPVAJ+U7i4zr9XGF/kb2RGsdehglGTV+vngqA==" + }, + "babel-plugin-transform-minify-booleans": { + "version": "6.8.3", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-minify-booleans/-/babel-plugin-transform-minify-booleans-6.8.3.tgz", + "integrity": "sha512-bPbUhkeN2Nc0KH0/A19GwQGj8w+CvdJzyu8t59VoEDgsNMQ9Bopzi5DrVkrSsVjbYUaZpzq/DYLrH+wD5K2Tig==" + }, + "babel-plugin-transform-property-literals": { + "version": "6.8.5", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-property-literals/-/babel-plugin-transform-property-literals-6.8.5.tgz", + "integrity": "sha512-MmiQsQ5AcIaRZMJD0zY5C4H3xuHm06/nWgtOsz7AXV44VEIXIlPiJ39IFYJ4Qx67/fEm8zJAedzR8t+B7d10Bg==", + "requires": { + "esutils": "2.0.2" + } + }, + "babel-plugin-transform-regenerator": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", + "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=", + "requires": { + "regenerator-transform": "0.10.1" + } + }, + "babel-plugin-transform-regexp-constructors": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-regexp-constructors/-/babel-plugin-transform-regexp-constructors-0.2.0.tgz", + "integrity": "sha512-7IsQ6aQx6LAaOqy97/PthTf+5Nx9grZww3r6E62IdWe76Yr8KsuwVjxzqSPQvESJqTE3EMADQ9S0RtwWDGNG9Q==" + }, + "babel-plugin-transform-remove-console": { + "version": "6.8.5", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-remove-console/-/babel-plugin-transform-remove-console-6.8.5.tgz", + "integrity": "sha512-uuCKvtweCyIvvC8fi92EcWRtO2Kt5KMNMRK6BhpDXdeb3sxvGM7453RSmgeu4DlKns3OlvY9Ep5Q9m5a7RQAgg==" + }, + "babel-plugin-transform-remove-debugger": { + "version": "6.8.5", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-remove-debugger/-/babel-plugin-transform-remove-debugger-6.8.5.tgz", + "integrity": "sha512-InDQDdHPOLJKM+G6oXrEesf+P29QFBmcTXID+TAvZziVz+38xe2VO/Bn3FcRcRtnOOycbgsJkUNp9jIK+ist6g==" + }, + "babel-plugin-transform-remove-undefined": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-remove-undefined/-/babel-plugin-transform-remove-undefined-0.2.0.tgz", + "integrity": "sha512-O8v57tPMHkp89kA4ZfQEYds/pzgvz/QYerBJjIuL5/Jc7RnvMVRA5gJY9zFKP7WayW8WOSBV4vh8Y8FJRio+ow==", + "requires": { + "babel-helper-evaluate-path": "0.2.0" + } + }, + "babel-plugin-transform-simplify-comparison-operators": { + "version": "6.8.5", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-simplify-comparison-operators/-/babel-plugin-transform-simplify-comparison-operators-6.8.5.tgz", + "integrity": "sha512-B3HlBZb+Uq86nRj5yNPO6pJ3noEdqHvzYkEYoUWtrsWTv48ZIRatYlumoOiif/v8llF13YjYjx9zhyznDx+N9g==" + }, + "babel-plugin-transform-strict-mode": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", + "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-plugin-transform-undefined-to-void": { + "version": "6.8.3", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-undefined-to-void/-/babel-plugin-transform-undefined-to-void-6.8.3.tgz", + "integrity": "sha512-goYwp8dMrzHD6x9GjZ2M85Mk2vxf1h85CnUgAjfftUnlJvzF4uj5MrbReHBTbjQ96C8CuRzvhYZ3tv8H3Sc1ZA==" + }, + "babel-preset-env": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.6.1.tgz", + "integrity": "sha512-W6VIyA6Ch9ePMI7VptNn2wBM6dbG0eSz25HEiL40nQXCsXGTGZSTZu1Iap+cj3Q0S5a7T9+529l/5Bkvd+afNA==", + "requires": { + "babel-plugin-check-es2015-constants": "6.22.0", + "babel-plugin-syntax-trailing-function-commas": "6.22.0", + "babel-plugin-transform-async-to-generator": "6.24.1", + "babel-plugin-transform-es2015-arrow-functions": "6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0", + "babel-plugin-transform-es2015-block-scoping": "6.26.0", + "babel-plugin-transform-es2015-classes": "6.24.1", + "babel-plugin-transform-es2015-computed-properties": "6.24.1", + "babel-plugin-transform-es2015-destructuring": "6.23.0", + "babel-plugin-transform-es2015-duplicate-keys": "6.24.1", + "babel-plugin-transform-es2015-for-of": "6.23.0", + "babel-plugin-transform-es2015-function-name": "6.24.1", + "babel-plugin-transform-es2015-literals": "6.22.0", + "babel-plugin-transform-es2015-modules-amd": "6.24.1", + "babel-plugin-transform-es2015-modules-commonjs": "6.26.0", + "babel-plugin-transform-es2015-modules-systemjs": "6.24.1", + "babel-plugin-transform-es2015-modules-umd": "6.24.1", + "babel-plugin-transform-es2015-object-super": "6.24.1", + "babel-plugin-transform-es2015-parameters": "6.24.1", + "babel-plugin-transform-es2015-shorthand-properties": "6.24.1", + "babel-plugin-transform-es2015-spread": "6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "6.24.1", + "babel-plugin-transform-es2015-template-literals": "6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "6.23.0", + "babel-plugin-transform-es2015-unicode-regex": "6.24.1", + "babel-plugin-transform-exponentiation-operator": "6.24.1", + "babel-plugin-transform-regenerator": "6.26.0", + "browserslist": "2.10.1", + "invariant": "2.2.2", + "semver": "5.4.1" + } + }, + "babel-preset-minify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-minify/-/babel-preset-minify-0.2.0.tgz", + "integrity": "sha512-mR8Q44RmMzm18bM2Lqd9uiPopzk5GDCtVuquNbLFmX6lOKnqWoenaNBxnWW0UhBFC75lEHTIgNGCbnsRI0pJVw==", + "requires": { + "babel-plugin-minify-builtins": "0.2.0", + "babel-plugin-minify-constant-folding": "0.2.0", + "babel-plugin-minify-dead-code-elimination": "0.2.0", + "babel-plugin-minify-flip-comparisons": "0.2.0", + "babel-plugin-minify-guarded-expressions": "0.2.0", + "babel-plugin-minify-infinity": "0.2.0", + "babel-plugin-minify-mangle-names": "0.2.0", + "babel-plugin-minify-numeric-literals": "0.2.0", + "babel-plugin-minify-replace": "0.2.0", + "babel-plugin-minify-simplify": "0.2.0", + "babel-plugin-minify-type-constructors": "0.2.0", + "babel-plugin-transform-inline-consecutive-adds": "0.2.0", + "babel-plugin-transform-member-expression-literals": "6.8.5", + "babel-plugin-transform-merge-sibling-variables": "6.8.6", + "babel-plugin-transform-minify-booleans": "6.8.3", + "babel-plugin-transform-property-literals": "6.8.5", + "babel-plugin-transform-regexp-constructors": "0.2.0", + "babel-plugin-transform-remove-console": "6.8.5", + "babel-plugin-transform-remove-debugger": "6.8.5", + "babel-plugin-transform-remove-undefined": "0.2.0", + "babel-plugin-transform-simplify-comparison-operators": "6.8.5", + "babel-plugin-transform-undefined-to-void": "6.8.3", + "lodash.isplainobject": "4.0.6" + } + }, + "babel-register": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", + "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", + "requires": { + "babel-core": "6.26.0", + "babel-runtime": "6.26.0", + "core-js": "2.5.3", + "home-or-tmp": "2.0.0", + "lodash": "4.17.4", + "mkdirp": "0.5.1", + "source-map-support": "0.4.18" + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "requires": { + "core-js": "2.5.3", + "regenerator-runtime": "0.11.1" + } + }, + "babel-template": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", + "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", + "requires": { + "babel-runtime": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0", + "babylon": "6.18.0", + "lodash": "4.17.4" + } + }, + "babel-traverse": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", + "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", + "requires": { + "babel-code-frame": "6.26.0", + "babel-messages": "6.23.0", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "babylon": "6.18.0", + "debug": "2.6.9", + "globals": "9.18.0", + "invariant": "2.2.2", + "lodash": "4.17.4" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "babel-types": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "requires": { + "babel-runtime": "6.26.0", + "esutils": "2.0.2", + "lodash": "4.17.4", + "to-fast-properties": "1.0.3" + } + }, + "babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==" + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -241,6 +1038,15 @@ "concat-map": "0.0.1" } }, + "browserslist": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.10.1.tgz", + "integrity": "sha512-vUe1YhphiCb5lJ4YQwA5VbmAhZgv9cwgAQm/rZT6GA2X97ewDMOLPyDr08iGsqvPajvC/wEwWBZNtFFa8l4Hlw==", + "requires": { + "caniuse-lite": "1.0.30000784", + "electron-to-chromium": "1.3.30" + } + }, "builtin-modules": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", @@ -284,6 +1090,11 @@ } } }, + "caniuse-lite": { + "version": "1.0.30000784", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000784.tgz", + "integrity": "sha1-EpztdOmhKApEGIC2zSvOMO9Z5sA=" + }, "caseless": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", @@ -454,6 +1265,16 @@ "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=" }, + "convert-source-map": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz", + "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=" + }, + "core-js": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.3.tgz", + "integrity": "sha1-isw4NFgk8W2DZbfJtCWRaOjtYD4=" + }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -584,6 +1405,14 @@ "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" }, + "detect-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", + "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", + "requires": { + "repeating": "2.0.1" + } + }, "doctrine": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.2.tgz", @@ -601,6 +1430,19 @@ "jsbn": "0.1.1" } }, + "electron-releases": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/electron-releases/-/electron-releases-2.1.0.tgz", + "integrity": "sha512-cyKFD1bTE/UgULXfaueIN1k5EPFzs+FRc/rvCY5tIynefAPqopQEgjr0EzY+U3Dqrk/G4m9tXSPuZ77v6dL/Rw==" + }, + "electron-to-chromium": { + "version": "1.3.30", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.30.tgz", + "integrity": "sha512-zx1Prv7kYLfc4OA60FhxGbSo4qrEjgSzpo1/37i7l9ltXPYOoQBtjQxY9KmsgfHnBxHlBGXwLlsbt/gub1w5lw==", + "requires": { + "electron-releases": "2.1.0" + } + }, "entities": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", @@ -968,6 +1810,11 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=" }, + "estree-walker": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.2.1.tgz", + "integrity": "sha1-va/oCVOD2EFNXcLs9MkXO225QS4=" + }, "esutils": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", @@ -1320,14 +2167,6 @@ "function-bind": "1.1.1" } }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "requires": { - "ansi-regex": "2.1.1" - } - }, "has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", @@ -1354,6 +2193,15 @@ "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=" }, + "home-or-tmp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", + "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", + "requires": { + "os-homedir": "1.0.2", + "os-tmpdir": "1.0.2" + } + }, "hosted-git-info": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz", @@ -1516,6 +2364,14 @@ "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=" }, + "invariant": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz", + "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=", + "requires": { + "loose-envify": "1.3.1" + } + }, "invert-kv": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", @@ -1667,6 +2523,11 @@ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", "optional": true }, + "jsesc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", + "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=" + }, "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", @@ -1685,6 +2546,11 @@ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, + "json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=" + }, "jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", @@ -1800,11 +2666,29 @@ "resolved": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz", "integrity": "sha1-9HGh2khr5g9quVXRcRVSPdHSVdU=" }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" + }, "lodash.mergewith": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.0.tgz", "integrity": "sha1-FQzwoWeR9ZA7iJHqsVRgknS96lU=" }, + "lodash.some": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz", + "integrity": "sha1-G7nzFO9ri63tE7VJFpsqlF62jk0=" + }, + "loose-envify": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", + "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", + "requires": { + "js-tokens": "3.0.2" + } + }, "loud-rejection": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", @@ -2069,14 +2953,6 @@ } } }, - "nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", - "requires": { - "abbrev": "1.1.1" - } - }, "normalize-package-data": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", @@ -2329,6 +3205,11 @@ "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.9.2.tgz", "integrity": "sha512-piXx9N2WT8hWb7PBbX1glAuJVIkEyUV9F5fMXFINpZ0x3otVOFKKeGmeuiclFJlP/UrgTckyV606VjH2rNK4bw==" }, + "private": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==" + }, "process-nextick-args": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", @@ -2451,6 +3332,56 @@ "strip-indent": "1.0.1" } }, + "regenerate": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.3.tgz", + "integrity": "sha512-jVpo1GadrDAK59t/0jRx5VxYWQEDkkEKi6+HjE3joFVLfDOh9Xrdh0dF1eSq+BI/SwvTQ44gSscJ8N5zYL61sg==" + }, + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" + }, + "regenerator-transform": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz", + "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "private": "0.1.8" + } + }, + "regexpu-core": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", + "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", + "requires": { + "regenerate": "1.3.3", + "regjsgen": "0.2.0", + "regjsparser": "0.1.5" + } + }, + "regjsgen": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", + "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=" + }, + "regjsparser": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", + "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", + "requires": { + "jsesc": "0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=" + } + } + }, "relateurl": { "version": "0.2.7", "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", @@ -2548,6 +3479,38 @@ "glob": "7.1.2" } }, + "rollup": { + "version": "0.53.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-0.53.2.tgz", + "integrity": "sha512-7KbFOFV9FSxPYmcTi+0LuciI0uixNAz7F1B7u05QxXxVVV8FcFazpd19C/ybLz5//NP4N2L8rmnK0mT9ki+NvA==" + }, + "rollup-plugin-babel": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/rollup-plugin-babel/-/rollup-plugin-babel-3.0.3.tgz", + "integrity": "sha512-5kzM/Rr4jQSRPLc2eN5NuD+CI/6AAy7S1O18Ogu4U3nq1Q42VJn0C9EMtqnvxtfwf1XrezOtdA9ro1VZI5B0mA==", + "requires": { + "rollup-pluginutils": "1.5.2" + } + }, + "rollup-plugin-babel-minify": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-babel-minify/-/rollup-plugin-babel-minify-3.1.2.tgz", + "integrity": "sha512-6rEWn3Pf4DTlt0ejNGNhWXEZMTOKV7AfCgF97IuEJRy8U3i2+JgttHpmXkdaldyp7v9sWKRfTwWhn11iIcIY3g==", + "requires": { + "@comandeer/babel-plugin-banner": "1.0.0", + "babel-core": "6.26.0", + "babel-preset-minify": "0.2.0" + } + }, + "rollup-pluginutils": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-1.5.2.tgz", + "integrity": "sha1-HhVud4+UtyVb+hs9AXi+j1xVJAg=", + "requires": { + "estree-walker": "0.2.1", + "minimatch": "3.0.4" + } + }, "run-async": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", @@ -2633,6 +3596,11 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" }, + "slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=" + }, "slice-ansi": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", @@ -2654,6 +3622,21 @@ "amdefine": "1.0.1" } }, + "source-map-support": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", + "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", + "requires": { + "source-map": "0.5.7" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, "spdx-correct": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", @@ -2765,14 +3748,6 @@ "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=" }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "2.1.1" - } - }, "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -2798,11 +3773,6 @@ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" - }, "table": { "version": "3.8.3", "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", @@ -2911,6 +3881,11 @@ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" }, + "to-fast-properties": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=" + }, "tough-cookie": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz", @@ -2924,6 +3899,11 @@ "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=" }, + "trim-right": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", + "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=" + }, "true-case-path": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.2.tgz", diff --git a/package.json b/package.json index 6d4b549fd..f65937027 100644 --- a/package.json +++ b/package.json @@ -1,18 +1,23 @@ { "dependencies": { + "babel-preset-env": "^1.6.1", + "chalk": "^2.3.0", "fs-extra": "^4.0.2", "html-minifier": "^3.5.7", "markdown-it": "^8.4.0", "node-sass": "^4.7.2", "prettier": "^1.9.2", + "rollup": "^0.53.2", + "rollup-plugin-babel": "^3.0.3", + "rollup-plugin-babel-minify": "^3.1.2", "semistandard": "^11.0.0", - "chalk": "^2.3.0", "tape": "^4.8.0" }, "name": "30-seconds-of-code", "description": "A collection of useful JavaScript snippets.", - "version": "1.0.0", - "main": "index.js", + "version": "0.0.0", + "main": "dist/_30s.js", + "module": "dist/_30s.esm.js", "scripts": { "builder": "node ./scripts/build.js", "linter": "node ./scripts/lint.js", @@ -25,7 +30,11 @@ "type": "git", "url": "git+https://github.com/Chalarangelo/30-seconds-of-code.git" }, - "keywords": ["javascript", "snippets", "list"], + "keywords": [ + "javascript", + "snippets", + "list" + ], "author": "Chalarangelo (chalarangelo@gmail.com)", "license": "MIT", "bugs": { diff --git a/scripts/module.js b/scripts/module.js index f6753b11b..295e50fd9 100644 --- a/scripts/module.js +++ b/scripts/module.js @@ -1,5 +1,5 @@ /* - Builds the `Snippet` module. + Builds the `_30s` module. */ const fs = require('fs-extra'); const cp = require('child_process'); @@ -27,7 +27,10 @@ try { let exportStr = 'export default {'; for (const snippet of snippets) { - const snippetData = fs.readFileSync(path.join(SNIPPETS_PATH, snippet), 'utf8'); + const snippetData = fs.readFileSync( + path.join(SNIPPETS_PATH, snippet), + 'utf8' + ); const snippetName = snippet.replace('.md', ''); const isNodeSnippet = tagDatabase @@ -35,27 +38,30 @@ try { .split('\n')[0] .includes('node'); - if (!isNodeSnippet) { - const importData = fs.readFileSync(IMPORTS); - fs.writeFileSync( - IMPORTS, - importData + `\nimport { ${snippetName} } from './temp/${snippetName}.js'` - ); - exportStr += `${snippetName},`; + const importData = fs.readFileSync(IMPORTS); + fs.writeFileSync( + IMPORTS, + importData + `\nimport { ${snippetName} } from './temp/${snippetName}.js'` + ); + exportStr += `${snippetName},`; - fs.writeFileSync( - `${TEMP_PATH}/${snippetName}.js`, - 'export ' + snippetData.match(codeRE)[1].replace('\n', '') - ); - } + const code = snippetData.match(codeRE)[1].replace('\n', ''); + + const toWrite = isNodeSnippet + ? `${code + .replace('const ' + snippetName, 'export const ' + snippetName) + // Prevents errors from being thrown in browser environment + .replace('require(', 'typeof require !== "undefined" && require(')}` + : `export ${code}`; + + fs.writeFileSync(`${TEMP_PATH}/${snippetName}.js`, toWrite); } exportStr += '}'; - const importData = fs.readFileSync(IMPORTS); - fs.writeFileSync(IMPORTS, importData + `\n${exportStr}`); + fs.appendFileSync(IMPORTS, `\n${exportStr}`); - cp.execSync('rollup -c scripts/rollup.js'); + cp.execSync('node ./scripts/rollup.js'); fs.removeSync(TEMP_PATH); fs.unlink(IMPORTS); diff --git a/scripts/rollup.js b/scripts/rollup.js index 963eccb4f..1e5431fd1 100644 --- a/scripts/rollup.js +++ b/scripts/rollup.js @@ -1,19 +1,58 @@ -import babel from 'rollup-plugin-babel'; -import minify from 'rollup-plugin-babel-minify'; +const fs = require('fs-extra'); +const { rollup } = require('rollup'); +const babel = require('rollup-plugin-babel'); +const minify = require('rollup-plugin-babel-minify'); -export default { - input: './imports.js', - output: { - file: './module/TSOC.js', - format: 'umd', - name: 'TSOC' - }, - externalHelpers: true, - plugins: [ - babel({ - presets: ['es2015-rollup'], - plugins: ['transform-object-assign', 'transform-object-rest-spread'] - }), - minify({ comments: false }) - ] -}; +const INPUT_FILE = './imports.js'; +const MODULE_NAME = '_30s'; +const DIST = './dist'; + +if (!fs.existsSync(DIST)) fs.mkdirSync(DIST); + +const es5 = () => babel({ presets: [['env', { modules: false }]] }); +const min = () => minify({ comments: false }); + +(async () => { + const bundle = await rollup({ input: INPUT_FILE }); + const bundleES5 = await rollup({ input: INPUT_FILE, plugins: [es5()] }); + const bundleMin = await rollup({ input: INPUT_FILE, plugins: [min()] }); + const bundleES5Min = await rollup({ + input: INPUT_FILE, + plugins: [es5(), min()] + }); + + // UMD ES2017 + await bundle.write({ + file: `${DIST}/${MODULE_NAME}.js`, + name: MODULE_NAME, + format: 'umd' + }); + + // UMD ES2017 minified + await bundleMin.write({ + file: `${DIST}/${MODULE_NAME}.min.js`, + name: MODULE_NAME, + format: 'umd' + }); + + // UMD ES5 + await bundleES5.write({ + file: `${DIST}/${MODULE_NAME}.es5.js`, + name: MODULE_NAME, + format: 'umd' + }); + + // UMD ES5 min + await bundleES5Min.write({ + file: `${DIST}/${MODULE_NAME}.es5.min.js`, + name: MODULE_NAME, + format: 'umd' + }); + + // ESM ES2017 + await bundle.write({ + file: `${DIST}/${MODULE_NAME}.esm.js`, + name: MODULE_NAME, + format: 'es' + }); +})(); From e445c6219affc1c635a2a079cc45d487b206de00 Mon Sep 17 00:00:00 2001 From: atomiks Date: Tue, 2 Jan 2018 01:16:15 +1100 Subject: [PATCH 04/61] Add dist + NOTICE.md --- dist/NOTICE.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 dist/NOTICE.md diff --git a/dist/NOTICE.md b/dist/NOTICE.md new file mode 100644 index 000000000..f30f7b1d7 --- /dev/null +++ b/dist/NOTICE.md @@ -0,0 +1,15 @@ +# WARNING! + +The `_30s` module is not production ready. Do NOT use it in production websites. +It is strictly for testing purposes at this moment in time. Snippets do not have +any unit tests written and will not be reliable. + +Snippet names can and will change without notice between minor versions. + +Given the version `0.x.y`: + +* `x` indicates a snippet name change. +* `y` indicates a new snippet or fix. + +If your project is not serious and you do not care about the above issues, you will want +to use the `es5` version and also include `babel-polyfill` for widest browser support. From 9f3705fe78d327555ccaa828e6fe7185a1acf1dc Mon Sep 17 00:00:00 2001 From: atomiks Date: Tue, 2 Jan 2018 02:47:03 +1100 Subject: [PATCH 05/61] don't need to be funcs --- scripts/rollup.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/rollup.js b/scripts/rollup.js index 1e5431fd1..216ba426c 100644 --- a/scripts/rollup.js +++ b/scripts/rollup.js @@ -9,16 +9,16 @@ const DIST = './dist'; if (!fs.existsSync(DIST)) fs.mkdirSync(DIST); -const es5 = () => babel({ presets: [['env', { modules: false }]] }); -const min = () => minify({ comments: false }); +const es5 = babel({ presets: [['env', { modules: false }]] }); +const min = minify({ comments: false }); (async () => { const bundle = await rollup({ input: INPUT_FILE }); - const bundleES5 = await rollup({ input: INPUT_FILE, plugins: [es5()] }); - const bundleMin = await rollup({ input: INPUT_FILE, plugins: [min()] }); + const bundleES5 = await rollup({ input: INPUT_FILE, plugins: [es5] }); + const bundleMin = await rollup({ input: INPUT_FILE, plugins: [min] }); const bundleES5Min = await rollup({ input: INPUT_FILE, - plugins: [es5(), min()] + plugins: [es5, min] }); // UMD ES2017 From fe6e45a4f01854266fc70d434b6fc14bcc35601a Mon Sep 17 00:00:00 2001 From: atomiks Date: Tue, 2 Jan 2018 08:40:31 +1100 Subject: [PATCH 06/61] Add defer snippet --- snippets/defer.md | 21 +++++++++++++++++++++ tag_database | 1 + 2 files changed, 22 insertions(+) create mode 100644 snippets/defer.md diff --git a/snippets/defer.md b/snippets/defer.md new file mode 100644 index 000000000..88706b86d --- /dev/null +++ b/snippets/defer.md @@ -0,0 +1,21 @@ +### defer + +Defers invoking a function until the current call stack has cleared. + +Use `window.setTimeout()` with a timeout of 1ms to add a new event to the browser +event queue and allow the rendering engine to complete its work. Use the spread/rest (`...`) +operator to supply the function with an arbitrary number of arguments. + +```js +const defer = (fn, ...args) => setTimeout(fn, 1, ...args); +``` + +```js +// Example A: +defer(console.log, 'a'), console.log('b'); // logs 'b' then 'a' + +// Example B: +document.querySelector('#someElement').innerHTML = 'Hello'; +longRunningFunction(); // The browser will not update the HTML until this has finished +defer(longRunningFunction); // The browser will update the HTML then run the function +``` diff --git a/tag_database b/tag_database index 708f71b32..13d2ab730 100644 --- a/tag_database +++ b/tag_database @@ -22,6 +22,7 @@ countVowels:string currentURL:browser curry:function deepFlatten:array +defer:function detectDeviceType:browser difference:array differenceWith:array From c58488d1e71a279360d79c700e05ffbc0e8a31e4 Mon Sep 17 00:00:00 2001 From: atomiks Date: Tue, 2 Jan 2018 09:40:46 +1100 Subject: [PATCH 07/61] Add once snippet --- snippets/once.md | 27 +++++++++++++++++++++++++++ tag_database | 1 + 2 files changed, 28 insertions(+) create mode 100644 snippets/once.md diff --git a/snippets/once.md b/snippets/once.md new file mode 100644 index 000000000..a3b3e6adb --- /dev/null +++ b/snippets/once.md @@ -0,0 +1,27 @@ +### once + +Ensures a function is called only once. + +Utilizing a closure, use a variable flag and set it to true once the function is called +for the first time, preventing it from being called again. Allow the function to be supplied +with an arbitrary number of arguments using the spread/rest (`...`) operator. + +```js +const once = fn => { + let called = false; + return (...args) => { + if (!called) { + fn(...args); + called = true; + } + }; +}; +``` + +```js +const startApp = event => { + // initializes the app + console.log(event); // access to any arguments supplied +}; +document.addEventListener('click', once(startApp)); // only runs `startApp` once upon click +``` diff --git a/tag_database b/tag_database index 708f71b32..19bf1cbab 100644 --- a/tag_database +++ b/tag_database @@ -95,6 +95,7 @@ negate:logic nthElement:array objectFromPairs:object objectToPairs:object +once:function onUserInputChange:browser orderBy:object palindrome:string From d4cbe8fa51d6c37c6f61801c9e7d835c5d5119a5 Mon Sep 17 00:00:00 2001 From: atomiks Date: Tue, 2 Jan 2018 09:47:52 +1100 Subject: [PATCH 08/61] Update defer.md --- snippets/defer.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/snippets/defer.md b/snippets/defer.md index 88706b86d..1a0a63649 100644 --- a/snippets/defer.md +++ b/snippets/defer.md @@ -2,7 +2,7 @@ Defers invoking a function until the current call stack has cleared. -Use `window.setTimeout()` with a timeout of 1ms to add a new event to the browser +Use `setTimeout()` with a timeout of 1ms to add a new event to the browser event queue and allow the rendering engine to complete its work. Use the spread/rest (`...`) operator to supply the function with an arbitrary number of arguments. @@ -16,6 +16,6 @@ defer(console.log, 'a'), console.log('b'); // logs 'b' then 'a' // Example B: document.querySelector('#someElement').innerHTML = 'Hello'; -longRunningFunction(); // The browser will not update the HTML until this has finished -defer(longRunningFunction); // The browser will update the HTML then run the function +longRunningFunction(); // the browser will not update the HTML until this has finished +defer(longRunningFunction); // the browser will update the HTML then run the function ``` From 1e4ecc1cdc47857dcded48ee122e98e66676ccb0 Mon Sep 17 00:00:00 2001 From: atomiks Date: Tue, 2 Jan 2018 11:17:52 +1100 Subject: [PATCH 09/61] Add runAsync snippet --- snippets/runAsync.md | 53 ++++++++++++++++++++++++++++++++++++++++++++ tag_database | 1 + 2 files changed, 54 insertions(+) create mode 100644 snippets/runAsync.md diff --git a/snippets/runAsync.md b/snippets/runAsync.md new file mode 100644 index 000000000..eabd79e18 --- /dev/null +++ b/snippets/runAsync.md @@ -0,0 +1,53 @@ +### runAsync + +Runs a function in a separate thread by using a Web Worker, allowing +long running functions to not block the UI. + +Create a new `Worker` using a `Blob` object URL, the contents of which should be the +stringified version of the supplied function. Immediately post the return value of calling +the function back. Return a promise, listening for `onmessage` and `onerror` events +and resolving the data posted back from the worker, or throwing an error. + +```js +const runAsync = fn => { + const blob = ` + var fn = ${fn.toString()}; + this.postMessage(fn()); + `; + const worker = new Worker( + URL.createObjectURL(new Blob([blob]), { + type: 'application/javascript; charset=utf-8' + }) + ); + return new Promise((res, rej) => { + worker.onmessage = ({ data }) => { + res(data), worker.terminate(); + }; + worker.onerror = err => { + rej(err), worker.terminate(); + }; + }); +}; +``` + +```js +const longRunningFunction = () => { + let result = 0; + for (var i = 0; i < 1000; i++) { + for (var j = 0; j < 700; j++) { + for (var k = 0; k < 300; k++) { + result = result + i + j + k; + } + } + } + return result; +}; + +// NOTE: Since the function is running in a different context, closures are not supported. +// The function supplied to `runAsync` gets stringified, so everything becomes literal. +// All variables and functions must be defined inside. +runAsync(longRunningFunction).then(console.log); // 209685000000 +runAsync(() => 10 ** 3).then(console.log); // 1000 +let outsideVariable = 50; +runAsync(() => typeof outsideVariable).then(console.log); // 'undefined' +``` diff --git a/tag_database b/tag_database index 708f71b32..e2c8d9950 100644 --- a/tag_database +++ b/tag_database @@ -118,6 +118,7 @@ repeatString:string reverseString:string RGBToHex:utility round:math +runAsync:browser runPromisesInSeries:function sample:array sampleSize:array From c900a7758d86308ca99161386251f4d1dd4ad703 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Tue, 2 Jan 2018 10:35:33 +0200 Subject: [PATCH 10/61] Update runAsync.md --- snippets/runAsync.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/snippets/runAsync.md b/snippets/runAsync.md index eabd79e18..8ab34943e 100644 --- a/snippets/runAsync.md +++ b/snippets/runAsync.md @@ -1,12 +1,10 @@ ### runAsync -Runs a function in a separate thread by using a Web Worker, allowing -long running functions to not block the UI. +Runs a function in a separate thread by using a [Web Worker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers), allowing long running functions to not block the UI. -Create a new `Worker` using a `Blob` object URL, the contents of which should be the -stringified version of the supplied function. Immediately post the return value of calling -the function back. Return a promise, listening for `onmessage` and `onerror` events -and resolving the data posted back from the worker, or throwing an error. +Create a new `Worker` using a `Blob` object URL, the contents of which should be the stringified version of the supplied function. +Immediately post the return value of calling the function back. +Return a promise, listening for `onmessage` and `onerror` events and resolving the data posted back from the worker, or throwing an error. ```js const runAsync = fn => { From ff498190745fe5706e33dbd826abf921be22f89b Mon Sep 17 00:00:00 2001 From: Travis CI Date: Tue, 2 Jan 2018 08:38:48 +0000 Subject: [PATCH 11/61] Travis build: 835 [ci skip] --- README.md | 61 +++++++++++++++++++++++++++++++++++++++++++++++++ docs/index.html | 40 +++++++++++++++++++++++++++++++- 2 files changed, 100 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2e0f09565..66b72362a 100644 --- a/README.md +++ b/README.md @@ -100,6 +100,7 @@ * [`httpsRedirect`](#httpsredirect) * [`onUserInputChange`](#onuserinputchange) * [`redirect`](#redirect) +* [`runAsync`](#runasync) * [`scrollToTop`](#scrolltotop) * [`setStyle`](#setstyle) * [`show`](#show) @@ -1974,6 +1975,66 @@ redirect('https://google.com');
[⬆ Back to top](#table-of-contents) +### runAsync + +Runs a function in a separate thread by using a [Web Worker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers), allowing long running functions to not block the UI. + +Create a new `Worker` using a `Blob` object URL, the contents of which should be the stringified version of the supplied function. +Immediately post the return value of calling the function back. +Return a promise, listening for `onmessage` and `onerror` events and resolving the data posted back from the worker, or throwing an error. + +```js +const runAsync = fn => { + const blob = ` + var fn = ${fn.toString()}; + this.postMessage(fn()); + `; + const worker = new Worker( + URL.createObjectURL(new Blob([blob]), { + type: 'application/javascript; charset=utf-8' + }) + ); + return new Promise((res, rej) => { + worker.onmessage = ({ data }) => { + res(data), worker.terminate(); + }; + worker.onerror = err => { + rej(err), worker.terminate(); + }; + }); +}; +``` + +
+Examples + +```js +const longRunningFunction = () => { + let result = 0; + for (var i = 0; i < 1000; i++) { + for (var j = 0; j < 700; j++) { + for (var k = 0; k < 300; k++) { + result = result + i + j + k; + } + } + } + return result; +}; + +// NOTE: Since the function is running in a different context, closures are not supported. +// The function supplied to `runAsync` gets stringified, so everything becomes literal. +// All variables and functions must be defined inside. +runAsync(longRunningFunction).then(console.log); // 209685000000 +runAsync(() => 10 ** 3).then(console.log); // 1000 +let outsideVariable = 50; +runAsync(() => typeof outsideVariable).then(console.log); // 'undefined' +``` + +
+ +
[⬆ Back to top](#table-of-contents) + + ### scrollToTop Smooth-scrolls to the top of the page. diff --git a/docs/index.html b/docs/index.html index bf8aeebab..2bab29808 100644 --- a/docs/index.html +++ b/docs/index.html @@ -59,7 +59,7 @@ wrapper.appendChild(box); box.appendChild(el); }); - }

 30 seconds of code Curated collection of useful JavaScript snippets that you can understand in 30 seconds or less.

 

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.

 

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);
 
Promise.resolve([1, 2, 3])
   .then(call('map', x => 2 * x))
   .then(console.log); //[ 2, 4, 6 ]
@@ -418,6 +418,44 @@ elementIsVisibleInViewport(el, true); // true // (partially visible)
 

redirect

Redirects to a specified URL.

Use window.location.href or window.location.replace() to redirect to url. Pass a second argument to simulate a link click (true - default) or an HTTP redirect (false).

const redirect = (url, asLink = true) =>
   asLink ? (window.location.href = url) : window.location.replace(url);
 
redirect('https://google.com');
+

runAsync

Runs a function in a separate thread by using a Web Worker, allowing long running functions to not block the UI.

Create a new Worker using a Blob object URL, the contents of which should be the stringified version of the supplied function. Immediately post the return value of calling the function back. Return a promise, listening for onmessage and onerror events and resolving the data posted back from the worker, or throwing an error.

const runAsync = fn => {
+  const blob = `
+    var fn = ${fn.toString()};
+    this.postMessage(fn());
+  `;
+  const worker = new Worker(
+    URL.createObjectURL(new Blob([blob]), {
+      type: 'application/javascript; charset=utf-8'
+    })
+  );
+  return new Promise((res, rej) => {
+    worker.onmessage = ({ data }) => {
+      res(data), worker.terminate();
+    };
+    worker.onerror = err => {
+      rej(err), worker.terminate();
+    };
+  });
+};
+
const longRunningFunction = () => {
+  let result = 0;
+  for (var i = 0; i < 1000; i++) {
+    for (var j = 0; j < 700; j++) {
+      for (var k = 0; k < 300; k++) {
+        result = result + i + j + k;
+      }
+    }
+  }
+  return result;
+};
+
+// NOTE: Since the function is running in a different context, closures are not supported.
+// The function supplied to `runAsync` gets stringified, so everything becomes literal.
+// All variables and functions must be defined inside.
+runAsync(longRunningFunction).then(console.log); // 209685000000
+runAsync(() => 10 ** 3).then(console.log); // 1000
+let outsideVariable = 50;
+runAsync(() => typeof outsideVariable).then(console.log); // 'undefined'
 

scrollToTop

Smooth-scrolls to the top of the page.

Get distance from top using document.documentElement.scrollTop or document.body.scrollTop. Scroll by a fraction of the distance from the top. Use window.requestAnimationFrame() to animate the scrolling.

const scrollToTop = () => {
   const c = document.documentElement.scrollTop || document.body.scrollTop;
   if (c > 0) {

From 9d565ae9f700f83dc269459b91225caffbd5bfe4 Mon Sep 17 00:00:00 2001
From: Angelos Chalaris 
Date: Tue, 2 Jan 2018 10:39:19 +0200
Subject: [PATCH 12/61] Update defer.md

---
 snippets/defer.md | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/snippets/defer.md b/snippets/defer.md
index 1a0a63649..7403d4c36 100644
--- a/snippets/defer.md
+++ b/snippets/defer.md
@@ -2,9 +2,7 @@
 
 Defers invoking a function until the current call stack has cleared.
 
-Use `setTimeout()` with a timeout of 1ms to add a new event to the browser
-event queue and allow the rendering engine to complete its work. Use the spread/rest (`...`)
-operator to supply the function with an arbitrary number of arguments.
+Use `setTimeout()` with a timeout of 1ms to add a new event to the browser event queue and allow the rendering engine to complete its work. Use the spread (`...`) operator to supply the function with an arbitrary number of arguments.
 
 ```js
 const defer = (fn, ...args) => setTimeout(fn, 1, ...args);

From 8d8b110f3b0cbb227218b0f5adb3a100b33ab794 Mon Sep 17 00:00:00 2001
From: Travis CI 
Date: Tue, 2 Jan 2018 08:42:50 +0000
Subject: [PATCH 13/61] Travis build: 837 [ci skip]

---
 README.md       | 29 +++++++++++++++++++++++++++++
 docs/index.html | 10 +++++++++-
 2 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 66b72362a..78735dc9a 100644
--- a/README.md
+++ b/README.md
@@ -130,6 +130,7 @@
 * [`chainAsync`](#chainasync)
 * [`compose`](#compose)
 * [`curry`](#curry)
+* [`defer`](#defer)
 * [`functionName`](#functionname)
 * [`memoize`](#memoize)
 * [`runPromisesInSeries`](#runpromisesinseries)
@@ -2378,6 +2379,34 @@ curry(Math.min, 3)(10)(50)(2); // 2
 
[⬆ Back to top](#table-of-contents) +### defer + +Defers invoking a function until the current call stack has cleared. + +Use `setTimeout()` with a timeout of 1ms to add a new event to the browser event queue and allow the rendering engine to complete its work. Use the spread (`...`) operator to supply the function with an arbitrary number of arguments. + +```js +const defer = (fn, ...args) => setTimeout(fn, 1, ...args); +``` + +
+Examples + +```js +// Example A: +defer(console.log, 'a'), console.log('b'); // logs 'b' then 'a' + +// Example B: +document.querySelector('#someElement').innerHTML = 'Hello'; +longRunningFunction(); // the browser will not update the HTML until this has finished +defer(longRunningFunction); // the browser will update the HTML then run the function +``` + +
+ +
[⬆ Back to top](#table-of-contents) + + ### functionName Logs the name of a function. diff --git a/docs/index.html b/docs/index.html index 2bab29808..8f7cd32cc 100644 --- a/docs/index.html +++ b/docs/index.html @@ -59,7 +59,7 @@ wrapper.appendChild(box); box.appendChild(el); }); - }

 30 seconds of code Curated collection of useful JavaScript snippets that you can understand in 30 seconds or less.

 

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.

 

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);
 
Promise.resolve([1, 2, 3])
   .then(call('map', x => 2 * x))
   .then(console.log); //[ 2, 4, 6 ]
@@ -527,6 +527,14 @@ multiplyAndAdd5(5, 2); // 15
   arity <= args.length ? fn(...args) : curry.bind(null, fn, arity, ...args);
 
curry(Math.pow)(2)(10); // 1024
 curry(Math.min, 3)(10)(50)(2); // 2
+

defer

Defers invoking a function until the current call stack has cleared.

Use setTimeout() with a timeout of 1ms to add a new event to the browser event queue and allow the rendering engine to complete its work. Use the spread (...) operator to supply the function with an arbitrary number of arguments.

const defer = (fn, ...args) => setTimeout(fn, 1, ...args);
+
// Example A:
+defer(console.log, 'a'), console.log('b'); // logs 'b' then 'a'
+
+// Example B:
+document.querySelector('#someElement').innerHTML = 'Hello';
+longRunningFunction(); // the browser will not update the HTML until this has finished
+defer(longRunningFunction); // the browser will update the HTML then run the function
 

functionName

Logs the name of a function.

Use console.debug() and the name property of the passed method to log the method's name to the debug channel of the console.

const functionName = fn => (console.debug(fn.name), fn);
 
functionName(Math.max); // max (logged in debug channel of console)
 

memoize

Returns the memoized (cached) function.

Use Object.create(null) to create an empty object without Object.prototype (so that those properties are not resolved if the input value is something like 'hasOwnProperty'). Return a function which takes a single argument to be supplied to the memoized function by first checking if the function's output for that specific input value is already cached, or store and return it if not.

const memoize = fn => {

From 96b88893e39aa3e299e28800049c8a48eb7c9854 Mon Sep 17 00:00:00 2001
From: Angelos Chalaris 
Date: Tue, 2 Jan 2018 10:44:42 +0200
Subject: [PATCH 14/61] Update once.md

---
 snippets/once.md | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/snippets/once.md b/snippets/once.md
index a3b3e6adb..01d6216d1 100644
--- a/snippets/once.md
+++ b/snippets/once.md
@@ -2,9 +2,8 @@
 
 Ensures a function is called only once.
 
-Utilizing a closure, use a variable flag and set it to true once the function is called
-for the first time, preventing it from being called again. Allow the function to be supplied
-with an arbitrary number of arguments using the spread/rest (`...`) operator.
+Utilizing a closure, use a flag, `called`, and set it to `true` once the function is called for the first time, preventing it from being called again. 
+Allow the function to be supplied with an arbitrary number of arguments using the spread (`...`) operator.
 
 ```js
 const once = fn => {

From 5011497935a84cc0d9556e510d87d573a55a07f1 Mon Sep 17 00:00:00 2001
From: Angelos Chalaris 
Date: Tue, 2 Jan 2018 10:48:08 +0200
Subject: [PATCH 15/61] Updated to use @skatcat31's suggestion

---
 snippets/once.md | 10 +---------
 1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/snippets/once.md b/snippets/once.md
index 01d6216d1..18e5fc886 100644
--- a/snippets/once.md
+++ b/snippets/once.md
@@ -6,15 +6,7 @@ Utilizing a closure, use a flag, `called`, and set it to `true` once the functio
 Allow the function to be supplied with an arbitrary number of arguments using the spread (`...`) operator.
 
 ```js
-const once = fn => {
-  let called = false;
-  return (...args) => {
-    if (!called) {
-      fn(...args);
-      called = true;
-    }
-  };
-};
+const once = fn => (called => (...args) => !called ? (called = true, fn(...args)) : undefined)()
 ```
 
 ```js

From 6e6916e265809116e865b93879c832922b1c6ae3 Mon Sep 17 00:00:00 2001
From: Travis CI 
Date: Tue, 2 Jan 2018 08:50:06 +0000
Subject: [PATCH 16/61] Travis build: 840 [ci skip]

---
 README.md        | 29 +++++++++++++++++++++++++++++
 docs/index.html  |  9 ++++++++-
 snippets/once.md |  3 ++-
 3 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index 78735dc9a..0c5ef52ad 100644
--- a/README.md
+++ b/README.md
@@ -133,6 +133,7 @@
 * [`defer`](#defer)
 * [`functionName`](#functionname)
 * [`memoize`](#memoize)
+* [`once`](#once)
 * [`runPromisesInSeries`](#runpromisesinseries)
 * [`sleep`](#sleep)
 
@@ -2458,6 +2459,34 @@ anagramsCached('javascript'); // returns virtually instantly since it's now cach
 
[⬆ Back to top](#table-of-contents) +### once + +Ensures a function is called only once. + +Utilizing a closure, use a flag, `called`, and set it to `true` once the function is called for the first time, preventing it from being called again. +Allow the function to be supplied with an arbitrary number of arguments using the spread (`...`) operator. + +```js +const once = fn => + (called => (...args) => (!called ? ((called = true), fn(...args)) : undefined))(); +``` + +
+Examples + +```js +const startApp = event => { + // initializes the app + console.log(event); // access to any arguments supplied +}; +document.addEventListener('click', once(startApp)); // only runs `startApp` once upon click +``` + +
+ +
[⬆ Back to top](#table-of-contents) + + ### runPromisesInSeries Runs an array of promises in series. diff --git a/docs/index.html b/docs/index.html index 8f7cd32cc..840b6d38d 100644 --- a/docs/index.html +++ b/docs/index.html @@ -59,7 +59,7 @@ wrapper.appendChild(box); box.appendChild(el); }); - }

 30 seconds of code Curated collection of useful JavaScript snippets that you can understand in 30 seconds or less.

 

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.

 

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);
 
Promise.resolve([1, 2, 3])
   .then(call('map', x => 2 * x))
   .then(console.log); //[ 2, 4, 6 ]
@@ -545,6 +545,13 @@ defer(longRunningFunction); // the browser will update the HTML then run the fun
 const anagramsCached = memoize(anagrams);
 anagramsCached('javascript'); // takes a long time
 anagramsCached('javascript'); // returns virtually instantly since it's now cached
+

once

Ensures a function is called only once.

Utilizing a closure, use a flag, called, and set it to true once the function is called for the first time, preventing it from being called again. Allow the function to be supplied with an arbitrary number of arguments using the spread (...) operator.

const once = fn =>
+  (called => (...args) => (!called ? ((called = true), fn(...args)) : undefined))();
+
const startApp = event => {
+  // initializes the app
+  console.log(event); // access to any arguments supplied
+};
+document.addEventListener('click', once(startApp)); // only runs `startApp` once upon click
 

runPromisesInSeries

Runs an array of promises in series.

Use Array.reduce() to create a promise chain, where each promise returns the next promise when resolved.

const runPromisesInSeries = ps => ps.reduce((p, next) => p.then(next), Promise.resolve());
 
const delay = d => new Promise(r => setTimeout(r, d));
 runPromisesInSeries([() => delay(1000), () => delay(2000)]); // //executes each promise sequentially, taking a total of 3 seconds to complete
diff --git a/snippets/once.md b/snippets/once.md
index 18e5fc886..ea32a6843 100644
--- a/snippets/once.md
+++ b/snippets/once.md
@@ -6,7 +6,8 @@ Utilizing a closure, use a flag, `called`, and set it to `true` once the functio
 Allow the function to be supplied with an arbitrary number of arguments using the spread (`...`) operator.
 
 ```js
-const once = fn => (called => (...args) => !called ? (called = true, fn(...args)) : undefined)()
+const once = fn =>
+  (called => (...args) => (!called ? ((called = true), fn(...args)) : undefined))();
 ```
 
 ```js

From ba3cf0ea2ae362aadf4bb82e18802c6fb7816923 Mon Sep 17 00:00:00 2001
From: Rohit Tanwar 
Date: Tue, 2 Jan 2018 16:16:47 +0530
Subject: [PATCH 17/61] add RPN snippets

---
 snippets/infixToPostFix.md | 24 ++++++++++++++++++++++++
 snippets/postfixToInfix.md | 29 +++++++++++++++++++++++++++++
 2 files changed, 53 insertions(+)
 create mode 100644 snippets/infixToPostFix.md
 create mode 100644 snippets/postfixToInfix.md

diff --git a/snippets/infixToPostFix.md b/snippets/infixToPostFix.md
new file mode 100644
index 000000000..3fd859e37
--- /dev/null
+++ b/snippets/infixToPostFix.md
@@ -0,0 +1,24 @@
+const infix  = expr => {
+  let rpn = ''
+  let solve = expr.replace(/\^/g,'**').match(/([0-9]+|[\+\(\)\/\-]|\*+)/g).filter(el => !/\s+/.test(el) && el !== '')
+  let stack = []
+  let precedence = {'**':5,'/':4,'*':4,'+':3,'-':3}
+  solve.forEach(symbol => {
+    if(!isNaN(parseFloat(symbol)) && isFinite(symbol)){
+      rpn += symbol + ' '
+    }
+    else if (Object.keys(precedence).includes(symbol)) {
+      while(((precedence[symbol] < precedence[stack[stack.length-1]]) || ((precedence[symbol] == precedence[stack[stack.length-1]]) && symbol !== "**"))&&(stack[stack.length - 1] !== '(')) {
+        rpn += stack.pop() +  ' '
+      }
+      stack.push(symbol)
+    }
+    else if(symbol === '('){stack.push(symbol)}
+    else if(symbol === ')'){while (stack[stack.length - 1] !== '('){rpn += stack.pop() + ' '; if (stack.length === 0){throw `Mismatched parantheses`}} stack.pop()}
+    else {throw `${symbol} is not a recognized symbol`}
+  })
+  while(stack.length !== 0){
+    rpn += stack.pop() +  ' '
+  }
+  return rpn
+}
diff --git a/snippets/postfixToInfix.md b/snippets/postfixToInfix.md
new file mode 100644
index 000000000..c54bd44f0
--- /dev/null
+++ b/snippets/postfixToInfix.md
@@ -0,0 +1,29 @@
+const postFix = RPN => {
+  let convert = RPN.replace(/\^/g,'**').split(/\s+/g).filter(el => !/\s+/.test(el) && el !== '')
+  let stack = []
+  let result = []
+  let friends = {"+" : ["+","-","*","/"],"-":[],"/":["*"],"*":["/","*"],"**":["+","-","*","/"]}
+  convert.forEach(symbol => {
+    if(!isNaN(parseFloat(symbol)) && isFinite(symbol)){
+      result.push(symbol)
+    }
+    else if (Object.keys(friends).includes(symbol)) {
+      a = result.pop()
+      b = result.pop()
+      if(stack.length !==0){
+          if(friends[symbol].includes(stack.pop())){
+            result.push(`${b} ${symbol} ${a}`)
+            stack.push(symbol)
+          }
+          else{
+            result.push(`(${b}) ${symbol} ${a}`)
+            stack.push(symbol)
+          }
+      }
+      else {result.push(`${b} ${symbol} ${a}`);stack.push(symbol)}
+    }
+    else throw `${symbol} is not a recognized symbol`
+  })
+  if(result.length === 1) return result.pop()
+  else throw `${RPN} is not a correct RPN`
+}

From 78c29a1ddb76b7eb76536b0c5c15d31e66193a02 Mon Sep 17 00:00:00 2001
From: Rohit Tanwar 
Date: Tue, 2 Jan 2018 16:39:26 +0530
Subject: [PATCH 18/61] fixed typos

---
 snippets/RPNSolver.md      | 24 ++++++++++++++++++++++++
 snippets/infixToPostFix.md | 11 ++++++++++-
 snippets/postfixToInfix.md | 11 ++++++++++-
 3 files changed, 44 insertions(+), 2 deletions(-)
 create mode 100644 snippets/RPNSolver.md

diff --git a/snippets/RPNSolver.md b/snippets/RPNSolver.md
new file mode 100644
index 000000000..2cfb59be5
--- /dev/null
+++ b/snippets/RPNSolver.md
@@ -0,0 +1,24 @@
+### RPNSolver
+
+Solves the given reverse polish notation
+
+``` js
+const RPNSolver = RPN => {
+  const operators = {'*' : (a,b) => a * b, '+' : (a,b) => a + b, '-' : (a,b) => a - b, '/' : (a,b) => a / b, '**': (a,b) => a ** b}
+  let [stack,solve] = [[],RPN.replace(/\^/g,'**').split(/\s+/g).filter(el => !/\s+/.test(el) && el !== '')]
+  solve.forEach(symbol => {
+    if(!isNaN(parseFloat(symbol)) && isFinite(symbol)) {stack.push(symbol)}
+          else if (Object.keys(operators).includes(symbol)) {
+          let [a,b] = [stack.pop(),stack.pop()]
+          stack.push(operators[symbol](parseFloat(b),parseFloat(a)))
+        } else { throw `${symbol} is not a recognized symbol` }
+  }
+)
+ if(stack.length === 1)  return stack.pop()
+  else  throw `${RPN} is not a proper RPN. Please check it and try again`
+}
+```
+
+```js
+
+```
diff --git a/snippets/infixToPostFix.md b/snippets/infixToPostFix.md
index 3fd859e37..b05496977 100644
--- a/snippets/infixToPostFix.md
+++ b/snippets/infixToPostFix.md
@@ -1,4 +1,9 @@
-const infix  = expr => {
+### infixToPostfix
+
+Works perfectly! 
+
+```js
+const infixToPostfix  = expr => {
   let rpn = ''
   let solve = expr.replace(/\^/g,'**').match(/([0-9]+|[\+\(\)\/\-]|\*+)/g).filter(el => !/\s+/.test(el) && el !== '')
   let stack = []
@@ -22,3 +27,7 @@ const infix  = expr => {
   }
   return rpn
 }
+```
+```js
+
+```
diff --git a/snippets/postfixToInfix.md b/snippets/postfixToInfix.md
index c54bd44f0..19e191c6b 100644
--- a/snippets/postfixToInfix.md
+++ b/snippets/postfixToInfix.md
@@ -1,4 +1,9 @@
-const postFix = RPN => {
+### postfixToInfix
+
+ This one has few errors and does not work properply
+
+```js
+const postfixToInfix = RPN => {
   let convert = RPN.replace(/\^/g,'**').split(/\s+/g).filter(el => !/\s+/.test(el) && el !== '')
   let stack = []
   let result = []
@@ -27,3 +32,7 @@ const postFix = RPN => {
   if(result.length === 1) return result.pop()
   else throw `${RPN} is not a correct RPN`
 }
+```
+```js
+
+```

From a5fc517f2b732c2a492c6af89be6488ceee0cbd2 Mon Sep 17 00:00:00 2001
From: Rohit Tanwar 
Date: Tue, 2 Jan 2018 16:40:19 +0530
Subject: [PATCH 19/61] fixed typos

---
 snippets/RPNSolver.md | 24 ------------------------
 1 file changed, 24 deletions(-)
 delete mode 100644 snippets/RPNSolver.md

diff --git a/snippets/RPNSolver.md b/snippets/RPNSolver.md
deleted file mode 100644
index 2cfb59be5..000000000
--- a/snippets/RPNSolver.md
+++ /dev/null
@@ -1,24 +0,0 @@
-### RPNSolver
-
-Solves the given reverse polish notation
-
-``` js
-const RPNSolver = RPN => {
-  const operators = {'*' : (a,b) => a * b, '+' : (a,b) => a + b, '-' : (a,b) => a - b, '/' : (a,b) => a / b, '**': (a,b) => a ** b}
-  let [stack,solve] = [[],RPN.replace(/\^/g,'**').split(/\s+/g).filter(el => !/\s+/.test(el) && el !== '')]
-  solve.forEach(symbol => {
-    if(!isNaN(parseFloat(symbol)) && isFinite(symbol)) {stack.push(symbol)}
-          else if (Object.keys(operators).includes(symbol)) {
-          let [a,b] = [stack.pop(),stack.pop()]
-          stack.push(operators[symbol](parseFloat(b),parseFloat(a)))
-        } else { throw `${symbol} is not a recognized symbol` }
-  }
-)
- if(stack.length === 1)  return stack.pop()
-  else  throw `${RPN} is not a proper RPN. Please check it and try again`
-}
-```
-
-```js
-
-```

From 7d612d04716727f50b8ccf2c8886d854849a87ad Mon Sep 17 00:00:00 2001
From: Semen Zhydenko 
Date: Tue, 2 Jan 2018 12:43:47 +0100
Subject: [PATCH 20/61] Fixed typos

---
 .github/ISSUE_TEMPLATE.md | 2 +-
 .travis/push.sh           | 2 +-
 COLLABORATING.md          | 2 +-
 README.md                 | 2 +-
 docs/index.html           | 2 +-
 snippets/shuffle.md       | 2 +-
 6 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
index 1f302a060..80717b4fd 100644
--- a/.github/ISSUE_TEMPLATE.md
+++ b/.github/ISSUE_TEMPLATE.md
@@ -4,7 +4,7 @@
 
 
 ## [FEATURE] _REPLACE THIS WITH A BRIEF SUMMARY OF THE SUGGESTED SNIPPET_
-**Category:** 
+**Category:** 
 ### Description 
 
 
diff --git a/.travis/push.sh b/.travis/push.sh
index ac6939000..dd539799c 100755
--- a/.travis/push.sh
+++ b/.travis/push.sh
@@ -6,7 +6,7 @@ setup_git() {
 commit_website_files() {
   if [ $TRAVIS_EVENT_TYPE != "pull_request" ]; then
     if [ $TRAVIS_BRANCH == "master" ]; then
-      echo "Commiting to master branch..."
+      echo "Committing to master branch..."
       git checkout master
       git add *
       git commit --message "Travis build: $TRAVIS_BUILD_NUMBER [ci skip]"
diff --git a/COLLABORATING.md b/COLLABORATING.md
index fdf6ab673..a38c4d52d 100644
--- a/COLLABORATING.md
+++ b/COLLABORATING.md
@@ -14,7 +14,7 @@ As a member of the team that manages **30 seconds of code**, you have the follow
 ## Guidelines for merging pull requests and making changes to the project
 
 - **[Usual guidelines](https://github.com/Chalarangelo/30-seconds-of-code/blob/master/CONTRIBUTING.md) apply.** Make sure to follow them, like everybody else.
-- **For a pull request to be considered ready to merge, there should be at least 2 (preferrably 3) reviews approving it for merge.** There are, however, certain exceptions:
+- **For a pull request to be considered ready to merge, there should be at least 2 (preferably 3) reviews approving it for merge.** There are, however, certain exceptions:
   - **If a pull request only fixes typos**, there is no need to wait for a second reviewer (unless you are not absolutely certain these were not typos in the first place).
   - **If a pull request only clarifies a snippet's description or enforces the styleguide for an existng snippet**, you might be able to merge it without getting a second reviewer to review it, but only if you are absolutely certain about it.
   - **Make sure pull requests pass the Travis CI build**, otherwise try and find out what's wrong and inform the author of the pull request.
diff --git a/README.md b/README.md
index 0c5ef52ad..3d77ed57c 100644
--- a/README.md
+++ b/README.md
@@ -1357,7 +1357,7 @@ sampleSize([1, 2, 3], 4); // [2,3,1]
 
 Randomizes the order of the values of an array, returning a new array.
 
-Uses the Fisher-Yates algoritm to reorder the elements of the array, based on the [Lodash implementation](https://github.com/lodash/lodash/blob/b2ea6b1cd251796dcb5f9700c4911a7b6223920b/shuffle.js), but as a pure function.
+Uses the Fisher-Yates algorithm to reorder the elements of the array, based on the [Lodash implementation](https://github.com/lodash/lodash/blob/b2ea6b1cd251796dcb5f9700c4911a7b6223920b/shuffle.js), but as a pure function.
 
 ```js
 const shuffle = ([...arr]) => {
diff --git a/docs/index.html b/docs/index.html
index 840b6d38d..aa095370e 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -289,7 +289,7 @@ reducedFilter(data, ['id', 'name'], item => item.age > 24); // [{ id: 2, n
 };
 
sampleSize([1, 2, 3], 2); // [3,1]
 sampleSize([1, 2, 3], 4); // [2,3,1]
-

shuffle

Randomizes the order of the values of an array, returning a new array.

Uses the Fisher-Yates algoritm to reorder the elements of the array, based on the Lodash implementation, but as a pure function.

const shuffle = ([...arr]) => {
+

shuffle

Randomizes the order of the values of an array, returning a new array.

Uses the Fisher-Yates algorithm to reorder the elements of the array, based on the Lodash implementation, but as a pure function.

const shuffle = ([...arr]) => {
   let m = arr.length;
   while (m) {
     const i = Math.floor(Math.random() * m--);
diff --git a/snippets/shuffle.md b/snippets/shuffle.md
index 2b6229634..a9e1c64aa 100644
--- a/snippets/shuffle.md
+++ b/snippets/shuffle.md
@@ -2,7 +2,7 @@
 
 Randomizes the order of the values of an array, returning a new array.
 
-Uses the Fisher-Yates algoritm to reorder the elements of the array, based on the [Lodash implementation](https://github.com/lodash/lodash/blob/b2ea6b1cd251796dcb5f9700c4911a7b6223920b/shuffle.js), but as a pure function.
+Uses the Fisher-Yates algorithm to reorder the elements of the array, based on the [Lodash implementation](https://github.com/lodash/lodash/blob/b2ea6b1cd251796dcb5f9700c4911a7b6223920b/shuffle.js), but as a pure function.
 
 ```js
 const shuffle = ([...arr]) => {

From eed6b2c3351c626c00491c915c03e2509ec181f0 Mon Sep 17 00:00:00 2001
From: Angelos Chalaris 
Date: Tue, 2 Jan 2018 16:38:10 +0200
Subject: [PATCH 21/61] Added comments to the module building scripts

---
 dist/_30s.es5.js     | 1101 ++++++++++++++++++++++++++++++++++++++++++
 dist/_30s.es5.min.js |    1 +
 dist/_30s.esm.js     |  664 +++++++++++++++++++++++++
 dist/_30s.js         |  672 ++++++++++++++++++++++++++
 dist/_30s.min.js     |    1 +
 scripts/module.js    |   36 +-
 scripts/rollup.js    |   12 +-
 7 files changed, 2465 insertions(+), 22 deletions(-)
 create mode 100644 dist/_30s.es5.js
 create mode 100644 dist/_30s.es5.min.js
 create mode 100644 dist/_30s.esm.js
 create mode 100644 dist/_30s.js
 create mode 100644 dist/_30s.min.js

diff --git a/dist/_30s.es5.js b/dist/_30s.es5.js
new file mode 100644
index 000000000..a798209c9
--- /dev/null
+++ b/dist/_30s.es5.js
@@ -0,0 +1,1101 @@
+(function (global, factory) {
+	typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+	typeof define === 'function' && define.amd ? define(factory) :
+	(global._30s = factory());
+}(this, (function () { 'use strict';
+
+var anagrams = function anagrams(str) {
+  if (str.length <= 2) return str.length === 2 ? [str, str[1] + str[0]] : [str];
+  return str.split('').reduce(function (acc, letter, i) {
+    return acc.concat(anagrams(str.slice(0, i) + str.slice(i + 1)).map(function (val) {
+      return letter + val;
+    }));
+  }, []);
+};
+
+var arrayToHtmlList = function arrayToHtmlList(arr, listID) {
+  return arr.map(function (item) {
+    return document.querySelector('#' + listID).innerHTML += '
  • ' + item + '
  • '; + }); +}; + +var average = function average() { + var _ref; + + var nums = (_ref = []).concat.apply(_ref, arguments); + return nums.reduce(function (acc, val) { + return acc + val; + }, 0) / nums.length; +}; + +var bottomVisible = function bottomVisible() { + return document.documentElement.clientHeight + window.scrollY >= (document.documentElement.scrollHeight || document.documentElement.clientHeight); +}; + +var byteSize = function byteSize(str) { + return new Blob([str]).size; +}; + +var call = function call(key) { + for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + + return function (context) { + return context[key].apply(context, args); + }; +}; + +function _toArray(arr) { return Array.isArray(arr) ? arr : Array.from(arr); } + +var capitalize = function capitalize(_ref) { + var _ref2 = _toArray(_ref), + first = _ref2[0], + rest = _ref2.slice(1); + + var lowerRest = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + return first.toUpperCase() + (lowerRest ? rest.join('').toLowerCase() : rest.join('')); +}; + +var capitalizeEveryWord = function capitalizeEveryWord(str) { + return str.replace(/\b[a-z]/g, function (char) { + return char.toUpperCase(); + }); +}; + +var chainAsync = function chainAsync(fns) { + var curr = 0; + var next = function next() { + return fns[curr++](next); + }; + next(); +}; + +var chunk = function chunk(arr, size) { + return Array.from({ length: Math.ceil(arr.length / size) }, function (v, i) { + return arr.slice(i * size, i * size + size); + }); +}; + +var clampNumber = function clampNumber(num, a, b) { + return Math.max(Math.min(num, Math.max(a, b)), Math.min(a, b)); +}; + +var cleanObj = function cleanObj(obj) { + var keysToKeep = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; + var childIndicator = arguments[2]; + + Object.keys(obj).forEach(function (key) { + if (key === childIndicator) { + cleanObj(obj[key], keysToKeep, childIndicator); + } else if (!keysToKeep.includes(key)) { + delete obj[key]; + } + }); + return obj; +}; + +var coalesce = function coalesce() { + for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + return args.find(function (_) { + return ![undefined, null].includes(_); + }); +}; + +var coalesceFactory = function coalesceFactory(valid) { + return function () { + for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + return args.find(valid); + }; +}; + +var collatz = function collatz(n) { + return n % 2 == 0 ? n / 2 : 3 * n + 1; +}; + +var collectInto = function collectInto(fn) { + return function () { + for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + return fn(args); + }; +}; + +var compact = function compact(arr) { + return arr.filter(Boolean); +}; + +var compose = function compose() { + for (var _len = arguments.length, fns = Array(_len), _key = 0; _key < _len; _key++) { + fns[_key] = arguments[_key]; + } + + return fns.reduce(function (f, g) { + return function () { + return f(g.apply(undefined, arguments)); + }; + }); +}; + +var countOccurrences = function countOccurrences(arr, value) { + return arr.reduce(function (a, v) { + return v === value ? a + 1 : a + 0; + }, 0); +}; + +var countVowels = function countVowels(str) { + return (str.match(/[aeiou]/gi) || []).length; +}; + +var currentURL = function currentURL() { + return window.location.href; +}; + +var curry = function curry(fn) { + for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { + args[_key - 2] = arguments[_key]; + } + + var arity = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : fn.length; + return arity <= args.length ? fn.apply(undefined, args) : curry.bind.apply(curry, [null, fn, arity].concat(args)); +}; + +function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } + +var deepFlatten = function deepFlatten(arr) { + var _ref; + + return (_ref = []).concat.apply(_ref, _toConsumableArray(arr.map(function (v) { + return Array.isArray(v) ? deepFlatten(v) : v; + }))); +}; + +var detectDeviceType = function detectDeviceType() { + return (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ? 'Mobile' : 'Desktop' + ); +}; + +var difference = function difference(a, b) { + var s = new Set(b); + return a.filter(function (x) { + return !s.has(x); + }); +}; + +var differenceWith = function differenceWith(arr, val, comp) { + return arr.filter(function (a) { + return !val.find(function (b) { + return comp(a, b); + }); + }); +}; + +function _toConsumableArray$1(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } + +var digitize = function digitize(n) { + return [].concat(_toConsumableArray$1('' + n)).map(function (i) { + return parseInt(i); + }); +}; + +var distance = function distance(x0, y0, x1, y1) { + return Math.hypot(x1 - x0, y1 - y0); +}; + +function _toConsumableArray$2(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } + +var distinctValuesOfArray = function distinctValuesOfArray(arr) { + return [].concat(_toConsumableArray$2(new Set(arr))); +}; + +var dropElements = function dropElements(arr, func) { + while (arr.length > 0 && !func(arr[0])) { + arr = arr.slice(1); + }return arr; +}; + +var dropRight = function dropRight(arr) { + var n = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; + return arr.slice(0, -n); +}; + +var elementIsVisibleInViewport = function elementIsVisibleInViewport(el) { + var partiallyVisible = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + var _el$getBoundingClient = el.getBoundingClientRect(), + top = _el$getBoundingClient.top, + left = _el$getBoundingClient.left, + bottom = _el$getBoundingClient.bottom, + right = _el$getBoundingClient.right; + + var _window = window, + innerHeight = _window.innerHeight, + innerWidth = _window.innerWidth; + + return partiallyVisible ? (top > 0 && top < innerHeight || bottom > 0 && bottom < innerHeight) && (left > 0 && left < innerWidth || right > 0 && right < innerWidth) : top >= 0 && left >= 0 && bottom <= innerHeight && right <= innerWidth; +}; + +var escapeHTML = function escapeHTML(str) { + return str.replace(/[&<>'"]/g, function (tag) { + return { + '&': '&', + '<': '<', + '>': '>', + "'": ''', + '"': '"' + }[tag] || tag; + }); +}; + +var escapeRegExp = function escapeRegExp(str) { + return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); +}; + +var everyNth = function everyNth(arr, nth) { + return arr.filter(function (e, i) { + return i % nth === nth - 1; + }); +}; + +var extendHex = function extendHex(shortHex) { + return '#' + shortHex.slice(shortHex.startsWith('#') ? 1 : 0).split('').map(function (x) { + return x + x; + }).join(''); +}; + +var factorial = function factorial(n) { + return n < 0 ? function () { + throw new TypeError('Negative numbers are not allowed!'); + }() : n <= 1 ? 1 : n * factorial(n - 1); +}; + +var fibonacci = function fibonacci(n) { + return Array.from({ length: n }).reduce(function (acc, val, i) { + return acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i); + }, []); +}; + +var fibonacciCountUntilNum = function fibonacciCountUntilNum(num) { + return Math.ceil(Math.log(num * Math.sqrt(5) + 1 / 2) / Math.log((Math.sqrt(5) + 1) / 2)); +}; + +var fibonacciUntilNum = function fibonacciUntilNum(num) { + var n = Math.ceil(Math.log(num * Math.sqrt(5) + 1 / 2) / Math.log((Math.sqrt(5) + 1) / 2)); + return Array.from({ length: n }).reduce(function (acc, val, i) { + return acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i); + }, []); +}; + +var filterNonUnique = function filterNonUnique(arr) { + return arr.filter(function (i) { + return arr.indexOf(i) === arr.lastIndexOf(i); + }); +}; + +function _toConsumableArray$3(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } + +var flatten = function flatten(arr) { + var _ref; + + return (_ref = []).concat.apply(_ref, _toConsumableArray$3(arr)); +}; + +var flattenDepth = function flattenDepth(arr) { + var depth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; + return depth != 1 ? arr.reduce(function (a, v) { + return a.concat(Array.isArray(v) ? flattenDepth(v, depth - 1) : v); + }, []) : arr.reduce(function (a, v) { + return a.concat(v); + }, []); +}; + +var flip = function flip(fn) { + return function () { + for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + return fn.apply(undefined, [args.pop()].concat(args)); + }; +}; + +var fromCamelCase = function fromCamelCase(str) { + var separator = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '_'; + return str.replace(/([a-z\d])([A-Z])/g, '$1' + separator + '$2').replace(/([A-Z]+)([A-Z][a-z\d]+)/g, '$1' + separator + '$2').toLowerCase(); +}; + +var functionName = function functionName(fn) { + return console.debug(fn.name), fn; +}; + +var gcd = function gcd() { + var _ref; + + var data = (_ref = []).concat.apply(_ref, arguments); + var helperGcd = function helperGcd(x, y) { + return !y ? x : gcd(y, x % y); + }; + return data.reduce(function (a, b) { + return helperGcd(a, b); + }); +}; + +var getDaysDiffBetweenDates = function getDaysDiffBetweenDates(dateInitial, dateFinal) { + return (dateFinal - dateInitial) / (1000 * 3600 * 24); +}; + +var getScrollPosition = function getScrollPosition() { + var el = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : window; + return { + x: el.pageXOffset !== undefined ? el.pageXOffset : el.scrollLeft, + y: el.pageYOffset !== undefined ? el.pageYOffset : el.scrollTop + }; +}; + +var getStyle = function getStyle(el, ruleName) { + return getComputedStyle(el)[ruleName]; +}; + +var getType = function getType(v) { + return v === undefined ? 'undefined' : v === null ? 'null' : v.constructor.name.toLowerCase(); +}; + +var getURLParameters = function getURLParameters(url) { + return url.match(/([^?=&]+)(=([^&]*))/g).reduce(function (a, v) { + return a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1), a; + }, {}); +}; + +var groupBy = function groupBy(arr, func) { + return arr.map(typeof func === 'function' ? func : function (val) { + return val[func]; + }).reduce(function (acc, val, i) { + acc[val] = (acc[val] || []).concat(arr[i]); + return acc; + }, {}); +}; + +var hammingDistance = function hammingDistance(num1, num2) { + return ((num1 ^ num2).toString(2).match(/1/g) || '').length; +}; + +var hasClass = function hasClass(el, className) { + return el.classList.contains(className); +}; + +var head = function head(arr) { + return arr[0]; +}; + +function _toConsumableArray$4(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } + +var hexToRGB = function hexToRGB(hex) { + var alpha = false, + h = hex.slice(hex.startsWith('#') ? 1 : 0); + if (h.length === 3) h = [].concat(_toConsumableArray$4(h)).map(function (x) { + return x + x; + }).join('');else if (h.length === 8) alpha = true; + h = parseInt(h, 16); + return 'rgb' + (alpha ? 'a' : '') + '(' + (h >>> (alpha ? 24 : 16)) + ', ' + ((h & (alpha ? 0x00ff0000 : 0x00ff00)) >>> (alpha ? 16 : 8)) + ', ' + ((h & (alpha ? 0x0000ff00 : 0x0000ff)) >>> (alpha ? 8 : 0)) + (alpha ? ', ' + (h & 0x000000ff) : '') + ')'; +}; + +var hide = function hide() { + for (var _len = arguments.length, el = Array(_len), _key = 0; _key < _len; _key++) { + el[_key] = arguments[_key]; + } + + return [].concat(el).forEach(function (e) { + return e.style.display = 'none'; + }); +}; + +var httpsRedirect = function httpsRedirect() { + if (location.protocol !== 'https:') location.replace('https://' + location.href.split('//')[1]); +}; + +var initial = function initial(arr) { + return arr.slice(0, -1); +}; + +var initialize2DArray = function initialize2DArray(w, h) { + var val = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; + return Array(h).fill().map(function () { + return Array(w).fill(val); + }); +}; + +var initializeArrayWithRange = function initializeArrayWithRange(end) { + var start = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + return Array.from({ length: end + 1 - start }).map(function (v, i) { + return i + start; + }); +}; + +var initializeArrayWithValues = function initializeArrayWithValues(n) { + var value = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + return Array(n).fill(value); +}; + +var inRange = function inRange(n, start) { + var end = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; + + if (end && start > end) end = [start, start = end][0]; + return end == null ? n >= 0 && n < start : n >= start && n < end; +}; + +var intersection = function intersection(a, b) { + var s = new Set(b); + return a.filter(function (x) { + return s.has(x); + }); +}; + +var isArmstrongNumber = function isArmstrongNumber(digits) { + return function (arr) { + return arr.reduce(function (a, d) { + return a + Math.pow(parseInt(d), arr.length); + }, 0) == digits; + }((digits + '').split('')); +}; + +var isArray = function isArray(val) { + return !!val && Array.isArray(val); +}; + +var isBoolean = function isBoolean(val) { + return typeof val === 'boolean'; +}; + +var isDivisible = function isDivisible(dividend, divisor) { + return dividend % divisor === 0; +}; + +var isEven = function isEven(num) { + return num % 2 === 0; +}; + +var isFunction = function isFunction(val) { + return val && typeof val === 'function'; +}; + +var isNumber = function isNumber(val) { + return typeof val === 'number'; +}; + +var isPrime = function isPrime(num) { + var boundary = Math.floor(Math.sqrt(num)); + for (var i = 2; i * i <= boundary; i++) { + if (num % i == 0) return false; + }return num >= 2; +}; + +var isString = function isString(val) { + return typeof val === 'string'; +}; + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +var isSymbol = function isSymbol(val) { + return (typeof val === 'undefined' ? 'undefined' : _typeof(val)) === 'symbol'; +}; + +var JSONToDate = function JSONToDate(arr) { + var dt = new Date(parseInt(arr.toString().substr(6))); + return dt.getDate() + "/" + (dt.getMonth() + 1) + "/" + dt.getFullYear(); +}; + +var fs = typeof require !== "undefined" && require('fs'); +var JSONToFile = function JSONToFile(obj, filename) { + return fs.writeFile(filename + ".json", JSON.stringify(obj, null, 2)); +}; + +var last = function last(arr) { + return arr[arr.length - 1]; +}; + +var lcm = function lcm() { + var _ref; + + var gcd = function gcd(x, y) { + return !y ? x : gcd(y, x % y); + }; + var _lcm = function _lcm(x, y) { + return x * y / gcd(x, y); + }; + return (_ref = []).concat.apply(_ref, arguments).reduce(function (a, b) { + return _lcm(a, b); + }); +}; + +var lowercaseKeys = function lowercaseKeys(obj) { + return Object.keys(obj).reduce(function (acc, key) { + acc[key.toLowerCase()] = obj[key]; + return acc; + }, {}); +}; + +var mapObject = function mapObject(arr, fn) { + return function (a) { + return a = [arr, arr.map(fn)], a[0].reduce(function (acc, val, ind) { + return acc[val] = a[1][ind], acc; + }, {}); + }(); +}; + +function _toConsumableArray$5(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } + +var max = function max() { + var _ref; + + return Math.max.apply(Math, _toConsumableArray$5((_ref = []).concat.apply(_ref, arguments))); +}; + +function _toConsumableArray$6(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } + +var median = function median(arr) { + var mid = Math.floor(arr.length / 2), + nums = [].concat(_toConsumableArray$6(arr)).sort(function (a, b) { + return a - b; + }); + return arr.length % 2 !== 0 ? nums[mid] : (nums[mid - 1] + nums[mid]) / 2; +}; + +function _toConsumableArray$7(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } + +var min = function min(arr) { + var _ref; + + return Math.min.apply(Math, _toConsumableArray$7((_ref = []).concat.apply(_ref, _toConsumableArray$7(arr)))); +}; + +var negate = function negate(func) { + return function () { + return !func.apply(undefined, arguments); + }; +}; + +var nthElement = function nthElement(arr) { + var n = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + return (n > 0 ? arr.slice(n, n + 1) : arr.slice(n))[0]; +}; + +var objectFromPairs = function objectFromPairs(arr) { + return arr.reduce(function (a, v) { + return a[v[0]] = v[1], a; + }, {}); +}; + +var objectToPairs = function objectToPairs(obj) { + return Object.keys(obj).map(function (k) { + return [k, obj[k]]; + }); +}; + +var onUserInputChange = function onUserInputChange(callback) { + var type = 'mouse', + lastTime = 0; + var mousemoveHandler = function mousemoveHandler() { + var now = performance.now(); + if (now - lastTime < 20) type = 'mouse', callback(type), document.removeEventListener('mousemove', mousemoveHandler); + lastTime = now; + }; + document.addEventListener('touchstart', function () { + if (type === 'touch') return; + type = 'touch', callback(type), document.addEventListener('mousemove', mousemoveHandler); + }); +}; + +var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); + +function _toConsumableArray$8(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } + +var orderBy = function orderBy(arr, props, orders) { + return [].concat(_toConsumableArray$8(arr)).sort(function (a, b) { + return props.reduce(function (acc, prop, i) { + if (acc === 0) { + var _ref = orders && orders[i] === 'desc' ? [b[prop], a[prop]] : [a[prop], b[prop]], + _ref2 = _slicedToArray(_ref, 2), + p1 = _ref2[0], + p2 = _ref2[1]; + + acc = p1 > p2 ? 1 : p1 < p2 ? -1 : 0; + } + return acc; + }, 0); + }); +}; + +var palindrome = function palindrome(str) { + var s = str.toLowerCase().replace(/[\W_]/g, ''); + return s === s.split('').reverse().join(''); +}; + +var percentile = function percentile(arr, val) { + return 100 * arr.reduce(function (acc, v) { + return acc + (v < val ? 1 : 0) + (v === val ? 0.5 : 0); + }, 0) / arr.length; +}; + +var pick = function pick(obj, arr) { + return arr.reduce(function (acc, curr) { + return curr in obj && (acc[curr] = obj[curr]), acc; + }, {}); +}; + +var pipeFunctions = function pipeFunctions() { + for (var _len = arguments.length, fns = Array(_len), _key = 0; _key < _len; _key++) { + fns[_key] = arguments[_key]; + } + + return fns.reduce(function (f, g) { + return function () { + return g(f.apply(undefined, arguments)); + }; + }); +}; + +var powerset = function powerset(arr) { + return arr.reduce(function (a, v) { + return a.concat(a.map(function (r) { + return [v].concat(r); + })); + }, [[]]); +}; + +var primes = function primes(num) { + var arr = Array.from({ length: num - 1 }).map(function (x, i) { + return i + 2; + }), + sqroot = Math.floor(Math.sqrt(num)), + numsTillSqroot = Array.from({ length: sqroot - 1 }).map(function (x, i) { + return i + 2; + }); + numsTillSqroot.forEach(function (x) { + return arr = arr.filter(function (y) { + return y % x !== 0 || y == x; + }); + }); + return arr; +}; + +var promisify = function promisify(func) { + return function () { + for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + return new Promise(function (resolve, reject) { + return func.apply(undefined, args.concat([function (err, result) { + return err ? reject(err) : resolve(result); + }])); + }); + }; +}; + +var pull = function pull(arr) { + for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + + var argState = Array.isArray(args[0]) ? args[0] : args; + var pulled = arr.filter(function (v, i) { + return !argState.includes(v); + }); + arr.length = 0; + pulled.forEach(function (v) { + return arr.push(v); + }); +}; + +var pullAtIndex = function pullAtIndex(arr, pullArr) { + var removed = []; + var pulled = arr.map(function (v, i) { + return pullArr.includes(i) ? removed.push(v) : v; + }).filter(function (v, i) { + return !pullArr.includes(i); + }); + arr.length = 0; + pulled.forEach(function (v) { + return arr.push(v); + }); + return removed; +}; + +var pullAtValue = function pullAtValue(arr, pullArr) { + var removed = [], + pushToRemove = arr.forEach(function (v, i) { + return pullArr.includes(v) ? removed.push(v) : v; + }), + mutateTo = arr.filter(function (v, i) { + return !pullArr.includes(v); + }); + arr.length = 0; + mutateTo.forEach(function (v) { + return arr.push(v); + }); + return removed; +}; + +function _toConsumableArray$9(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } + +function _toArray$1(arr) { return Array.isArray(arr) ? arr : Array.from(arr); } + +var quickSort = function quickSort(_ref, desc) { + var _ref2 = _toArray$1(_ref), + n = _ref2[0], + nums = _ref2.slice(1); + + return isNaN(n) ? [] : [].concat(_toConsumableArray$9(quickSort(nums.filter(function (v) { + return desc ? v > n : v <= n; + }), desc)), [n], _toConsumableArray$9(quickSort(nums.filter(function (v) { + return !desc ? v > n : v <= n; + }), desc))); +}; + +var randomHexColorCode = function randomHexColorCode() { + var n = (Math.random() * 0xfffff | 0).toString(16); + return '#' + (n.length !== 6 ? (Math.random() * 0xf | 0).toString(16) + n : n); +}; + +var randomIntegerInRange = function randomIntegerInRange(min, max) { + return Math.floor(Math.random() * (max - min + 1)) + min; +}; + +var randomNumberInRange = function randomNumberInRange(min, max) { + return Math.random() * (max - min) + min; +}; + +var fs$1 = typeof require !== "undefined" && require('fs'); +var readFileLines = function readFileLines(filename) { + return fs$1.readFileSync(filename).toString('UTF8').split('\n'); +}; + +var redirect = function redirect(url) { + var asLink = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + return asLink ? window.location.href = url : window.location.replace(url); +}; + +var remove = function remove(arr, func) { + return Array.isArray(arr) ? arr.filter(func).reduce(function (acc, val) { + arr.splice(arr.indexOf(val), 1); + return acc.concat(val); + }, []) : []; +}; + +var repeatString = function repeatString() { + var str = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; + var num = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 2; + + return num >= 0 ? str.repeat(num) : str; +}; + +var reverseString = function reverseString(str) { + return str.split('').reverse().join(''); +}; + +var RGBToHex = function RGBToHex(r, g, b) { + return ((r << 16) + (g << 8) + b).toString(16).padStart(6, '0'); +}; + +var round = function round(n) { + var decimals = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + return Number(Math.round(n + "e" + decimals) + "e-" + decimals); +}; + +var runPromisesInSeries = function runPromisesInSeries(ps) { + return ps.reduce(function (p, next) { + return p.then(next); + }, Promise.resolve()); +}; + +var sample = function sample(arr) { + return arr[Math.floor(Math.random() * arr.length)]; +}; + +var scrollToTop = function scrollToTop() { + var c = document.documentElement.scrollTop || document.body.scrollTop; + if (c > 0) { + window.requestAnimationFrame(scrollToTop); + window.scrollTo(0, c - c / 8); + } +}; + +var sdbm = function sdbm(str) { + var arr = str.split(''); + return arr.reduce(function (hashCode, currentVal) { + return hashCode = currentVal.charCodeAt(0) + (hashCode << 6) + (hashCode << 16) - hashCode; + }, 0); +}; + +var select = function select(from, selector) { + return selector.split('.').reduce(function (prev, cur) { + return prev && prev[cur]; + }, from); +}; + +var setStyle = function setStyle(el, ruleName, value) { + return el.style[ruleName] = value; +}; + +var shallowClone = function shallowClone(obj) { + return Object.assign({}, obj); +}; + +var show = function show() { + for (var _len = arguments.length, el = Array(_len), _key = 0; _key < _len; _key++) { + el[_key] = arguments[_key]; + } + + return [].concat(el).forEach(function (e) { + return e.style.display = ''; + }); +}; + +function _toArray$2(arr) { return Array.isArray(arr) ? arr : Array.from(arr); } + +var shuffle = function shuffle(_ref) { + var _ref2 = _toArray$2(_ref), + arr = _ref2.slice(0); + + var m = arr.length; + while (m) { + var i = Math.floor(Math.random() * m--); + var _ref3 = [arr[i], arr[m]]; + arr[m] = _ref3[0]; + arr[i] = _ref3[1]; + } + return arr; +}; + +var similarity = function similarity(arr, values) { + return arr.filter(function (v) { + return values.includes(v); + }); +}; + +var sleep = function sleep(ms) { + return new Promise(function (resolve) { + return setTimeout(resolve, ms); + }); +}; + +var sortCharactersInString = function sortCharactersInString(str) { + return str.split('').sort(function (a, b) { + return a.localeCompare(b); + }).join(''); +}; + +var speechSynthesis = function speechSynthesis(message) { + var msg = new SpeechSynthesisUtterance(message); + msg.voice = window.speechSynthesis.getVoices()[0]; + window.speechSynthesis.speak(msg); +}; + +var splitLines = function splitLines(str) { + return str.split(/\r?\n/); +}; + +function _toConsumableArray$10(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } + +var spreadOver = function spreadOver(fn) { + return function (argsArr) { + return fn.apply(undefined, _toConsumableArray$10(argsArr)); + }; +}; + +var standardDeviation = function standardDeviation(arr) { + var usePopulation = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + var mean = arr.reduce(function (acc, val) { + return acc + val; + }, 0) / arr.length; + return Math.sqrt(arr.reduce(function (acc, val) { + return acc.concat(Math.pow(val - mean, 2)); + }, []).reduce(function (acc, val) { + return acc + val; + }, 0) / (arr.length - (usePopulation ? 0 : 1))); +}; + +var sum = function sum() { + var _ref; + + return (_ref = []).concat.apply(_ref, arguments).reduce(function (acc, val) { + return acc + val; + }, 0); +}; + +function _toConsumableArray$11(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } + +var symmetricDifference = function symmetricDifference(a, b) { + var sA = new Set(a), + sB = new Set(b); + return [].concat(_toConsumableArray$11(a.filter(function (x) { + return !sB.has(x); + })), _toConsumableArray$11(b.filter(function (x) { + return !sA.has(x); + }))); +}; + +var tail = function tail(arr) { + return arr.length > 1 ? arr.slice(1) : arr; +}; + +var take = function take(arr) { + var n = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; + return arr.slice(0, n); +}; + +var takeRight = function takeRight(arr) { + var n = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; + return arr.slice(arr.length - n, arr.length); +}; + +var timeTaken = function timeTaken(callback) { + console.time('timeTaken'); + var r = callback(); + console.timeEnd('timeTaken'); + return r; +}; + +var toCamelCase = function toCamelCase(str) { + var s = str && str.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g).map(function (x) { + return x.slice(0, 1).toUpperCase() + x.slice(1).toLowerCase(); + }).join(''); + return s.slice(0, 1).toLowerCase() + s.slice(1); +}; + +var toDecimalMark = function toDecimalMark(num) { + return num.toLocaleString('en-US'); +}; + +var toEnglishDate = function toEnglishDate(time) { + try { + return new Date(time).toISOString().split('T')[0].replace(/-/g, '/'); + } catch (e) {} +}; + +var toggleClass = function toggleClass(el, className) { + return el.classList.toggle(className); +}; + +var toKebabCase = function toKebabCase(str) { + return str && str.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g).map(function (x) { + return x.toLowerCase(); + }).join('-'); +}; + +var tomorrow = function tomorrow() { + return new Date(new Date().getTime() + 86400000).toISOString().split('T')[0]; +}; + +var toOrdinalSuffix = function toOrdinalSuffix(num) { + var int = parseInt(num), + digits = [int % 10, int % 100], + ordinals = ['st', 'nd', 'rd', 'th'], + oPattern = [1, 2, 3, 4], + tPattern = [11, 12, 13, 14, 15, 16, 17, 18, 19]; + return oPattern.includes(digits[0]) && !tPattern.includes(digits[1]) ? int + ordinals[digits[0] - 1] : int + ordinals[3]; +}; + +var toSnakeCase = function toSnakeCase(str) { + str && str.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g).map(function (x) { + return x.toLowerCase(); + }).join('_'); +}; + +var truncateString = function truncateString(str, num) { + return str.length > num ? str.slice(0, num > 3 ? num - 3 : num) + '...' : str; +}; + +var truthCheckCollection = function truthCheckCollection(collection, pre) { + return collection.every(function (obj) { + return obj[pre]; + }); +}; + +var unescapeHTML = function unescapeHTML(str) { + return str.replace(/&|<|>|'|"/g, function (tag) { + return { + '&': '&', + '<': '<', + '>': '>', + ''': "'", + '"': '"' + }[tag] || tag; + }); +}; + +function _toConsumableArray$12(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } + +var union = function union(a, b) { + return Array.from(new Set([].concat(_toConsumableArray$12(a), _toConsumableArray$12(b)))); +}; + +var UUIDGeneratorBrowser = function UUIDGeneratorBrowser() { + return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, function (c) { + return (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16); + }); +}; + +var crypto$1 = typeof require !== "undefined" && require('crypto'); +var UUIDGeneratorNode = function UUIDGeneratorNode() { + return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, function (c) { + return (c ^ crypto$1.randomBytes(1)[0] & 15 >> c / 4).toString(16); + }); +}; + +var validateNumber = function validateNumber(n) { + return !isNaN(parseFloat(n)) && isFinite(n) && Number(n) == n; +}; + +var without = function without(arr) { + for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + + return arr.filter(function (v) { + return !args.includes(v); + }); +}; + +var words = function words(str) { + var pattern = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : /[^a-zA-Z-]+/; + return str.split(pattern).filter(Boolean); +}; + +function _toConsumableArray$13(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } + +var zip = function zip() { + for (var _len = arguments.length, arrays = Array(_len), _key = 0; _key < _len; _key++) { + arrays[_key] = arguments[_key]; + } + + var maxLength = Math.max.apply(Math, _toConsumableArray$13(arrays.map(function (x) { + return x.length; + }))); + return Array.from({ length: maxLength }).map(function (_, i) { + return Array.from({ length: arrays.length }, function (_, k) { + return arrays[k][i]; + }); + }); +}; + +var zipObject = function zipObject(props, values) { + return props.reduce(function (obj, prop, index) { + return obj[prop] = values[index], obj; + }, {}); +}; + +var imports = { anagrams: anagrams, arrayToHtmlList: arrayToHtmlList, average: average, bottomVisible: bottomVisible, byteSize: byteSize, call: call, capitalize: capitalize, capitalizeEveryWord: capitalizeEveryWord, chainAsync: chainAsync, chunk: chunk, clampNumber: clampNumber, cleanObj: cleanObj, coalesce: coalesce, coalesceFactory: coalesceFactory, collatz: collatz, collectInto: collectInto, compact: compact, compose: compose, countOccurrences: countOccurrences, countVowels: countVowels, currentURL: currentURL, curry: curry, deepFlatten: deepFlatten, detectDeviceType: detectDeviceType, difference: difference, differenceWith: differenceWith, digitize: digitize, distance: distance, distinctValuesOfArray: distinctValuesOfArray, dropElements: dropElements, dropRight: dropRight, elementIsVisibleInViewport: elementIsVisibleInViewport, escapeHTML: escapeHTML, escapeRegExp: escapeRegExp, everyNth: everyNth, extendHex: extendHex, factorial: factorial, fibonacci: fibonacci, fibonacciCountUntilNum: fibonacciCountUntilNum, fibonacciUntilNum: fibonacciUntilNum, filterNonUnique: filterNonUnique, flatten: flatten, flattenDepth: flattenDepth, flip: flip, fromCamelCase: fromCamelCase, functionName: functionName, gcd: gcd, getDaysDiffBetweenDates: getDaysDiffBetweenDates, getScrollPosition: getScrollPosition, getStyle: getStyle, getType: getType, getURLParameters: getURLParameters, groupBy: groupBy, hammingDistance: hammingDistance, hasClass: hasClass, head: head, hexToRGB: hexToRGB, hide: hide, httpsRedirect: httpsRedirect, initial: initial, initialize2DArray: initialize2DArray, initializeArrayWithRange: initializeArrayWithRange, initializeArrayWithValues: initializeArrayWithValues, inRange: inRange, intersection: intersection, isArmstrongNumber: isArmstrongNumber, isArray: isArray, isBoolean: isBoolean, isDivisible: isDivisible, isEven: isEven, isFunction: isFunction, isNumber: isNumber, isPrime: isPrime, isString: isString, isSymbol: isSymbol, JSONToDate: JSONToDate, JSONToFile: JSONToFile, last: last, lcm: lcm, lowercaseKeys: lowercaseKeys, mapObject: mapObject, max: max, median: median, min: min, negate: negate, nthElement: nthElement, objectFromPairs: objectFromPairs, objectToPairs: objectToPairs, onUserInputChange: onUserInputChange, orderBy: orderBy, palindrome: palindrome, percentile: percentile, pick: pick, pipeFunctions: pipeFunctions, powerset: powerset, primes: primes, promisify: promisify, pull: pull, pullAtIndex: pullAtIndex, pullAtValue: pullAtValue, quickSort: quickSort, randomHexColorCode: randomHexColorCode, randomIntegerInRange: randomIntegerInRange, randomNumberInRange: randomNumberInRange, readFileLines: readFileLines, redirect: redirect, remove: remove, repeatString: repeatString, reverseString: reverseString, RGBToHex: RGBToHex, round: round, runPromisesInSeries: runPromisesInSeries, sample: sample, scrollToTop: scrollToTop, sdbm: sdbm, select: select, setStyle: setStyle, shallowClone: shallowClone, show: show, shuffle: shuffle, similarity: similarity, sleep: sleep, sortCharactersInString: sortCharactersInString, speechSynthesis: speechSynthesis, splitLines: splitLines, spreadOver: spreadOver, standardDeviation: standardDeviation, sum: sum, symmetricDifference: symmetricDifference, tail: tail, take: take, takeRight: takeRight, timeTaken: timeTaken, toCamelCase: toCamelCase, toDecimalMark: toDecimalMark, toEnglishDate: toEnglishDate, toggleClass: toggleClass, toKebabCase: toKebabCase, tomorrow: tomorrow, toOrdinalSuffix: toOrdinalSuffix, toSnakeCase: toSnakeCase, truncateString: truncateString, truthCheckCollection: truthCheckCollection, unescapeHTML: unescapeHTML, union: union, UUIDGeneratorBrowser: UUIDGeneratorBrowser, UUIDGeneratorNode: UUIDGeneratorNode, validateNumber: validateNumber, without: without, words: words, zip: zip, zipObject: zipObject }; + +return imports; + +}))); diff --git a/dist/_30s.es5.min.js b/dist/_30s.es5.min.js new file mode 100644 index 000000000..e5913f715 --- /dev/null +++ b/dist/_30s.es5.min.js @@ -0,0 +1 @@ +(function(a,b){'object'==typeof exports&&'undefined'!=typeof module?module.exports=b():'function'==typeof define&&define.amd?define(b):a._30s=b()})(this,function(){'use strict';function a(a){return Array.isArray(a)?a:Array.from(a)}function b(a){if(Array.isArray(a)){for(var b=0,c=Array(a.length);b=b.length?2===b.length?[b,b[1]+b[0]]:[b]:b.split('').reduce(function(c,d,e){return c.concat(a(b.slice(0,e)+b.slice(e+1)).map(function(a){return d+a}))},[])},arrayToHtmlList:function(a,b){return a.map(function(a){return document.querySelector('#'+b).innerHTML+='
  • '+a+'
  • '})},average:function(){var a,b=(a=[]).concat.apply(a,arguments);return b.reduce(function(a,b){return a+b},0)/b.length},bottomVisible:function(){return document.documentElement.clientHeight+window.scrollY>=(document.documentElement.scrollHeight||document.documentElement.clientHeight)},byteSize:function(a){return new Blob([a]).size},call:function(a){for(var b=arguments.length,c=Array(1'"]/g,function(a){return{"&":'&',"<":'<',">":'>',"'":''','"':'"'}[a]||a})},escapeRegExp:function(a){return a.replace(/[.*+?^${}()|[\]\\]/g,'\\$&')},everyNth:function(a,b){return a.filter(function(a,c){return c%b==b-1})},extendHex:function(a){return'#'+a.slice(a.startsWith('#')?1:0).split('').map(function(a){return a+a}).join('')},factorial:function a(b){return 0>b?function(){throw new TypeError('Negative numbers are not allowed!')}():1>=b?1:b*a(b-1)},fibonacci:function(a){return Array.from({length:a}).reduce(function(a,b,c){return a.concat(1>>(b?24:16))+', '+((c&(b?16711680:65280))>>>(b?16:8))+', '+((c&(b?65280:255))>>>(b?8:0))+(b?', '+(255&c):'')+')'},hide:function(){for(var a=arguments.length,b=Array(a),c=0;cc&&(c=b),null==c?0<=a&&a=b&&ae-c&&(b='mouse',a(b),document.removeEventListener('mousemove',d)),c=e};document.addEventListener('touchstart',function(){'touch'==b||(b='touch',a(b),document.addEventListener('mousemove',d))})},orderBy:function(a,c,d){return[].concat(j(a)).sort(function(e,a){return c.reduce(function(b,c,f){if(0===b){var g=d&&'desc'===d[f]?[a[c],e[c]]:[e[c],a[c]],h=A(g,2),i=h[0],j=h[1];b=i>j?1:ie:a<=e}),c)),[e],k(a(f.filter(function(a){return c?a<=e:a>e}),c)))},randomHexColorCode:function(){var a=(0|1048575*Math.random()).toString(16);return'#'+(6===a.length?a:(0|15*Math.random()).toString(16)+a)},randomIntegerInRange:function(a,b){return r(Math.random()*(b-a+1))+a},randomNumberInRange:function(a,b){return Math.random()*(b-a)+a},readFileLines:function(a){return B.readFileSync(a).toString('UTF8').split('\n')},redirect:function(a){var b=1b?a.slice(0,3',"'":'\'',""":'"'}[a]||a})},union:function(c,a){return Array.from(new Set([].concat(p(c),p(a))))},UUIDGeneratorBrowser:function(){return'10000000-1000-4000-8000-100000000000'.replace(/[018]/g,function(a){return(a^crypto.getRandomValues(new Uint8Array(1))[0]&15>>a/4).toString(16)})},UUIDGeneratorNode:function(){return'10000000-1000-4000-8000-100000000000'.replace(/[018]/g,function(a){return(a^C.randomBytes(1)[0]&15>>a/4).toString(16)})},validateNumber:function(a){return!isNaN(parseFloat(a))&&isFinite(a)&&+a==a},without:function(a){for(var b=arguments.length,c=Array(1 { + if (str.length <= 2) return str.length === 2 ? [str, str[1] + str[0]] : [str]; + return str + .split('') + .reduce( + (acc, letter, i) => + acc.concat(anagrams(str.slice(0, i) + str.slice(i + 1)).map(val => letter + val)), + [] + ); +}; + +const arrayToHtmlList = (arr, listID) => + arr.map(item => (document.querySelector('#' + listID).innerHTML += `
  • ${item}
  • `)); + +const average = (...arr) => { + const nums = [].concat(...arr); + return nums.reduce((acc, val) => acc + val, 0) / nums.length; +}; + +const bottomVisible = () => + document.documentElement.clientHeight + window.scrollY >= + (document.documentElement.scrollHeight || document.documentElement.clientHeight); + +const byteSize = str => new Blob([str]).size; + +const call = (key, ...args) => context => context[key](...args); + +const capitalize = ([first, ...rest], lowerRest = false) => + first.toUpperCase() + (lowerRest ? rest.join('').toLowerCase() : rest.join('')); + +const capitalizeEveryWord = str => str.replace(/\b[a-z]/g, char => char.toUpperCase()); + +const chainAsync = fns => { + let curr = 0; + const next = () => fns[curr++](next); + next(); +}; + +const chunk = (arr, size) => + Array.from({ length: Math.ceil(arr.length / size) }, (v, i) => + arr.slice(i * size, i * size + size) + ); + +const clampNumber = (num, a, b) => Math.max(Math.min(num, Math.max(a, b)), Math.min(a, b)); + +const cleanObj = (obj, keysToKeep = [], childIndicator) => { + Object.keys(obj).forEach(key => { + if (key === childIndicator) { + cleanObj(obj[key], keysToKeep, childIndicator); + } else if (!keysToKeep.includes(key)) { + delete obj[key]; + } + }); + return obj; +}; + +const coalesce = (...args) => args.find(_ => ![undefined, null].includes(_)); + +const coalesceFactory = valid => (...args) => args.find(valid); + +const collatz = n => (n % 2 == 0 ? n / 2 : 3 * n + 1); + +const collectInto = fn => (...args) => fn(args); + +const compact = arr => arr.filter(Boolean); + +const compose = (...fns) => fns.reduce((f, g) => (...args) => f(g(...args))); + +const countOccurrences = (arr, value) => arr.reduce((a, v) => (v === value ? a + 1 : a + 0), 0); + +const countVowels = str => (str.match(/[aeiou]/gi) || []).length; + +const currentURL = () => window.location.href; + +const curry = (fn, arity = fn.length, ...args) => + arity <= args.length ? fn(...args) : curry.bind(null, fn, arity, ...args); + +const deepFlatten = arr => [].concat(...arr.map(v => (Array.isArray(v) ? deepFlatten(v) : v))); + +const detectDeviceType = () => + /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) + ? 'Mobile' + : 'Desktop'; + +const difference = (a, b) => { + const s = new Set(b); + return a.filter(x => !s.has(x)); +}; + +const differenceWith = (arr, val, comp) => arr.filter(a => !val.find(b => comp(a, b))); + +const digitize = n => [...('' + n)].map(i => parseInt(i)); + +const distance = (x0, y0, x1, y1) => Math.hypot(x1 - x0, y1 - y0); + +const distinctValuesOfArray = arr => [...new Set(arr)]; + +const dropElements = (arr, func) => { + while (arr.length > 0 && !func(arr[0])) arr = arr.slice(1); + return arr; +}; + +const dropRight = (arr, n = 1) => arr.slice(0, -n); + +const elementIsVisibleInViewport = (el, partiallyVisible = false) => { + const { top, left, bottom, right } = el.getBoundingClientRect(); + const { innerHeight, innerWidth } = window; + return partiallyVisible + ? ((top > 0 && top < innerHeight) || (bottom > 0 && bottom < innerHeight)) && + ((left > 0 && left < innerWidth) || (right > 0 && right < innerWidth)) + : top >= 0 && left >= 0 && bottom <= innerHeight && right <= innerWidth; +}; + +const escapeHTML = str => + str.replace( + /[&<>'"]/g, + tag => + ({ + '&': '&', + '<': '<', + '>': '>', + "'": ''', + '"': '"' + }[tag] || tag) + ); + +const escapeRegExp = str => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + +const everyNth = (arr, nth) => arr.filter((e, i) => i % nth === nth - 1); + +const extendHex = shortHex => + '#' + + shortHex + .slice(shortHex.startsWith('#') ? 1 : 0) + .split('') + .map(x => x + x) + .join(''); + +const factorial = n => + n < 0 + ? (() => { + throw new TypeError('Negative numbers are not allowed!'); + })() + : n <= 1 ? 1 : n * factorial(n - 1); + +const fibonacci = n => + Array.from({ length: n }).reduce( + (acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i), + [] + ); + +const fibonacciCountUntilNum = num => + Math.ceil(Math.log(num * Math.sqrt(5) + 1 / 2) / Math.log((Math.sqrt(5) + 1) / 2)); + +const fibonacciUntilNum = num => { + let n = Math.ceil(Math.log(num * Math.sqrt(5) + 1 / 2) / Math.log((Math.sqrt(5) + 1) / 2)); + return Array.from({ length: n }).reduce( + (acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i), + [] + ); +}; + +const filterNonUnique = arr => arr.filter(i => arr.indexOf(i) === arr.lastIndexOf(i)); + +const flatten = arr => [].concat(...arr); + +const flattenDepth = (arr, depth = 1) => + depth != 1 + ? arr.reduce((a, v) => a.concat(Array.isArray(v) ? flattenDepth(v, depth - 1) : v), []) + : arr.reduce((a, v) => a.concat(v), []); + +const flip = fn => (...args) => fn(args.pop(), ...args); + +const fromCamelCase = (str, separator = '_') => + str + .replace(/([a-z\d])([A-Z])/g, '$1' + separator + '$2') + .replace(/([A-Z]+)([A-Z][a-z\d]+)/g, '$1' + separator + '$2') + .toLowerCase(); + +const functionName = fn => (console.debug(fn.name), fn); + +const gcd = (...arr) => { + let data = [].concat(...arr); + const helperGcd = (x, y) => (!y ? x : gcd(y, x % y)); + return data.reduce((a, b) => helperGcd(a, b)); +}; + +const getDaysDiffBetweenDates = (dateInitial, dateFinal) => + (dateFinal - dateInitial) / (1000 * 3600 * 24); + +const getScrollPosition = (el = window) => ({ + x: el.pageXOffset !== undefined ? el.pageXOffset : el.scrollLeft, + y: el.pageYOffset !== undefined ? el.pageYOffset : el.scrollTop +}); + +const getStyle = (el, ruleName) => getComputedStyle(el)[ruleName]; + +const getType = v => + v === undefined ? 'undefined' : v === null ? 'null' : v.constructor.name.toLowerCase(); + +const getURLParameters = url => + url + .match(/([^?=&]+)(=([^&]*))/g) + .reduce((a, v) => (a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1), a), {}); + +const groupBy = (arr, func) => + arr.map(typeof func === 'function' ? func : val => val[func]).reduce((acc, val, i) => { + acc[val] = (acc[val] || []).concat(arr[i]); + return acc; + }, {}); + +const hammingDistance = (num1, num2) => ((num1 ^ num2).toString(2).match(/1/g) || '').length; + +const hasClass = (el, className) => el.classList.contains(className); + +const head = arr => arr[0]; + +const hexToRGB = hex => { + let alpha = false, + h = hex.slice(hex.startsWith('#') ? 1 : 0); + if (h.length === 3) h = [...h].map(x => x + x).join(''); + else if (h.length === 8) alpha = true; + h = parseInt(h, 16); + return ( + 'rgb' + + (alpha ? 'a' : '') + + '(' + + (h >>> (alpha ? 24 : 16)) + + ', ' + + ((h & (alpha ? 0x00ff0000 : 0x00ff00)) >>> (alpha ? 16 : 8)) + + ', ' + + ((h & (alpha ? 0x0000ff00 : 0x0000ff)) >>> (alpha ? 8 : 0)) + + (alpha ? `, ${h & 0x000000ff}` : '') + + ')' + ); +}; + +const hide = (...el) => [...el].forEach(e => (e.style.display = 'none')); + +const httpsRedirect = () => { + if (location.protocol !== 'https:') location.replace('https://' + location.href.split('//')[1]); +}; + +const initial = arr => arr.slice(0, -1); + +const initialize2DArray = (w, h, val = null) => + Array(h) + .fill() + .map(() => Array(w).fill(val)); + +const initializeArrayWithRange = (end, start = 0) => + Array.from({ length: end + 1 - start }).map((v, i) => i + start); + +const initializeArrayWithValues = (n, value = 0) => Array(n).fill(value); + +const inRange = (n, start, end = null) => { + if (end && start > end) end = [start, (start = end)][0]; + return end == null ? n >= 0 && n < start : n >= start && n < end; +}; + +const intersection = (a, b) => { + const s = new Set(b); + return a.filter(x => s.has(x)); +}; + +const isArmstrongNumber = digits => + (arr => arr.reduce((a, d) => a + Math.pow(parseInt(d), arr.length), 0) == digits)( + (digits + '').split('') + ); + +const isArray = val => !!val && Array.isArray(val); + +const isBoolean = val => typeof val === 'boolean'; + +const isDivisible = (dividend, divisor) => dividend % divisor === 0; + +const isEven = num => num % 2 === 0; + +const isFunction = val => val && typeof val === 'function'; + +const isNumber = val => typeof val === 'number'; + +const isPrime = num => { + const boundary = Math.floor(Math.sqrt(num)); + for (var i = 2; i * i <= boundary; i++) if (num % i == 0) return false; + return num >= 2; +}; + +const isString = val => typeof val === 'string'; + +const isSymbol = val => typeof val === 'symbol'; + +const JSONToDate = arr => { + const dt = new Date(parseInt(arr.toString().substr(6))); + return `${dt.getDate()}/${dt.getMonth() + 1}/${dt.getFullYear()}`; +}; + +const fs = typeof require !== "undefined" && require('fs'); +const JSONToFile = (obj, filename) => + fs.writeFile(`${filename}.json`, JSON.stringify(obj, null, 2)); + +const last = arr => arr[arr.length - 1]; + +const lcm = (...arr) => { + const gcd = (x, y) => (!y ? x : gcd(y, x % y)); + const _lcm = (x, y) => x * y / gcd(x, y); + return [].concat(...arr).reduce((a, b) => _lcm(a, b)); +}; + +const lowercaseKeys = obj => + Object.keys(obj).reduce((acc, key) => { + acc[key.toLowerCase()] = obj[key]; + return acc; + }, {}); + +const mapObject = (arr, fn) => + (a => ( + a = [arr, arr.map(fn)], a[0].reduce((acc, val, ind) => (acc[val] = a[1][ind], acc), {})))(); + +const max = (...arr) => Math.max(...[].concat(...arr)); + +const median = arr => { + const mid = Math.floor(arr.length / 2), + nums = [...arr].sort((a, b) => a - b); + return arr.length % 2 !== 0 ? nums[mid] : (nums[mid - 1] + nums[mid]) / 2; +}; + +const min = arr => Math.min(...[].concat(...arr)); + +const negate = func => (...args) => !func(...args); + +const nthElement = (arr, n = 0) => (n > 0 ? arr.slice(n, n + 1) : arr.slice(n))[0]; + +const objectFromPairs = arr => arr.reduce((a, v) => (a[v[0]] = v[1], a), {}); + +const objectToPairs = obj => Object.keys(obj).map(k => [k, obj[k]]); + +const onUserInputChange = callback => { + let type = 'mouse', + lastTime = 0; + const mousemoveHandler = () => { + const now = performance.now(); + if (now - lastTime < 20) + type = 'mouse', callback(type), document.removeEventListener('mousemove', mousemoveHandler); + lastTime = now; + }; + document.addEventListener('touchstart', () => { + if (type === 'touch') return; + type = 'touch', callback(type), document.addEventListener('mousemove', mousemoveHandler); + }); +}; + +const orderBy = (arr, props, orders) => + [...arr].sort((a, b) => + props.reduce((acc, prop, i) => { + if (acc === 0) { + const [p1, p2] = orders && orders[i] === 'desc' ? [b[prop], a[prop]] : [a[prop], b[prop]]; + acc = p1 > p2 ? 1 : p1 < p2 ? -1 : 0; + } + return acc; + }, 0) + ); + +const palindrome = str => { + const s = str.toLowerCase().replace(/[\W_]/g, ''); + return ( + s === + s + .split('') + .reverse() + .join('') + ); +}; + +const percentile = (arr, val) => + 100 * arr.reduce((acc, v) => acc + (v < val ? 1 : 0) + (v === val ? 0.5 : 0), 0) / arr.length; + +const pick = (obj, arr) => + arr.reduce((acc, curr) => (curr in obj && (acc[curr] = obj[curr]), acc), {}); + +const pipeFunctions = (...fns) => fns.reduce((f, g) => (...args) => g(f(...args))); + +const powerset = arr => arr.reduce((a, v) => a.concat(a.map(r => [v].concat(r))), [[]]); + +const primes = num => { + let arr = Array.from({ length: num - 1 }).map((x, i) => i + 2), + sqroot = Math.floor(Math.sqrt(num)), + numsTillSqroot = Array.from({ length: sqroot - 1 }).map((x, i) => i + 2); + numsTillSqroot.forEach(x => (arr = arr.filter(y => y % x !== 0 || y == x))); + return arr; +}; + +const promisify = func => (...args) => + new Promise((resolve, reject) => + func(...args, (err, result) => (err ? reject(err) : resolve(result))) + ); + +const pull = (arr, ...args) => { + let argState = Array.isArray(args[0]) ? args[0] : args; + let pulled = arr.filter((v, i) => !argState.includes(v)); + arr.length = 0; + pulled.forEach(v => arr.push(v)); +}; + +const pullAtIndex = (arr, pullArr) => { + let removed = []; + let pulled = arr + .map((v, i) => (pullArr.includes(i) ? removed.push(v) : v)) + .filter((v, i) => !pullArr.includes(i)); + arr.length = 0; + pulled.forEach(v => arr.push(v)); + return removed; +}; + +const pullAtValue = (arr, pullArr) => { + let removed = [], + pushToRemove = arr.forEach((v, i) => (pullArr.includes(v) ? removed.push(v) : v)), + mutateTo = arr.filter((v, i) => !pullArr.includes(v)); + arr.length = 0; + mutateTo.forEach(v => arr.push(v)); + return removed; +}; + +const quickSort = ([n, ...nums], desc) => + isNaN(n) + ? [] + : [ + ...quickSort(nums.filter(v => (desc ? v > n : v <= n)), desc), + n, + ...quickSort(nums.filter(v => (!desc ? v > n : v <= n)), desc) + ]; + +const randomHexColorCode = () => { + let n = ((Math.random() * 0xfffff) | 0).toString(16); + return '#' + (n.length !== 6 ? ((Math.random() * 0xf) | 0).toString(16) + n : n); +}; + +const randomIntegerInRange = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min; + +const randomNumberInRange = (min, max) => Math.random() * (max - min) + min; + +const fs$1 = typeof require !== "undefined" && require('fs'); +const readFileLines = filename => + fs$1 + .readFileSync(filename) + .toString('UTF8') + .split('\n'); + +const redirect = (url, asLink = true) => + asLink ? (window.location.href = url) : window.location.replace(url); + +const remove = (arr, func) => + Array.isArray(arr) + ? arr.filter(func).reduce((acc, val) => { + arr.splice(arr.indexOf(val), 1); + return acc.concat(val); + }, []) + : []; + +const repeatString = (str = '', num = 2) => { + return num >= 0 ? str.repeat(num) : str; +}; + +const reverseString = str => + str + .split('') + .reverse() + .join(''); + +const RGBToHex = (r, g, b) => ((r << 16) + (g << 8) + b).toString(16).padStart(6, '0'); + +const round = (n, decimals = 0) => Number(`${Math.round(`${n}e${decimals}`)}e-${decimals}`); + +const runPromisesInSeries = ps => ps.reduce((p, next) => p.then(next), Promise.resolve()); + +const sample = arr => arr[Math.floor(Math.random() * arr.length)]; + +const scrollToTop = () => { + const c = document.documentElement.scrollTop || document.body.scrollTop; + if (c > 0) { + window.requestAnimationFrame(scrollToTop); + window.scrollTo(0, c - c / 8); + } +}; + +const sdbm = str => { + let arr = str.split(''); + return arr.reduce( + (hashCode, currentVal) => + (hashCode = currentVal.charCodeAt(0) + (hashCode << 6) + (hashCode << 16) - hashCode), + 0 + ); +}; + +const select = (from, selector) => + selector.split('.').reduce((prev, cur) => prev && prev[cur], from); + +const setStyle = (el, ruleName, value) => (el.style[ruleName] = value); + +const shallowClone = obj => Object.assign({}, obj); + +const show = (...el) => [...el].forEach(e => (e.style.display = '')); + +const shuffle = ([...arr]) => { + let m = arr.length; + while (m) { + const i = Math.floor(Math.random() * m--); + [arr[m], arr[i]] = [arr[i], arr[m]]; + } + return arr; +}; + +const similarity = (arr, values) => arr.filter(v => values.includes(v)); + +const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); + +const sortCharactersInString = str => + str + .split('') + .sort((a, b) => a.localeCompare(b)) + .join(''); + +const speechSynthesis = message => { + const msg = new SpeechSynthesisUtterance(message); + msg.voice = window.speechSynthesis.getVoices()[0]; + window.speechSynthesis.speak(msg); +}; + +const splitLines = str => str.split(/\r?\n/); + +const spreadOver = fn => argsArr => fn(...argsArr); + +const standardDeviation = (arr, usePopulation = false) => { + const mean = arr.reduce((acc, val) => acc + val, 0) / arr.length; + return Math.sqrt( + arr + .reduce((acc, val) => acc.concat(Math.pow(val - mean, 2)), []) + .reduce((acc, val) => acc + val, 0) / + (arr.length - (usePopulation ? 0 : 1)) + ); +}; + +const sum = (...arr) => [].concat(...arr).reduce((acc, val) => acc + val, 0); + +const symmetricDifference = (a, b) => { + const sA = new Set(a), + sB = new Set(b); + return [...a.filter(x => !sB.has(x)), ...b.filter(x => !sA.has(x))]; +}; + +const tail = arr => (arr.length > 1 ? arr.slice(1) : arr); + +const take = (arr, n = 1) => arr.slice(0, n); + +const takeRight = (arr, n = 1) => arr.slice(arr.length - n, arr.length); + +const timeTaken = callback => { + console.time('timeTaken'); + const r = callback(); + console.timeEnd('timeTaken'); + return r; +}; + +const toCamelCase = str => { + let s = + str && + str + .match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g) + .map(x => x.slice(0, 1).toUpperCase() + x.slice(1).toLowerCase()) + .join(''); + return s.slice(0, 1).toLowerCase() + s.slice(1); +}; + +const toDecimalMark = num => num.toLocaleString('en-US'); + +const toEnglishDate = time => { + try { + return new Date(time) + .toISOString() + .split('T')[0] + .replace(/-/g, '/'); + } catch (e) {} +}; + +const toggleClass = (el, className) => el.classList.toggle(className); + +const toKebabCase = str => + str && + str + .match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g) + .map(x => x.toLowerCase()) + .join('-'); + +const tomorrow = () => new Date(new Date().getTime() + 86400000).toISOString().split('T')[0]; + +const toOrdinalSuffix = num => { + const int = parseInt(num), + digits = [int % 10, int % 100], + ordinals = ['st', 'nd', 'rd', 'th'], + oPattern = [1, 2, 3, 4], + tPattern = [11, 12, 13, 14, 15, 16, 17, 18, 19]; + return oPattern.includes(digits[0]) && !tPattern.includes(digits[1]) + ? int + ordinals[digits[0] - 1] + : int + ordinals[3]; +}; + +const toSnakeCase = str => { + str && + str + .match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g) + .map(x => x.toLowerCase()) + .join('_'); +}; + +const truncateString = (str, num) => + str.length > num ? str.slice(0, num > 3 ? num - 3 : num) + '...' : str; + +const truthCheckCollection = (collection, pre) => collection.every(obj => obj[pre]); + +const unescapeHTML = str => + str.replace( + /&|<|>|'|"/g, + tag => + ({ + '&': '&', + '<': '<', + '>': '>', + ''': "'", + '"': '"' + }[tag] || tag) + ); + +const union = (a, b) => Array.from(new Set([...a, ...b])); + +const UUIDGeneratorBrowser = () => + ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c => + (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16) + ); + +const crypto$1 = typeof require !== "undefined" && require('crypto'); +const UUIDGeneratorNode = () => + ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c => + (c ^ (crypto$1.randomBytes(1)[0] & (15 >> (c / 4)))).toString(16) + ); + +const validateNumber = n => !isNaN(parseFloat(n)) && isFinite(n) && Number(n) == n; + +const without = (arr, ...args) => arr.filter(v => !args.includes(v)); + +const words = (str, pattern = /[^a-zA-Z-]+/) => str.split(pattern).filter(Boolean); + +const zip = (...arrays) => { + const maxLength = Math.max(...arrays.map(x => x.length)); + return Array.from({ length: maxLength }).map((_, i) => { + return Array.from({ length: arrays.length }, (_, k) => arrays[k][i]); + }); +}; + +const zipObject = (props, values) => + props.reduce((obj, prop, index) => (obj[prop] = values[index], obj), {}); + +var imports = {anagrams,arrayToHtmlList,average,bottomVisible,byteSize,call,capitalize,capitalizeEveryWord,chainAsync,chunk,clampNumber,cleanObj,coalesce,coalesceFactory,collatz,collectInto,compact,compose,countOccurrences,countVowels,currentURL,curry,deepFlatten,detectDeviceType,difference,differenceWith,digitize,distance,distinctValuesOfArray,dropElements,dropRight,elementIsVisibleInViewport,escapeHTML,escapeRegExp,everyNth,extendHex,factorial,fibonacci,fibonacciCountUntilNum,fibonacciUntilNum,filterNonUnique,flatten,flattenDepth,flip,fromCamelCase,functionName,gcd,getDaysDiffBetweenDates,getScrollPosition,getStyle,getType,getURLParameters,groupBy,hammingDistance,hasClass,head,hexToRGB,hide,httpsRedirect,initial,initialize2DArray,initializeArrayWithRange,initializeArrayWithValues,inRange,intersection,isArmstrongNumber,isArray,isBoolean,isDivisible,isEven,isFunction,isNumber,isPrime,isString,isSymbol,JSONToDate,JSONToFile,last,lcm,lowercaseKeys,mapObject,max,median,min,negate,nthElement,objectFromPairs,objectToPairs,onUserInputChange,orderBy,palindrome,percentile,pick,pipeFunctions,powerset,primes,promisify,pull,pullAtIndex,pullAtValue,quickSort,randomHexColorCode,randomIntegerInRange,randomNumberInRange,readFileLines,redirect,remove,repeatString,reverseString,RGBToHex,round,runPromisesInSeries,sample,scrollToTop,sdbm,select,setStyle,shallowClone,show,shuffle,similarity,sleep,sortCharactersInString,speechSynthesis,splitLines,spreadOver,standardDeviation,sum,symmetricDifference,tail,take,takeRight,timeTaken,toCamelCase,toDecimalMark,toEnglishDate,toggleClass,toKebabCase,tomorrow,toOrdinalSuffix,toSnakeCase,truncateString,truthCheckCollection,unescapeHTML,union,UUIDGeneratorBrowser,UUIDGeneratorNode,validateNumber,without,words,zip,zipObject,} + +export default imports; diff --git a/dist/_30s.js b/dist/_30s.js new file mode 100644 index 000000000..a5f06c222 --- /dev/null +++ b/dist/_30s.js @@ -0,0 +1,672 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global._30s = factory()); +}(this, (function () { 'use strict'; + +const anagrams = str => { + if (str.length <= 2) return str.length === 2 ? [str, str[1] + str[0]] : [str]; + return str + .split('') + .reduce( + (acc, letter, i) => + acc.concat(anagrams(str.slice(0, i) + str.slice(i + 1)).map(val => letter + val)), + [] + ); +}; + +const arrayToHtmlList = (arr, listID) => + arr.map(item => (document.querySelector('#' + listID).innerHTML += `
  • ${item}
  • `)); + +const average = (...arr) => { + const nums = [].concat(...arr); + return nums.reduce((acc, val) => acc + val, 0) / nums.length; +}; + +const bottomVisible = () => + document.documentElement.clientHeight + window.scrollY >= + (document.documentElement.scrollHeight || document.documentElement.clientHeight); + +const byteSize = str => new Blob([str]).size; + +const call = (key, ...args) => context => context[key](...args); + +const capitalize = ([first, ...rest], lowerRest = false) => + first.toUpperCase() + (lowerRest ? rest.join('').toLowerCase() : rest.join('')); + +const capitalizeEveryWord = str => str.replace(/\b[a-z]/g, char => char.toUpperCase()); + +const chainAsync = fns => { + let curr = 0; + const next = () => fns[curr++](next); + next(); +}; + +const chunk = (arr, size) => + Array.from({ length: Math.ceil(arr.length / size) }, (v, i) => + arr.slice(i * size, i * size + size) + ); + +const clampNumber = (num, a, b) => Math.max(Math.min(num, Math.max(a, b)), Math.min(a, b)); + +const cleanObj = (obj, keysToKeep = [], childIndicator) => { + Object.keys(obj).forEach(key => { + if (key === childIndicator) { + cleanObj(obj[key], keysToKeep, childIndicator); + } else if (!keysToKeep.includes(key)) { + delete obj[key]; + } + }); + return obj; +}; + +const coalesce = (...args) => args.find(_ => ![undefined, null].includes(_)); + +const coalesceFactory = valid => (...args) => args.find(valid); + +const collatz = n => (n % 2 == 0 ? n / 2 : 3 * n + 1); + +const collectInto = fn => (...args) => fn(args); + +const compact = arr => arr.filter(Boolean); + +const compose = (...fns) => fns.reduce((f, g) => (...args) => f(g(...args))); + +const countOccurrences = (arr, value) => arr.reduce((a, v) => (v === value ? a + 1 : a + 0), 0); + +const countVowels = str => (str.match(/[aeiou]/gi) || []).length; + +const currentURL = () => window.location.href; + +const curry = (fn, arity = fn.length, ...args) => + arity <= args.length ? fn(...args) : curry.bind(null, fn, arity, ...args); + +const deepFlatten = arr => [].concat(...arr.map(v => (Array.isArray(v) ? deepFlatten(v) : v))); + +const detectDeviceType = () => + /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) + ? 'Mobile' + : 'Desktop'; + +const difference = (a, b) => { + const s = new Set(b); + return a.filter(x => !s.has(x)); +}; + +const differenceWith = (arr, val, comp) => arr.filter(a => !val.find(b => comp(a, b))); + +const digitize = n => [...('' + n)].map(i => parseInt(i)); + +const distance = (x0, y0, x1, y1) => Math.hypot(x1 - x0, y1 - y0); + +const distinctValuesOfArray = arr => [...new Set(arr)]; + +const dropElements = (arr, func) => { + while (arr.length > 0 && !func(arr[0])) arr = arr.slice(1); + return arr; +}; + +const dropRight = (arr, n = 1) => arr.slice(0, -n); + +const elementIsVisibleInViewport = (el, partiallyVisible = false) => { + const { top, left, bottom, right } = el.getBoundingClientRect(); + const { innerHeight, innerWidth } = window; + return partiallyVisible + ? ((top > 0 && top < innerHeight) || (bottom > 0 && bottom < innerHeight)) && + ((left > 0 && left < innerWidth) || (right > 0 && right < innerWidth)) + : top >= 0 && left >= 0 && bottom <= innerHeight && right <= innerWidth; +}; + +const escapeHTML = str => + str.replace( + /[&<>'"]/g, + tag => + ({ + '&': '&', + '<': '<', + '>': '>', + "'": ''', + '"': '"' + }[tag] || tag) + ); + +const escapeRegExp = str => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + +const everyNth = (arr, nth) => arr.filter((e, i) => i % nth === nth - 1); + +const extendHex = shortHex => + '#' + + shortHex + .slice(shortHex.startsWith('#') ? 1 : 0) + .split('') + .map(x => x + x) + .join(''); + +const factorial = n => + n < 0 + ? (() => { + throw new TypeError('Negative numbers are not allowed!'); + })() + : n <= 1 ? 1 : n * factorial(n - 1); + +const fibonacci = n => + Array.from({ length: n }).reduce( + (acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i), + [] + ); + +const fibonacciCountUntilNum = num => + Math.ceil(Math.log(num * Math.sqrt(5) + 1 / 2) / Math.log((Math.sqrt(5) + 1) / 2)); + +const fibonacciUntilNum = num => { + let n = Math.ceil(Math.log(num * Math.sqrt(5) + 1 / 2) / Math.log((Math.sqrt(5) + 1) / 2)); + return Array.from({ length: n }).reduce( + (acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i), + [] + ); +}; + +const filterNonUnique = arr => arr.filter(i => arr.indexOf(i) === arr.lastIndexOf(i)); + +const flatten = arr => [].concat(...arr); + +const flattenDepth = (arr, depth = 1) => + depth != 1 + ? arr.reduce((a, v) => a.concat(Array.isArray(v) ? flattenDepth(v, depth - 1) : v), []) + : arr.reduce((a, v) => a.concat(v), []); + +const flip = fn => (...args) => fn(args.pop(), ...args); + +const fromCamelCase = (str, separator = '_') => + str + .replace(/([a-z\d])([A-Z])/g, '$1' + separator + '$2') + .replace(/([A-Z]+)([A-Z][a-z\d]+)/g, '$1' + separator + '$2') + .toLowerCase(); + +const functionName = fn => (console.debug(fn.name), fn); + +const gcd = (...arr) => { + let data = [].concat(...arr); + const helperGcd = (x, y) => (!y ? x : gcd(y, x % y)); + return data.reduce((a, b) => helperGcd(a, b)); +}; + +const getDaysDiffBetweenDates = (dateInitial, dateFinal) => + (dateFinal - dateInitial) / (1000 * 3600 * 24); + +const getScrollPosition = (el = window) => ({ + x: el.pageXOffset !== undefined ? el.pageXOffset : el.scrollLeft, + y: el.pageYOffset !== undefined ? el.pageYOffset : el.scrollTop +}); + +const getStyle = (el, ruleName) => getComputedStyle(el)[ruleName]; + +const getType = v => + v === undefined ? 'undefined' : v === null ? 'null' : v.constructor.name.toLowerCase(); + +const getURLParameters = url => + url + .match(/([^?=&]+)(=([^&]*))/g) + .reduce((a, v) => (a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1), a), {}); + +const groupBy = (arr, func) => + arr.map(typeof func === 'function' ? func : val => val[func]).reduce((acc, val, i) => { + acc[val] = (acc[val] || []).concat(arr[i]); + return acc; + }, {}); + +const hammingDistance = (num1, num2) => ((num1 ^ num2).toString(2).match(/1/g) || '').length; + +const hasClass = (el, className) => el.classList.contains(className); + +const head = arr => arr[0]; + +const hexToRGB = hex => { + let alpha = false, + h = hex.slice(hex.startsWith('#') ? 1 : 0); + if (h.length === 3) h = [...h].map(x => x + x).join(''); + else if (h.length === 8) alpha = true; + h = parseInt(h, 16); + return ( + 'rgb' + + (alpha ? 'a' : '') + + '(' + + (h >>> (alpha ? 24 : 16)) + + ', ' + + ((h & (alpha ? 0x00ff0000 : 0x00ff00)) >>> (alpha ? 16 : 8)) + + ', ' + + ((h & (alpha ? 0x0000ff00 : 0x0000ff)) >>> (alpha ? 8 : 0)) + + (alpha ? `, ${h & 0x000000ff}` : '') + + ')' + ); +}; + +const hide = (...el) => [...el].forEach(e => (e.style.display = 'none')); + +const httpsRedirect = () => { + if (location.protocol !== 'https:') location.replace('https://' + location.href.split('//')[1]); +}; + +const initial = arr => arr.slice(0, -1); + +const initialize2DArray = (w, h, val = null) => + Array(h) + .fill() + .map(() => Array(w).fill(val)); + +const initializeArrayWithRange = (end, start = 0) => + Array.from({ length: end + 1 - start }).map((v, i) => i + start); + +const initializeArrayWithValues = (n, value = 0) => Array(n).fill(value); + +const inRange = (n, start, end = null) => { + if (end && start > end) end = [start, (start = end)][0]; + return end == null ? n >= 0 && n < start : n >= start && n < end; +}; + +const intersection = (a, b) => { + const s = new Set(b); + return a.filter(x => s.has(x)); +}; + +const isArmstrongNumber = digits => + (arr => arr.reduce((a, d) => a + Math.pow(parseInt(d), arr.length), 0) == digits)( + (digits + '').split('') + ); + +const isArray = val => !!val && Array.isArray(val); + +const isBoolean = val => typeof val === 'boolean'; + +const isDivisible = (dividend, divisor) => dividend % divisor === 0; + +const isEven = num => num % 2 === 0; + +const isFunction = val => val && typeof val === 'function'; + +const isNumber = val => typeof val === 'number'; + +const isPrime = num => { + const boundary = Math.floor(Math.sqrt(num)); + for (var i = 2; i * i <= boundary; i++) if (num % i == 0) return false; + return num >= 2; +}; + +const isString = val => typeof val === 'string'; + +const isSymbol = val => typeof val === 'symbol'; + +const JSONToDate = arr => { + const dt = new Date(parseInt(arr.toString().substr(6))); + return `${dt.getDate()}/${dt.getMonth() + 1}/${dt.getFullYear()}`; +}; + +const fs = typeof require !== "undefined" && require('fs'); +const JSONToFile = (obj, filename) => + fs.writeFile(`${filename}.json`, JSON.stringify(obj, null, 2)); + +const last = arr => arr[arr.length - 1]; + +const lcm = (...arr) => { + const gcd = (x, y) => (!y ? x : gcd(y, x % y)); + const _lcm = (x, y) => x * y / gcd(x, y); + return [].concat(...arr).reduce((a, b) => _lcm(a, b)); +}; + +const lowercaseKeys = obj => + Object.keys(obj).reduce((acc, key) => { + acc[key.toLowerCase()] = obj[key]; + return acc; + }, {}); + +const mapObject = (arr, fn) => + (a => ( + a = [arr, arr.map(fn)], a[0].reduce((acc, val, ind) => (acc[val] = a[1][ind], acc), {})))(); + +const max = (...arr) => Math.max(...[].concat(...arr)); + +const median = arr => { + const mid = Math.floor(arr.length / 2), + nums = [...arr].sort((a, b) => a - b); + return arr.length % 2 !== 0 ? nums[mid] : (nums[mid - 1] + nums[mid]) / 2; +}; + +const min = arr => Math.min(...[].concat(...arr)); + +const negate = func => (...args) => !func(...args); + +const nthElement = (arr, n = 0) => (n > 0 ? arr.slice(n, n + 1) : arr.slice(n))[0]; + +const objectFromPairs = arr => arr.reduce((a, v) => (a[v[0]] = v[1], a), {}); + +const objectToPairs = obj => Object.keys(obj).map(k => [k, obj[k]]); + +const onUserInputChange = callback => { + let type = 'mouse', + lastTime = 0; + const mousemoveHandler = () => { + const now = performance.now(); + if (now - lastTime < 20) + type = 'mouse', callback(type), document.removeEventListener('mousemove', mousemoveHandler); + lastTime = now; + }; + document.addEventListener('touchstart', () => { + if (type === 'touch') return; + type = 'touch', callback(type), document.addEventListener('mousemove', mousemoveHandler); + }); +}; + +const orderBy = (arr, props, orders) => + [...arr].sort((a, b) => + props.reduce((acc, prop, i) => { + if (acc === 0) { + const [p1, p2] = orders && orders[i] === 'desc' ? [b[prop], a[prop]] : [a[prop], b[prop]]; + acc = p1 > p2 ? 1 : p1 < p2 ? -1 : 0; + } + return acc; + }, 0) + ); + +const palindrome = str => { + const s = str.toLowerCase().replace(/[\W_]/g, ''); + return ( + s === + s + .split('') + .reverse() + .join('') + ); +}; + +const percentile = (arr, val) => + 100 * arr.reduce((acc, v) => acc + (v < val ? 1 : 0) + (v === val ? 0.5 : 0), 0) / arr.length; + +const pick = (obj, arr) => + arr.reduce((acc, curr) => (curr in obj && (acc[curr] = obj[curr]), acc), {}); + +const pipeFunctions = (...fns) => fns.reduce((f, g) => (...args) => g(f(...args))); + +const powerset = arr => arr.reduce((a, v) => a.concat(a.map(r => [v].concat(r))), [[]]); + +const primes = num => { + let arr = Array.from({ length: num - 1 }).map((x, i) => i + 2), + sqroot = Math.floor(Math.sqrt(num)), + numsTillSqroot = Array.from({ length: sqroot - 1 }).map((x, i) => i + 2); + numsTillSqroot.forEach(x => (arr = arr.filter(y => y % x !== 0 || y == x))); + return arr; +}; + +const promisify = func => (...args) => + new Promise((resolve, reject) => + func(...args, (err, result) => (err ? reject(err) : resolve(result))) + ); + +const pull = (arr, ...args) => { + let argState = Array.isArray(args[0]) ? args[0] : args; + let pulled = arr.filter((v, i) => !argState.includes(v)); + arr.length = 0; + pulled.forEach(v => arr.push(v)); +}; + +const pullAtIndex = (arr, pullArr) => { + let removed = []; + let pulled = arr + .map((v, i) => (pullArr.includes(i) ? removed.push(v) : v)) + .filter((v, i) => !pullArr.includes(i)); + arr.length = 0; + pulled.forEach(v => arr.push(v)); + return removed; +}; + +const pullAtValue = (arr, pullArr) => { + let removed = [], + pushToRemove = arr.forEach((v, i) => (pullArr.includes(v) ? removed.push(v) : v)), + mutateTo = arr.filter((v, i) => !pullArr.includes(v)); + arr.length = 0; + mutateTo.forEach(v => arr.push(v)); + return removed; +}; + +const quickSort = ([n, ...nums], desc) => + isNaN(n) + ? [] + : [ + ...quickSort(nums.filter(v => (desc ? v > n : v <= n)), desc), + n, + ...quickSort(nums.filter(v => (!desc ? v > n : v <= n)), desc) + ]; + +const randomHexColorCode = () => { + let n = ((Math.random() * 0xfffff) | 0).toString(16); + return '#' + (n.length !== 6 ? ((Math.random() * 0xf) | 0).toString(16) + n : n); +}; + +const randomIntegerInRange = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min; + +const randomNumberInRange = (min, max) => Math.random() * (max - min) + min; + +const fs$1 = typeof require !== "undefined" && require('fs'); +const readFileLines = filename => + fs$1 + .readFileSync(filename) + .toString('UTF8') + .split('\n'); + +const redirect = (url, asLink = true) => + asLink ? (window.location.href = url) : window.location.replace(url); + +const remove = (arr, func) => + Array.isArray(arr) + ? arr.filter(func).reduce((acc, val) => { + arr.splice(arr.indexOf(val), 1); + return acc.concat(val); + }, []) + : []; + +const repeatString = (str = '', num = 2) => { + return num >= 0 ? str.repeat(num) : str; +}; + +const reverseString = str => + str + .split('') + .reverse() + .join(''); + +const RGBToHex = (r, g, b) => ((r << 16) + (g << 8) + b).toString(16).padStart(6, '0'); + +const round = (n, decimals = 0) => Number(`${Math.round(`${n}e${decimals}`)}e-${decimals}`); + +const runPromisesInSeries = ps => ps.reduce((p, next) => p.then(next), Promise.resolve()); + +const sample = arr => arr[Math.floor(Math.random() * arr.length)]; + +const scrollToTop = () => { + const c = document.documentElement.scrollTop || document.body.scrollTop; + if (c > 0) { + window.requestAnimationFrame(scrollToTop); + window.scrollTo(0, c - c / 8); + } +}; + +const sdbm = str => { + let arr = str.split(''); + return arr.reduce( + (hashCode, currentVal) => + (hashCode = currentVal.charCodeAt(0) + (hashCode << 6) + (hashCode << 16) - hashCode), + 0 + ); +}; + +const select = (from, selector) => + selector.split('.').reduce((prev, cur) => prev && prev[cur], from); + +const setStyle = (el, ruleName, value) => (el.style[ruleName] = value); + +const shallowClone = obj => Object.assign({}, obj); + +const show = (...el) => [...el].forEach(e => (e.style.display = '')); + +const shuffle = ([...arr]) => { + let m = arr.length; + while (m) { + const i = Math.floor(Math.random() * m--); + [arr[m], arr[i]] = [arr[i], arr[m]]; + } + return arr; +}; + +const similarity = (arr, values) => arr.filter(v => values.includes(v)); + +const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); + +const sortCharactersInString = str => + str + .split('') + .sort((a, b) => a.localeCompare(b)) + .join(''); + +const speechSynthesis = message => { + const msg = new SpeechSynthesisUtterance(message); + msg.voice = window.speechSynthesis.getVoices()[0]; + window.speechSynthesis.speak(msg); +}; + +const splitLines = str => str.split(/\r?\n/); + +const spreadOver = fn => argsArr => fn(...argsArr); + +const standardDeviation = (arr, usePopulation = false) => { + const mean = arr.reduce((acc, val) => acc + val, 0) / arr.length; + return Math.sqrt( + arr + .reduce((acc, val) => acc.concat(Math.pow(val - mean, 2)), []) + .reduce((acc, val) => acc + val, 0) / + (arr.length - (usePopulation ? 0 : 1)) + ); +}; + +const sum = (...arr) => [].concat(...arr).reduce((acc, val) => acc + val, 0); + +const symmetricDifference = (a, b) => { + const sA = new Set(a), + sB = new Set(b); + return [...a.filter(x => !sB.has(x)), ...b.filter(x => !sA.has(x))]; +}; + +const tail = arr => (arr.length > 1 ? arr.slice(1) : arr); + +const take = (arr, n = 1) => arr.slice(0, n); + +const takeRight = (arr, n = 1) => arr.slice(arr.length - n, arr.length); + +const timeTaken = callback => { + console.time('timeTaken'); + const r = callback(); + console.timeEnd('timeTaken'); + return r; +}; + +const toCamelCase = str => { + let s = + str && + str + .match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g) + .map(x => x.slice(0, 1).toUpperCase() + x.slice(1).toLowerCase()) + .join(''); + return s.slice(0, 1).toLowerCase() + s.slice(1); +}; + +const toDecimalMark = num => num.toLocaleString('en-US'); + +const toEnglishDate = time => { + try { + return new Date(time) + .toISOString() + .split('T')[0] + .replace(/-/g, '/'); + } catch (e) {} +}; + +const toggleClass = (el, className) => el.classList.toggle(className); + +const toKebabCase = str => + str && + str + .match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g) + .map(x => x.toLowerCase()) + .join('-'); + +const tomorrow = () => new Date(new Date().getTime() + 86400000).toISOString().split('T')[0]; + +const toOrdinalSuffix = num => { + const int = parseInt(num), + digits = [int % 10, int % 100], + ordinals = ['st', 'nd', 'rd', 'th'], + oPattern = [1, 2, 3, 4], + tPattern = [11, 12, 13, 14, 15, 16, 17, 18, 19]; + return oPattern.includes(digits[0]) && !tPattern.includes(digits[1]) + ? int + ordinals[digits[0] - 1] + : int + ordinals[3]; +}; + +const toSnakeCase = str => { + str && + str + .match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g) + .map(x => x.toLowerCase()) + .join('_'); +}; + +const truncateString = (str, num) => + str.length > num ? str.slice(0, num > 3 ? num - 3 : num) + '...' : str; + +const truthCheckCollection = (collection, pre) => collection.every(obj => obj[pre]); + +const unescapeHTML = str => + str.replace( + /&|<|>|'|"/g, + tag => + ({ + '&': '&', + '<': '<', + '>': '>', + ''': "'", + '"': '"' + }[tag] || tag) + ); + +const union = (a, b) => Array.from(new Set([...a, ...b])); + +const UUIDGeneratorBrowser = () => + ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c => + (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16) + ); + +const crypto$1 = typeof require !== "undefined" && require('crypto'); +const UUIDGeneratorNode = () => + ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c => + (c ^ (crypto$1.randomBytes(1)[0] & (15 >> (c / 4)))).toString(16) + ); + +const validateNumber = n => !isNaN(parseFloat(n)) && isFinite(n) && Number(n) == n; + +const without = (arr, ...args) => arr.filter(v => !args.includes(v)); + +const words = (str, pattern = /[^a-zA-Z-]+/) => str.split(pattern).filter(Boolean); + +const zip = (...arrays) => { + const maxLength = Math.max(...arrays.map(x => x.length)); + return Array.from({ length: maxLength }).map((_, i) => { + return Array.from({ length: arrays.length }, (_, k) => arrays[k][i]); + }); +}; + +const zipObject = (props, values) => + props.reduce((obj, prop, index) => (obj[prop] = values[index], obj), {}); + +var imports = {anagrams,arrayToHtmlList,average,bottomVisible,byteSize,call,capitalize,capitalizeEveryWord,chainAsync,chunk,clampNumber,cleanObj,coalesce,coalesceFactory,collatz,collectInto,compact,compose,countOccurrences,countVowels,currentURL,curry,deepFlatten,detectDeviceType,difference,differenceWith,digitize,distance,distinctValuesOfArray,dropElements,dropRight,elementIsVisibleInViewport,escapeHTML,escapeRegExp,everyNth,extendHex,factorial,fibonacci,fibonacciCountUntilNum,fibonacciUntilNum,filterNonUnique,flatten,flattenDepth,flip,fromCamelCase,functionName,gcd,getDaysDiffBetweenDates,getScrollPosition,getStyle,getType,getURLParameters,groupBy,hammingDistance,hasClass,head,hexToRGB,hide,httpsRedirect,initial,initialize2DArray,initializeArrayWithRange,initializeArrayWithValues,inRange,intersection,isArmstrongNumber,isArray,isBoolean,isDivisible,isEven,isFunction,isNumber,isPrime,isString,isSymbol,JSONToDate,JSONToFile,last,lcm,lowercaseKeys,mapObject,max,median,min,negate,nthElement,objectFromPairs,objectToPairs,onUserInputChange,orderBy,palindrome,percentile,pick,pipeFunctions,powerset,primes,promisify,pull,pullAtIndex,pullAtValue,quickSort,randomHexColorCode,randomIntegerInRange,randomNumberInRange,readFileLines,redirect,remove,repeatString,reverseString,RGBToHex,round,runPromisesInSeries,sample,scrollToTop,sdbm,select,setStyle,shallowClone,show,shuffle,similarity,sleep,sortCharactersInString,speechSynthesis,splitLines,spreadOver,standardDeviation,sum,symmetricDifference,tail,take,takeRight,timeTaken,toCamelCase,toDecimalMark,toEnglishDate,toggleClass,toKebabCase,tomorrow,toOrdinalSuffix,toSnakeCase,truncateString,truthCheckCollection,unescapeHTML,union,UUIDGeneratorBrowser,UUIDGeneratorNode,validateNumber,without,words,zip,zipObject,} + +return imports; + +}))); diff --git a/dist/_30s.min.js b/dist/_30s.min.js new file mode 100644 index 000000000..d30867b5d --- /dev/null +++ b/dist/_30s.min.js @@ -0,0 +1 @@ +(function(a,b){'object'==typeof exports&&'undefined'!=typeof module?module.exports=b():'function'==typeof define&&define.amd?define(b):a._30s=b()})(this,function(){'use strict';var a=Math.floor,b=Math.sqrt,c=Math.pow,d=Math.log,e=Math.min,f=Math.max,g=Math.ceil;const h=(a)=>2>=a.length?2===a.length?[a,a[1]+a[0]]:[a]:a.split('').reduce((b,c,d)=>b.concat(h(a.slice(0,d)+a.slice(d+1)).map((a)=>c+a)),[]),i=(a,b=[],c)=>(Object.keys(a).forEach((d)=>{d===c?i(a[d],b,c):!b.includes(d)&&delete a[d]}),a),j=(a,b=a.length,...c)=>b<=c.length?a(...c):j.bind(null,a,b,...c),k=(a)=>[].concat(...a.map((a)=>Array.isArray(a)?k(a):a)),l=(a)=>0>a?(()=>{throw new TypeError('Negative numbers are not allowed!')})():1>=a?1:a*l(a-1),m=(a,b=1)=>1==b?a.reduce((b,a)=>b.concat(a),[]):a.reduce((c,a)=>c.concat(Array.isArray(a)?m(a,b-1):a),[]),n=(...a)=>{let b=[].concat(...a);const c=(a,b)=>b?n(b,a%b):a;return b.reduce((d,a)=>c(d,a))},o='undefined'!=typeof require&&require('fs'),p=([a,...b],c)=>isNaN(a)?[]:[...p(b.filter((b)=>c?b>a:b<=a),c),a,...p(b.filter((b)=>c?b<=a:b>a),c)],q='undefined'!=typeof require&&require('fs'),r=()=>{const a=document.documentElement.scrollTop||document.body.scrollTop;0a.map((a)=>document.querySelector('#'+b).innerHTML+=`
  • ${a}
  • `),average:(...a)=>{const b=[].concat(...a);return b.reduce((a,b)=>a+b,0)/b.length},bottomVisible:()=>document.documentElement.clientHeight+window.scrollY>=(document.documentElement.scrollHeight||document.documentElement.clientHeight),byteSize:(a)=>new Blob([a]).size,call:(a,...b)=>(c)=>c[a](...b),capitalize:([a,...b],c=!1)=>a.toUpperCase()+(c?b.join('').toLowerCase():b.join('')),capitalizeEveryWord:(a)=>a.replace(/\b[a-z]/g,(a)=>a.toUpperCase()),chainAsync:(a)=>{let b=0;const c=()=>a[b++](c);c()},chunk:(a,b)=>Array.from({length:g(a.length/b)},(c,d)=>a.slice(d*b,d*b+b)),clampNumber:(c,d,a)=>f(e(c,f(d,a)),e(d,a)),cleanObj:i,coalesce:(...a)=>a.find((a)=>![void 0,null].includes(a)),coalesceFactory:(a)=>(...b)=>b.find(a),collatz:(a)=>0==a%2?a/2:3*a+1,collectInto:(a)=>(...b)=>a(b),compact:(a)=>a.filter(Boolean),compose:(...a)=>a.reduce((a,b)=>(...c)=>a(b(...c))),countOccurrences:(a,b)=>a.reduce((c,a)=>a===b?c+1:c+0,0),countVowels:(a)=>(a.match(/[aeiou]/gi)||[]).length,currentURL:()=>window.location.href,curry:j,deepFlatten:k,detectDeviceType:()=>/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)?'Mobile':'Desktop',difference:(c,a)=>{const b=new Set(a);return c.filter((a)=>!b.has(a))},differenceWith:(a,b,c)=>a.filter((d)=>!b.find((a)=>c(d,a))),digitize:(a)=>[...(''+a)].map((a)=>parseInt(a)),distance:(a,b,c,d)=>Math.hypot(c-a,d-b),distinctValuesOfArray:(a)=>[...new Set(a)],dropElements:(a,b)=>{for(;0a.slice(0,-b),elementIsVisibleInViewport:(a,b=!1)=>{const{top:c,left:d,bottom:e,right:f}=a.getBoundingClientRect(),{innerHeight:g,innerWidth:h}=window;return b?(0a.replace(/[&<>'"]/g,(a)=>({"&":'&',"<":'<',">":'>',"'":''','"':'"'})[a]||a),escapeRegExp:(a)=>a.replace(/[.*+?^${}()|[\]\\]/g,'\\$&'),everyNth:(a,b)=>a.filter((a,c)=>c%b==b-1),extendHex:(a)=>'#'+a.slice(a.startsWith('#')?1:0).split('').map((a)=>a+a).join(''),factorial:l,fibonacci:(a)=>Array.from({length:a}).reduce((a,b,c)=>a.concat(1g(d(2.23606797749979*a+1/2)/0.48121182505960347),fibonacciUntilNum:(a)=>{let b=g(d(2.23606797749979*a+1/2)/0.48121182505960347);return Array.from({length:b}).reduce((a,b,c)=>a.concat(1a.filter((b)=>a.indexOf(b)===a.lastIndexOf(b)),flatten:(a)=>[].concat(...a),flattenDepth:m,flip:(a)=>(...b)=>a(b.pop(),...b),fromCamelCase:(a,b='_')=>a.replace(/([a-z\d])([A-Z])/g,'$1'+b+'$2').replace(/([A-Z]+)([A-Z][a-z\d]+)/g,'$1'+b+'$2').toLowerCase(),functionName:(a)=>(console.debug(a.name),a),gcd:n,getDaysDiffBetweenDates:(a,b)=>(b-a)/86400000,getScrollPosition:(a=window)=>({x:a.pageXOffset===void 0?a.scrollLeft:a.pageXOffset,y:a.pageYOffset===void 0?a.scrollTop:a.pageYOffset}),getStyle:(a,b)=>getComputedStyle(a)[b],getType:(a)=>a===void 0?'undefined':null===a?'null':a.constructor.name.toLowerCase(),getURLParameters:(a)=>a.match(/([^?=&]+)(=([^&]*))/g).reduce((b,a)=>(b[a.slice(0,a.indexOf('='))]=a.slice(a.indexOf('=')+1),b),{}),groupBy:(a,b)=>a.map('function'==typeof b?b:(a)=>a[b]).reduce((b,c,d)=>(b[c]=(b[c]||[]).concat(a[d]),b),{}),hammingDistance:(a,b)=>((a^b).toString(2).match(/1/g)||'').length,hasClass:(a,b)=>a.classList.contains(b),head:(a)=>a[0],hexToRGB:(a)=>{let b=!1,c=a.slice(a.startsWith('#')?1:0);return 3===c.length?c=[...c].map((a)=>a+a).join(''):8===c.length&&(b=!0),c=parseInt(c,16),'rgb'+(b?'a':'')+'('+(c>>>(b?24:16))+', '+((c&(b?16711680:65280))>>>(b?16:8))+', '+((c&(b?65280:255))>>>(b?8:0))+(b?`, ${255&c}`:'')+')'},hide:(...a)=>[...a].forEach((a)=>a.style.display='none'),httpsRedirect:()=>{'https:'!==location.protocol&&location.replace('https://'+location.href.split('//')[1])},initial:(a)=>a.slice(0,-1),initialize2DArray:(a,b,c=null)=>Array(b).fill().map(()=>Array(a).fill(c)),initializeArrayWithRange:(a,b=0)=>Array.from({length:a+1-b}).map((a,c)=>c+b),initializeArrayWithValues:(a,b=0)=>Array(a).fill(b),inRange:(a,b,c=null)=>(c&&b>c&&(c=b),null==c?0<=a&&a=b&&a{const b=new Set(a);return c.filter((a)=>b.has(a))},isArmstrongNumber:(a)=>((b)=>b.reduce((e,a)=>e+c(parseInt(a),b.length),0)==a)((a+'').split('')),isArray:(a)=>!!a&&Array.isArray(a),isBoolean:(a)=>'boolean'==typeof a,isDivisible:(a,b)=>0==a%b,isEven:(a)=>0==a%2,isFunction:(a)=>a&&'function'==typeof a,isNumber:(a)=>'number'==typeof a,isPrime:(c)=>{const d=a(b(c));for(var e=2;e*e<=d;e++)if(0==c%e)return!1;return 2<=c},isString:(a)=>'string'==typeof a,isSymbol:(a)=>'symbol'==typeof a,JSONToDate:(a)=>{const b=new Date(parseInt(a.toString().substr(6)));return`${b.getDate()}/${b.getMonth()+1}/${b.getFullYear()}`},JSONToFile:(a,b)=>o.writeFile(`${b}.json`,JSON.stringify(a,null,2)),last:(a)=>a[a.length-1],lcm:(...a)=>{const b=(a,c)=>c?b(c,a%c):a,c=(a,c)=>a*c/b(a,c);return[].concat(...a).reduce((d,a)=>c(d,a))},lowercaseKeys:(a)=>Object.keys(a).reduce((b,c)=>(b[c.toLowerCase()]=a[c],b),{}),mapObject:(b,c)=>((d)=>(d=[b,b.map(c)],d[0].reduce((a,b,c)=>(a[b]=d[1][c],a),{})))(),max:(...a)=>f(...[].concat(...a)),median:(b)=>{const c=a(b.length/2),d=[...b].sort((c,a)=>c-a);return 0==b.length%2?(d[c-1]+d[c])/2:d[c]},min:(a)=>e(...[].concat(...a)),negate:(a)=>(...b)=>!a(...b),nthElement:(a,b=0)=>(0a.reduce((b,a)=>(b[a[0]]=a[1],b),{}),objectToPairs:(a)=>Object.keys(a).map((b)=>[b,a[b]]),onUserInputChange:(a)=>{let b='mouse',c=0;const d=()=>{const e=performance.now();20>e-c&&(b='mouse',a(b),document.removeEventListener('mousemove',d)),c=e};document.addEventListener('touchstart',()=>{'touch'==b||(b='touch',a(b),document.addEventListener('mousemove',d))})},orderBy:(a,c,d)=>[...a].sort((e,a)=>c.reduce((b,c,f)=>{if(0===b){const[g,h]=d&&'desc'===d[f]?[a[c],e[c]]:[e[c],a[c]];b=g>h?1:g{const b=a.toLowerCase().replace(/[\W_]/g,'');return b===b.split('').reverse().join('')},percentile:(a,b)=>100*a.reduce((a,c)=>a+(cb.reduce((b,c)=>(c in a&&(b[c]=a[c]),b),{}),pipeFunctions:(...a)=>a.reduce((a,b)=>(...c)=>b(a(...c))),powerset:(a)=>a.reduce((b,a)=>b.concat(b.map((b)=>[a].concat(b))),[[]]),primes:(c)=>{let d=Array.from({length:c-1}).map((a,b)=>b+2),e=a(b(c)),f=Array.from({length:e-1}).map((a,b)=>b+2);return f.forEach((a)=>d=d.filter((b)=>0!=b%a||b==a)),d},promisify:(a)=>(...b)=>new Promise((c,d)=>a(...b,(a,b)=>a?d(a):c(b))),pull:(a,...b)=>{let c=Array.isArray(b[0])?b[0]:b,d=a.filter((a)=>!c.includes(a));a.length=0,d.forEach((b)=>a.push(b))},pullAtIndex:(a,b)=>{let c=[],d=a.map((a,d)=>b.includes(d)?c.push(a):a).filter((a,c)=>!b.includes(c));return a.length=0,d.forEach((b)=>a.push(b)),c},pullAtValue:(a,b)=>{let c=[],d=a.forEach((a)=>b.includes(a)?c.push(a):a),e=a.filter((a)=>!b.includes(a));return a.length=0,e.forEach((b)=>a.push(b)),c},quickSort:p,randomHexColorCode:()=>{let a=(0|1048575*Math.random()).toString(16);return'#'+(6===a.length?a:(0|15*Math.random()).toString(16)+a)},randomIntegerInRange:(b,c)=>a(Math.random()*(c-b+1))+b,randomNumberInRange:(a,b)=>Math.random()*(b-a)+a,readFileLines:(a)=>q.readFileSync(a).toString('UTF8').split('\n'),redirect:(a,b=!0)=>b?window.location.href=a:window.location.replace(a),remove:(a,b)=>Array.isArray(a)?a.filter(b).reduce((b,c)=>(a.splice(a.indexOf(c),1),b.concat(c)),[]):[],repeatString:(a='',b=2)=>0<=b?a.repeat(b):a,reverseString:(a)=>a.split('').reverse().join(''),RGBToHex:(a,c,d)=>((a<<16)+(c<<8)+d).toString(16).padStart(6,'0'),round:(a,b=0)=>+`${Math.round(`${a}e${b}`)}e-${b}`,runPromisesInSeries:(a)=>a.reduce((a,b)=>a.then(b),Promise.resolve()),sample:(b)=>b[a(Math.random()*b.length)],scrollToTop:r,sdbm:(a)=>{let b=a.split('');return b.reduce((a,b)=>a=b.charCodeAt(0)+(a<<6)+(a<<16)-a,0)},select:(a,b)=>b.split('.').reduce((a,b)=>a&&a[b],a),setStyle:(a,b,c)=>a.style[b]=c,shallowClone:(a)=>Object.assign({},a),show:(...a)=>[...a].forEach((a)=>a.style.display=''),shuffle:([...b])=>{for(let c=b.length;c;){const d=a(Math.random()*c--);[b[c],b[d]]=[b[d],b[c]]}return b},similarity:(a,b)=>a.filter((a)=>b.includes(a)),sleep:(a)=>new Promise((b)=>setTimeout(b,a)),sortCharactersInString:(a)=>a.split('').sort((c,a)=>c.localeCompare(a)).join(''),speechSynthesis:(a)=>{const b=new SpeechSynthesisUtterance(a);b.voice=window.speechSynthesis.getVoices()[0],window.speechSynthesis.speak(b)},splitLines:(a)=>a.split(/\r?\n/),spreadOver:(a)=>(b)=>a(...b),standardDeviation:(a,d=!1)=>{const e=a.reduce((a,b)=>a+b,0)/a.length;return b(a.reduce((a,b)=>a.concat(c(b-e,2)),[]).reduce((a,b)=>a+b,0)/(a.length-(d?0:1)))},sum:(...a)=>[].concat(...a).reduce((a,b)=>a+b,0),symmetricDifference:(c,a)=>{const b=new Set(c),d=new Set(a);return[...c.filter((a)=>!d.has(a)),...a.filter((a)=>!b.has(a))]},tail:(a)=>1a.slice(0,b),takeRight:(a,b=1)=>a.slice(a.length-b,a.length),timeTaken:(a)=>{console.time('timeTaken');const b=a();return console.timeEnd('timeTaken'),b},toCamelCase:(a)=>{let b=a&&a.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g).map((a)=>a.slice(0,1).toUpperCase()+a.slice(1).toLowerCase()).join('');return b.slice(0,1).toLowerCase()+b.slice(1)},toDecimalMark:(a)=>a.toLocaleString('en-US'),toEnglishDate:(a)=>{try{return new Date(a).toISOString().split('T')[0].replace(/-/g,'/')}catch(a){}},toggleClass:(a,b)=>a.classList.toggle(b),toKebabCase:(a)=>a&&a.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g).map((a)=>a.toLowerCase()).join('-'),tomorrow:()=>new Date(new Date().getTime()+8.64e7).toISOString().split('T')[0],toOrdinalSuffix:(a)=>{const b=parseInt(a),c=[b%10,b%100],d=['st','nd','rd','th'];return[1,2,3,4].includes(c[0])&&![11,12,13,14,15,16,17,18,19].includes(c[1])?b+d[c[0]-1]:b+d[3]},toSnakeCase:(a)=>{a&&a.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g).map((a)=>a.toLowerCase()).join('_')},truncateString:(a,b)=>a.length>b?a.slice(0,3a.every((a)=>a[b]),unescapeHTML:(a)=>a.replace(/&|<|>|'|"/g,(a)=>({"&":'&',"<":'<',">":'>',"'":'\'',""":'"'})[a]||a),union:(c,a)=>Array.from(new Set([...c,...a])),UUIDGeneratorBrowser:()=>'10000000-1000-4000-8000-100000000000'.replace(/[018]/g,(a)=>(a^crypto.getRandomValues(new Uint8Array(1))[0]&15>>a/4).toString(16)),UUIDGeneratorNode:()=>'10000000-1000-4000-8000-100000000000'.replace(/[018]/g,(a)=>(a^s.randomBytes(1)[0]&15>>a/4).toString(16)),validateNumber:(a)=>!isNaN(parseFloat(a))&&isFinite(a)&&+a==a,without:(a,...b)=>a.filter((a)=>!b.includes(a)),words:(a,b=/[^a-zA-Z-]+/)=>a.split(b).filter(Boolean),zip:(...a)=>{const b=f(...a.map((a)=>a.length));return Array.from({length:b}).map((b,c)=>Array.from({length:a.length},(b,d)=>a[d][c]))},zipObject:(a,b)=>a.reduce((a,c,d)=>(a[c]=b[d],a),{})}}); diff --git a/scripts/module.js b/scripts/module.js index 295e50fd9..981b86760 100644 --- a/scripts/module.js +++ b/scripts/module.js @@ -1,74 +1,74 @@ /* Builds the `_30s` module. */ +// Load modules const fs = require('fs-extra'); const cp = require('child_process'); const path = require('path'); const chalk = require('chalk'); - +// Set variables for paths const SNIPPETS_PATH = './snippets'; const TEMP_PATH = './temp'; const IMPORTS = './imports.js'; - +// Regex for selecting code blocks const codeRE = /```\s*js([\s\S]*?)```/; - +// Start the timer of the script console.time('Module'); - +// Load tag data from the database and snippets from their folder try { const tagDatabase = fs.readFileSync('tag_database', 'utf8'); const snippets = fs.readdirSync(SNIPPETS_PATH); - + // Create `temp` folder if it doesn't already exist. if (!fs.existsSync(TEMP_PATH)) { fs.mkdirSync(TEMP_PATH); } - + // Write `imports.js` fs.writeFileSync(IMPORTS, ''); - let exportStr = 'export default {'; - + // Read all snippets and store them appropriately for (const snippet of snippets) { const snippetData = fs.readFileSync( path.join(SNIPPETS_PATH, snippet), 'utf8' ); const snippetName = snippet.replace('.md', ''); - + // Check if a snippet is Node-only const isNodeSnippet = tagDatabase .slice(tagDatabase.indexOf(snippetName) + snippetName.length + 1) .split('\n')[0] .includes('node'); - + // Read `imports.js` and write the data const importData = fs.readFileSync(IMPORTS); fs.writeFileSync( IMPORTS, importData + `\nimport { ${snippetName} } from './temp/${snippetName}.js'` ); exportStr += `${snippetName},`; - + // Find the code in each snippet const code = snippetData.match(codeRE)[1].replace('\n', ''); - + // Store the data to be written const toWrite = isNodeSnippet ? `${code .replace('const ' + snippetName, 'export const ' + snippetName) // Prevents errors from being thrown in browser environment .replace('require(', 'typeof require !== "undefined" && require(')}` : `export ${code}`; - + // Write data to the proper file fs.writeFileSync(`${TEMP_PATH}/${snippetName}.js`, toWrite); } - + // Write to the proper files and start the `rollup` script exportStr += '}'; - fs.appendFileSync(IMPORTS, `\n${exportStr}`); - cp.execSync('node ./scripts/rollup.js'); - + // Clean up temporary data fs.removeSync(TEMP_PATH); fs.unlink(IMPORTS); - + // Log a success message console.log(`${chalk.green('SUCCESS!')} Snippet module built!`); + // Log the time taken console.timeEnd('Module'); } catch (err) { + // Handle errors (hopefully not!) console.log(`${chalk.red('ERROR!')} During module creation: ${err}`); process.exit(1); } diff --git a/scripts/rollup.js b/scripts/rollup.js index 216ba426c..4fe1951a6 100644 --- a/scripts/rollup.js +++ b/scripts/rollup.js @@ -1,17 +1,21 @@ +/* + Part of the process for building the `_30s` module. +*/ +// Load modules const fs = require('fs-extra'); const { rollup } = require('rollup'); const babel = require('rollup-plugin-babel'); const minify = require('rollup-plugin-babel-minify'); - +// Set variables for paths const INPUT_FILE = './imports.js'; const MODULE_NAME = '_30s'; const DIST = './dist'; - +// Create `dist` folder if not existing if (!fs.existsSync(DIST)) fs.mkdirSync(DIST); - +// Setup babel and minification const es5 = babel({ presets: [['env', { modules: false }]] }); const min = minify({ comments: false }); - +// Create the bundles (async () => { const bundle = await rollup({ input: INPUT_FILE }); const bundleES5 = await rollup({ input: INPUT_FILE, plugins: [es5] }); From eaa153aebd29f2bb1a75bf6e5a13a548619b36ae Mon Sep 17 00:00:00 2001 From: Travis CI Date: Tue, 2 Jan 2018 14:53:00 +0000 Subject: [PATCH 22/61] Travis build: 848 [ci skip] --- yarn.lock | 798 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 790 insertions(+), 8 deletions(-) diff --git a/yarn.lock b/yarn.lock index b4d7dfd07..c7dec9cb4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,10 @@ # yarn lockfile v1 +"@comandeer/babel-plugin-banner@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@comandeer/babel-plugin-banner/-/babel-plugin-banner-1.0.0.tgz#40bcce0bbee084b5b02545a33635d053c248356f" + abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" @@ -140,7 +144,7 @@ aws4@^1.2.1, aws4@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" -babel-code-frame@^6.16.0: +babel-code-frame@^6.16.0, babel-code-frame@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" dependencies: @@ -148,6 +152,625 @@ babel-code-frame@^6.16.0: esutils "^2.0.2" js-tokens "^3.0.2" +babel-core@^6.21.0, babel-core@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.0.tgz#af32f78b31a6fcef119c87b0fd8d9753f03a0bb8" + dependencies: + babel-code-frame "^6.26.0" + babel-generator "^6.26.0" + babel-helpers "^6.24.1" + babel-messages "^6.23.0" + babel-register "^6.26.0" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + convert-source-map "^1.5.0" + debug "^2.6.8" + json5 "^0.5.1" + lodash "^4.17.4" + minimatch "^3.0.4" + path-is-absolute "^1.0.1" + private "^0.1.7" + slash "^1.0.0" + source-map "^0.5.6" + +babel-generator@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.0.tgz#ac1ae20070b79f6e3ca1d3269613053774f20dc5" + dependencies: + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + detect-indent "^4.0.0" + jsesc "^1.3.0" + lodash "^4.17.4" + source-map "^0.5.6" + trim-right "^1.0.1" + +babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" + dependencies: + babel-helper-explode-assignable-expression "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-call-delegate@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-define-map@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-helper-evaluate-path@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-helper-evaluate-path/-/babel-helper-evaluate-path-0.2.0.tgz#0bb2eb01996c0cef53c5e8405e999fe4a0244c08" + +babel-helper-explode-assignable-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" + dependencies: + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-flip-expressions@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-helper-flip-expressions/-/babel-helper-flip-expressions-0.2.0.tgz#160d2090a3d9f9c64a750905321a0bc218f884ec" + +babel-helper-function-name@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" + dependencies: + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-get-function-arity@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-hoist-variables@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-is-nodes-equiv@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/babel-helper-is-nodes-equiv/-/babel-helper-is-nodes-equiv-0.0.1.tgz#34e9b300b1479ddd98ec77ea0bbe9342dfe39684" + +babel-helper-is-void-0@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-helper-is-void-0/-/babel-helper-is-void-0-0.2.0.tgz#6ed0ada8a9b1c5b6e88af6b47c1b3b5c080860eb" + +babel-helper-mark-eval-scopes@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-helper-mark-eval-scopes/-/babel-helper-mark-eval-scopes-0.2.0.tgz#7648aaf2ec92aae9b09a20ad91e8df5e1fcc94b2" + +babel-helper-optimise-call-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-regex@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" + dependencies: + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-helper-remap-async-to-generator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-remove-or-void@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-helper-remove-or-void/-/babel-helper-remove-or-void-0.2.0.tgz#8e46ad5b30560d57d7510b3fd93f332ee7c67386" + +babel-helper-replace-supers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" + dependencies: + babel-helper-optimise-call-expression "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-to-multiple-sequence-expressions@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-helper-to-multiple-sequence-expressions/-/babel-helper-to-multiple-sequence-expressions-0.2.0.tgz#d1a419634c6cb301f27858c659167cfee0a9d318" + +babel-helpers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-messages@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-check-es2015-constants@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-minify-builtins@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-builtins/-/babel-plugin-minify-builtins-0.2.0.tgz#317f824b0907210b6348671bb040ca072e2e0c82" + dependencies: + babel-helper-evaluate-path "^0.2.0" + +babel-plugin-minify-constant-folding@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-constant-folding/-/babel-plugin-minify-constant-folding-0.2.0.tgz#8c70b528b2eb7c13e94d95c8789077d4cdbc3970" + dependencies: + babel-helper-evaluate-path "^0.2.0" + +babel-plugin-minify-dead-code-elimination@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-dead-code-elimination/-/babel-plugin-minify-dead-code-elimination-0.2.0.tgz#e8025ee10a1e5e4f202633a6928ce892c33747e3" + dependencies: + babel-helper-evaluate-path "^0.2.0" + babel-helper-mark-eval-scopes "^0.2.0" + babel-helper-remove-or-void "^0.2.0" + lodash.some "^4.6.0" + +babel-plugin-minify-flip-comparisons@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-flip-comparisons/-/babel-plugin-minify-flip-comparisons-0.2.0.tgz#0c9c8e93155c8f09dedad8118b634c259f709ef5" + dependencies: + babel-helper-is-void-0 "^0.2.0" + +babel-plugin-minify-guarded-expressions@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-guarded-expressions/-/babel-plugin-minify-guarded-expressions-0.2.0.tgz#8a8c950040fce3e258a12e6eb21eab94ad7235ab" + dependencies: + babel-helper-flip-expressions "^0.2.0" + +babel-plugin-minify-infinity@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-infinity/-/babel-plugin-minify-infinity-0.2.0.tgz#30960c615ddbc657c045bb00a1d8eb4af257cf03" + +babel-plugin-minify-mangle-names@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-mangle-names/-/babel-plugin-minify-mangle-names-0.2.0.tgz#719892297ff0106a6ec1a4b0fc062f1f8b6a8529" + dependencies: + babel-helper-mark-eval-scopes "^0.2.0" + +babel-plugin-minify-numeric-literals@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-numeric-literals/-/babel-plugin-minify-numeric-literals-0.2.0.tgz#5746e851700167a380c05e93f289a7070459a0d1" + +babel-plugin-minify-replace@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-replace/-/babel-plugin-minify-replace-0.2.0.tgz#3c1f06bc4e6d3e301eacb763edc1be611efc39b0" + +babel-plugin-minify-simplify@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-simplify/-/babel-plugin-minify-simplify-0.2.0.tgz#21ceec4857100c5476d7cef121f351156e5c9bc0" + dependencies: + babel-helper-flip-expressions "^0.2.0" + babel-helper-is-nodes-equiv "^0.0.1" + babel-helper-to-multiple-sequence-expressions "^0.2.0" + +babel-plugin-minify-type-constructors@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-type-constructors/-/babel-plugin-minify-type-constructors-0.2.0.tgz#7f3b6458be0863cfd59e9985bed6d134aa7a2e17" + dependencies: + babel-helper-is-void-0 "^0.2.0" + +babel-plugin-syntax-async-functions@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" + +babel-plugin-syntax-exponentiation-operator@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" + +babel-plugin-syntax-trailing-function-commas@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" + +babel-plugin-transform-async-to-generator@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" + dependencies: + babel-helper-remap-async-to-generator "^6.24.1" + babel-plugin-syntax-async-functions "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-arrow-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoping@^6.23.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" + dependencies: + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-plugin-transform-es2015-classes@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" + dependencies: + babel-helper-define-map "^6.24.1" + babel-helper-function-name "^6.24.1" + babel-helper-optimise-call-expression "^6.24.1" + babel-helper-replace-supers "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-computed-properties@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-destructuring@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-duplicate-keys@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-for-of@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-function-name@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-literals@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015-modules-amd@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" + dependencies: + babel-plugin-transform-es2015-modules-commonjs "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz#0d8394029b7dc6abe1a97ef181e00758dd2e5d8a" + dependencies: + babel-plugin-transform-strict-mode "^6.24.1" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-types "^6.26.0" + +babel-plugin-transform-es2015-modules-systemjs@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-modules-umd@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" + dependencies: + babel-plugin-transform-es2015-modules-amd "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-object-super@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" + dependencies: + babel-helper-replace-supers "^6.24.1" + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-parameters@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" + dependencies: + babel-helper-call-delegate "^6.24.1" + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-shorthand-properties@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-spread@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-sticky-regex@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-template-literals@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-typeof-symbol@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-unicode-regex@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + regexpu-core "^2.0.0" + +babel-plugin-transform-exponentiation-operator@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e" + dependencies: + babel-helper-builder-binary-assignment-operator-visitor "^6.24.1" + babel-plugin-syntax-exponentiation-operator "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-inline-consecutive-adds@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-inline-consecutive-adds/-/babel-plugin-transform-inline-consecutive-adds-0.2.0.tgz#15dae78921057f4004f8eafd79e15ddc5f12f426" + +babel-plugin-transform-member-expression-literals@^6.8.5: + version "6.8.5" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-member-expression-literals/-/babel-plugin-transform-member-expression-literals-6.8.5.tgz#e06ae305cf48d819822e93a70d79269f04d89eec" + +babel-plugin-transform-merge-sibling-variables@^6.8.6: + version "6.8.6" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-merge-sibling-variables/-/babel-plugin-transform-merge-sibling-variables-6.8.6.tgz#6d21efa5ee4981f71657fae716f9594bb2622aef" + +babel-plugin-transform-minify-booleans@^6.8.3: + version "6.8.3" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-minify-booleans/-/babel-plugin-transform-minify-booleans-6.8.3.tgz#5906ed776d3718250519abf1bace44b0b613ddf9" + +babel-plugin-transform-property-literals@^6.8.5: + version "6.8.5" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-property-literals/-/babel-plugin-transform-property-literals-6.8.5.tgz#67ed5930b34805443452c8b9690c7ebe1e206c40" + dependencies: + esutils "^2.0.2" + +babel-plugin-transform-regenerator@^6.22.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" + dependencies: + regenerator-transform "^0.10.0" + +babel-plugin-transform-regexp-constructors@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-regexp-constructors/-/babel-plugin-transform-regexp-constructors-0.2.0.tgz#6aa5dd0acc515db4be929bbcec4ed4c946c534a3" + +babel-plugin-transform-remove-console@^6.8.5: + version "6.8.5" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-remove-console/-/babel-plugin-transform-remove-console-6.8.5.tgz#fde9d2d3d725530b0fadd8d31078402410386810" + +babel-plugin-transform-remove-debugger@^6.8.5: + version "6.8.5" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-remove-debugger/-/babel-plugin-transform-remove-debugger-6.8.5.tgz#809584d412bf918f071fdf41e1fdb15ea89cdcd5" + +babel-plugin-transform-remove-undefined@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-remove-undefined/-/babel-plugin-transform-remove-undefined-0.2.0.tgz#94f052062054c707e8d094acefe79416b63452b1" + dependencies: + babel-helper-evaluate-path "^0.2.0" + +babel-plugin-transform-simplify-comparison-operators@^6.8.5: + version "6.8.5" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-simplify-comparison-operators/-/babel-plugin-transform-simplify-comparison-operators-6.8.5.tgz#a838786baf40cc33a93b95ae09e05591227e43bf" + +babel-plugin-transform-strict-mode@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-undefined-to-void@^6.8.3: + version "6.8.3" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-undefined-to-void/-/babel-plugin-transform-undefined-to-void-6.8.3.tgz#fc52707f6ee1ddc71bb91b0d314fbefdeef9beb4" + +babel-preset-env@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.6.1.tgz#a18b564cc9b9afdf4aae57ae3c1b0d99188e6f48" + dependencies: + babel-plugin-check-es2015-constants "^6.22.0" + babel-plugin-syntax-trailing-function-commas "^6.22.0" + babel-plugin-transform-async-to-generator "^6.22.0" + babel-plugin-transform-es2015-arrow-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoped-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoping "^6.23.0" + babel-plugin-transform-es2015-classes "^6.23.0" + babel-plugin-transform-es2015-computed-properties "^6.22.0" + babel-plugin-transform-es2015-destructuring "^6.23.0" + babel-plugin-transform-es2015-duplicate-keys "^6.22.0" + babel-plugin-transform-es2015-for-of "^6.23.0" + babel-plugin-transform-es2015-function-name "^6.22.0" + babel-plugin-transform-es2015-literals "^6.22.0" + babel-plugin-transform-es2015-modules-amd "^6.22.0" + babel-plugin-transform-es2015-modules-commonjs "^6.23.0" + babel-plugin-transform-es2015-modules-systemjs "^6.23.0" + babel-plugin-transform-es2015-modules-umd "^6.23.0" + babel-plugin-transform-es2015-object-super "^6.22.0" + babel-plugin-transform-es2015-parameters "^6.23.0" + babel-plugin-transform-es2015-shorthand-properties "^6.22.0" + babel-plugin-transform-es2015-spread "^6.22.0" + babel-plugin-transform-es2015-sticky-regex "^6.22.0" + babel-plugin-transform-es2015-template-literals "^6.22.0" + babel-plugin-transform-es2015-typeof-symbol "^6.23.0" + babel-plugin-transform-es2015-unicode-regex "^6.22.0" + babel-plugin-transform-exponentiation-operator "^6.22.0" + babel-plugin-transform-regenerator "^6.22.0" + browserslist "^2.1.2" + invariant "^2.2.2" + semver "^5.3.0" + +babel-preset-minify@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-preset-minify/-/babel-preset-minify-0.2.0.tgz#006566552d9b83834472273f306c0131062a0acc" + dependencies: + babel-plugin-minify-builtins "^0.2.0" + babel-plugin-minify-constant-folding "^0.2.0" + babel-plugin-minify-dead-code-elimination "^0.2.0" + babel-plugin-minify-flip-comparisons "^0.2.0" + babel-plugin-minify-guarded-expressions "^0.2.0" + babel-plugin-minify-infinity "^0.2.0" + babel-plugin-minify-mangle-names "^0.2.0" + babel-plugin-minify-numeric-literals "^0.2.0" + babel-plugin-minify-replace "^0.2.0" + babel-plugin-minify-simplify "^0.2.0" + babel-plugin-minify-type-constructors "^0.2.0" + babel-plugin-transform-inline-consecutive-adds "^0.2.0" + babel-plugin-transform-member-expression-literals "^6.8.5" + babel-plugin-transform-merge-sibling-variables "^6.8.6" + babel-plugin-transform-minify-booleans "^6.8.3" + babel-plugin-transform-property-literals "^6.8.5" + babel-plugin-transform-regexp-constructors "^0.2.0" + babel-plugin-transform-remove-console "^6.8.5" + babel-plugin-transform-remove-debugger "^6.8.5" + babel-plugin-transform-remove-undefined "^0.2.0" + babel-plugin-transform-simplify-comparison-operators "^6.8.5" + babel-plugin-transform-undefined-to-void "^6.8.3" + lodash.isplainobject "^4.0.6" + +babel-register@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" + dependencies: + babel-core "^6.26.0" + babel-runtime "^6.26.0" + core-js "^2.5.0" + home-or-tmp "^2.0.0" + lodash "^4.17.4" + mkdirp "^0.5.1" + source-map-support "^0.4.15" + +babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.11.0" + +babel-template@^6.24.1, babel-template@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" + dependencies: + babel-runtime "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + lodash "^4.17.4" + +babel-traverse@^6.24.1, babel-traverse@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" + dependencies: + babel-code-frame "^6.26.0" + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + debug "^2.6.8" + globals "^9.18.0" + invariant "^2.2.2" + lodash "^4.17.4" + +babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" + dependencies: + babel-runtime "^6.26.0" + esutils "^2.0.2" + lodash "^4.17.4" + to-fast-properties "^1.0.3" + +babylon@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" + balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" @@ -189,6 +812,13 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +browserslist@^2.1.2: + version "2.10.2" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.10.2.tgz#0838eec4b3db2d860cee13bf6c0691e7e8133822" + dependencies: + caniuse-lite "^1.0.30000784" + electron-to-chromium "^1.3.30" + builtin-modules@^1.0.0, builtin-modules@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" @@ -225,6 +855,10 @@ camelcase@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" +caniuse-lite@^1.0.30000784: + version "1.0.30000784" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000784.tgz#129ced74e9a1280a441880b6cd2bce30ef59e6c0" + caseless@~0.11.0: version "0.11.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.11.0.tgz#715b96ea9841593cc33067923f5ec60ebda4f7d7" @@ -327,6 +961,14 @@ contains-path@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" +convert-source-map@^1.5.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5" + +core-js@^2.4.0, core-js@^2.5.0: + version "2.5.3" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.3.tgz#8acc38345824f16d8365b7c9b4259168e8ed603e" + core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -432,6 +1074,12 @@ delegates@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" +detect-indent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" + dependencies: + repeating "^2.0.0" + doctrine@1.5.0, doctrine@^1.2.2: version "1.5.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" @@ -451,6 +1099,16 @@ ecc-jsbn@~0.1.1: dependencies: jsbn "~0.1.0" +electron-releases@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/electron-releases/-/electron-releases-2.1.0.tgz#c5614bf811f176ce3c836e368a0625782341fd4e" + +electron-to-chromium@^1.3.30: + version "1.3.30" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.30.tgz#9666f532a64586651fc56a72513692e820d06a80" + dependencies: + electron-releases "^2.1.0" + entities@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0" @@ -682,6 +1340,10 @@ estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" +estree-walker@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.2.1.tgz#bdafe8095383d8414d5dc2ecf4c9173b6db9412e" + esutils@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" @@ -880,7 +1542,7 @@ glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@~7.1.1, glob@~7.1.2: once "^1.3.0" path-is-absolute "^1.0.0" -globals@^9.14.0: +globals@^9.14.0, globals@^9.18.0: version "9.18.0" resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" @@ -977,6 +1639,13 @@ hoek@4.x.x: version "4.2.0" resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d" +home-or-tmp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.1" + hosted-git-info@^2.1.4: version "2.5.0" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c" @@ -1061,6 +1730,12 @@ interpret@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614" +invariant@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360" + dependencies: + loose-envify "^1.0.0" + invert-kv@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" @@ -1179,7 +1854,7 @@ js-base64@^2.1.8: version "2.4.0" resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.4.0.tgz#9e566fee624751a1d720c966cd6226d29d4025aa" -js-tokens@^3.0.2: +js-tokens@^3.0.0, js-tokens@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" @@ -1194,6 +1869,14 @@ jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" +jsesc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + json-schema-traverse@^0.3.0: version "0.3.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" @@ -1212,6 +1895,10 @@ json-stringify-safe@~5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" +json5@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + jsonfile@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" @@ -1296,14 +1983,28 @@ lodash.cond@^4.3.0: version "4.5.2" resolved "https://registry.yarnpkg.com/lodash.cond/-/lodash.cond-4.5.2.tgz#f471a1da486be60f6ab955d17115523dd1d255d5" +lodash.isplainobject@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" + lodash.mergewith@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.0.tgz#150cf0a16791f5903b8891eab154609274bdea55" -lodash@^4.0.0, lodash@^4.3.0, lodash@~4.17.4: +lodash.some@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d" + +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" +loose-envify@^1.0.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" + dependencies: + js-tokens "^3.0.0" + loud-rejection@^1.0.0: version "1.6.0" resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" @@ -1538,7 +2239,7 @@ os-locale@^1.4.0: dependencies: lcid "^1.0.0" -os-tmpdir@^1.0.0: +os-tmpdir@^1.0.0, os-tmpdir@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" @@ -1581,7 +2282,7 @@ path-exists@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" -path-is-absolute@^1.0.0: +path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" @@ -1658,6 +2359,10 @@ prettier@^1.9.2: version "1.9.2" resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.9.2.tgz#96bc2132f7a32338e6078aeb29727178c6335827" +private@^0.1.6, private@^0.1.7: + version "0.1.8" + resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" + process-nextick-args@~1.0.6: version "1.0.7" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" @@ -1730,6 +2435,40 @@ redent@^1.0.0: indent-string "^2.1.0" strip-indent "^1.0.1" +regenerate@^1.2.1: + version "1.3.3" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.3.tgz#0c336d3980553d755c39b586ae3b20aa49c82b7f" + +regenerator-runtime@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" + +regenerator-transform@^0.10.0: + version "0.10.1" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" + dependencies: + babel-runtime "^6.18.0" + babel-types "^6.19.0" + private "^0.1.6" + +regexpu-core@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" + dependencies: + regenerate "^1.2.1" + regjsgen "^0.2.0" + regjsparser "^0.1.4" + +regjsgen@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" + +regjsparser@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" + dependencies: + jsesc "~0.5.0" + relateurl@0.2.x: version "0.2.7" resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" @@ -1842,6 +2581,31 @@ rimraf@2, rimraf@^2.2.8: dependencies: glob "^7.0.5" +rollup-plugin-babel-minify@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/rollup-plugin-babel-minify/-/rollup-plugin-babel-minify-3.1.2.tgz#86a99d00b3d60984281baaeff4eb1f0eb509b053" + dependencies: + "@comandeer/babel-plugin-banner" "^1.0.0" + babel-core "^6.21.0" + babel-preset-minify "^0.2.0" + +rollup-plugin-babel@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/rollup-plugin-babel/-/rollup-plugin-babel-3.0.3.tgz#63adedc863130327512a4a9006efc2241c5b7c15" + dependencies: + rollup-pluginutils "^1.5.0" + +rollup-pluginutils@^1.5.0: + version "1.5.2" + resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-1.5.2.tgz#1e156e778f94b7255bfa1b3d0178be8f5c552408" + dependencies: + estree-walker "^0.2.1" + minimatch "^3.0.2" + +rollup@^0.53.2: + version "0.53.3" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-0.53.3.tgz#e7b6777623df912bd0ca30dc24be791d6ebc8e5a" + run-async@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/run-async/-/run-async-0.1.0.tgz#c8ad4a5e110661e402a7d21b530e009f25f8e389" @@ -1891,7 +2655,7 @@ semistandard@^11.0.0: eslint-plugin-standard "~3.0.1" standard-engine "~7.0.0" -"semver@2 || 3 || 4 || 5": +"semver@2 || 3 || 4 || 5", semver@^5.3.0: version "5.4.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" @@ -1915,6 +2679,10 @@ signal-exit@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + slice-ansi@0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" @@ -1931,7 +2699,13 @@ sntp@2.x.x: dependencies: hoek "4.x.x" -source-map@0.5.x: +source-map-support@^0.4.15: + version "0.4.18" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" + dependencies: + source-map "^0.5.6" + +source-map@0.5.x, source-map@^0.5.6: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" @@ -2112,6 +2886,10 @@ 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" +to-fast-properties@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" + tough-cookie@~2.3.0, tough-cookie@~2.3.3: version "2.3.3" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561" @@ -2122,6 +2900,10 @@ trim-newlines@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" +trim-right@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" + "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" From c679f5d6b8911efab8aa48f6f29c06a766013d67 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Tue, 2 Jan 2018 16:53:59 +0200 Subject: [PATCH 23/61] Converted dependencies to devDependencies --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f65937027..f7d3ce35e 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "dependencies": { + "devDependencies": { "babel-preset-env": "^1.6.1", "chalk": "^2.3.0", "fs-extra": "^4.0.2", From f2988dda852cd9e360c713958de5cb7273f81806 Mon Sep 17 00:00:00 2001 From: atomiks Date: Wed, 3 Jan 2018 02:31:48 +1100 Subject: [PATCH 24/61] allow for this context binding --- snippets/once.md | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/snippets/once.md b/snippets/once.md index ea32a6843..0705672a9 100644 --- a/snippets/once.md +++ b/snippets/once.md @@ -2,18 +2,23 @@ Ensures a function is called only once. -Utilizing a closure, use a flag, `called`, and set it to `true` once the function is called for the first time, preventing it from being called again. -Allow the function to be supplied with an arbitrary number of arguments using the spread (`...`) operator. +Utilizing a closure, use a flag, `called`, and set it to `true` once the function is called for the first time, preventing it from being called again. In order to allow the function to have its `this` context changed (such as in an event listener), the `function` keyword must be used, and the supplied function must have the context applied. +Allow the function to be supplied with an arbitrary number of arguments using the rest/spread (`...`) operator. ```js -const once = fn => - (called => (...args) => (!called ? ((called = true), fn(...args)) : undefined))(); -``` - -```js -const startApp = event => { - // initializes the app - console.log(event); // access to any arguments supplied +const once = fn => { + let called = false; + return function(...args) { + if (called) return; +    called = true; +    return fn.apply(this, args); + }; }; -document.addEventListener('click', once(startApp)); // only runs `startApp` once upon click +``` + +```js +const startApp = function(event) { + console.log(this, event); // document.body, MouseEvent +}; +document.body.addEventListener('click', once(startApp)); // only runs `startApp` once upon click ``` From abbfd00707e6a5c26cd0b5438af4d5d988975889 Mon Sep 17 00:00:00 2001 From: Rohit Tanwar Date: Tue, 2 Jan 2018 21:14:44 +0530 Subject: [PATCH 25/61] fixed typos --- snippets/infixToPostFix.md | 2 +- snippets/postfixToInfix.md | 37 ++++++++++++++++++++----------------- 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/snippets/infixToPostFix.md b/snippets/infixToPostFix.md index b05496977..84371ddbc 100644 --- a/snippets/infixToPostFix.md +++ b/snippets/infixToPostFix.md @@ -1,6 +1,6 @@ ### infixToPostfix -Works perfectly! +Works perfectly! ```js const infixToPostfix = expr => { diff --git a/snippets/postfixToInfix.md b/snippets/postfixToInfix.md index 19e191c6b..52d1a89bb 100644 --- a/snippets/postfixToInfix.md +++ b/snippets/postfixToInfix.md @@ -1,32 +1,35 @@ ### postfixToInfix - This one has few errors and does not work properply -```js +``` js const postfixToInfix = RPN => { let convert = RPN.replace(/\^/g,'**').split(/\s+/g).filter(el => !/\s+/.test(el) && el !== '') let stack = [] let result = [] - let friends = {"+" : ["+","-","*","/"],"-":[],"/":["*"],"*":["/","*"],"**":["+","-","*","/"]} + let precedence = {null : 4 ,'**':3 ,'/' : 2,'*': 2,'+':1,'-':1 } convert.forEach(symbol => { + let stra,strb if(!isNaN(parseFloat(symbol)) && isFinite(symbol)){ result.push(symbol) + stack.push(null) } - else if (Object.keys(friends).includes(symbol)) { - a = result.pop() - b = result.pop() - if(stack.length !==0){ - if(friends[symbol].includes(stack.pop())){ - result.push(`${b} ${symbol} ${a}`) - stack.push(symbol) - } - else{ - result.push(`(${b}) ${symbol} ${a}`) - stack.push(symbol) - } + else if (Object.keys(precedence).includes(symbol)) { + let [a,b,opa,opb] = [result.pop(),result.pop(),stack.pop(),stack.pop()] + if(precedence[opb] < precedence[symbol]) { + strb = `(${b})` } - else {result.push(`${b} ${symbol} ${a}`);stack.push(symbol)} - } + else{ + strb = `${b}` + } + if((precedence[opa] < precedence[symbol]) || ((precedence[opa] === precedence[symbol]) && ["/","-"].includes(symbol) )){ + stra = `(${a})` + } + else { + stra = `${a}` + } + result.push(strb +symbol + stra) + stack.push(symbol) + } else throw `${symbol} is not a recognized symbol` }) if(result.length === 1) return result.pop() From d451f85e8d989f48a19fec430a103edd1aebdac4 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Tue, 2 Jan 2018 17:49:07 +0200 Subject: [PATCH 26/61] Updated for cron jobs --- .travis.yml | 1 + scripts/module.js | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/.travis.yml b/.travis.yml index 7b3a3486c..ffb9c3da1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,6 +12,7 @@ script: - npm run linter - npm run builder - npm run webber +- npm run module after_success: - chmod +x .travis/push.sh - .travis/push.sh diff --git a/scripts/module.js b/scripts/module.js index 981b86760..02b8258f9 100644 --- a/scripts/module.js +++ b/scripts/module.js @@ -1,6 +1,11 @@ /* Builds the `_30s` module. */ +const isTravisCI = () => 'TRAVIS' in process.env && 'CI' in process.env; +if(isTravisCI && process.env['TRAVIS_EVENT_TYPE'] !== 'cron') { + console.log(`${chalk.green('NOBUILD')} Build terminated, not a cron job!`); + process.exit(0); +} // Load modules const fs = require('fs-extra'); const cp = require('child_process'); From 61b94a7929881c669114fb5430953d305e1aac66 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Tue, 2 Jan 2018 17:52:37 +0200 Subject: [PATCH 27/61] Fixed bug in the module builder --- scripts/module.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/scripts/module.js b/scripts/module.js index 02b8258f9..4d8afad0c 100644 --- a/scripts/module.js +++ b/scripts/module.js @@ -1,16 +1,18 @@ /* Builds the `_30s` module. */ -const isTravisCI = () => 'TRAVIS' in process.env && 'CI' in process.env; -if(isTravisCI && process.env['TRAVIS_EVENT_TYPE'] !== 'cron') { - console.log(`${chalk.green('NOBUILD')} Build terminated, not a cron job!`); - process.exit(0); -} // Load modules const fs = require('fs-extra'); const cp = require('child_process'); const path = require('path'); 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; +// Check if on Travis and, if not a cron job, terminate. +if(isTravisCI && process.env['TRAVIS_EVENT_TYPE'] !== 'cron') { + console.log(`${chalk.green('NOBUILD')} Build terminated, not a cron job!`); + process.exit(0); +} // Set variables for paths const SNIPPETS_PATH = './snippets'; const TEMP_PATH = './temp'; From b92101f0f5b0717b70c7f76815608f13863ab9e5 Mon Sep 17 00:00:00 2001 From: Travis CI Date: Tue, 2 Jan 2018 15:53:39 +0000 Subject: [PATCH 28/61] Travis build: 855 [ci skip] --- README.md | 21 +++++++++++++-------- docs/index.html | 17 +++++++++++------ snippets/once.md | 4 ++-- 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 3d77ed57c..831b363dd 100644 --- a/README.md +++ b/README.md @@ -2463,23 +2463,28 @@ anagramsCached('javascript'); // returns virtually instantly since it's now cach Ensures a function is called only once. -Utilizing a closure, use a flag, `called`, and set it to `true` once the function is called for the first time, preventing it from being called again. -Allow the function to be supplied with an arbitrary number of arguments using the spread (`...`) operator. +Utilizing a closure, use a flag, `called`, and set it to `true` once the function is called for the first time, preventing it from being called again. In order to allow the function to have its `this` context changed (such as in an event listener), the `function` keyword must be used, and the supplied function must have the context applied. +Allow the function to be supplied with an arbitrary number of arguments using the rest/spread (`...`) operator. ```js -const once = fn => - (called => (...args) => (!called ? ((called = true), fn(...args)) : undefined))(); +const once = fn => { + let called = false; + return function(...args) { + if (called) return; + called = true; + return fn.apply(this, args); + }; +}; ```
    Examples ```js -const startApp = event => { - // initializes the app - console.log(event); // access to any arguments supplied +const startApp = function(event) { + console.log(this, event); // document.body, MouseEvent }; -document.addEventListener('click', once(startApp)); // only runs `startApp` once upon click +document.body.addEventListener('click', once(startApp)); // only runs `startApp` once upon click ```
    diff --git a/docs/index.html b/docs/index.html index aa095370e..92f670e5d 100644 --- a/docs/index.html +++ b/docs/index.html @@ -545,13 +545,18 @@ defer(longRunningFunction); // the browser will update the HTML then run the fun const anagramsCached = memoize(anagrams); anagramsCached('javascript'); // takes a long time anagramsCached('javascript'); // returns virtually instantly since it's now cached -

    once

    Ensures a function is called only once.

    Utilizing a closure, use a flag, called, and set it to true once the function is called for the first time, preventing it from being called again. Allow the function to be supplied with an arbitrary number of arguments using the spread (...) operator.

    const once = fn =>
    -  (called => (...args) => (!called ? ((called = true), fn(...args)) : undefined))();
    -
    const startApp = event => {
    -  // initializes the app
    -  console.log(event); // access to any arguments supplied
    +

    once

    Ensures a function is called only once.

    Utilizing a closure, use a flag, called, and set it to true once the function is called for the first time, preventing it from being called again. In order to allow the function to have its this context changed (such as in an event listener), the function keyword must be used, and the supplied function must have the context applied. Allow the function to be supplied with an arbitrary number of arguments using the rest/spread (...) operator.

    const once = fn => {
    +  let called = false;
    +  return function(...args) {
    +    if (called) return;
    +    called = true;
    +    return fn.apply(this, args);
    +  };
     };
    -document.addEventListener('click', once(startApp)); // only runs `startApp` once upon click
    +
    const startApp = function(event) {
    +  console.log(this, event); // document.body, MouseEvent
    +};
    +document.body.addEventListener('click', once(startApp)); // only runs `startApp` once upon click
     

    runPromisesInSeries

    Runs an array of promises in series.

    Use Array.reduce() to create a promise chain, where each promise returns the next promise when resolved.

    const runPromisesInSeries = ps => ps.reduce((p, next) => p.then(next), Promise.resolve());
     
    const delay = d => new Promise(r => setTimeout(r, d));
     runPromisesInSeries([() => delay(1000), () => delay(2000)]); // //executes each promise sequentially, taking a total of 3 seconds to complete
    diff --git a/snippets/once.md b/snippets/once.md
    index 0705672a9..92ef9c7be 100644
    --- a/snippets/once.md
    +++ b/snippets/once.md
    @@ -10,8 +10,8 @@ const once = fn => {
       let called = false;
       return function(...args) {
         if (called) return;
    -    called = true;
    -    return fn.apply(this, args);
    +    called = true;
    +    return fn.apply(this, args);
       };
     };
     ```
    
    From 092aa988a9c952302c86f740737bffd2b1f1a258 Mon Sep 17 00:00:00 2001
    From: Angelos Chalaris 
    Date: Tue, 2 Jan 2018 17:55:41 +0200
    Subject: [PATCH 29/61] Fixed the travis process
    
    ---
     scripts/module.js | 3 +--
     1 file changed, 1 insertion(+), 2 deletions(-)
    
    diff --git a/scripts/module.js b/scripts/module.js
    index 4d8afad0c..cd812d7d1 100644
    --- a/scripts/module.js
    +++ b/scripts/module.js
    @@ -8,8 +8,7 @@ const path = require('path');
     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;
    -// Check if on Travis and, if not a cron job, terminate.
    -if(isTravisCI && process.env['TRAVIS_EVENT_TYPE'] !== 'cron') {
    +if(isTravisCI() && process.env['TRAVIS_EVENT_TYPE'] !== 'cron') {
       console.log(`${chalk.green('NOBUILD')} Build terminated, not a cron job!`);
       process.exit(0);
     }
    
    From 308146e22aedead25278f9b7262bdd26328cf295 Mon Sep 17 00:00:00 2001
    From: Travis CI 
    Date: Tue, 2 Jan 2018 15:58:26 +0000
    Subject: [PATCH 30/61] Travis build: 857 [ci skip]
    
    ---
     dist/_30s.es5.js     | 443 ++++++++++++++++++++++++++++++++++++-------
     dist/_30s.es5.min.js |   2 +-
     dist/_30s.esm.js     | 273 ++++++++++++++++++++++----
     dist/_30s.js         | 273 ++++++++++++++++++++++----
     dist/_30s.min.js     |   5 +-
     5 files changed, 848 insertions(+), 148 deletions(-)
    
    diff --git a/dist/_30s.es5.js b/dist/_30s.es5.js
    index a798209c9..e35faf55b 100644
    --- a/dist/_30s.es5.js
    +++ b/dist/_30s.es5.js
    @@ -4,6 +4,33 @@
     	(global._30s = factory());
     }(this, (function () { 'use strict';
     
    +var JSONToDate = function JSONToDate(arr) {
    +  var dt = new Date(parseInt(arr.toString().substr(6)));
    +  return dt.getDate() + "/" + (dt.getMonth() + 1) + "/" + dt.getFullYear();
    +};
    +
    +var fs = typeof require !== "undefined" && require('fs');
    +var JSONToFile = function JSONToFile(obj, filename) {
    +  return fs.writeFile(filename + ".json", JSON.stringify(obj, null, 2));
    +};
    +
    +var RGBToHex = function RGBToHex(r, g, b) {
    +  return ((r << 16) + (g << 8) + b).toString(16).padStart(6, '0');
    +};
    +
    +var UUIDGeneratorBrowser = function UUIDGeneratorBrowser() {
    +  return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, function (c) {
    +    return (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16);
    +  });
    +};
    +
    +var crypto$1 = typeof require !== "undefined" && require('crypto');
    +var UUIDGeneratorNode = function UUIDGeneratorNode() {
    +  return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, function (c) {
    +    return (c ^ crypto$1.randomBytes(1)[0] & 15 >> c / 4).toString(16);
    +  });
    +};
    +
     var anagrams = function anagrams(str) {
       if (str.length <= 2) return str.length === 2 ? [str, str[1] + str[0]] : [str];
       return str.split('').reduce(function (acc, letter, i) {
    @@ -95,6 +122,10 @@ var cleanObj = function cleanObj(obj) {
       return obj;
     };
     
    +var cloneRegExp = function cloneRegExp(regExp) {
    +  return new RegExp(regExp.source, regExp.flags);
    +};
    +
     var coalesce = function coalesce() {
       for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
         args[_key] = arguments[_key];
    @@ -145,6 +176,23 @@ var compose = function compose() {
       });
     };
     
    +var copyToClipboard = function copyToClipboard(str) {
    +  var el = document.createElement('textarea');
    +  el.value = str;
    +  el.setAttribute('readonly', '');
    +  el.style.position = 'absolute';
    +  el.style.left = '-9999px';
    +  document.body.appendChild(el);
    +  var selected = document.getSelection().rangeCount > 0 ? document.getSelection().getRangeAt(0) : false;
    +  el.select();
    +  document.execCommand('copy');
    +  document.body.removeChild(el);
    +  if (selected) {
    +    document.getSelection().removeAllRanges();
    +    document.getSelection().addRange(selected);
    +  }
    +};
    +
     var countOccurrences = function countOccurrences(arr, value) {
       return arr.reduce(function (a, v) {
         return v === value ? a + 1 : a + 0;
    @@ -178,6 +226,14 @@ var deepFlatten = function deepFlatten(arr) {
       })));
     };
     
    +var defer = function defer(fn) {
    +  for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
    +    args[_key - 1] = arguments[_key];
    +  }
    +
    +  return setTimeout.apply(undefined, [fn, 1].concat(args));
    +};
    +
     var detectDeviceType = function detectDeviceType() {
       return (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ? 'Mobile' : 'Desktop'
       );
    @@ -243,6 +299,24 @@ var elementIsVisibleInViewport = function elementIsVisibleInViewport(el) {
         return partiallyVisible ? (top > 0 && top < innerHeight || bottom > 0 && bottom < innerHeight) && (left > 0 && left < innerWidth || right > 0 && right < innerWidth) : top >= 0 && left >= 0 && bottom <= innerHeight && right <= innerWidth;
     };
     
    +var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
    +
    +var elo = function elo(_ref) {
    +  var _ref2 = _slicedToArray(_ref, 2),
    +      a = _ref2[0],
    +      b = _ref2[1];
    +
    +  var kFactor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 32;
    +
    +  var expectedScore = function expectedScore(self, opponent) {
    +    return 1 / (1 + Math.pow(10, (opponent - self) / 400));
    +  };
    +  var newRating = function newRating(rating, i) {
    +    return rating + kFactor * (i - expectedScore(i ? a : b, i ? b : a));
    +  };
    +  return [newRating(a, 1), newRating(b, 0)];
    +};
    +
     var escapeHTML = function escapeHTML(str) {
       return str.replace(/[&<>'"]/g, function (tag) {
         return {
    @@ -391,6 +465,16 @@ var hasClass = function hasClass(el, className) {
       return el.classList.contains(className);
     };
     
    +var hasFlags = function hasFlags() {
    +  for (var _len = arguments.length, flags = Array(_len), _key = 0; _key < _len; _key++) {
    +    flags[_key] = arguments[_key];
    +  }
    +
    +  return flags.every(function (flag) {
    +    return process.argv.includes(/^-{1,2}/.test(flag) ? flag : '--' + flag);
    +  });
    +};
    +
     var head = function head(arr) {
       return arr[0];
     };
    @@ -421,6 +505,13 @@ var httpsRedirect = function httpsRedirect() {
       if (location.protocol !== 'https:') location.replace('https://' + location.href.split('//')[1]);
     };
     
    +var inRange = function inRange(n, start) {
    +  var end = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
    +
    +  if (end && start > end) end = [start, start = end][0];
    +  return end == null ? n >= 0 && n < start : n >= start && n < end;
    +};
    +
     var initial = function initial(arr) {
       return arr.slice(0, -1);
     };
    @@ -444,13 +535,6 @@ var initializeArrayWithValues = function initializeArrayWithValues(n) {
       return Array(n).fill(value);
     };
     
    -var inRange = function inRange(n, start) {
    -  var end = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
    -
    -  if (end && start > end) end = [start, start = end][0];
    -  return end == null ? n >= 0 && n < start : n >= start && n < end;
    -};
    -
     var intersection = function intersection(a, b) {
       var s = new Set(b);
       return a.filter(function (x) {
    @@ -458,6 +542,18 @@ var intersection = function intersection(a, b) {
       });
     };
     
    +var invertKeyValues = function invertKeyValues(obj) {
    +  return Object.keys(obj).reduce(function (acc, key) {
    +    acc[obj[key]] = key;
    +    return acc;
    +  }, {});
    +};
    +
    +var isAbsoluteURL = function isAbsoluteURL(str) {
    +  return (/^[a-z][a-z0-9+.-]*:/.test(str)
    +  );
    +};
    +
     var isArmstrongNumber = function isArmstrongNumber(digits) {
       return function (arr) {
         return arr.reduce(function (a, d) {
    @@ -470,6 +566,16 @@ var isArray = function isArray(val) {
       return !!val && Array.isArray(val);
     };
     
    +function _toConsumableArray$5(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
    +
    +var isArrayLike = function isArrayLike(val) {
    +  try {
    +    return [].concat(_toConsumableArray$5(val)), true;
    +  } catch (e) {
    +    return false;
    +  }
    +};
    +
     var isBoolean = function isBoolean(val) {
       return typeof val === 'boolean';
     };
    @@ -486,35 +592,97 @@ var isFunction = function isFunction(val) {
       return val && typeof val === 'function';
     };
     
    +var isNull = function isNull(val) {
    +  return val === null;
    +};
    +
     var isNumber = function isNumber(val) {
       return typeof val === 'number';
     };
     
     var isPrime = function isPrime(num) {
       var boundary = Math.floor(Math.sqrt(num));
    -  for (var i = 2; i * i <= boundary; i++) {
    +  for (var i = 2; i <= boundary; i++) {
         if (num % i == 0) return false;
       }return num >= 2;
     };
     
    +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
    +
    +var isPrimitive = function isPrimitive(val) {
    +  return !['object', 'function'].includes(typeof val === 'undefined' ? 'undefined' : _typeof(val)) || val === null;
    +};
    +
    +var _typeof$1 = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
    +
    +var isPromiseLike = function isPromiseLike(obj) {
    +  return obj !== null && ((typeof obj === 'undefined' ? 'undefined' : _typeof$1(obj)) === 'object' || typeof obj === 'function') && typeof obj.then === 'function';
    +};
    +
    +var _slicedToArray$1 = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
    +
    +var isSorted = function isSorted(arr) {
    +  var direction = arr[0] > arr[1] ? -1 : 1;
    +  var _iteratorNormalCompletion = true;
    +  var _didIteratorError = false;
    +  var _iteratorError = undefined;
    +
    +  try {
    +    for (var _iterator = arr.entries()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
    +      var _ref = _step.value;
    +
    +      var _ref2 = _slicedToArray$1(_ref, 2);
    +
    +      var i = _ref2[0];
    +      var val = _ref2[1];
    +
    +      if (i === arr.length - 1) return direction;else if ((val - arr[i + 1]) * direction > 0) return 0;
    +    }
    +  } catch (err) {
    +    _didIteratorError = true;
    +    _iteratorError = err;
    +  } finally {
    +    try {
    +      if (!_iteratorNormalCompletion && _iterator.return) {
    +        _iterator.return();
    +      }
    +    } finally {
    +      if (_didIteratorError) {
    +        throw _iteratorError;
    +      }
    +    }
    +  }
    +};
    +
     var isString = function isString(val) {
       return typeof val === 'string';
     };
     
    -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
    +var _typeof$2 = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
     
     var isSymbol = function isSymbol(val) {
    -  return (typeof val === 'undefined' ? 'undefined' : _typeof(val)) === 'symbol';
    +  return (typeof val === 'undefined' ? 'undefined' : _typeof$2(val)) === 'symbol';
     };
     
    -var JSONToDate = function JSONToDate(arr) {
    -  var dt = new Date(parseInt(arr.toString().substr(6)));
    -  return dt.getDate() + "/" + (dt.getMonth() + 1) + "/" + dt.getFullYear();
    +var isTravisCI = function isTravisCI() {
    +  return 'TRAVIS' in process.env && 'CI' in process.env;
     };
     
    -var fs = typeof require !== "undefined" && require('fs');
    -var JSONToFile = function JSONToFile(obj, filename) {
    -  return fs.writeFile(filename + ".json", JSON.stringify(obj, null, 2));
    +var isValidJSON = function isValidJSON(obj) {
    +  try {
    +    JSON.parse(obj);
    +    return true;
    +  } catch (e) {
    +    return false;
    +  }
    +};
    +
    +var join = function join(arr) {
    +  var separator = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ',';
    +  var end = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : separator;
    +  return arr.reduce(function (acc, val, i) {
    +    return i == arr.length - 2 ? acc + val + end : i == arr.length - 1 ? acc + val : acc + val + separator;
    +  }, '');
     };
     
     var last = function last(arr) {
    @@ -550,30 +718,43 @@ var mapObject = function mapObject(arr, fn) {
       }();
     };
     
    -function _toConsumableArray$5(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
    -
    -var max = function max() {
    -  var _ref;
    -
    -  return Math.max.apply(Math, _toConsumableArray$5((_ref = []).concat.apply(_ref, arguments)));
    +var mask = function mask(cc) {
    +  var num = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 4;
    +  var mask = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '*';
    +  return ('' + cc).slice(0, -num).replace(/./g, mask) + ('' + cc).slice(-num);
     };
     
     function _toConsumableArray$6(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
     
    +var max = function max() {
    +  var _ref;
    +
    +  return Math.max.apply(Math, _toConsumableArray$6((_ref = []).concat.apply(_ref, arguments)));
    +};
    +
    +function _toConsumableArray$7(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
    +
     var median = function median(arr) {
       var mid = Math.floor(arr.length / 2),
    -      nums = [].concat(_toConsumableArray$6(arr)).sort(function (a, b) {
    +      nums = [].concat(_toConsumableArray$7(arr)).sort(function (a, b) {
         return a - b;
       });
       return arr.length % 2 !== 0 ? nums[mid] : (nums[mid - 1] + nums[mid]) / 2;
     };
     
    -function _toConsumableArray$7(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
    +var memoize = function memoize(fn) {
    +  var cache = Object.create(null);
    +  return function (value) {
    +    return cache[value] || (cache[value] = fn(value));
    +  };
    +};
    +
    +function _toConsumableArray$8(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
     
     var min = function min(arr) {
       var _ref;
     
    -  return Math.min.apply(Math, _toConsumableArray$7((_ref = []).concat.apply(_ref, _toConsumableArray$7(arr))));
    +  return Math.min.apply(Math, _toConsumableArray$8((_ref = []).concat.apply(_ref, _toConsumableArray$8(arr))));
     };
     
     var negate = function negate(func) {
    @@ -613,16 +794,30 @@ var onUserInputChange = function onUserInputChange(callback) {
       });
     };
     
    -var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
    +var once = function once(fn) {
    +  var called = false;
    +  return function () {
    +    if (called) return;
    +    called = true;
     
    -function _toConsumableArray$8(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
    +    for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
    +      args[_key] = arguments[_key];
    +    }
    +
    +    return fn.apply(this, args);
    +  };
    +};
    +
    +var _slicedToArray$2 = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
    +
    +function _toConsumableArray$9(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
     
     var orderBy = function orderBy(arr, props, orders) {
    -  return [].concat(_toConsumableArray$8(arr)).sort(function (a, b) {
    +  return [].concat(_toConsumableArray$9(arr)).sort(function (a, b) {
         return props.reduce(function (acc, prop, i) {
           if (acc === 0) {
             var _ref = orders && orders[i] === 'desc' ? [b[prop], a[prop]] : [a[prop], b[prop]],
    -            _ref2 = _slicedToArray(_ref, 2),
    +            _ref2 = _slicedToArray$2(_ref, 2),
                 p1 = _ref2[0],
                 p2 = _ref2[1];
     
    @@ -670,6 +865,17 @@ var powerset = function powerset(arr) {
       }, [[]]);
     };
     
    +var prettyBytes = function prettyBytes(num) {
    +  var precision = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 3;
    +  var addSpace = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
    +
    +  var UNITS = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
    +  if (Math.abs(num) < 1) return num + (addSpace ? ' ' : '') + UNITS[0];
    +  var exponent = Math.min(Math.floor(Math.log10(num < 0 ? -num : num) / 3), UNITS.length - 1);
    +  var n = Number(((num < 0 ? -num : num) / Math.pow(1000, exponent)).toPrecision(precision));
    +  return (num < 0 ? '-' : '') + n + (addSpace ? ' ' : '') + UNITS[exponent];
    +};
    +
     var primes = function primes(num) {
       var arr = Array.from({ length: num - 1 }).map(function (x, i) {
         return i + 2;
    @@ -744,7 +950,7 @@ var pullAtValue = function pullAtValue(arr, pullArr) {
       return removed;
     };
     
    -function _toConsumableArray$9(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
    +function _toConsumableArray$10(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
     
     function _toArray$1(arr) { return Array.isArray(arr) ? arr : Array.from(arr); }
     
    @@ -753,9 +959,9 @@ var quickSort = function quickSort(_ref, desc) {
           n = _ref2[0],
           nums = _ref2.slice(1);
     
    -  return isNaN(n) ? [] : [].concat(_toConsumableArray$9(quickSort(nums.filter(function (v) {
    +  return isNaN(n) ? [] : [].concat(_toConsumableArray$10(quickSort(nums.filter(function (v) {
         return desc ? v > n : v <= n;
    -  }), desc)), [n], _toConsumableArray$9(quickSort(nums.filter(function (v) {
    +  }), desc)), [n], _toConsumableArray$10(quickSort(nums.filter(function (v) {
         return !desc ? v > n : v <= n;
       }), desc)));
     };
    @@ -783,6 +989,15 @@ var redirect = function redirect(url) {
       return asLink ? window.location.href = url : window.location.replace(url);
     };
     
    +var reducedFilter = function reducedFilter(data, keys, fn) {
    +  return data.filter(fn).map(function (el) {
    +    return keys.reduce(function (acc, key) {
    +      acc[key] = el[key];
    +      return acc;
    +    }, {});
    +  });
    +};
    +
     var remove = function remove(arr, func) {
       return Array.isArray(arr) ? arr.filter(func).reduce(function (acc, val) {
         arr.splice(arr.indexOf(val), 1);
    @@ -801,15 +1016,28 @@ var reverseString = function reverseString(str) {
       return str.split('').reverse().join('');
     };
     
    -var RGBToHex = function RGBToHex(r, g, b) {
    -  return ((r << 16) + (g << 8) + b).toString(16).padStart(6, '0');
    -};
    -
     var round = function round(n) {
       var decimals = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
       return Number(Math.round(n + "e" + decimals) + "e-" + decimals);
     };
     
    +var runAsync = function runAsync(fn) {
    +  var blob = '\n    var fn = ' + fn.toString() + ';\n    this.postMessage(fn());\n  ';
    +  var worker = new Worker(URL.createObjectURL(new Blob([blob]), {
    +    type: 'application/javascript; charset=utf-8'
    +  }));
    +  return new Promise(function (res, rej) {
    +    worker.onmessage = function (_ref) {
    +      var data = _ref.data;
    +
    +      res(data), worker.terminate();
    +    };
    +    worker.onerror = function (err) {
    +      rej(err), worker.terminate();
    +    };
    +  });
    +};
    +
     var runPromisesInSeries = function runPromisesInSeries(ps) {
       return ps.reduce(function (p, next) {
         return p.then(next);
    @@ -820,6 +1048,24 @@ var sample = function sample(arr) {
       return arr[Math.floor(Math.random() * arr.length)];
     };
     
    +function _toArray$2(arr) { return Array.isArray(arr) ? arr : Array.from(arr); }
    +
    +var sampleSize = function sampleSize(_ref) {
    +  var _ref2 = _toArray$2(_ref),
    +      arr = _ref2.slice(0);
    +
    +  var n = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
    +
    +  var m = arr.length;
    +  while (m) {
    +    var i = Math.floor(Math.random() * m--);
    +    var _ref3 = [arr[i], arr[m]];
    +    arr[m] = _ref3[0];
    +    arr[i] = _ref3[1];
    +  }
    +  return arr.slice(0, n);
    +};
    +
     var scrollToTop = function scrollToTop() {
       var c = document.documentElement.scrollTop || document.body.scrollTop;
       if (c > 0) {
    @@ -859,10 +1105,10 @@ var show = function show() {
       });
     };
     
    -function _toArray$2(arr) { return Array.isArray(arr) ? arr : Array.from(arr); }
    +function _toArray$3(arr) { return Array.isArray(arr) ? arr : Array.from(arr); }
     
     var shuffle = function shuffle(_ref) {
    -  var _ref2 = _toArray$2(_ref),
    +  var _ref2 = _toArray$3(_ref),
           arr = _ref2.slice(0);
     
       var m = arr.length;
    @@ -881,18 +1127,72 @@ var similarity = function similarity(arr, values) {
       });
     };
     
    +var _typeof$3 = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
    +
    +var size = function size(value) {
    +  return Array.isArray(value) ? value.length : value && (typeof value === 'undefined' ? 'undefined' : _typeof$3(value)) === 'object' ? value.size || value.length || Object.keys(value).length : typeof value === 'string' ? new Blob([value]).size : 0;
    +};
    +
     var sleep = function sleep(ms) {
       return new Promise(function (resolve) {
         return setTimeout(resolve, ms);
       });
     };
     
    +var solveRPN = function solveRPN(rpn) {
    +  var OPERATORS = {
    +    '*': function _(a, b) {
    +      return a * b;
    +    },
    +    '+': function _(a, b) {
    +      return a + b;
    +    },
    +    '-': function _(a, b) {
    +      return a - b;
    +    },
    +    '/': function _(a, b) {
    +      return a / b;
    +    },
    +    '**': function _(a, b) {
    +      return Math.pow(a, b);
    +    }
    +  };
    +  var _ref = [[], rpn.replace(/\^/g, '**').split(/\s+/g).filter(function (el) {
    +    return !/\s+/.test(el) && el !== '';
    +  })],
    +      stack = _ref[0],
    +      solve = _ref[1];
    +
    +  solve.forEach(function (symbol) {
    +    if (!isNaN(parseFloat(symbol)) && isFinite(symbol)) {
    +      stack.push(symbol);
    +    } else if (Object.keys(OPERATORS).includes(symbol)) {
    +      var _ref2 = [stack.pop(), stack.pop()],
    +          a = _ref2[0],
    +          b = _ref2[1];
    +
    +      stack.push(OPERATORS[symbol](parseFloat(b), parseFloat(a)));
    +    } else {
    +      throw symbol + ' is not a recognized symbol';
    +    }
    +  });
    +  if (stack.length === 1) return stack.pop();else throw rpn + ' is not a proper RPN. Please check it and try again';
    +};
    +
     var sortCharactersInString = function sortCharactersInString(str) {
       return str.split('').sort(function (a, b) {
         return a.localeCompare(b);
       }).join('');
     };
     
    +var sortedIndex = function sortedIndex(arr, n) {
    +  var isDescending = arr[0] > arr[arr.length - 1];
    +  var index = arr.findIndex(function (el) {
    +    return isDescending ? n >= el : n <= el;
    +  });
    +  return index === -1 ? arr.length : index;
    +};
    +
     var speechSynthesis = function speechSynthesis(message) {
       var msg = new SpeechSynthesisUtterance(message);
       msg.voice = window.speechSynthesis.getVoices()[0];
    @@ -903,11 +1203,11 @@ var splitLines = function splitLines(str) {
       return str.split(/\r?\n/);
     };
     
    -function _toConsumableArray$10(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
    +function _toConsumableArray$11(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
     
     var spreadOver = function spreadOver(fn) {
       return function (argsArr) {
    -    return fn.apply(undefined, _toConsumableArray$10(argsArr));
    +    return fn.apply(undefined, _toConsumableArray$11(argsArr));
       };
     };
     
    @@ -932,14 +1232,24 @@ var sum = function sum() {
       }, 0);
     };
     
    -function _toConsumableArray$11(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
    +var sumPower = function sumPower(end) {
    +  var power = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 2;
    +  var start = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
    +  return Array(end + 1 - start).fill(0).map(function (x, i) {
    +    return Math.pow(i + start, power);
    +  }).reduce(function (a, b) {
    +    return a + b;
    +  }, 0);
    +};
    +
    +function _toConsumableArray$12(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
     
     var symmetricDifference = function symmetricDifference(a, b) {
       var sA = new Set(a),
           sB = new Set(b);
    -  return [].concat(_toConsumableArray$11(a.filter(function (x) {
    +  return [].concat(_toConsumableArray$12(a.filter(function (x) {
         return !sB.has(x);
    -  })), _toConsumableArray$11(b.filter(function (x) {
    +  })), _toConsumableArray$12(b.filter(function (x) {
         return !sA.has(x);
       })));
     };
    @@ -982,20 +1292,12 @@ var toEnglishDate = function toEnglishDate(time) {
       } catch (e) {}
     };
     
    -var toggleClass = function toggleClass(el, className) {
    -  return el.classList.toggle(className);
    -};
    -
     var toKebabCase = function toKebabCase(str) {
       return str && str.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g).map(function (x) {
         return x.toLowerCase();
       }).join('-');
     };
     
    -var tomorrow = function tomorrow() {
    -  return new Date(new Date().getTime() + 86400000).toISOString().split('T')[0];
    -};
    -
     var toOrdinalSuffix = function toOrdinalSuffix(num) {
       var int = parseInt(num),
           digits = [int % 10, int % 100],
    @@ -1006,11 +1308,19 @@ var toOrdinalSuffix = function toOrdinalSuffix(num) {
     };
     
     var toSnakeCase = function toSnakeCase(str) {
    -  str && str.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g).map(function (x) {
    +  return str && str.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g).map(function (x) {
         return x.toLowerCase();
       }).join('_');
     };
     
    +var toggleClass = function toggleClass(el, className) {
    +  return el.classList.toggle(className);
    +};
    +
    +var tomorrow = function tomorrow() {
    +  return new Date(new Date().getTime() + 86400000).toISOString().split('T')[0];
    +};
    +
     var truncateString = function truncateString(str, num) {
       return str.length > num ? str.slice(0, num > 3 ? num - 3 : num) + '...' : str;
     };
    @@ -1033,23 +1343,14 @@ var unescapeHTML = function unescapeHTML(str) {
       });
     };
     
    -function _toConsumableArray$12(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
    +function _toConsumableArray$13(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
     
     var union = function union(a, b) {
    -  return Array.from(new Set([].concat(_toConsumableArray$12(a), _toConsumableArray$12(b))));
    +  return Array.from(new Set([].concat(_toConsumableArray$13(a), _toConsumableArray$13(b))));
     };
     
    -var UUIDGeneratorBrowser = function UUIDGeneratorBrowser() {
    -  return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, function (c) {
    -    return (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16);
    -  });
    -};
    -
    -var crypto$1 = typeof require !== "undefined" && require('crypto');
    -var UUIDGeneratorNode = function UUIDGeneratorNode() {
    -  return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, function (c) {
    -    return (c ^ crypto$1.randomBytes(1)[0] & 15 >> c / 4).toString(16);
    -  });
    +var untildify = function untildify(str) {
    +  return str.replace(/^~($|\/|\\)/, (typeof require !== "undefined" && require('os').homedir()) + "$1");
     };
     
     var validateNumber = function validateNumber(n) {
    @@ -1071,14 +1372,20 @@ var words = function words(str) {
       return str.split(pattern).filter(Boolean);
     };
     
    -function _toConsumableArray$13(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
    +var yesNo = function yesNo(val) {
    +  var def = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
    +  return (/^(y|yes)$/i.test(val) ? true : /^(n|no)$/i.test(val) ? false : def
    +  );
    +};
    +
    +function _toConsumableArray$14(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
     
     var zip = function zip() {
       for (var _len = arguments.length, arrays = Array(_len), _key = 0; _key < _len; _key++) {
         arrays[_key] = arguments[_key];
       }
     
    -  var maxLength = Math.max.apply(Math, _toConsumableArray$13(arrays.map(function (x) {
    +  var maxLength = Math.max.apply(Math, _toConsumableArray$14(arrays.map(function (x) {
         return x.length;
       })));
       return Array.from({ length: maxLength }).map(function (_, i) {
    @@ -1094,7 +1401,7 @@ var zipObject = function zipObject(props, values) {
       }, {});
     };
     
    -var imports = { anagrams: anagrams, arrayToHtmlList: arrayToHtmlList, average: average, bottomVisible: bottomVisible, byteSize: byteSize, call: call, capitalize: capitalize, capitalizeEveryWord: capitalizeEveryWord, chainAsync: chainAsync, chunk: chunk, clampNumber: clampNumber, cleanObj: cleanObj, coalesce: coalesce, coalesceFactory: coalesceFactory, collatz: collatz, collectInto: collectInto, compact: compact, compose: compose, countOccurrences: countOccurrences, countVowels: countVowels, currentURL: currentURL, curry: curry, deepFlatten: deepFlatten, detectDeviceType: detectDeviceType, difference: difference, differenceWith: differenceWith, digitize: digitize, distance: distance, distinctValuesOfArray: distinctValuesOfArray, dropElements: dropElements, dropRight: dropRight, elementIsVisibleInViewport: elementIsVisibleInViewport, escapeHTML: escapeHTML, escapeRegExp: escapeRegExp, everyNth: everyNth, extendHex: extendHex, factorial: factorial, fibonacci: fibonacci, fibonacciCountUntilNum: fibonacciCountUntilNum, fibonacciUntilNum: fibonacciUntilNum, filterNonUnique: filterNonUnique, flatten: flatten, flattenDepth: flattenDepth, flip: flip, fromCamelCase: fromCamelCase, functionName: functionName, gcd: gcd, getDaysDiffBetweenDates: getDaysDiffBetweenDates, getScrollPosition: getScrollPosition, getStyle: getStyle, getType: getType, getURLParameters: getURLParameters, groupBy: groupBy, hammingDistance: hammingDistance, hasClass: hasClass, head: head, hexToRGB: hexToRGB, hide: hide, httpsRedirect: httpsRedirect, initial: initial, initialize2DArray: initialize2DArray, initializeArrayWithRange: initializeArrayWithRange, initializeArrayWithValues: initializeArrayWithValues, inRange: inRange, intersection: intersection, isArmstrongNumber: isArmstrongNumber, isArray: isArray, isBoolean: isBoolean, isDivisible: isDivisible, isEven: isEven, isFunction: isFunction, isNumber: isNumber, isPrime: isPrime, isString: isString, isSymbol: isSymbol, JSONToDate: JSONToDate, JSONToFile: JSONToFile, last: last, lcm: lcm, lowercaseKeys: lowercaseKeys, mapObject: mapObject, max: max, median: median, min: min, negate: negate, nthElement: nthElement, objectFromPairs: objectFromPairs, objectToPairs: objectToPairs, onUserInputChange: onUserInputChange, orderBy: orderBy, palindrome: palindrome, percentile: percentile, pick: pick, pipeFunctions: pipeFunctions, powerset: powerset, primes: primes, promisify: promisify, pull: pull, pullAtIndex: pullAtIndex, pullAtValue: pullAtValue, quickSort: quickSort, randomHexColorCode: randomHexColorCode, randomIntegerInRange: randomIntegerInRange, randomNumberInRange: randomNumberInRange, readFileLines: readFileLines, redirect: redirect, remove: remove, repeatString: repeatString, reverseString: reverseString, RGBToHex: RGBToHex, round: round, runPromisesInSeries: runPromisesInSeries, sample: sample, scrollToTop: scrollToTop, sdbm: sdbm, select: select, setStyle: setStyle, shallowClone: shallowClone, show: show, shuffle: shuffle, similarity: similarity, sleep: sleep, sortCharactersInString: sortCharactersInString, speechSynthesis: speechSynthesis, splitLines: splitLines, spreadOver: spreadOver, standardDeviation: standardDeviation, sum: sum, symmetricDifference: symmetricDifference, tail: tail, take: take, takeRight: takeRight, timeTaken: timeTaken, toCamelCase: toCamelCase, toDecimalMark: toDecimalMark, toEnglishDate: toEnglishDate, toggleClass: toggleClass, toKebabCase: toKebabCase, tomorrow: tomorrow, toOrdinalSuffix: toOrdinalSuffix, toSnakeCase: toSnakeCase, truncateString: truncateString, truthCheckCollection: truthCheckCollection, unescapeHTML: unescapeHTML, union: union, UUIDGeneratorBrowser: UUIDGeneratorBrowser, UUIDGeneratorNode: UUIDGeneratorNode, validateNumber: validateNumber, without: without, words: words, zip: zip, zipObject: zipObject };
    +var imports = { JSONToDate: JSONToDate, JSONToFile: JSONToFile, RGBToHex: RGBToHex, UUIDGeneratorBrowser: UUIDGeneratorBrowser, UUIDGeneratorNode: UUIDGeneratorNode, anagrams: anagrams, arrayToHtmlList: arrayToHtmlList, average: average, bottomVisible: bottomVisible, byteSize: byteSize, call: call, capitalize: capitalize, capitalizeEveryWord: capitalizeEveryWord, chainAsync: chainAsync, chunk: chunk, clampNumber: clampNumber, cleanObj: cleanObj, cloneRegExp: cloneRegExp, coalesce: coalesce, coalesceFactory: coalesceFactory, collatz: collatz, collectInto: collectInto, compact: compact, compose: compose, copyToClipboard: copyToClipboard, countOccurrences: countOccurrences, countVowels: countVowels, currentURL: currentURL, curry: curry, deepFlatten: deepFlatten, defer: defer, detectDeviceType: detectDeviceType, difference: difference, differenceWith: differenceWith, digitize: digitize, distance: distance, distinctValuesOfArray: distinctValuesOfArray, dropElements: dropElements, dropRight: dropRight, elementIsVisibleInViewport: elementIsVisibleInViewport, elo: elo, escapeHTML: escapeHTML, escapeRegExp: escapeRegExp, everyNth: everyNth, extendHex: extendHex, factorial: factorial, fibonacci: fibonacci, fibonacciCountUntilNum: fibonacciCountUntilNum, fibonacciUntilNum: fibonacciUntilNum, filterNonUnique: filterNonUnique, flatten: flatten, flattenDepth: flattenDepth, flip: flip, fromCamelCase: fromCamelCase, functionName: functionName, gcd: gcd, getDaysDiffBetweenDates: getDaysDiffBetweenDates, getScrollPosition: getScrollPosition, getStyle: getStyle, getType: getType, getURLParameters: getURLParameters, groupBy: groupBy, hammingDistance: hammingDistance, hasClass: hasClass, hasFlags: hasFlags, head: head, hexToRGB: hexToRGB, hide: hide, httpsRedirect: httpsRedirect, inRange: inRange, initial: initial, initialize2DArray: initialize2DArray, initializeArrayWithRange: initializeArrayWithRange, initializeArrayWithValues: initializeArrayWithValues, intersection: intersection, invertKeyValues: invertKeyValues, isAbsoluteURL: isAbsoluteURL, isArmstrongNumber: isArmstrongNumber, isArray: isArray, isArrayLike: isArrayLike, isBoolean: isBoolean, isDivisible: isDivisible, isEven: isEven, isFunction: isFunction, isNull: isNull, isNumber: isNumber, isPrime: isPrime, isPrimitive: isPrimitive, isPromiseLike: isPromiseLike, isSorted: isSorted, isString: isString, isSymbol: isSymbol, isTravisCI: isTravisCI, isValidJSON: isValidJSON, join: join, last: last, lcm: lcm, lowercaseKeys: lowercaseKeys, mapObject: mapObject, mask: mask, max: max, median: median, memoize: memoize, min: min, negate: negate, nthElement: nthElement, objectFromPairs: objectFromPairs, objectToPairs: objectToPairs, onUserInputChange: onUserInputChange, once: once, orderBy: orderBy, palindrome: palindrome, percentile: percentile, pick: pick, pipeFunctions: pipeFunctions, powerset: powerset, prettyBytes: prettyBytes, primes: primes, promisify: promisify, pull: pull, pullAtIndex: pullAtIndex, pullAtValue: pullAtValue, quickSort: quickSort, randomHexColorCode: randomHexColorCode, randomIntegerInRange: randomIntegerInRange, randomNumberInRange: randomNumberInRange, readFileLines: readFileLines, redirect: redirect, reducedFilter: reducedFilter, remove: remove, repeatString: repeatString, reverseString: reverseString, round: round, runAsync: runAsync, runPromisesInSeries: runPromisesInSeries, sample: sample, sampleSize: sampleSize, scrollToTop: scrollToTop, sdbm: sdbm, select: select, setStyle: setStyle, shallowClone: shallowClone, show: show, shuffle: shuffle, similarity: similarity, size: size, sleep: sleep, solveRPN: solveRPN, sortCharactersInString: sortCharactersInString, sortedIndex: sortedIndex, speechSynthesis: speechSynthesis, splitLines: splitLines, spreadOver: spreadOver, standardDeviation: standardDeviation, sum: sum, sumPower: sumPower, symmetricDifference: symmetricDifference, tail: tail, take: take, takeRight: takeRight, timeTaken: timeTaken, toCamelCase: toCamelCase, toDecimalMark: toDecimalMark, toEnglishDate: toEnglishDate, toKebabCase: toKebabCase, toOrdinalSuffix: toOrdinalSuffix, toSnakeCase: toSnakeCase, toggleClass: toggleClass, tomorrow: tomorrow, truncateString: truncateString, truthCheckCollection: truthCheckCollection, unescapeHTML: unescapeHTML, union: union, untildify: untildify, validateNumber: validateNumber, without: without, words: words, yesNo: yesNo, zip: zip, zipObject: zipObject };
     
     return imports;
     
    diff --git a/dist/_30s.es5.min.js b/dist/_30s.es5.min.js
    index e5913f715..2aaef218f 100644
    --- a/dist/_30s.es5.min.js
    +++ b/dist/_30s.es5.min.js
    @@ -1 +1 @@
    -(function(a,b){'object'==typeof exports&&'undefined'!=typeof module?module.exports=b():'function'==typeof define&&define.amd?define(b):a._30s=b()})(this,function(){'use strict';function a(a){return Array.isArray(a)?a:Array.from(a)}function b(a){if(Array.isArray(a)){for(var b=0,c=Array(a.length);b=b.length?2===b.length?[b,b[1]+b[0]]:[b]:b.split('').reduce(function(c,d,e){return c.concat(a(b.slice(0,e)+b.slice(e+1)).map(function(a){return d+a}))},[])},arrayToHtmlList:function(a,b){return a.map(function(a){return document.querySelector('#'+b).innerHTML+='
  • '+a+'
  • '})},average:function(){var a,b=(a=[]).concat.apply(a,arguments);return b.reduce(function(a,b){return a+b},0)/b.length},bottomVisible:function(){return document.documentElement.clientHeight+window.scrollY>=(document.documentElement.scrollHeight||document.documentElement.clientHeight)},byteSize:function(a){return new Blob([a]).size},call:function(a){for(var b=arguments.length,c=Array(1'"]/g,function(a){return{"&":'&',"<":'<',">":'>',"'":''','"':'"'}[a]||a})},escapeRegExp:function(a){return a.replace(/[.*+?^${}()|[\]\\]/g,'\\$&')},everyNth:function(a,b){return a.filter(function(a,c){return c%b==b-1})},extendHex:function(a){return'#'+a.slice(a.startsWith('#')?1:0).split('').map(function(a){return a+a}).join('')},factorial:function a(b){return 0>b?function(){throw new TypeError('Negative numbers are not allowed!')}():1>=b?1:b*a(b-1)},fibonacci:function(a){return Array.from({length:a}).reduce(function(a,b,c){return a.concat(1>>(b?24:16))+', '+((c&(b?16711680:65280))>>>(b?16:8))+', '+((c&(b?65280:255))>>>(b?8:0))+(b?', '+(255&c):'')+')'},hide:function(){for(var a=arguments.length,b=Array(a),c=0;cc&&(c=b),null==c?0<=a&&a=b&&ae-c&&(b='mouse',a(b),document.removeEventListener('mousemove',d)),c=e};document.addEventListener('touchstart',function(){'touch'==b||(b='touch',a(b),document.addEventListener('mousemove',d))})},orderBy:function(a,c,d){return[].concat(j(a)).sort(function(e,a){return c.reduce(function(b,c,f){if(0===b){var g=d&&'desc'===d[f]?[a[c],e[c]]:[e[c],a[c]],h=A(g,2),i=h[0],j=h[1];b=i>j?1:ie:a<=e}),c)),[e],k(a(f.filter(function(a){return c?a<=e:a>e}),c)))},randomHexColorCode:function(){var a=(0|1048575*Math.random()).toString(16);return'#'+(6===a.length?a:(0|15*Math.random()).toString(16)+a)},randomIntegerInRange:function(a,b){return r(Math.random()*(b-a+1))+a},randomNumberInRange:function(a,b){return Math.random()*(b-a)+a},readFileLines:function(a){return B.readFileSync(a).toString('UTF8').split('\n')},redirect:function(a){var b=1b?a.slice(0,3',"'":'\'',""":'"'}[a]||a})},union:function(c,a){return Array.from(new Set([].concat(p(c),p(a))))},UUIDGeneratorBrowser:function(){return'10000000-1000-4000-8000-100000000000'.replace(/[018]/g,function(a){return(a^crypto.getRandomValues(new Uint8Array(1))[0]&15>>a/4).toString(16)})},UUIDGeneratorNode:function(){return'10000000-1000-4000-8000-100000000000'.replace(/[018]/g,function(a){return(a^C.randomBytes(1)[0]&15>>a/4).toString(16)})},validateNumber:function(a){return!isNaN(parseFloat(a))&&isFinite(a)&&+a==a},without:function(a){for(var b=arguments.length,c=Array(1>a/4).toString(16)})},UUIDGeneratorNode:function(){return'10000000-1000-4000-8000-100000000000'.replace(/[018]/g,function(a){return(a^B.randomBytes(1)[0]&15>>a/4).toString(16)})},anagrams:function a(b){return 2>=b.length?2===b.length?[b,b[1]+b[0]]:[b]:b.split('').reduce(function(c,d,e){return c.concat(a(b.slice(0,e)+b.slice(e+1)).map(function(a){return d+a}))},[])},arrayToHtmlList:function(a,b){return a.map(function(a){return document.querySelector('#'+b).innerHTML+='
  • '+a+'
  • '})},average:function(){var a,b=(a=[]).concat.apply(a,arguments);return b.reduce(function(a,b){return a+b},0)/b.length},bottomVisible:function(){return document.documentElement.clientHeight+window.scrollY>=(document.documentElement.scrollHeight||document.documentElement.clientHeight)},byteSize:function(a){return new Blob([a]).size},call:function(a){for(var b=arguments.length,c=Array(1'"]/g,function(a){return{"&":'&',"<":'<',">":'>',"'":''','"':'"'}[a]||a})},escapeRegExp:function(a){return a.replace(/[.*+?^${}()|[\]\\]/g,'\\$&')},everyNth:function(a,b){return a.filter(function(a,c){return c%b==b-1})},extendHex:function(a){return'#'+a.slice(a.startsWith('#')?1:0).split('').map(function(a){return a+a}).join('')},factorial:function a(b){return 0>b?function(){throw new TypeError('Negative numbers are not allowed!')}():1>=b?1:b*a(b-1)},fibonacci:function(a){return Array.from({length:a}).reduce(function(a,b,c){return a.concat(1>>(b?24:16))+', '+((c&(b?16711680:65280))>>>(b?16:8))+', '+((c&(b?65280:255))>>>(b?8:0))+(b?', '+(255&c):'')+')'},hide:function(){for(var a=arguments.length,b=Array(a),c=0;cc&&(c=b),null==c?0<=a&&a=b&&aa[1]?-1:1,d=!0,e=!1;try{for(var f,g=a.entries()[Symbol.iterator]();!(d=(f=g.next()).done);d=!0){var h=f.value,j=F(h,2),k=j[0],i=j[1];if(k===a.length-1)return c;if(0<(i-a[k+1])*c)return 0}}catch(a){e=!0,b=a}finally{try{!d&&g.return&&g.return()}finally{if(e)throw b}}},isString:function(a){return'string'==typeof a},isSymbol:function(a){return'symbol'===('undefined'==typeof a?'undefined':G(a))},isTravisCI:function(){return'TRAVIS'in process.env&&'CI'in process.env},isValidJSON:function(a){try{return JSON.parse(a),!0}catch(a){return!1}},join:function(a){var b=1e-c&&(b='mouse',a(b),document.removeEventListener('mousemove',d)),c=e};document.addEventListener('touchstart',function(){'touch'==b||(b='touch',a(b),document.addEventListener('mousemove',d))})},once:function(a){var b=!1;return function(){if(!b){b=!0;for(var c=arguments.length,d=Array(c),e=0;ej?1:iMath.abs(a))return a+(c?' ':'')+d[0];var e=x(t(Math.log10(0>a?-a:a)/3),d.length-1),f=+((0>a?-a:a)/w(1e3,e)).toPrecision(b);return(0>a?'-':'')+f+(c?' ':'')+d[e]},primes:function(a){var b=Array.from({length:a-1}).map(function(a,b){return b+2}),c=t(u(a)),d=Array.from({length:c-1}).map(function(a,b){return b+2});return d.forEach(function(a){return b=b.filter(function(b){return 0!=b%a||b==a})}),b},promisify:function(a){return function(){for(var b=arguments.length,c=Array(b),d=0;de:a<=e}),c)),[e],l(a(f.filter(function(a){return c?a<=e:a>e}),c)))},randomHexColorCode:function(){var a=(0|1048575*Math.random()).toString(16);return'#'+(6===a.length?a:(0|15*Math.random()).toString(16)+a)},randomIntegerInRange:function(a,b){return t(Math.random()*(b-a+1))+a},randomNumberInRange:function(a,b){return Math.random()*(b-a)+a},readFileLines:function(a){return I.readFileSync(a).toString('UTF8').split('\n')},redirect:function(a){var b=1a[a.length-1],d=a.findIndex(function(a){return c?b>=a:b<=a});return-1===d?a.length:d},speechSynthesis:function(a){var b=new SpeechSynthesisUtterance(a);b.voice=window.speechSynthesis.getVoices()[0],window.speechSynthesis.speak(b)},splitLines:function(a){return a.split(/\r?\n/)},spreadOver:function(a){return function(b){return a.apply(void 0,p(b))}},standardDeviation:function(a){var b=1b?a.slice(0,3',"'":'\'',""":'"'}[a]||a})},union:function(c,a){return Array.from(new Set([].concat(r(c),r(a))))},untildify:function(a){return a.replace(/^~($|\/|\\)/,('undefined'!=typeof require&&require('os').homedir())+'$1')},validateNumber:function(a){return!isNaN(parseFloat(a))&&isFinite(a)&&+a==a},without:function(a){for(var b=arguments.length,c=Array(1 { + const dt = new Date(parseInt(arr.toString().substr(6))); + return `${dt.getDate()}/${dt.getMonth() + 1}/${dt.getFullYear()}`; +}; + +const fs = typeof require !== "undefined" && require('fs'); +const JSONToFile = (obj, filename) => + fs.writeFile(`${filename}.json`, JSON.stringify(obj, null, 2)); + +const RGBToHex = (r, g, b) => ((r << 16) + (g << 8) + b).toString(16).padStart(6, '0'); + +const UUIDGeneratorBrowser = () => + ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c => + (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16) + ); + +const crypto$1 = typeof require !== "undefined" && require('crypto'); +const UUIDGeneratorNode = () => + ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c => + (c ^ (crypto$1.randomBytes(1)[0] & (15 >> (c / 4)))).toString(16) + ); + const anagrams = str => { if (str.length <= 2) return str.length === 2 ? [str, str[1] + str[0]] : [str]; return str @@ -54,6 +76,8 @@ const cleanObj = (obj, keysToKeep = [], childIndicator) => { return obj; }; +const cloneRegExp = regExp => new RegExp(regExp.source, regExp.flags); + const coalesce = (...args) => args.find(_ => ![undefined, null].includes(_)); const coalesceFactory = valid => (...args) => args.find(valid); @@ -66,6 +90,24 @@ const compact = arr => arr.filter(Boolean); const compose = (...fns) => fns.reduce((f, g) => (...args) => f(g(...args))); +const copyToClipboard = str => { + const el = document.createElement('textarea'); + el.value = str; + el.setAttribute('readonly', ''); + el.style.position = 'absolute'; + el.style.left = '-9999px'; + document.body.appendChild(el); + const selected = + document.getSelection().rangeCount > 0 ? document.getSelection().getRangeAt(0) : false; + el.select(); + document.execCommand('copy'); + document.body.removeChild(el); + if (selected) { + document.getSelection().removeAllRanges(); + document.getSelection().addRange(selected); + } +}; + const countOccurrences = (arr, value) => arr.reduce((a, v) => (v === value ? a + 1 : a + 0), 0); const countVowels = str => (str.match(/[aeiou]/gi) || []).length; @@ -77,6 +119,8 @@ const curry = (fn, arity = fn.length, ...args) => const deepFlatten = arr => [].concat(...arr.map(v => (Array.isArray(v) ? deepFlatten(v) : v))); +const defer = (fn, ...args) => setTimeout(fn, 1, ...args); + const detectDeviceType = () => /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ? 'Mobile' @@ -111,6 +155,12 @@ const elementIsVisibleInViewport = (el, partiallyVisible = false) => { : top >= 0 && left >= 0 && bottom <= innerHeight && right <= innerWidth; }; +const elo = ([a, b], kFactor = 32) => { + const expectedScore = (self, opponent) => 1 / (1 + 10 ** ((opponent - self) / 400)); + const newRating = (rating, i) => rating + kFactor * (i - expectedScore(i ? a : b, i ? b : a)); + return [newRating(a, 1), newRating(b, 0)]; +}; + const escapeHTML = str => str.replace( /[&<>'"]/g, @@ -213,6 +263,9 @@ const hammingDistance = (num1, num2) => ((num1 ^ num2).toString(2).match(/1/g) | const hasClass = (el, className) => el.classList.contains(className); +const hasFlags = (...flags) => + flags.every(flag => process.argv.includes(/^-{1,2}/.test(flag) ? flag : '--' + flag)); + const head = arr => arr[0]; const hexToRGB = hex => { @@ -241,6 +294,11 @@ const httpsRedirect = () => { if (location.protocol !== 'https:') location.replace('https://' + location.href.split('//')[1]); }; +const inRange = (n, start, end = null) => { + if (end && start > end) end = [start, (start = end)][0]; + return end == null ? n >= 0 && n < start : n >= start && n < end; +}; + const initial = arr => arr.slice(0, -1); const initialize2DArray = (w, h, val = null) => @@ -253,23 +311,34 @@ const initializeArrayWithRange = (end, start = 0) => const initializeArrayWithValues = (n, value = 0) => Array(n).fill(value); -const inRange = (n, start, end = null) => { - if (end && start > end) end = [start, (start = end)][0]; - return end == null ? n >= 0 && n < start : n >= start && n < end; -}; - const intersection = (a, b) => { const s = new Set(b); return a.filter(x => s.has(x)); }; +const invertKeyValues = obj => + Object.keys(obj).reduce((acc, key) => { + acc[obj[key]] = key; + return acc; + }, {}); + +const isAbsoluteURL = str => /^[a-z][a-z0-9+.-]*:/.test(str); + const isArmstrongNumber = digits => - (arr => arr.reduce((a, d) => a + Math.pow(parseInt(d), arr.length), 0) == digits)( + (arr => arr.reduce((a, d) => a + parseInt(d) ** arr.length, 0) == digits)( (digits + '').split('') ); const isArray = val => !!val && Array.isArray(val); +const isArrayLike = val => { + try { + return [...val], true; + } catch (e) { + return false; + } +}; + const isBoolean = val => typeof val === 'boolean'; const isDivisible = (dividend, divisor) => dividend % divisor === 0; @@ -278,26 +347,53 @@ const isEven = num => num % 2 === 0; const isFunction = val => val && typeof val === 'function'; +const isNull = val => val === null; + const isNumber = val => typeof val === 'number'; const isPrime = num => { const boundary = Math.floor(Math.sqrt(num)); - for (var i = 2; i * i <= boundary; i++) if (num % i == 0) return false; + for (var i = 2; i <= boundary; i++) if (num % i == 0) return false; return num >= 2; }; +const isPrimitive = val => !['object', 'function'].includes(typeof val) || val === null; + +const isPromiseLike = obj => + obj !== null && + (typeof obj === 'object' || typeof obj === 'function') && + typeof obj.then === 'function'; + +const isSorted = arr => { + const direction = arr[0] > arr[1] ? -1 : 1; + for (let [i, val] of arr.entries()) + if (i === arr.length - 1) return direction; + else if ((val - arr[i + 1]) * direction > 0) return 0; +}; + const isString = val => typeof val === 'string'; const isSymbol = val => typeof val === 'symbol'; -const JSONToDate = arr => { - const dt = new Date(parseInt(arr.toString().substr(6))); - return `${dt.getDate()}/${dt.getMonth() + 1}/${dt.getFullYear()}`; +const isTravisCI = () => 'TRAVIS' in process.env && 'CI' in process.env; + +const isValidJSON = obj => { + try { + JSON.parse(obj); + return true; + } catch (e) { + return false; + } }; -const fs = typeof require !== "undefined" && require('fs'); -const JSONToFile = (obj, filename) => - fs.writeFile(`${filename}.json`, JSON.stringify(obj, null, 2)); +const join = (arr, separator = ',', end = separator) => + arr.reduce( + (acc, val, i) => + i == arr.length - 2 + ? acc + val + end + : i == arr.length - 1 ? acc + val : acc + val + separator, + '' + ); const last = arr => arr[arr.length - 1]; @@ -317,6 +413,9 @@ const mapObject = (arr, fn) => (a => ( a = [arr, arr.map(fn)], a[0].reduce((acc, val, ind) => (acc[val] = a[1][ind], acc), {})))(); +const mask = (cc, num = 4, mask = '*') => + ('' + cc).slice(0, -num).replace(/./g, mask) + ('' + cc).slice(-num); + const max = (...arr) => Math.max(...[].concat(...arr)); const median = arr => { @@ -325,6 +424,11 @@ const median = arr => { return arr.length % 2 !== 0 ? nums[mid] : (nums[mid - 1] + nums[mid]) / 2; }; +const memoize = fn => { + const cache = Object.create(null); + return value => cache[value] || (cache[value] = fn(value)); +}; + const min = arr => Math.min(...[].concat(...arr)); const negate = func => (...args) => !func(...args); @@ -350,6 +454,15 @@ const onUserInputChange = callback => { }); }; +const once = fn => { + let called = false; + return function(...args) { + if (called) return; + called = true; + return fn.apply(this, args); + }; +}; + const orderBy = (arr, props, orders) => [...arr].sort((a, b) => props.reduce((acc, prop, i) => { @@ -382,6 +495,14 @@ const pipeFunctions = (...fns) => fns.reduce((f, g) => (...args) => g(f(...args) const powerset = arr => arr.reduce((a, v) => a.concat(a.map(r => [v].concat(r))), [[]]); +const prettyBytes = (num, precision = 3, addSpace = true) => { + const UNITS = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; + if (Math.abs(num) < 1) return num + (addSpace ? ' ' : '') + UNITS[0]; + const exponent = Math.min(Math.floor(Math.log10(num < 0 ? -num : num) / 3), UNITS.length - 1); + const n = Number(((num < 0 ? -num : num) / 1000 ** exponent).toPrecision(precision)); + return (num < 0 ? '-' : '') + n + (addSpace ? ' ' : '') + UNITS[exponent]; +}; + const primes = num => { let arr = Array.from({ length: num - 1 }).map((x, i) => i + 2), sqroot = Math.floor(Math.sqrt(num)), @@ -449,6 +570,14 @@ const readFileLines = filename => const redirect = (url, asLink = true) => asLink ? (window.location.href = url) : window.location.replace(url); +const reducedFilter = (data, keys, fn) => + data.filter(fn).map(el => + keys.reduce((acc, key) => { + acc[key] = el[key]; + return acc; + }, {}) + ); + const remove = (arr, func) => Array.isArray(arr) ? arr.filter(func).reduce((acc, val) => { @@ -467,14 +596,41 @@ const reverseString = str => .reverse() .join(''); -const RGBToHex = (r, g, b) => ((r << 16) + (g << 8) + b).toString(16).padStart(6, '0'); - const round = (n, decimals = 0) => Number(`${Math.round(`${n}e${decimals}`)}e-${decimals}`); +const runAsync = fn => { + const blob = ` + var fn = ${fn.toString()}; + this.postMessage(fn()); + `; + const worker = new Worker( + URL.createObjectURL(new Blob([blob]), { + type: 'application/javascript; charset=utf-8' + }) + ); + return new Promise((res, rej) => { + worker.onmessage = ({ data }) => { + res(data), worker.terminate(); + }; + worker.onerror = err => { + rej(err), worker.terminate(); + }; + }); +}; + const runPromisesInSeries = ps => ps.reduce((p, next) => p.then(next), Promise.resolve()); const sample = arr => arr[Math.floor(Math.random() * arr.length)]; +const sampleSize = ([...arr], n = 1) => { + let m = arr.length; + while (m) { + const i = Math.floor(Math.random() * m--); + [arr[m], arr[i]] = [arr[i], arr[m]]; + } + return arr.slice(0, n); +}; + const scrollToTop = () => { const c = document.documentElement.scrollTop || document.body.scrollTop; if (c > 0) { @@ -512,14 +668,56 @@ const shuffle = ([...arr]) => { const similarity = (arr, values) => arr.filter(v => values.includes(v)); +const size = value => + Array.isArray(value) + ? value.length + : value && typeof value === 'object' + ? value.size || value.length || Object.keys(value).length + : typeof value === 'string' ? new Blob([value]).size : 0; + const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); +const solveRPN = rpn => { + const OPERATORS = { + '*': (a, b) => a * b, + '+': (a, b) => a + b, + '-': (a, b) => a - b, + '/': (a, b) => a / b, + '**': (a, b) => a ** b + }; + const [stack, solve] = [ + [], + rpn + .replace(/\^/g, '**') + .split(/\s+/g) + .filter(el => !/\s+/.test(el) && el !== '') + ]; + solve.forEach(symbol => { + if (!isNaN(parseFloat(symbol)) && isFinite(symbol)) { + stack.push(symbol); + } else if (Object.keys(OPERATORS).includes(symbol)) { + const [a, b] = [stack.pop(), stack.pop()]; + stack.push(OPERATORS[symbol](parseFloat(b), parseFloat(a))); + } else { + throw `${symbol} is not a recognized symbol`; + } + }); + if (stack.length === 1) return stack.pop(); + else throw `${rpn} is not a proper RPN. Please check it and try again`; +}; + const sortCharactersInString = str => str .split('') .sort((a, b) => a.localeCompare(b)) .join(''); +const sortedIndex = (arr, n) => { + const isDescending = arr[0] > arr[arr.length - 1]; + const index = arr.findIndex(el => (isDescending ? n >= el : n <= el)); + return index === -1 ? arr.length : index; +}; + const speechSynthesis = message => { const msg = new SpeechSynthesisUtterance(message); msg.voice = window.speechSynthesis.getVoices()[0]; @@ -533,15 +731,19 @@ const spreadOver = fn => argsArr => fn(...argsArr); const standardDeviation = (arr, usePopulation = false) => { const mean = arr.reduce((acc, val) => acc + val, 0) / arr.length; return Math.sqrt( - arr - .reduce((acc, val) => acc.concat(Math.pow(val - mean, 2)), []) - .reduce((acc, val) => acc + val, 0) / + arr.reduce((acc, val) => acc.concat((val - mean) ** 2), []).reduce((acc, val) => acc + val, 0) / (arr.length - (usePopulation ? 0 : 1)) ); }; const sum = (...arr) => [].concat(...arr).reduce((acc, val) => acc + val, 0); +const sumPower = (end, power = 2, start = 1) => + Array(end + 1 - start) + .fill(0) + .map((x, i) => (i + start) ** power) + .reduce((a, b) => a + b, 0); + const symmetricDifference = (a, b) => { const sA = new Set(a), sB = new Set(b); @@ -582,8 +784,6 @@ const toEnglishDate = time => { } catch (e) {} }; -const toggleClass = (el, className) => el.classList.toggle(className); - const toKebabCase = str => str && str @@ -591,8 +791,6 @@ const toKebabCase = str => .map(x => x.toLowerCase()) .join('-'); -const tomorrow = () => new Date(new Date().getTime() + 86400000).toISOString().split('T')[0]; - const toOrdinalSuffix = num => { const int = parseInt(num), digits = [int % 10, int % 100], @@ -604,13 +802,16 @@ const toOrdinalSuffix = num => { : int + ordinals[3]; }; -const toSnakeCase = str => { +const toSnakeCase = str => str && - str - .match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g) - .map(x => x.toLowerCase()) - .join('_'); -}; + str + .match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g) + .map(x => x.toLowerCase()) + .join('_'); + +const toggleClass = (el, className) => el.classList.toggle(className); + +const tomorrow = () => new Date(new Date().getTime() + 86400000).toISOString().split('T')[0]; const truncateString = (str, num) => str.length > num ? str.slice(0, num > 3 ? num - 3 : num) + '...' : str; @@ -632,16 +833,7 @@ const unescapeHTML = str => const union = (a, b) => Array.from(new Set([...a, ...b])); -const UUIDGeneratorBrowser = () => - ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c => - (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16) - ); - -const crypto$1 = typeof require !== "undefined" && require('crypto'); -const UUIDGeneratorNode = () => - ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c => - (c ^ (crypto$1.randomBytes(1)[0] & (15 >> (c / 4)))).toString(16) - ); +const untildify = str => str.replace(/^~($|\/|\\)/, `${typeof require !== "undefined" && require('os').homedir()}$1`); const validateNumber = n => !isNaN(parseFloat(n)) && isFinite(n) && Number(n) == n; @@ -649,6 +841,9 @@ const without = (arr, ...args) => arr.filter(v => !args.includes(v)); const words = (str, pattern = /[^a-zA-Z-]+/) => str.split(pattern).filter(Boolean); +const yesNo = (val, def = false) => + /^(y|yes)$/i.test(val) ? true : /^(n|no)$/i.test(val) ? false : def; + const zip = (...arrays) => { const maxLength = Math.max(...arrays.map(x => x.length)); return Array.from({ length: maxLength }).map((_, i) => { @@ -659,6 +854,6 @@ const zip = (...arrays) => { const zipObject = (props, values) => props.reduce((obj, prop, index) => (obj[prop] = values[index], obj), {}); -var imports = {anagrams,arrayToHtmlList,average,bottomVisible,byteSize,call,capitalize,capitalizeEveryWord,chainAsync,chunk,clampNumber,cleanObj,coalesce,coalesceFactory,collatz,collectInto,compact,compose,countOccurrences,countVowels,currentURL,curry,deepFlatten,detectDeviceType,difference,differenceWith,digitize,distance,distinctValuesOfArray,dropElements,dropRight,elementIsVisibleInViewport,escapeHTML,escapeRegExp,everyNth,extendHex,factorial,fibonacci,fibonacciCountUntilNum,fibonacciUntilNum,filterNonUnique,flatten,flattenDepth,flip,fromCamelCase,functionName,gcd,getDaysDiffBetweenDates,getScrollPosition,getStyle,getType,getURLParameters,groupBy,hammingDistance,hasClass,head,hexToRGB,hide,httpsRedirect,initial,initialize2DArray,initializeArrayWithRange,initializeArrayWithValues,inRange,intersection,isArmstrongNumber,isArray,isBoolean,isDivisible,isEven,isFunction,isNumber,isPrime,isString,isSymbol,JSONToDate,JSONToFile,last,lcm,lowercaseKeys,mapObject,max,median,min,negate,nthElement,objectFromPairs,objectToPairs,onUserInputChange,orderBy,palindrome,percentile,pick,pipeFunctions,powerset,primes,promisify,pull,pullAtIndex,pullAtValue,quickSort,randomHexColorCode,randomIntegerInRange,randomNumberInRange,readFileLines,redirect,remove,repeatString,reverseString,RGBToHex,round,runPromisesInSeries,sample,scrollToTop,sdbm,select,setStyle,shallowClone,show,shuffle,similarity,sleep,sortCharactersInString,speechSynthesis,splitLines,spreadOver,standardDeviation,sum,symmetricDifference,tail,take,takeRight,timeTaken,toCamelCase,toDecimalMark,toEnglishDate,toggleClass,toKebabCase,tomorrow,toOrdinalSuffix,toSnakeCase,truncateString,truthCheckCollection,unescapeHTML,union,UUIDGeneratorBrowser,UUIDGeneratorNode,validateNumber,without,words,zip,zipObject,} +var imports = {JSONToDate,JSONToFile,RGBToHex,UUIDGeneratorBrowser,UUIDGeneratorNode,anagrams,arrayToHtmlList,average,bottomVisible,byteSize,call,capitalize,capitalizeEveryWord,chainAsync,chunk,clampNumber,cleanObj,cloneRegExp,coalesce,coalesceFactory,collatz,collectInto,compact,compose,copyToClipboard,countOccurrences,countVowels,currentURL,curry,deepFlatten,defer,detectDeviceType,difference,differenceWith,digitize,distance,distinctValuesOfArray,dropElements,dropRight,elementIsVisibleInViewport,elo,escapeHTML,escapeRegExp,everyNth,extendHex,factorial,fibonacci,fibonacciCountUntilNum,fibonacciUntilNum,filterNonUnique,flatten,flattenDepth,flip,fromCamelCase,functionName,gcd,getDaysDiffBetweenDates,getScrollPosition,getStyle,getType,getURLParameters,groupBy,hammingDistance,hasClass,hasFlags,head,hexToRGB,hide,httpsRedirect,inRange,initial,initialize2DArray,initializeArrayWithRange,initializeArrayWithValues,intersection,invertKeyValues,isAbsoluteURL,isArmstrongNumber,isArray,isArrayLike,isBoolean,isDivisible,isEven,isFunction,isNull,isNumber,isPrime,isPrimitive,isPromiseLike,isSorted,isString,isSymbol,isTravisCI,isValidJSON,join,last,lcm,lowercaseKeys,mapObject,mask,max,median,memoize,min,negate,nthElement,objectFromPairs,objectToPairs,onUserInputChange,once,orderBy,palindrome,percentile,pick,pipeFunctions,powerset,prettyBytes,primes,promisify,pull,pullAtIndex,pullAtValue,quickSort,randomHexColorCode,randomIntegerInRange,randomNumberInRange,readFileLines,redirect,reducedFilter,remove,repeatString,reverseString,round,runAsync,runPromisesInSeries,sample,sampleSize,scrollToTop,sdbm,select,setStyle,shallowClone,show,shuffle,similarity,size,sleep,solveRPN,sortCharactersInString,sortedIndex,speechSynthesis,splitLines,spreadOver,standardDeviation,sum,sumPower,symmetricDifference,tail,take,takeRight,timeTaken,toCamelCase,toDecimalMark,toEnglishDate,toKebabCase,toOrdinalSuffix,toSnakeCase,toggleClass,tomorrow,truncateString,truthCheckCollection,unescapeHTML,union,untildify,validateNumber,without,words,yesNo,zip,zipObject,} export default imports; diff --git a/dist/_30s.js b/dist/_30s.js index a5f06c222..87d430f0b 100644 --- a/dist/_30s.js +++ b/dist/_30s.js @@ -4,6 +4,28 @@ (global._30s = factory()); }(this, (function () { 'use strict'; +const JSONToDate = arr => { + const dt = new Date(parseInt(arr.toString().substr(6))); + return `${dt.getDate()}/${dt.getMonth() + 1}/${dt.getFullYear()}`; +}; + +const fs = typeof require !== "undefined" && require('fs'); +const JSONToFile = (obj, filename) => + fs.writeFile(`${filename}.json`, JSON.stringify(obj, null, 2)); + +const RGBToHex = (r, g, b) => ((r << 16) + (g << 8) + b).toString(16).padStart(6, '0'); + +const UUIDGeneratorBrowser = () => + ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c => + (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16) + ); + +const crypto$1 = typeof require !== "undefined" && require('crypto'); +const UUIDGeneratorNode = () => + ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c => + (c ^ (crypto$1.randomBytes(1)[0] & (15 >> (c / 4)))).toString(16) + ); + const anagrams = str => { if (str.length <= 2) return str.length === 2 ? [str, str[1] + str[0]] : [str]; return str @@ -60,6 +82,8 @@ const cleanObj = (obj, keysToKeep = [], childIndicator) => { return obj; }; +const cloneRegExp = regExp => new RegExp(regExp.source, regExp.flags); + const coalesce = (...args) => args.find(_ => ![undefined, null].includes(_)); const coalesceFactory = valid => (...args) => args.find(valid); @@ -72,6 +96,24 @@ const compact = arr => arr.filter(Boolean); const compose = (...fns) => fns.reduce((f, g) => (...args) => f(g(...args))); +const copyToClipboard = str => { + const el = document.createElement('textarea'); + el.value = str; + el.setAttribute('readonly', ''); + el.style.position = 'absolute'; + el.style.left = '-9999px'; + document.body.appendChild(el); + const selected = + document.getSelection().rangeCount > 0 ? document.getSelection().getRangeAt(0) : false; + el.select(); + document.execCommand('copy'); + document.body.removeChild(el); + if (selected) { + document.getSelection().removeAllRanges(); + document.getSelection().addRange(selected); + } +}; + const countOccurrences = (arr, value) => arr.reduce((a, v) => (v === value ? a + 1 : a + 0), 0); const countVowels = str => (str.match(/[aeiou]/gi) || []).length; @@ -83,6 +125,8 @@ const curry = (fn, arity = fn.length, ...args) => const deepFlatten = arr => [].concat(...arr.map(v => (Array.isArray(v) ? deepFlatten(v) : v))); +const defer = (fn, ...args) => setTimeout(fn, 1, ...args); + const detectDeviceType = () => /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ? 'Mobile' @@ -117,6 +161,12 @@ const elementIsVisibleInViewport = (el, partiallyVisible = false) => { : top >= 0 && left >= 0 && bottom <= innerHeight && right <= innerWidth; }; +const elo = ([a, b], kFactor = 32) => { + const expectedScore = (self, opponent) => 1 / (1 + 10 ** ((opponent - self) / 400)); + const newRating = (rating, i) => rating + kFactor * (i - expectedScore(i ? a : b, i ? b : a)); + return [newRating(a, 1), newRating(b, 0)]; +}; + const escapeHTML = str => str.replace( /[&<>'"]/g, @@ -219,6 +269,9 @@ const hammingDistance = (num1, num2) => ((num1 ^ num2).toString(2).match(/1/g) | const hasClass = (el, className) => el.classList.contains(className); +const hasFlags = (...flags) => + flags.every(flag => process.argv.includes(/^-{1,2}/.test(flag) ? flag : '--' + flag)); + const head = arr => arr[0]; const hexToRGB = hex => { @@ -247,6 +300,11 @@ const httpsRedirect = () => { if (location.protocol !== 'https:') location.replace('https://' + location.href.split('//')[1]); }; +const inRange = (n, start, end = null) => { + if (end && start > end) end = [start, (start = end)][0]; + return end == null ? n >= 0 && n < start : n >= start && n < end; +}; + const initial = arr => arr.slice(0, -1); const initialize2DArray = (w, h, val = null) => @@ -259,23 +317,34 @@ const initializeArrayWithRange = (end, start = 0) => const initializeArrayWithValues = (n, value = 0) => Array(n).fill(value); -const inRange = (n, start, end = null) => { - if (end && start > end) end = [start, (start = end)][0]; - return end == null ? n >= 0 && n < start : n >= start && n < end; -}; - const intersection = (a, b) => { const s = new Set(b); return a.filter(x => s.has(x)); }; +const invertKeyValues = obj => + Object.keys(obj).reduce((acc, key) => { + acc[obj[key]] = key; + return acc; + }, {}); + +const isAbsoluteURL = str => /^[a-z][a-z0-9+.-]*:/.test(str); + const isArmstrongNumber = digits => - (arr => arr.reduce((a, d) => a + Math.pow(parseInt(d), arr.length), 0) == digits)( + (arr => arr.reduce((a, d) => a + parseInt(d) ** arr.length, 0) == digits)( (digits + '').split('') ); const isArray = val => !!val && Array.isArray(val); +const isArrayLike = val => { + try { + return [...val], true; + } catch (e) { + return false; + } +}; + const isBoolean = val => typeof val === 'boolean'; const isDivisible = (dividend, divisor) => dividend % divisor === 0; @@ -284,26 +353,53 @@ const isEven = num => num % 2 === 0; const isFunction = val => val && typeof val === 'function'; +const isNull = val => val === null; + const isNumber = val => typeof val === 'number'; const isPrime = num => { const boundary = Math.floor(Math.sqrt(num)); - for (var i = 2; i * i <= boundary; i++) if (num % i == 0) return false; + for (var i = 2; i <= boundary; i++) if (num % i == 0) return false; return num >= 2; }; +const isPrimitive = val => !['object', 'function'].includes(typeof val) || val === null; + +const isPromiseLike = obj => + obj !== null && + (typeof obj === 'object' || typeof obj === 'function') && + typeof obj.then === 'function'; + +const isSorted = arr => { + const direction = arr[0] > arr[1] ? -1 : 1; + for (let [i, val] of arr.entries()) + if (i === arr.length - 1) return direction; + else if ((val - arr[i + 1]) * direction > 0) return 0; +}; + const isString = val => typeof val === 'string'; const isSymbol = val => typeof val === 'symbol'; -const JSONToDate = arr => { - const dt = new Date(parseInt(arr.toString().substr(6))); - return `${dt.getDate()}/${dt.getMonth() + 1}/${dt.getFullYear()}`; +const isTravisCI = () => 'TRAVIS' in process.env && 'CI' in process.env; + +const isValidJSON = obj => { + try { + JSON.parse(obj); + return true; + } catch (e) { + return false; + } }; -const fs = typeof require !== "undefined" && require('fs'); -const JSONToFile = (obj, filename) => - fs.writeFile(`${filename}.json`, JSON.stringify(obj, null, 2)); +const join = (arr, separator = ',', end = separator) => + arr.reduce( + (acc, val, i) => + i == arr.length - 2 + ? acc + val + end + : i == arr.length - 1 ? acc + val : acc + val + separator, + '' + ); const last = arr => arr[arr.length - 1]; @@ -323,6 +419,9 @@ const mapObject = (arr, fn) => (a => ( a = [arr, arr.map(fn)], a[0].reduce((acc, val, ind) => (acc[val] = a[1][ind], acc), {})))(); +const mask = (cc, num = 4, mask = '*') => + ('' + cc).slice(0, -num).replace(/./g, mask) + ('' + cc).slice(-num); + const max = (...arr) => Math.max(...[].concat(...arr)); const median = arr => { @@ -331,6 +430,11 @@ const median = arr => { return arr.length % 2 !== 0 ? nums[mid] : (nums[mid - 1] + nums[mid]) / 2; }; +const memoize = fn => { + const cache = Object.create(null); + return value => cache[value] || (cache[value] = fn(value)); +}; + const min = arr => Math.min(...[].concat(...arr)); const negate = func => (...args) => !func(...args); @@ -356,6 +460,15 @@ const onUserInputChange = callback => { }); }; +const once = fn => { + let called = false; + return function(...args) { + if (called) return; + called = true; + return fn.apply(this, args); + }; +}; + const orderBy = (arr, props, orders) => [...arr].sort((a, b) => props.reduce((acc, prop, i) => { @@ -388,6 +501,14 @@ const pipeFunctions = (...fns) => fns.reduce((f, g) => (...args) => g(f(...args) const powerset = arr => arr.reduce((a, v) => a.concat(a.map(r => [v].concat(r))), [[]]); +const prettyBytes = (num, precision = 3, addSpace = true) => { + const UNITS = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; + if (Math.abs(num) < 1) return num + (addSpace ? ' ' : '') + UNITS[0]; + const exponent = Math.min(Math.floor(Math.log10(num < 0 ? -num : num) / 3), UNITS.length - 1); + const n = Number(((num < 0 ? -num : num) / 1000 ** exponent).toPrecision(precision)); + return (num < 0 ? '-' : '') + n + (addSpace ? ' ' : '') + UNITS[exponent]; +}; + const primes = num => { let arr = Array.from({ length: num - 1 }).map((x, i) => i + 2), sqroot = Math.floor(Math.sqrt(num)), @@ -455,6 +576,14 @@ const readFileLines = filename => const redirect = (url, asLink = true) => asLink ? (window.location.href = url) : window.location.replace(url); +const reducedFilter = (data, keys, fn) => + data.filter(fn).map(el => + keys.reduce((acc, key) => { + acc[key] = el[key]; + return acc; + }, {}) + ); + const remove = (arr, func) => Array.isArray(arr) ? arr.filter(func).reduce((acc, val) => { @@ -473,14 +602,41 @@ const reverseString = str => .reverse() .join(''); -const RGBToHex = (r, g, b) => ((r << 16) + (g << 8) + b).toString(16).padStart(6, '0'); - const round = (n, decimals = 0) => Number(`${Math.round(`${n}e${decimals}`)}e-${decimals}`); +const runAsync = fn => { + const blob = ` + var fn = ${fn.toString()}; + this.postMessage(fn()); + `; + const worker = new Worker( + URL.createObjectURL(new Blob([blob]), { + type: 'application/javascript; charset=utf-8' + }) + ); + return new Promise((res, rej) => { + worker.onmessage = ({ data }) => { + res(data), worker.terminate(); + }; + worker.onerror = err => { + rej(err), worker.terminate(); + }; + }); +}; + const runPromisesInSeries = ps => ps.reduce((p, next) => p.then(next), Promise.resolve()); const sample = arr => arr[Math.floor(Math.random() * arr.length)]; +const sampleSize = ([...arr], n = 1) => { + let m = arr.length; + while (m) { + const i = Math.floor(Math.random() * m--); + [arr[m], arr[i]] = [arr[i], arr[m]]; + } + return arr.slice(0, n); +}; + const scrollToTop = () => { const c = document.documentElement.scrollTop || document.body.scrollTop; if (c > 0) { @@ -518,14 +674,56 @@ const shuffle = ([...arr]) => { const similarity = (arr, values) => arr.filter(v => values.includes(v)); +const size = value => + Array.isArray(value) + ? value.length + : value && typeof value === 'object' + ? value.size || value.length || Object.keys(value).length + : typeof value === 'string' ? new Blob([value]).size : 0; + const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); +const solveRPN = rpn => { + const OPERATORS = { + '*': (a, b) => a * b, + '+': (a, b) => a + b, + '-': (a, b) => a - b, + '/': (a, b) => a / b, + '**': (a, b) => a ** b + }; + const [stack, solve] = [ + [], + rpn + .replace(/\^/g, '**') + .split(/\s+/g) + .filter(el => !/\s+/.test(el) && el !== '') + ]; + solve.forEach(symbol => { + if (!isNaN(parseFloat(symbol)) && isFinite(symbol)) { + stack.push(symbol); + } else if (Object.keys(OPERATORS).includes(symbol)) { + const [a, b] = [stack.pop(), stack.pop()]; + stack.push(OPERATORS[symbol](parseFloat(b), parseFloat(a))); + } else { + throw `${symbol} is not a recognized symbol`; + } + }); + if (stack.length === 1) return stack.pop(); + else throw `${rpn} is not a proper RPN. Please check it and try again`; +}; + const sortCharactersInString = str => str .split('') .sort((a, b) => a.localeCompare(b)) .join(''); +const sortedIndex = (arr, n) => { + const isDescending = arr[0] > arr[arr.length - 1]; + const index = arr.findIndex(el => (isDescending ? n >= el : n <= el)); + return index === -1 ? arr.length : index; +}; + const speechSynthesis = message => { const msg = new SpeechSynthesisUtterance(message); msg.voice = window.speechSynthesis.getVoices()[0]; @@ -539,15 +737,19 @@ const spreadOver = fn => argsArr => fn(...argsArr); const standardDeviation = (arr, usePopulation = false) => { const mean = arr.reduce((acc, val) => acc + val, 0) / arr.length; return Math.sqrt( - arr - .reduce((acc, val) => acc.concat(Math.pow(val - mean, 2)), []) - .reduce((acc, val) => acc + val, 0) / + arr.reduce((acc, val) => acc.concat((val - mean) ** 2), []).reduce((acc, val) => acc + val, 0) / (arr.length - (usePopulation ? 0 : 1)) ); }; const sum = (...arr) => [].concat(...arr).reduce((acc, val) => acc + val, 0); +const sumPower = (end, power = 2, start = 1) => + Array(end + 1 - start) + .fill(0) + .map((x, i) => (i + start) ** power) + .reduce((a, b) => a + b, 0); + const symmetricDifference = (a, b) => { const sA = new Set(a), sB = new Set(b); @@ -588,8 +790,6 @@ const toEnglishDate = time => { } catch (e) {} }; -const toggleClass = (el, className) => el.classList.toggle(className); - const toKebabCase = str => str && str @@ -597,8 +797,6 @@ const toKebabCase = str => .map(x => x.toLowerCase()) .join('-'); -const tomorrow = () => new Date(new Date().getTime() + 86400000).toISOString().split('T')[0]; - const toOrdinalSuffix = num => { const int = parseInt(num), digits = [int % 10, int % 100], @@ -610,13 +808,16 @@ const toOrdinalSuffix = num => { : int + ordinals[3]; }; -const toSnakeCase = str => { +const toSnakeCase = str => str && - str - .match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g) - .map(x => x.toLowerCase()) - .join('_'); -}; + str + .match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g) + .map(x => x.toLowerCase()) + .join('_'); + +const toggleClass = (el, className) => el.classList.toggle(className); + +const tomorrow = () => new Date(new Date().getTime() + 86400000).toISOString().split('T')[0]; const truncateString = (str, num) => str.length > num ? str.slice(0, num > 3 ? num - 3 : num) + '...' : str; @@ -638,16 +839,7 @@ const unescapeHTML = str => const union = (a, b) => Array.from(new Set([...a, ...b])); -const UUIDGeneratorBrowser = () => - ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c => - (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16) - ); - -const crypto$1 = typeof require !== "undefined" && require('crypto'); -const UUIDGeneratorNode = () => - ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c => - (c ^ (crypto$1.randomBytes(1)[0] & (15 >> (c / 4)))).toString(16) - ); +const untildify = str => str.replace(/^~($|\/|\\)/, `${typeof require !== "undefined" && require('os').homedir()}$1`); const validateNumber = n => !isNaN(parseFloat(n)) && isFinite(n) && Number(n) == n; @@ -655,6 +847,9 @@ const without = (arr, ...args) => arr.filter(v => !args.includes(v)); const words = (str, pattern = /[^a-zA-Z-]+/) => str.split(pattern).filter(Boolean); +const yesNo = (val, def = false) => + /^(y|yes)$/i.test(val) ? true : /^(n|no)$/i.test(val) ? false : def; + const zip = (...arrays) => { const maxLength = Math.max(...arrays.map(x => x.length)); return Array.from({ length: maxLength }).map((_, i) => { @@ -665,7 +860,7 @@ const zip = (...arrays) => { const zipObject = (props, values) => props.reduce((obj, prop, index) => (obj[prop] = values[index], obj), {}); -var imports = {anagrams,arrayToHtmlList,average,bottomVisible,byteSize,call,capitalize,capitalizeEveryWord,chainAsync,chunk,clampNumber,cleanObj,coalesce,coalesceFactory,collatz,collectInto,compact,compose,countOccurrences,countVowels,currentURL,curry,deepFlatten,detectDeviceType,difference,differenceWith,digitize,distance,distinctValuesOfArray,dropElements,dropRight,elementIsVisibleInViewport,escapeHTML,escapeRegExp,everyNth,extendHex,factorial,fibonacci,fibonacciCountUntilNum,fibonacciUntilNum,filterNonUnique,flatten,flattenDepth,flip,fromCamelCase,functionName,gcd,getDaysDiffBetweenDates,getScrollPosition,getStyle,getType,getURLParameters,groupBy,hammingDistance,hasClass,head,hexToRGB,hide,httpsRedirect,initial,initialize2DArray,initializeArrayWithRange,initializeArrayWithValues,inRange,intersection,isArmstrongNumber,isArray,isBoolean,isDivisible,isEven,isFunction,isNumber,isPrime,isString,isSymbol,JSONToDate,JSONToFile,last,lcm,lowercaseKeys,mapObject,max,median,min,negate,nthElement,objectFromPairs,objectToPairs,onUserInputChange,orderBy,palindrome,percentile,pick,pipeFunctions,powerset,primes,promisify,pull,pullAtIndex,pullAtValue,quickSort,randomHexColorCode,randomIntegerInRange,randomNumberInRange,readFileLines,redirect,remove,repeatString,reverseString,RGBToHex,round,runPromisesInSeries,sample,scrollToTop,sdbm,select,setStyle,shallowClone,show,shuffle,similarity,sleep,sortCharactersInString,speechSynthesis,splitLines,spreadOver,standardDeviation,sum,symmetricDifference,tail,take,takeRight,timeTaken,toCamelCase,toDecimalMark,toEnglishDate,toggleClass,toKebabCase,tomorrow,toOrdinalSuffix,toSnakeCase,truncateString,truthCheckCollection,unescapeHTML,union,UUIDGeneratorBrowser,UUIDGeneratorNode,validateNumber,without,words,zip,zipObject,} +var imports = {JSONToDate,JSONToFile,RGBToHex,UUIDGeneratorBrowser,UUIDGeneratorNode,anagrams,arrayToHtmlList,average,bottomVisible,byteSize,call,capitalize,capitalizeEveryWord,chainAsync,chunk,clampNumber,cleanObj,cloneRegExp,coalesce,coalesceFactory,collatz,collectInto,compact,compose,copyToClipboard,countOccurrences,countVowels,currentURL,curry,deepFlatten,defer,detectDeviceType,difference,differenceWith,digitize,distance,distinctValuesOfArray,dropElements,dropRight,elementIsVisibleInViewport,elo,escapeHTML,escapeRegExp,everyNth,extendHex,factorial,fibonacci,fibonacciCountUntilNum,fibonacciUntilNum,filterNonUnique,flatten,flattenDepth,flip,fromCamelCase,functionName,gcd,getDaysDiffBetweenDates,getScrollPosition,getStyle,getType,getURLParameters,groupBy,hammingDistance,hasClass,hasFlags,head,hexToRGB,hide,httpsRedirect,inRange,initial,initialize2DArray,initializeArrayWithRange,initializeArrayWithValues,intersection,invertKeyValues,isAbsoluteURL,isArmstrongNumber,isArray,isArrayLike,isBoolean,isDivisible,isEven,isFunction,isNull,isNumber,isPrime,isPrimitive,isPromiseLike,isSorted,isString,isSymbol,isTravisCI,isValidJSON,join,last,lcm,lowercaseKeys,mapObject,mask,max,median,memoize,min,negate,nthElement,objectFromPairs,objectToPairs,onUserInputChange,once,orderBy,palindrome,percentile,pick,pipeFunctions,powerset,prettyBytes,primes,promisify,pull,pullAtIndex,pullAtValue,quickSort,randomHexColorCode,randomIntegerInRange,randomNumberInRange,readFileLines,redirect,reducedFilter,remove,repeatString,reverseString,round,runAsync,runPromisesInSeries,sample,sampleSize,scrollToTop,sdbm,select,setStyle,shallowClone,show,shuffle,similarity,size,sleep,solveRPN,sortCharactersInString,sortedIndex,speechSynthesis,splitLines,spreadOver,standardDeviation,sum,sumPower,symmetricDifference,tail,take,takeRight,timeTaken,toCamelCase,toDecimalMark,toEnglishDate,toKebabCase,toOrdinalSuffix,toSnakeCase,toggleClass,tomorrow,truncateString,truthCheckCollection,unescapeHTML,union,untildify,validateNumber,without,words,yesNo,zip,zipObject,} return imports; diff --git a/dist/_30s.min.js b/dist/_30s.min.js index d30867b5d..d30739b23 100644 --- a/dist/_30s.min.js +++ b/dist/_30s.min.js @@ -1 +1,4 @@ -(function(a,b){'object'==typeof exports&&'undefined'!=typeof module?module.exports=b():'function'==typeof define&&define.amd?define(b):a._30s=b()})(this,function(){'use strict';var a=Math.floor,b=Math.sqrt,c=Math.pow,d=Math.log,e=Math.min,f=Math.max,g=Math.ceil;const h=(a)=>2>=a.length?2===a.length?[a,a[1]+a[0]]:[a]:a.split('').reduce((b,c,d)=>b.concat(h(a.slice(0,d)+a.slice(d+1)).map((a)=>c+a)),[]),i=(a,b=[],c)=>(Object.keys(a).forEach((d)=>{d===c?i(a[d],b,c):!b.includes(d)&&delete a[d]}),a),j=(a,b=a.length,...c)=>b<=c.length?a(...c):j.bind(null,a,b,...c),k=(a)=>[].concat(...a.map((a)=>Array.isArray(a)?k(a):a)),l=(a)=>0>a?(()=>{throw new TypeError('Negative numbers are not allowed!')})():1>=a?1:a*l(a-1),m=(a,b=1)=>1==b?a.reduce((b,a)=>b.concat(a),[]):a.reduce((c,a)=>c.concat(Array.isArray(a)?m(a,b-1):a),[]),n=(...a)=>{let b=[].concat(...a);const c=(a,b)=>b?n(b,a%b):a;return b.reduce((d,a)=>c(d,a))},o='undefined'!=typeof require&&require('fs'),p=([a,...b],c)=>isNaN(a)?[]:[...p(b.filter((b)=>c?b>a:b<=a),c),a,...p(b.filter((b)=>c?b<=a:b>a),c)],q='undefined'!=typeof require&&require('fs'),r=()=>{const a=document.documentElement.scrollTop||document.body.scrollTop;0a.map((a)=>document.querySelector('#'+b).innerHTML+=`
  • ${a}
  • `),average:(...a)=>{const b=[].concat(...a);return b.reduce((a,b)=>a+b,0)/b.length},bottomVisible:()=>document.documentElement.clientHeight+window.scrollY>=(document.documentElement.scrollHeight||document.documentElement.clientHeight),byteSize:(a)=>new Blob([a]).size,call:(a,...b)=>(c)=>c[a](...b),capitalize:([a,...b],c=!1)=>a.toUpperCase()+(c?b.join('').toLowerCase():b.join('')),capitalizeEveryWord:(a)=>a.replace(/\b[a-z]/g,(a)=>a.toUpperCase()),chainAsync:(a)=>{let b=0;const c=()=>a[b++](c);c()},chunk:(a,b)=>Array.from({length:g(a.length/b)},(c,d)=>a.slice(d*b,d*b+b)),clampNumber:(c,d,a)=>f(e(c,f(d,a)),e(d,a)),cleanObj:i,coalesce:(...a)=>a.find((a)=>![void 0,null].includes(a)),coalesceFactory:(a)=>(...b)=>b.find(a),collatz:(a)=>0==a%2?a/2:3*a+1,collectInto:(a)=>(...b)=>a(b),compact:(a)=>a.filter(Boolean),compose:(...a)=>a.reduce((a,b)=>(...c)=>a(b(...c))),countOccurrences:(a,b)=>a.reduce((c,a)=>a===b?c+1:c+0,0),countVowels:(a)=>(a.match(/[aeiou]/gi)||[]).length,currentURL:()=>window.location.href,curry:j,deepFlatten:k,detectDeviceType:()=>/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)?'Mobile':'Desktop',difference:(c,a)=>{const b=new Set(a);return c.filter((a)=>!b.has(a))},differenceWith:(a,b,c)=>a.filter((d)=>!b.find((a)=>c(d,a))),digitize:(a)=>[...(''+a)].map((a)=>parseInt(a)),distance:(a,b,c,d)=>Math.hypot(c-a,d-b),distinctValuesOfArray:(a)=>[...new Set(a)],dropElements:(a,b)=>{for(;0a.slice(0,-b),elementIsVisibleInViewport:(a,b=!1)=>{const{top:c,left:d,bottom:e,right:f}=a.getBoundingClientRect(),{innerHeight:g,innerWidth:h}=window;return b?(0a.replace(/[&<>'"]/g,(a)=>({"&":'&',"<":'<',">":'>',"'":''','"':'"'})[a]||a),escapeRegExp:(a)=>a.replace(/[.*+?^${}()|[\]\\]/g,'\\$&'),everyNth:(a,b)=>a.filter((a,c)=>c%b==b-1),extendHex:(a)=>'#'+a.slice(a.startsWith('#')?1:0).split('').map((a)=>a+a).join(''),factorial:l,fibonacci:(a)=>Array.from({length:a}).reduce((a,b,c)=>a.concat(1g(d(2.23606797749979*a+1/2)/0.48121182505960347),fibonacciUntilNum:(a)=>{let b=g(d(2.23606797749979*a+1/2)/0.48121182505960347);return Array.from({length:b}).reduce((a,b,c)=>a.concat(1a.filter((b)=>a.indexOf(b)===a.lastIndexOf(b)),flatten:(a)=>[].concat(...a),flattenDepth:m,flip:(a)=>(...b)=>a(b.pop(),...b),fromCamelCase:(a,b='_')=>a.replace(/([a-z\d])([A-Z])/g,'$1'+b+'$2').replace(/([A-Z]+)([A-Z][a-z\d]+)/g,'$1'+b+'$2').toLowerCase(),functionName:(a)=>(console.debug(a.name),a),gcd:n,getDaysDiffBetweenDates:(a,b)=>(b-a)/86400000,getScrollPosition:(a=window)=>({x:a.pageXOffset===void 0?a.scrollLeft:a.pageXOffset,y:a.pageYOffset===void 0?a.scrollTop:a.pageYOffset}),getStyle:(a,b)=>getComputedStyle(a)[b],getType:(a)=>a===void 0?'undefined':null===a?'null':a.constructor.name.toLowerCase(),getURLParameters:(a)=>a.match(/([^?=&]+)(=([^&]*))/g).reduce((b,a)=>(b[a.slice(0,a.indexOf('='))]=a.slice(a.indexOf('=')+1),b),{}),groupBy:(a,b)=>a.map('function'==typeof b?b:(a)=>a[b]).reduce((b,c,d)=>(b[c]=(b[c]||[]).concat(a[d]),b),{}),hammingDistance:(a,b)=>((a^b).toString(2).match(/1/g)||'').length,hasClass:(a,b)=>a.classList.contains(b),head:(a)=>a[0],hexToRGB:(a)=>{let b=!1,c=a.slice(a.startsWith('#')?1:0);return 3===c.length?c=[...c].map((a)=>a+a).join(''):8===c.length&&(b=!0),c=parseInt(c,16),'rgb'+(b?'a':'')+'('+(c>>>(b?24:16))+', '+((c&(b?16711680:65280))>>>(b?16:8))+', '+((c&(b?65280:255))>>>(b?8:0))+(b?`, ${255&c}`:'')+')'},hide:(...a)=>[...a].forEach((a)=>a.style.display='none'),httpsRedirect:()=>{'https:'!==location.protocol&&location.replace('https://'+location.href.split('//')[1])},initial:(a)=>a.slice(0,-1),initialize2DArray:(a,b,c=null)=>Array(b).fill().map(()=>Array(a).fill(c)),initializeArrayWithRange:(a,b=0)=>Array.from({length:a+1-b}).map((a,c)=>c+b),initializeArrayWithValues:(a,b=0)=>Array(a).fill(b),inRange:(a,b,c=null)=>(c&&b>c&&(c=b),null==c?0<=a&&a=b&&a{const b=new Set(a);return c.filter((a)=>b.has(a))},isArmstrongNumber:(a)=>((b)=>b.reduce((e,a)=>e+c(parseInt(a),b.length),0)==a)((a+'').split('')),isArray:(a)=>!!a&&Array.isArray(a),isBoolean:(a)=>'boolean'==typeof a,isDivisible:(a,b)=>0==a%b,isEven:(a)=>0==a%2,isFunction:(a)=>a&&'function'==typeof a,isNumber:(a)=>'number'==typeof a,isPrime:(c)=>{const d=a(b(c));for(var e=2;e*e<=d;e++)if(0==c%e)return!1;return 2<=c},isString:(a)=>'string'==typeof a,isSymbol:(a)=>'symbol'==typeof a,JSONToDate:(a)=>{const b=new Date(parseInt(a.toString().substr(6)));return`${b.getDate()}/${b.getMonth()+1}/${b.getFullYear()}`},JSONToFile:(a,b)=>o.writeFile(`${b}.json`,JSON.stringify(a,null,2)),last:(a)=>a[a.length-1],lcm:(...a)=>{const b=(a,c)=>c?b(c,a%c):a,c=(a,c)=>a*c/b(a,c);return[].concat(...a).reduce((d,a)=>c(d,a))},lowercaseKeys:(a)=>Object.keys(a).reduce((b,c)=>(b[c.toLowerCase()]=a[c],b),{}),mapObject:(b,c)=>((d)=>(d=[b,b.map(c)],d[0].reduce((a,b,c)=>(a[b]=d[1][c],a),{})))(),max:(...a)=>f(...[].concat(...a)),median:(b)=>{const c=a(b.length/2),d=[...b].sort((c,a)=>c-a);return 0==b.length%2?(d[c-1]+d[c])/2:d[c]},min:(a)=>e(...[].concat(...a)),negate:(a)=>(...b)=>!a(...b),nthElement:(a,b=0)=>(0a.reduce((b,a)=>(b[a[0]]=a[1],b),{}),objectToPairs:(a)=>Object.keys(a).map((b)=>[b,a[b]]),onUserInputChange:(a)=>{let b='mouse',c=0;const d=()=>{const e=performance.now();20>e-c&&(b='mouse',a(b),document.removeEventListener('mousemove',d)),c=e};document.addEventListener('touchstart',()=>{'touch'==b||(b='touch',a(b),document.addEventListener('mousemove',d))})},orderBy:(a,c,d)=>[...a].sort((e,a)=>c.reduce((b,c,f)=>{if(0===b){const[g,h]=d&&'desc'===d[f]?[a[c],e[c]]:[e[c],a[c]];b=g>h?1:g{const b=a.toLowerCase().replace(/[\W_]/g,'');return b===b.split('').reverse().join('')},percentile:(a,b)=>100*a.reduce((a,c)=>a+(cb.reduce((b,c)=>(c in a&&(b[c]=a[c]),b),{}),pipeFunctions:(...a)=>a.reduce((a,b)=>(...c)=>b(a(...c))),powerset:(a)=>a.reduce((b,a)=>b.concat(b.map((b)=>[a].concat(b))),[[]]),primes:(c)=>{let d=Array.from({length:c-1}).map((a,b)=>b+2),e=a(b(c)),f=Array.from({length:e-1}).map((a,b)=>b+2);return f.forEach((a)=>d=d.filter((b)=>0!=b%a||b==a)),d},promisify:(a)=>(...b)=>new Promise((c,d)=>a(...b,(a,b)=>a?d(a):c(b))),pull:(a,...b)=>{let c=Array.isArray(b[0])?b[0]:b,d=a.filter((a)=>!c.includes(a));a.length=0,d.forEach((b)=>a.push(b))},pullAtIndex:(a,b)=>{let c=[],d=a.map((a,d)=>b.includes(d)?c.push(a):a).filter((a,c)=>!b.includes(c));return a.length=0,d.forEach((b)=>a.push(b)),c},pullAtValue:(a,b)=>{let c=[],d=a.forEach((a)=>b.includes(a)?c.push(a):a),e=a.filter((a)=>!b.includes(a));return a.length=0,e.forEach((b)=>a.push(b)),c},quickSort:p,randomHexColorCode:()=>{let a=(0|1048575*Math.random()).toString(16);return'#'+(6===a.length?a:(0|15*Math.random()).toString(16)+a)},randomIntegerInRange:(b,c)=>a(Math.random()*(c-b+1))+b,randomNumberInRange:(a,b)=>Math.random()*(b-a)+a,readFileLines:(a)=>q.readFileSync(a).toString('UTF8').split('\n'),redirect:(a,b=!0)=>b?window.location.href=a:window.location.replace(a),remove:(a,b)=>Array.isArray(a)?a.filter(b).reduce((b,c)=>(a.splice(a.indexOf(c),1),b.concat(c)),[]):[],repeatString:(a='',b=2)=>0<=b?a.repeat(b):a,reverseString:(a)=>a.split('').reverse().join(''),RGBToHex:(a,c,d)=>((a<<16)+(c<<8)+d).toString(16).padStart(6,'0'),round:(a,b=0)=>+`${Math.round(`${a}e${b}`)}e-${b}`,runPromisesInSeries:(a)=>a.reduce((a,b)=>a.then(b),Promise.resolve()),sample:(b)=>b[a(Math.random()*b.length)],scrollToTop:r,sdbm:(a)=>{let b=a.split('');return b.reduce((a,b)=>a=b.charCodeAt(0)+(a<<6)+(a<<16)-a,0)},select:(a,b)=>b.split('.').reduce((a,b)=>a&&a[b],a),setStyle:(a,b,c)=>a.style[b]=c,shallowClone:(a)=>Object.assign({},a),show:(...a)=>[...a].forEach((a)=>a.style.display=''),shuffle:([...b])=>{for(let c=b.length;c;){const d=a(Math.random()*c--);[b[c],b[d]]=[b[d],b[c]]}return b},similarity:(a,b)=>a.filter((a)=>b.includes(a)),sleep:(a)=>new Promise((b)=>setTimeout(b,a)),sortCharactersInString:(a)=>a.split('').sort((c,a)=>c.localeCompare(a)).join(''),speechSynthesis:(a)=>{const b=new SpeechSynthesisUtterance(a);b.voice=window.speechSynthesis.getVoices()[0],window.speechSynthesis.speak(b)},splitLines:(a)=>a.split(/\r?\n/),spreadOver:(a)=>(b)=>a(...b),standardDeviation:(a,d=!1)=>{const e=a.reduce((a,b)=>a+b,0)/a.length;return b(a.reduce((a,b)=>a.concat(c(b-e,2)),[]).reduce((a,b)=>a+b,0)/(a.length-(d?0:1)))},sum:(...a)=>[].concat(...a).reduce((a,b)=>a+b,0),symmetricDifference:(c,a)=>{const b=new Set(c),d=new Set(a);return[...c.filter((a)=>!d.has(a)),...a.filter((a)=>!b.has(a))]},tail:(a)=>1a.slice(0,b),takeRight:(a,b=1)=>a.slice(a.length-b,a.length),timeTaken:(a)=>{console.time('timeTaken');const b=a();return console.timeEnd('timeTaken'),b},toCamelCase:(a)=>{let b=a&&a.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g).map((a)=>a.slice(0,1).toUpperCase()+a.slice(1).toLowerCase()).join('');return b.slice(0,1).toLowerCase()+b.slice(1)},toDecimalMark:(a)=>a.toLocaleString('en-US'),toEnglishDate:(a)=>{try{return new Date(a).toISOString().split('T')[0].replace(/-/g,'/')}catch(a){}},toggleClass:(a,b)=>a.classList.toggle(b),toKebabCase:(a)=>a&&a.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g).map((a)=>a.toLowerCase()).join('-'),tomorrow:()=>new Date(new Date().getTime()+8.64e7).toISOString().split('T')[0],toOrdinalSuffix:(a)=>{const b=parseInt(a),c=[b%10,b%100],d=['st','nd','rd','th'];return[1,2,3,4].includes(c[0])&&![11,12,13,14,15,16,17,18,19].includes(c[1])?b+d[c[0]-1]:b+d[3]},toSnakeCase:(a)=>{a&&a.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g).map((a)=>a.toLowerCase()).join('_')},truncateString:(a,b)=>a.length>b?a.slice(0,3a.every((a)=>a[b]),unescapeHTML:(a)=>a.replace(/&|<|>|'|"/g,(a)=>({"&":'&',"<":'<',">":'>',"'":'\'',""":'"'})[a]||a),union:(c,a)=>Array.from(new Set([...c,...a])),UUIDGeneratorBrowser:()=>'10000000-1000-4000-8000-100000000000'.replace(/[018]/g,(a)=>(a^crypto.getRandomValues(new Uint8Array(1))[0]&15>>a/4).toString(16)),UUIDGeneratorNode:()=>'10000000-1000-4000-8000-100000000000'.replace(/[018]/g,(a)=>(a^s.randomBytes(1)[0]&15>>a/4).toString(16)),validateNumber:(a)=>!isNaN(parseFloat(a))&&isFinite(a)&&+a==a,without:(a,...b)=>a.filter((a)=>!b.includes(a)),words:(a,b=/[^a-zA-Z-]+/)=>a.split(b).filter(Boolean),zip:(...a)=>{const b=f(...a.map((a)=>a.length));return Array.from({length:b}).map((b,c)=>Array.from({length:a.length},(b,d)=>a[d][c]))},zipObject:(a,b)=>a.reduce((a,c,d)=>(a[c]=b[d],a),{})}}); +(function(a,b){'object'==typeof exports&&'undefined'!=typeof module?module.exports=b():'function'==typeof define&&define.amd?define(b):a._30s=b()})(this,function(){'use strict';var a=Math.floor,b=Math.sqrt,c=Math.log,d=Math.min,e=Math.max,f=Math.ceil;const g='undefined'!=typeof require&&require('fs'),h='undefined'!=typeof require&&require('crypto'),j=(a)=>2>=a.length?2===a.length?[a,a[1]+a[0]]:[a]:a.split('').reduce((b,c,d)=>b.concat(j(a.slice(0,d)+a.slice(d+1)).map((a)=>c+a)),[]),i=(a,b=[],c)=>(Object.keys(a).forEach((d)=>{d===c?i(a[d],b,c):!b.includes(d)&&delete a[d]}),a),k=(a,b=a.length,...c)=>b<=c.length?a(...c):k.bind(null,a,b,...c),l=(a)=>[].concat(...a.map((a)=>Array.isArray(a)?l(a):a)),m=(a)=>0>a?(()=>{throw new TypeError('Negative numbers are not allowed!')})():1>=a?1:a*m(a-1),n=(a,b=1)=>1==b?a.reduce((b,a)=>b.concat(a),[]):a.reduce((c,a)=>c.concat(Array.isArray(a)?n(a,b-1):a),[]),o=(...a)=>{let b=[].concat(...a);const c=(a,b)=>b?o(b,a%b):a;return b.reduce((d,a)=>c(d,a))},p=([a,...b],c)=>isNaN(a)?[]:[...p(b.filter((b)=>c?b>a:b<=a),c),a,...p(b.filter((b)=>c?b<=a:b>a),c)],q='undefined'!=typeof require&&require('fs'),r=()=>{const a=document.documentElement.scrollTop||document.body.scrollTop;0{const b=new Date(parseInt(a.toString().substr(6)));return`${b.getDate()}/${b.getMonth()+1}/${b.getFullYear()}`},JSONToFile:(a,b)=>g.writeFile(`${b}.json`,JSON.stringify(a,null,2)),RGBToHex:(a,c,d)=>((a<<16)+(c<<8)+d).toString(16).padStart(6,'0'),UUIDGeneratorBrowser:()=>'10000000-1000-4000-8000-100000000000'.replace(/[018]/g,(a)=>(a^crypto.getRandomValues(new Uint8Array(1))[0]&15>>a/4).toString(16)),UUIDGeneratorNode:()=>'10000000-1000-4000-8000-100000000000'.replace(/[018]/g,(a)=>(a^h.randomBytes(1)[0]&15>>a/4).toString(16)),anagrams:j,arrayToHtmlList:(a,b)=>a.map((a)=>document.querySelector('#'+b).innerHTML+=`
  • ${a}
  • `),average:(...a)=>{const b=[].concat(...a);return b.reduce((a,b)=>a+b,0)/b.length},bottomVisible:()=>document.documentElement.clientHeight+window.scrollY>=(document.documentElement.scrollHeight||document.documentElement.clientHeight),byteSize:(a)=>new Blob([a]).size,call:(a,...b)=>(c)=>c[a](...b),capitalize:([a,...b],c=!1)=>a.toUpperCase()+(c?b.join('').toLowerCase():b.join('')),capitalizeEveryWord:(a)=>a.replace(/\b[a-z]/g,(a)=>a.toUpperCase()),chainAsync:(a)=>{let b=0;const c=()=>a[b++](c);c()},chunk:(a,b)=>Array.from({length:f(a.length/b)},(c,d)=>a.slice(d*b,d*b+b)),clampNumber:(c,f,a)=>e(d(c,e(f,a)),d(f,a)),cleanObj:i,cloneRegExp:(a)=>new RegExp(a.source,a.flags),coalesce:(...a)=>a.find((a)=>![void 0,null].includes(a)),coalesceFactory:(a)=>(...b)=>b.find(a),collatz:(a)=>0==a%2?a/2:3*a+1,collectInto:(a)=>(...b)=>a(b),compact:(a)=>a.filter(Boolean),compose:(...a)=>a.reduce((a,b)=>(...c)=>a(b(...c))),copyToClipboard:(a)=>{const b=document.createElement('textarea');b.value=a,b.setAttribute('readonly',''),b.style.position='absolute',b.style.left='-9999px',document.body.appendChild(b);const c=!!(0a.reduce((c,a)=>a===b?c+1:c+0,0),countVowels:(a)=>(a.match(/[aeiou]/gi)||[]).length,currentURL:()=>window.location.href,curry:k,deepFlatten:l,defer:(a,...b)=>setTimeout(a,1,...b),detectDeviceType:()=>/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)?'Mobile':'Desktop',difference:(c,a)=>{const b=new Set(a);return c.filter((a)=>!b.has(a))},differenceWith:(a,b,c)=>a.filter((d)=>!b.find((a)=>c(d,a))),digitize:(a)=>[...(''+a)].map((a)=>parseInt(a)),distance:(a,b,c,d)=>Math.hypot(c-a,d-b),distinctValuesOfArray:(a)=>[...new Set(a)],dropElements:(a,b)=>{for(;0a.slice(0,-b),elementIsVisibleInViewport:(a,b=!1)=>{const{top:c,left:d,bottom:e,right:f}=a.getBoundingClientRect(),{innerHeight:g,innerWidth:h}=window;return b?(0{const d=(a,b)=>1/(1+10**((b-a)/400)),e=(e,f)=>e+b*(f-d(f?c:a,f?a:c));return[e(c,1),e(a,0)]},escapeHTML:(a)=>a.replace(/[&<>'"]/g,(a)=>({"&":'&',"<":'<',">":'>',"'":''','"':'"'})[a]||a),escapeRegExp:(a)=>a.replace(/[.*+?^${}()|[\]\\]/g,'\\$&'),everyNth:(a,b)=>a.filter((a,c)=>c%b==b-1),extendHex:(a)=>'#'+a.slice(a.startsWith('#')?1:0).split('').map((a)=>a+a).join(''),factorial:m,fibonacci:(a)=>Array.from({length:a}).reduce((a,b,c)=>a.concat(1f(c(2.23606797749979*a+1/2)/0.48121182505960347),fibonacciUntilNum:(a)=>{let b=f(c(2.23606797749979*a+1/2)/0.48121182505960347);return Array.from({length:b}).reduce((a,b,c)=>a.concat(1a.filter((b)=>a.indexOf(b)===a.lastIndexOf(b)),flatten:(a)=>[].concat(...a),flattenDepth:n,flip:(a)=>(...b)=>a(b.pop(),...b),fromCamelCase:(a,b='_')=>a.replace(/([a-z\d])([A-Z])/g,'$1'+b+'$2').replace(/([A-Z]+)([A-Z][a-z\d]+)/g,'$1'+b+'$2').toLowerCase(),functionName:(a)=>(console.debug(a.name),a),gcd:o,getDaysDiffBetweenDates:(a,b)=>(b-a)/86400000,getScrollPosition:(a=window)=>({x:a.pageXOffset===void 0?a.scrollLeft:a.pageXOffset,y:a.pageYOffset===void 0?a.scrollTop:a.pageYOffset}),getStyle:(a,b)=>getComputedStyle(a)[b],getType:(a)=>a===void 0?'undefined':null===a?'null':a.constructor.name.toLowerCase(),getURLParameters:(a)=>a.match(/([^?=&]+)(=([^&]*))/g).reduce((b,a)=>(b[a.slice(0,a.indexOf('='))]=a.slice(a.indexOf('=')+1),b),{}),groupBy:(a,b)=>a.map('function'==typeof b?b:(a)=>a[b]).reduce((b,c,d)=>(b[c]=(b[c]||[]).concat(a[d]),b),{}),hammingDistance:(a,b)=>((a^b).toString(2).match(/1/g)||'').length,hasClass:(a,b)=>a.classList.contains(b),hasFlags:(...a)=>a.every((a)=>process.argv.includes(/^-{1,2}/.test(a)?a:'--'+a)),head:(a)=>a[0],hexToRGB:(a)=>{let b=!1,c=a.slice(a.startsWith('#')?1:0);return 3===c.length?c=[...c].map((a)=>a+a).join(''):8===c.length&&(b=!0),c=parseInt(c,16),'rgb'+(b?'a':'')+'('+(c>>>(b?24:16))+', '+((c&(b?16711680:65280))>>>(b?16:8))+', '+((c&(b?65280:255))>>>(b?8:0))+(b?`, ${255&c}`:'')+')'},hide:(...a)=>[...a].forEach((a)=>a.style.display='none'),httpsRedirect:()=>{'https:'!==location.protocol&&location.replace('https://'+location.href.split('//')[1])},inRange:(a,b,c=null)=>(c&&b>c&&(c=b),null==c?0<=a&&a=b&&aa.slice(0,-1),initialize2DArray:(a,b,c=null)=>Array(b).fill().map(()=>Array(a).fill(c)),initializeArrayWithRange:(a,b=0)=>Array.from({length:a+1-b}).map((a,c)=>c+b),initializeArrayWithValues:(a,b=0)=>Array(a).fill(b),intersection:(c,a)=>{const b=new Set(a);return c.filter((a)=>b.has(a))},invertKeyValues:(a)=>Object.keys(a).reduce((b,c)=>(b[a[c]]=c,b),{}),isAbsoluteURL:(a)=>/^[a-z][a-z0-9+.-]*:/.test(a),isArmstrongNumber:(a)=>((b)=>b.reduce((c,a)=>c+parseInt(a)**b.length,0)==a)((a+'').split('')),isArray:(a)=>!!a&&Array.isArray(a),isArrayLike:(a)=>{try{return[...a],!0}catch(a){return!1}},isBoolean:(a)=>'boolean'==typeof a,isDivisible:(a,b)=>0==a%b,isEven:(a)=>0==a%2,isFunction:(a)=>a&&'function'==typeof a,isNull:(a)=>null===a,isNumber:(a)=>'number'==typeof a,isPrime:(c)=>{const d=a(b(c));for(var e=2;e<=d;e++)if(0==c%e)return!1;return 2<=c},isPrimitive:(a)=>!['object','function'].includes(typeof a)||null===a,isPromiseLike:(a)=>null!==a&&('object'==typeof a||'function'==typeof a)&&'function'==typeof a.then,isSorted:(a)=>{const b=a[0]>a[1]?-1:1;for(let[c,d]of a.entries()){if(c===a.length-1)return b;if(0<(d-a[c+1])*b)return 0}},isString:(a)=>'string'==typeof a,isSymbol:(a)=>'symbol'==typeof a,isTravisCI:()=>'TRAVIS'in process.env&&'CI'in process.env,isValidJSON:(a)=>{try{return JSON.parse(a),!0}catch(a){return!1}},join:(a,b=',',c=b)=>a.reduce((d,e,f)=>f==a.length-2?d+e+c:f==a.length-1?d+e:d+e+b,''),last:(a)=>a[a.length-1],lcm:(...a)=>{const b=(a,c)=>c?b(c,a%c):a,c=(a,c)=>a*c/b(a,c);return[].concat(...a).reduce((d,a)=>c(d,a))},lowercaseKeys:(a)=>Object.keys(a).reduce((b,c)=>(b[c.toLowerCase()]=a[c],b),{}),mapObject:(b,c)=>((d)=>(d=[b,b.map(c)],d[0].reduce((a,b,c)=>(a[b]=d[1][c],a),{})))(),mask:(a,b=4,c='*')=>(''+a).slice(0,-b).replace(/./g,c)+(''+a).slice(-b),max:(...a)=>e(...[].concat(...a)),median:(b)=>{const c=a(b.length/2),d=[...b].sort((c,a)=>c-a);return 0==b.length%2?(d[c-1]+d[c])/2:d[c]},memoize:(a)=>{const b=Object.create(null);return(c)=>b[c]||(b[c]=a(c))},min:(a)=>d(...[].concat(...a)),negate:(a)=>(...b)=>!a(...b),nthElement:(a,b=0)=>(0a.reduce((b,a)=>(b[a[0]]=a[1],b),{}),objectToPairs:(a)=>Object.keys(a).map((b)=>[b,a[b]]),onUserInputChange:(a)=>{let b='mouse',c=0;const d=()=>{const e=performance.now();20>e-c&&(b='mouse',a(b),document.removeEventListener('mousemove',d)),c=e};document.addEventListener('touchstart',()=>{'touch'==b||(b='touch',a(b),document.addEventListener('mousemove',d))})},once:(a)=>{let b=!1;return function(...c){if(!b)return b=!0,a.apply(this,c)}},orderBy:(a,c,d)=>[...a].sort((e,a)=>c.reduce((b,c,f)=>{if(0===b){const[g,h]=d&&'desc'===d[f]?[a[c],e[c]]:[e[c],a[c]];b=g>h?1:g{const b=a.toLowerCase().replace(/[\W_]/g,'');return b===b.split('').reverse().join('')},percentile:(a,b)=>100*a.reduce((a,c)=>a+(cb.reduce((b,c)=>(c in a&&(b[c]=a[c]),b),{}),pipeFunctions:(...a)=>a.reduce((a,b)=>(...c)=>b(a(...c))),powerset:(a)=>a.reduce((b,a)=>b.concat(b.map((b)=>[a].concat(b))),[[]]),prettyBytes:(b,c=3,e=!0)=>{const f=['B','KB','MB','GB','TB','PB','EB','ZB','YB'];if(1>Math.abs(b))return b+(e?' ':'')+f[0];const g=d(a(Math.log10(0>b?-b:b)/3),f.length-1),h=+((0>b?-b:b)/1e3**g).toPrecision(c);return(0>b?'-':'')+h+(e?' ':'')+f[g]},primes:(c)=>{let d=Array.from({length:c-1}).map((a,b)=>b+2),e=a(b(c)),f=Array.from({length:e-1}).map((a,b)=>b+2);return f.forEach((a)=>d=d.filter((b)=>0!=b%a||b==a)),d},promisify:(a)=>(...b)=>new Promise((c,d)=>a(...b,(a,b)=>a?d(a):c(b))),pull:(a,...b)=>{let c=Array.isArray(b[0])?b[0]:b,d=a.filter((a)=>!c.includes(a));a.length=0,d.forEach((b)=>a.push(b))},pullAtIndex:(a,b)=>{let c=[],d=a.map((a,d)=>b.includes(d)?c.push(a):a).filter((a,c)=>!b.includes(c));return a.length=0,d.forEach((b)=>a.push(b)),c},pullAtValue:(a,b)=>{let c=[],d=a.forEach((a)=>b.includes(a)?c.push(a):a),e=a.filter((a)=>!b.includes(a));return a.length=0,e.forEach((b)=>a.push(b)),c},quickSort:p,randomHexColorCode:()=>{let a=(0|1048575*Math.random()).toString(16);return'#'+(6===a.length?a:(0|15*Math.random()).toString(16)+a)},randomIntegerInRange:(b,c)=>a(Math.random()*(c-b+1))+b,randomNumberInRange:(a,b)=>Math.random()*(b-a)+a,readFileLines:(a)=>q.readFileSync(a).toString('UTF8').split('\n'),redirect:(a,b=!0)=>b?window.location.href=a:window.location.replace(a),reducedFilter:(a,b,c)=>a.filter(c).map((a)=>b.reduce((b,c)=>(b[c]=a[c],b),{})),remove:(a,b)=>Array.isArray(a)?a.filter(b).reduce((b,c)=>(a.splice(a.indexOf(c),1),b.concat(c)),[]):[],repeatString:(a='',b=2)=>0<=b?a.repeat(b):a,reverseString:(a)=>a.split('').reverse().join(''),round:(a,b=0)=>+`${Math.round(`${a}e${b}`)}e-${b}`,runAsync:(a)=>{const b=` + var fn = ${a.toString()}; + this.postMessage(fn()); + `,c=new Worker(URL.createObjectURL(new Blob([b]),{type:'application/javascript; charset=utf-8'}));return new Promise((a,b)=>{c.onmessage=({data:b})=>{a(b),c.terminate()},c.onerror=(a)=>{b(a),c.terminate()}})},runPromisesInSeries:(a)=>a.reduce((a,b)=>a.then(b),Promise.resolve()),sample:(b)=>b[a(Math.random()*b.length)],sampleSize:([...b],c=1)=>{for(let d=b.length;d;){const c=a(Math.random()*d--);[b[d],b[c]]=[b[c],b[d]]}return b.slice(0,c)},scrollToTop:r,sdbm:(a)=>{let b=a.split('');return b.reduce((a,b)=>a=b.charCodeAt(0)+(a<<6)+(a<<16)-a,0)},select:(a,b)=>b.split('.').reduce((a,b)=>a&&a[b],a),setStyle:(a,b,c)=>a.style[b]=c,shallowClone:(a)=>Object.assign({},a),show:(...a)=>[...a].forEach((a)=>a.style.display=''),shuffle:([...b])=>{for(let c=b.length;c;){const d=a(Math.random()*c--);[b[c],b[d]]=[b[d],b[c]]}return b},similarity:(a,b)=>a.filter((a)=>b.includes(a)),size:(a)=>Array.isArray(a)?a.length:a&&'object'==typeof a?a.size||a.length||Object.keys(a).length:'string'==typeof a?new Blob([a]).size:0,sleep:(a)=>new Promise((b)=>setTimeout(b,a)),solveRPN:(a)=>{const c={"*":(c,a)=>c*a,"+":(c,a)=>c+a,"-":(c,a)=>c-a,"/":(c,a)=>c/a,"**":(c,a)=>c**a},[d,b]=[[],a.replace(/\^/g,'**').split(/\s+/g).filter((a)=>!/\s+/.test(a)&&''!==a)];if(b.forEach((e)=>{if(!isNaN(parseFloat(e))&&isFinite(e))d.push(e);else if(Object.keys(c).includes(e)){const[f,a]=[d.pop(),d.pop()];d.push(c[e](parseFloat(a),parseFloat(f)))}else throw`${e} is not a recognized symbol`}),1===d.length)return d.pop();throw`${a} is not a proper RPN. Please check it and try again`},sortCharactersInString:(a)=>a.split('').sort((c,a)=>c.localeCompare(a)).join(''),sortedIndex:(a,b)=>{const c=a[0]>a[a.length-1],d=a.findIndex((a)=>c?b>=a:b<=a);return-1===d?a.length:d},speechSynthesis:(a)=>{const b=new SpeechSynthesisUtterance(a);b.voice=window.speechSynthesis.getVoices()[0],window.speechSynthesis.speak(b)},splitLines:(a)=>a.split(/\r?\n/),spreadOver:(a)=>(b)=>a(...b),standardDeviation:(a,c=!1)=>{const d=a.reduce((a,b)=>a+b,0)/a.length;return b(a.reduce((a,b)=>a.concat((b-d)**2),[]).reduce((a,b)=>a+b,0)/(a.length-(c?0:1)))},sum:(...a)=>[].concat(...a).reduce((a,b)=>a+b,0),sumPower:(a,b=2,c=1)=>Array(a+1-c).fill(0).map((a,d)=>(d+c)**b).reduce((c,a)=>c+a,0),symmetricDifference:(c,a)=>{const b=new Set(c),d=new Set(a);return[...c.filter((a)=>!d.has(a)),...a.filter((a)=>!b.has(a))]},tail:(a)=>1a.slice(0,b),takeRight:(a,b=1)=>a.slice(a.length-b,a.length),timeTaken:(a)=>{console.time('timeTaken');const b=a();return console.timeEnd('timeTaken'),b},toCamelCase:(a)=>{let b=a&&a.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g).map((a)=>a.slice(0,1).toUpperCase()+a.slice(1).toLowerCase()).join('');return b.slice(0,1).toLowerCase()+b.slice(1)},toDecimalMark:(a)=>a.toLocaleString('en-US'),toEnglishDate:(a)=>{try{return new Date(a).toISOString().split('T')[0].replace(/-/g,'/')}catch(a){}},toKebabCase:(a)=>a&&a.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g).map((a)=>a.toLowerCase()).join('-'),toOrdinalSuffix:(a)=>{const b=parseInt(a),c=[b%10,b%100],d=['st','nd','rd','th'];return[1,2,3,4].includes(c[0])&&![11,12,13,14,15,16,17,18,19].includes(c[1])?b+d[c[0]-1]:b+d[3]},toSnakeCase:(a)=>a&&a.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g).map((a)=>a.toLowerCase()).join('_'),toggleClass:(a,b)=>a.classList.toggle(b),tomorrow:()=>new Date(new Date().getTime()+8.64e7).toISOString().split('T')[0],truncateString:(a,b)=>a.length>b?a.slice(0,3a.every((a)=>a[b]),unescapeHTML:(a)=>a.replace(/&|<|>|'|"/g,(a)=>({"&":'&',"<":'<',">":'>',"'":'\'',""":'"'})[a]||a),union:(c,a)=>Array.from(new Set([...c,...a])),untildify:(a)=>a.replace(/^~($|\/|\\)/,`${'undefined'!=typeof require&&require('os').homedir()}$1`),validateNumber:(a)=>!isNaN(parseFloat(a))&&isFinite(a)&&+a==a,without:(a,...b)=>a.filter((a)=>!b.includes(a)),words:(a,b=/[^a-zA-Z-]+/)=>a.split(b).filter(Boolean),yesNo:(a,b=!1)=>!!/^(y|yes)$/i.test(a)||!/^(n|no)$/i.test(a)&&b,zip:(...a)=>{const b=e(...a.map((a)=>a.length));return Array.from({length:b}).map((b,c)=>Array.from({length:a.length},(b,d)=>a[d][c]))},zipObject:(a,b)=>a.reduce((a,c,d)=>(a[c]=b[d],a),{})}}); From fb57e9c4bed55842e504fe3565e964ccfccfb346 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Tue, 2 Jan 2018 18:03:50 +0200 Subject: [PATCH 31/61] Added a [cron] tag to cron builds --- .travis/push.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.travis/push.sh b/.travis/push.sh index dd539799c..9f5d53602 100755 --- a/.travis/push.sh +++ b/.travis/push.sh @@ -9,7 +9,11 @@ commit_website_files() { echo "Committing to master branch..." git checkout master git add * - git commit --message "Travis build: $TRAVIS_BUILD_NUMBER [ci skip]" + if [ $TRAVIS_EVENT_TYPE == "cron" ]; then + git commit --message "[cron] Travis build: $TRAVIS_BUILD_NUMBER [ci skip]" + else + git commit --message "Travis build: $TRAVIS_BUILD_NUMBER [ci skip]" + fi fi fi } From f0b2cb7f9c1585db1fdddd762e0f98596c4f6e0c Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Tue, 2 Jan 2018 21:20:22 +0200 Subject: [PATCH 32/61] Updated scripts and travis to handle cron jobs properly --- .travis/push.sh | 4 ++-- scripts/build.js | 7 ++++++- scripts/lint.js | 7 ++++++- scripts/module.js | 4 ++-- scripts/tag.js | 6 ++++++ scripts/web.js | 6 ++++++ 6 files changed, 28 insertions(+), 6 deletions(-) diff --git a/.travis/push.sh b/.travis/push.sh index 9f5d53602..0cd1495b3 100755 --- a/.travis/push.sh +++ b/.travis/push.sh @@ -10,9 +10,9 @@ commit_website_files() { git checkout master git add * if [ $TRAVIS_EVENT_TYPE == "cron" ]; then - git commit --message "[cron] Travis build: $TRAVIS_BUILD_NUMBER [ci skip]" + git commit --message "Travis build: $TRAVIS_BUILD_NUMBER [cron]" else - git commit --message "Travis build: $TRAVIS_BUILD_NUMBER [ci skip]" + git commit --message "Travis build: $TRAVIS_BUILD_NUMBER" fi fi fi diff --git a/scripts/build.js b/scripts/build.js index 879b8e9bf..eaab7dff8 100644 --- a/scripts/build.js +++ b/scripts/build.js @@ -6,7 +6,12 @@ const fs = require('fs-extra'); const path = require('path'); 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() && (/^Travis build: \d+/g.test(process.env['TRAVIS_COMMIT_MESSAGE'])) { + console.log(`${chalk.green('NOBUILD')} README build terminated, parent commit is a Travis build!`); + process.exit(0); +} const SNIPPETS_PATH = './snippets'; const STATIC_PARTS_PATH = './static-parts'; diff --git a/scripts/lint.js b/scripts/lint.js index 833ef3dbd..43a5d6546 100644 --- a/scripts/lint.js +++ b/scripts/lint.js @@ -9,7 +9,12 @@ const fs = require('fs-extra'); const cp = require('child_process'); const path = require('path'); 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() && (/^Travis build: \d+/g.test(process.env['TRAVIS_COMMIT_MESSAGE'])) { + console.log(`${chalk.green('NOBUILD')} Linting terminated, parent commit is a Travis build!`); + process.exit(0); +} const SNIPPETS_PATH = './snippets'; const TEMP_PATH = './temp'; diff --git a/scripts/module.js b/scripts/module.js index cd812d7d1..254afdeaa 100644 --- a/scripts/module.js +++ b/scripts/module.js @@ -8,8 +8,8 @@ const path = require('path'); 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') { - console.log(`${chalk.green('NOBUILD')} Build terminated, not a cron job!`); +if(isTravisCI() && (process.env['TRAVIS_EVENT_TYPE'] !== 'cron' || process.env['TRAVIS_EVENT_TYPE'] !== 'api')) { + console.log(`${chalk.green('NOBUILD')} Module build terminated, not a cron job or a custom build!`); process.exit(0); } // Set variables for paths diff --git a/scripts/tag.js b/scripts/tag.js index 2c8ed9b0a..14fb053f0 100644 --- a/scripts/tag.js +++ b/scripts/tag.js @@ -6,6 +6,12 @@ const fs = require('fs-extra'), path = require('path'), 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() && (/^Travis build: \d+/g.test(process.env['TRAVIS_COMMIT_MESSAGE'])) { + console.log(`${chalk.green('NOBUILD')} Tagging terminated, parent commit is a Travis build!`); + process.exit(0); +} // Set variables for paths const snippetsPath = './snippets'; // Set variables for script diff --git a/scripts/web.js b/scripts/web.js index ac72efc54..841faac15 100644 --- a/scripts/web.js +++ b/scripts/web.js @@ -8,6 +8,12 @@ const fs = require('fs-extra'), chalk = require('chalk'), md = require('markdown-it')(), minify = require('html-minifier').minify; + // 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() && (/^Travis build: \d+/g.test(process.env['TRAVIS_COMMIT_MESSAGE'])) { + console.log(`${chalk.green('NOBUILD')} index build terminated, parent commit is a Travis build!`); + process.exit(0); +} // Compile the mini.css framework and custom CSS styles, using `node-sass`. const sass = require('node-sass'); sass.render( From 0a4ada771c6d5473619d0f8f44c17e67c0712607 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Tue, 2 Jan 2018 21:23:56 +0200 Subject: [PATCH 33/61] Fixed scripts --- scripts/build.js | 2 +- scripts/lint.js | 2 +- scripts/tag.js | 2 +- scripts/web.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/build.js b/scripts/build.js index eaab7dff8..1b9a464a6 100644 --- a/scripts/build.js +++ b/scripts/build.js @@ -8,7 +8,7 @@ const path = require('path'); 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() && (/^Travis build: \d+/g.test(process.env['TRAVIS_COMMIT_MESSAGE'])) { +if(isTravisCI() && /^Travis build: \d+/g.test(process.env['TRAVIS_COMMIT_MESSAGE'])) { console.log(`${chalk.green('NOBUILD')} README build terminated, parent commit is a Travis build!`); process.exit(0); } diff --git a/scripts/lint.js b/scripts/lint.js index 43a5d6546..d8140b8a4 100644 --- a/scripts/lint.js +++ b/scripts/lint.js @@ -11,7 +11,7 @@ const path = require('path'); 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() && (/^Travis build: \d+/g.test(process.env['TRAVIS_COMMIT_MESSAGE'])) { +if(isTravisCI() && /^Travis build: \d+/g.test(process.env['TRAVIS_COMMIT_MESSAGE'])) { console.log(`${chalk.green('NOBUILD')} Linting terminated, parent commit is a Travis build!`); process.exit(0); } diff --git a/scripts/tag.js b/scripts/tag.js index 14fb053f0..bf57fd7cf 100644 --- a/scripts/tag.js +++ b/scripts/tag.js @@ -8,7 +8,7 @@ const fs = require('fs-extra'), 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() && (/^Travis build: \d+/g.test(process.env['TRAVIS_COMMIT_MESSAGE'])) { +if(isTravisCI() && /^Travis build: \d+/g.test(process.env['TRAVIS_COMMIT_MESSAGE'])) { console.log(`${chalk.green('NOBUILD')} Tagging terminated, parent commit is a Travis build!`); process.exit(0); } diff --git a/scripts/web.js b/scripts/web.js index 841faac15..68b0319e0 100644 --- a/scripts/web.js +++ b/scripts/web.js @@ -10,7 +10,7 @@ const fs = require('fs-extra'), minify = require('html-minifier').minify; // 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() && (/^Travis build: \d+/g.test(process.env['TRAVIS_COMMIT_MESSAGE'])) { +if(isTravisCI() && /^Travis build: \d+/g.test(process.env['TRAVIS_COMMIT_MESSAGE'])) { console.log(`${chalk.green('NOBUILD')} index build terminated, parent commit is a Travis build!`); process.exit(0); } From 038b7a921938474057d5e27dac01e1e9493b99d9 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Tue, 2 Jan 2018 21:41:13 +0200 Subject: [PATCH 34/61] Travis Build: 866 [api] --- .travis/push.sh | 2 + README.md | 4216 +++++++++++++++++++++--------------------- dist/_30s.es5.js | 114 +- dist/_30s.es5.min.js | 2 +- dist/_30s.esm.js | 82 +- dist/_30s.js | 82 +- dist/_30s.min.js | 4 +- 7 files changed, 2252 insertions(+), 2250 deletions(-) diff --git a/.travis/push.sh b/.travis/push.sh index 0cd1495b3..38e97512b 100755 --- a/.travis/push.sh +++ b/.travis/push.sh @@ -11,6 +11,8 @@ commit_website_files() { git add * if [ $TRAVIS_EVENT_TYPE == "cron" ]; then git commit --message "Travis build: $TRAVIS_BUILD_NUMBER [cron]" + elif [ $TRAVIS_EVENT_TYPE == "api" ]; then + git commit --message "Travis build: $TRAVIS_BUILD_NUMBER [custom]" else git commit --message "Travis build: $TRAVIS_BUILD_NUMBER" fi diff --git a/README.md b/README.md index 831b363dd..03cce1434 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,19 @@ -![Logo](/logo.png) - -# 30 seconds of code -[![License](https://img.shields.io/badge/license-CC0--1.0-blue.svg)](https://github.com/Chalarangelo/30-seconds-of-code/blob/master/LICENSE) [![Gitter chat](https://img.shields.io/badge/chat-on%20gitter-4FB999.svg)](https://gitter.im/30-seconds-of-code/Lobby) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](http://makeapullrequest.com) [![Travis Build](https://travis-ci.org/Chalarangelo/30-seconds-of-code.svg?branch=master)](https://travis-ci.org/Chalarangelo/30-seconds-of-code) [![Insight.io](https://img.shields.io/badge/insight.io-Ready-brightgreen.svg)](https://insight.io/github.com/Chalarangelo/30-seconds-of-code/tree/master/?source=0) [![js-semistandard-style](https://img.shields.io/badge/code%20style-semistandard-brightgreen.svg)](https://github.com/Flet/semistandard) - -> 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. -- Contributions welcome, please read the [contribution guide](CONTRIBUTING.md). -- 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/tsoc). Bear in mind that most of these snippets are not production-ready. - -## Table of Contents +![Logo](/logo.png) + +# 30 seconds of code +[![License](https://img.shields.io/badge/license-CC0--1.0-blue.svg)](https://github.com/Chalarangelo/30-seconds-of-code/blob/master/LICENSE) [![Gitter chat](https://img.shields.io/badge/chat-on%20gitter-4FB999.svg)](https://gitter.im/30-seconds-of-code/Lobby) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](http://makeapullrequest.com) [![Travis Build](https://travis-ci.org/Chalarangelo/30-seconds-of-code.svg?branch=master)](https://travis-ci.org/Chalarangelo/30-seconds-of-code) [![Insight.io](https://img.shields.io/badge/insight.io-Ready-brightgreen.svg)](https://insight.io/github.com/Chalarangelo/30-seconds-of-code/tree/master/?source=0) [![js-semistandard-style](https://img.shields.io/badge/code%20style-semistandard-brightgreen.svg)](https://github.com/Flet/semistandard) + +> 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. +- Contributions welcome, please read the [contribution guide](CONTRIBUTING.md). +- 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/tsoc). Bear in mind that most of these snippets are not production-ready. + +## Table of Contents ### 🔌 Adapter @@ -368,17 +368,17 @@ Object.assign(b, a); // == b
    [⬆ Back to top](#table-of-contents) -### pipeFunctions - -Performs left-to-right function composition. - -Use `Array.reduce()` with the spread operator (`...`) to perform left-to-right function composition. -The first (leftmost) function can accept one or more arguments; the remaining functions must be unary. - +### pipeFunctions + +Performs left-to-right function composition. + +Use `Array.reduce()` with the spread operator (`...`) to perform left-to-right function composition. +The first (leftmost) function can accept one or more arguments; the remaining functions must be unary. + ```js const pipeFunctions = (...fns) => fns.reduce((f, g) => (...args) => g(f(...args))); -``` - +``` +
    Examples @@ -387,36 +387,36 @@ const add5 = x => x + 5; const multiply = (x, y) => x * y; const multiplyAndAdd5 = pipeFunctions(multiply, add5); multiplyAndAdd5(5, 2); // 15 -``` +```

    [⬆ Back to top](#table-of-contents) -### promisify - -Converts an asynchronous function to return a promise. - -Use currying to return a function returning a `Promise` that calls the original function. -Use the `...rest` operator to pass in all the parameters. - -*In Node 8+, you can use [`util.promisify`](https://nodejs.org/api/util.html#util_util_promisify_original)* - +### promisify + +Converts an asynchronous function to return a promise. + +Use currying to return a function returning a `Promise` that calls the original function. +Use the `...rest` operator to pass in all the parameters. + +*In Node 8+, you can use [`util.promisify`](https://nodejs.org/api/util.html#util_util_promisify_original)* + ```js const promisify = func => (...args) => new Promise((resolve, reject) => func(...args, (err, result) => (err ? reject(err) : resolve(result))) ); -``` - +``` +
    Examples ```js const delay = promisify((d, cb) => setTimeout(cb, d)); delay(2000).then(() => console.log('Hi!')); // // Promise resolves after 2s -``` +```
    @@ -449,206 +449,206 @@ arrayMax([1, 2, 4]); // 4 --- ## 📚 Array -### chunk - -Chunks an array into smaller arrays of a specified size. - -Use `Array.from()` to create a new array, that fits the number of chunks that will be produced. -Use `Array.slice()` to map each element of the new array to a chunk the length of `size`. -If the original array can't be split evenly, the final chunk will contain the remaining elements. - +### chunk + +Chunks an array into smaller arrays of a specified size. + +Use `Array.from()` to create a new array, that fits the number of chunks that will be produced. +Use `Array.slice()` to map each element of the new array to a chunk the length of `size`. +If the original array can't be split evenly, the final chunk will contain the remaining elements. + ```js const chunk = (arr, size) => Array.from({ length: Math.ceil(arr.length / size) }, (v, i) => arr.slice(i * size, i * size + size) ); -``` - +``` +
    Examples ```js chunk([1, 2, 3, 4, 5], 2); // [[1,2],[3,4],[5]] -``` +```

    [⬆ Back to top](#table-of-contents) -### compact - -Removes falsey values from an array. - -Use `Array.filter()` to filter out falsey values (`false`, `null`, `0`, `""`, `undefined`, and `NaN`). - +### compact + +Removes falsey values from an array. + +Use `Array.filter()` to filter out falsey values (`false`, `null`, `0`, `""`, `undefined`, and `NaN`). + ```js const compact = arr => arr.filter(Boolean); -``` - +``` +
    Examples ```js compact([0, 1, false, 2, '', 3, 'a', 'e' * 23, NaN, 's', 34]); // [ 1, 2, 3, 'a', 's', 34 ] -``` +```

    [⬆ Back to top](#table-of-contents) -### countOccurrences - -Counts the occurrences of a value in an array. - -Use `Array.reduce()` to increment a counter each time you encounter the specific value inside the array. - +### countOccurrences + +Counts the occurrences of a value in an array. + +Use `Array.reduce()` to increment a counter each time you encounter the specific value inside the array. + ```js const countOccurrences = (arr, value) => arr.reduce((a, v) => (v === value ? a + 1 : a + 0), 0); -``` - +``` +
    Examples ```js countOccurrences([1, 1, 2, 1, 2, 3], 1); // 3 -``` +```

    [⬆ Back to top](#table-of-contents) -### deepFlatten - -Deep flattens an array. - -Use recursion. -Use `Array.concat()` with an empty array (`[]`) and the spread operator (`...`) to flatten an array. -Recursively flatten each element that is an array. - +### deepFlatten + +Deep flattens an array. + +Use recursion. +Use `Array.concat()` with an empty array (`[]`) and the spread operator (`...`) to flatten an array. +Recursively flatten each element that is an array. + ```js const deepFlatten = arr => [].concat(...arr.map(v => (Array.isArray(v) ? deepFlatten(v) : v))); -``` - +``` +
    Examples ```js deepFlatten([1, [2], [[3], 4], 5]); // [1,2,3,4,5] -``` +```

    [⬆ Back to top](#table-of-contents) -### difference - -Returns the difference between two arrays. - -Create a `Set` from `b`, then use `Array.filter()` on `a` to only keep values not contained in `b`. - +### difference + +Returns the difference between two arrays. + +Create a `Set` from `b`, then use `Array.filter()` on `a` to only keep values not contained in `b`. + ```js const difference = (a, b) => { const s = new Set(b); return a.filter(x => !s.has(x)); }; -``` - +``` +
    Examples ```js difference([1, 2, 3], [1, 2, 4]); // [3] -``` +```

    [⬆ Back to top](#table-of-contents) -### differenceWith - -Filters out all values from an array for which the comparator function does not return `true`. - -Use `Array.filter()` and `Array.find()` to find the appropriate values. - +### differenceWith + +Filters out all values from an array for which the comparator function does not return `true`. + +Use `Array.filter()` and `Array.find()` to find the appropriate values. + ```js const differenceWith = (arr, val, comp) => arr.filter(a => !val.find(b => comp(a, b))); -``` - +``` +
    Examples ```js differenceWith([1, 1.2, 1.5, 3], [1.9, 3], (a, b) => Math.round(a) == Math.round(b)); // [1, 1.2] -``` +```

    [⬆ Back to top](#table-of-contents) -### distinctValuesOfArray - -Returns all the distinct values of an array. - -Use ES6 `Set` and the `...rest` operator to discard all duplicated values. - +### distinctValuesOfArray + +Returns all the distinct values of an array. + +Use ES6 `Set` and the `...rest` operator to discard all duplicated values. + ```js const distinctValuesOfArray = arr => [...new Set(arr)]; -``` - +``` +
    Examples ```js distinctValuesOfArray([1, 2, 2, 3, 4, 4, 5]); // [1,2,3,4,5] -``` +```

    [⬆ Back to top](#table-of-contents) -### dropElements - -Removes elements in an array until the passed function returns `true`. Returns the remaining elements in the array. - -Loop through the array, using `Array.slice()` to drop the first element of the array until the returned value from the function is `true`. -Returns the remaining elements. - +### dropElements + +Removes elements in an array until the passed function returns `true`. Returns the remaining elements in the array. + +Loop through the array, using `Array.slice()` to drop the first element of the array until the returned value from the function is `true`. +Returns the remaining elements. + ```js const dropElements = (arr, func) => { while (arr.length > 0 && !func(arr[0])) arr = arr.slice(1); return arr; }; -``` - +``` +
    Examples ```js dropElements([1, 2, 3, 4], n => n >= 3); // [3,4] -``` +```

    [⬆ Back to top](#table-of-contents) -### dropRight - -Returns a new array with `n` elements removed from the right. - -Use `Array.slice()` to slice the remove the specified number of elements from the right. - +### dropRight + +Returns a new array with `n` elements removed from the right. + +Use `Array.slice()` to slice the remove the specified number of elements from the right. + ```js const dropRight = (arr, n = 1) => arr.slice(0, -n); -``` - +``` +
    Examples @@ -656,448 +656,448 @@ const dropRight = (arr, n = 1) => arr.slice(0, -n); dropRight([1, 2, 3]); // [1,2] dropRight([1, 2, 3], 2); // [1] dropRight([1, 2, 3], 42); // [] -``` +```

    [⬆ Back to top](#table-of-contents) -### everyNth - -Returns every nth element in an array. - -Use `Array.filter()` to create a new array that contains every nth element of a given array. - +### everyNth + +Returns every nth element in an array. + +Use `Array.filter()` to create a new array that contains every nth element of a given array. + ```js const everyNth = (arr, nth) => arr.filter((e, i) => i % nth === nth - 1); -``` - +``` +
    Examples ```js everyNth([1, 2, 3, 4, 5, 6], 2); // [ 2, 4, 6 ] -``` +```

    [⬆ Back to top](#table-of-contents) -### filterNonUnique - -Filters out the non-unique values in an array. - -Use `Array.filter()` for an array containing only the unique values. - +### filterNonUnique + +Filters out the non-unique values in an array. + +Use `Array.filter()` for an array containing only the unique values. + ```js const filterNonUnique = arr => arr.filter(i => arr.indexOf(i) === arr.lastIndexOf(i)); -``` - +``` +
    Examples ```js filterNonUnique([1, 2, 2, 3, 4, 4, 5]); // [1,3,5] -``` +```

    [⬆ Back to top](#table-of-contents) -### flatten - -Flattens an array. - -Use a new array and concatenate it with the spread input array causing a shallow denesting of any contained arrays. - +### flatten + +Flattens an array. + +Use a new array and concatenate it with the spread input array causing a shallow denesting of any contained arrays. + ```js const flatten = arr => [].concat(...arr); -``` - +``` +
    Examples ```js flatten([1, [2], 3, 4]); // [1,2,3,4] -``` +```

    [⬆ Back to top](#table-of-contents) -### flattenDepth - -Flattens an array up to the specified depth. - -Use recursion, decrementing `depth` by 1 for each level of depth. -Use `Array.reduce()` and `Array.concat()` to merge elements or arrays. -Base case, for `depth` equal to `1` stops recursion. -Omit the second element, `depth` to flatten only to a depth of `1` (single flatten). - +### flattenDepth + +Flattens an array up to the specified depth. + +Use recursion, decrementing `depth` by 1 for each level of depth. +Use `Array.reduce()` and `Array.concat()` to merge elements or arrays. +Base case, for `depth` equal to `1` stops recursion. +Omit the second element, `depth` to flatten only to a depth of `1` (single flatten). + ```js const flattenDepth = (arr, depth = 1) => depth != 1 ? arr.reduce((a, v) => a.concat(Array.isArray(v) ? flattenDepth(v, depth - 1) : v), []) : arr.reduce((a, v) => a.concat(v), []); -``` - +``` +
    Examples ```js flattenDepth([1, [2], 3, 4]); // [1,2,3,4] -``` +```

    [⬆ Back to top](#table-of-contents) -### groupBy - -Groups the elements of an array based on the given function. - -Use `Array.map()` to map the values of an array to a function or property name. -Use `Array.reduce()` to create an object, where the keys are produced from the mapped results. - +### groupBy + +Groups the elements of an array based on the given function. + +Use `Array.map()` to map the values of an array to a function or property name. +Use `Array.reduce()` to create an object, where the keys are produced from the mapped results. + ```js const groupBy = (arr, func) => arr.map(typeof func === 'function' ? func : val => val[func]).reduce((acc, val, i) => { acc[val] = (acc[val] || []).concat(arr[i]); return acc; }, {}); -``` - +``` +
    Examples ```js groupBy([6.1, 4.2, 6.3], Math.floor); // {4: [4.2], 6: [6.1, 6.3]} groupBy(['one', 'two', 'three'], 'length'); // {3: ['one', 'two'], 5: ['three']} -``` +```

    [⬆ Back to top](#table-of-contents) -### head - -Returns the head of a list. - -Use `arr[0]` to return the first element of the passed array. - +### head + +Returns the head of a list. + +Use `arr[0]` to return the first element of the passed array. + ```js const head = arr => arr[0]; -``` - +``` +
    Examples ```js head([1, 2, 3]); // 1 -``` +```

    [⬆ Back to top](#table-of-contents) -### initial - -Returns all the elements of an array except the last one. - -Use `arr.slice(0,-1)` to return all but the last element of the array. - +### initial + +Returns all the elements of an array except the last one. + +Use `arr.slice(0,-1)` to return all but the last element of the array. + ```js const initial = arr => arr.slice(0, -1); -``` - +``` +
    Examples ```js initial([1, 2, 3]); // [1,2] -``` +```

    [⬆ Back to top](#table-of-contents) -### initialize2DArray - -Initializes a 2D array of given width and height and value. - -Use `Array.map()` to generate h rows where each is a new array of size w initialize with value. If the value is not provided, default to `null`. - +### initialize2DArray + +Initializes a 2D array of given width and height and value. + +Use `Array.map()` to generate h rows where each is a new array of size w initialize with value. If the value is not provided, default to `null`. + ```js const initialize2DArray = (w, h, val = null) => Array(h) .fill() .map(() => Array(w).fill(val)); -``` - +``` +
    Examples ```js initialize2DArray(2, 2, 0); // [[0,0], [0,0]] -``` +```

    [⬆ Back to top](#table-of-contents) -### initializeArrayWithRange - -Initializes an array containing the numbers in the specified range where `start` and `end` are inclusive. - -Use `Array((end + 1) - start)` to create an array of the desired length, `Array.map()` to fill with the desired values in a range. -You can omit `start` to use a default value of `0`. - +### initializeArrayWithRange + +Initializes an array containing the numbers in the specified range where `start` and `end` are inclusive. + +Use `Array((end + 1) - start)` to create an array of the desired length, `Array.map()` to fill with the desired values in a range. +You can omit `start` to use a default value of `0`. + ```js const initializeArrayWithRange = (end, start = 0) => Array.from({ length: end + 1 - start }).map((v, i) => i + start); -``` - +``` +
    Examples ```js initializeArrayWithRange(5); // [0,1,2,3,4,5] initializeArrayWithRange(7, 3); // [3,4,5,6,7] -``` +```

    [⬆ Back to top](#table-of-contents) -### initializeArrayWithValues - -Initializes and fills an array with the specified values. - -Use `Array(n)` to create an array of the desired length, `fill(v)` to fill it with the desired values. -You can omit `value` to use a default value of `0`. - +### initializeArrayWithValues + +Initializes and fills an array with the specified values. + +Use `Array(n)` to create an array of the desired length, `fill(v)` to fill it with the desired values. +You can omit `value` to use a default value of `0`. + ```js const initializeArrayWithValues = (n, value = 0) => Array(n).fill(value); -``` - +``` +
    Examples ```js initializeArrayWithValues(5, 2); // [2,2,2,2,2] -``` +```

    [⬆ Back to top](#table-of-contents) -### intersection - -Returns a list of elements that exist in both arrays. - -Create a `Set` from `b`, then use `Array.filter()` on `a` to only keep values contained in `b`. - +### intersection + +Returns a list of elements that exist in both arrays. + +Create a `Set` from `b`, then use `Array.filter()` on `a` to only keep values contained in `b`. + ```js const intersection = (a, b) => { const s = new Set(b); return a.filter(x => s.has(x)); }; -``` - +``` +
    Examples ```js intersection([1, 2, 3], [4, 3, 2]); // [2,3] -``` +```

    [⬆ Back to top](#table-of-contents) -### isSorted - -Returns `1` if the array is sorted in ascending order, `-1` if it is sorted in descending order or `0` if it is not sorted. - -Calculate the ordering `direction` for the first two elements. -Use `Object.entries()` to loop over array objects and compare them in pairs. -Return `0` if the `direction` changes or the `direction` if the last element is reached. - +### isSorted + +Returns `1` if the array is sorted in ascending order, `-1` if it is sorted in descending order or `0` if it is not sorted. + +Calculate the ordering `direction` for the first two elements. +Use `Object.entries()` to loop over array objects and compare them in pairs. +Return `0` if the `direction` changes or the `direction` if the last element is reached. + ```js -const isSorted = arr => { - const direction = arr[0] > arr[1] ? -1 : 1; - for (let [i, val] of arr.entries()) - if (i === arr.length - 1) return direction; - else if ((val - arr[i + 1]) * direction > 0) return 0; -}; -``` - +const isSorted = arr => { + const direction = arr[0] > arr[1] ? -1 : 1; + for (let [i, val] of arr.entries()) + if (i === arr.length - 1) return direction; + else if ((val - arr[i + 1]) * direction > 0) return 0; +}; +``` +
    Examples ```js -isSorted([0, 1, 2, 3]); // 1 -isSorted([0, 1, 2, 2]); // 1 -isSorted([4, 3, 2]); // -1 -isSorted([4, 3, 5]); // 0 -``` +isSorted([0, 1, 2, 3]); // 1 +isSorted([0, 1, 2, 2]); // 1 +isSorted([4, 3, 2]); // -1 +isSorted([4, 3, 5]); // 0 +```

    [⬆ Back to top](#table-of-contents) -### join - -Joins all elements of an array into a string and returns this string. Uses a separator and an end separator. - -Use `Array.reduce()` to combine elements into a string. -Omit the second argument, `separator`, to use a default separator of `','`. -Omit the third argument, `end`, to use the same value as `separator` by default. - +### join + +Joins all elements of an array into a string and returns this string. Uses a separator and an end separator. + +Use `Array.reduce()` to combine elements into a string. +Omit the second argument, `separator`, to use a default separator of `','`. +Omit the third argument, `end`, to use the same value as `separator` by default. + ```js -const join = (arr, separator = ',', end = separator) => - arr.reduce( - (acc, val, i) => - i == arr.length - 2 - ? acc + val + end - : i == arr.length - 1 ? acc + val : acc + val + separator, - '' - ); -``` - +const join = (arr, separator = ',', end = separator) => + arr.reduce( + (acc, val, i) => + i == arr.length - 2 + ? acc + val + end + : i == arr.length - 1 ? acc + val : acc + val + separator, + '' + ); +``` +
    Examples ```js -join(); // '' -join(['pen', 'pineapple', 'apple', 'pen'], ',', '&'); //"pen,pineapple,apple&pen" -join(['pen', 'pineapple', 'apple', 'pen'], ','); //"pen,pineapple,apple,pen" -join(['pen', 'pineapple', 'apple', 'pen']); //"pen,pineapple,apple,pen" -``` +join(); // '' +join(['pen', 'pineapple', 'apple', 'pen'], ',', '&'); //"pen,pineapple,apple&pen" +join(['pen', 'pineapple', 'apple', 'pen'], ','); //"pen,pineapple,apple,pen" +join(['pen', 'pineapple', 'apple', 'pen']); //"pen,pineapple,apple,pen" +```

    [⬆ Back to top](#table-of-contents) -### last - -Returns the last element in an array. - -Use `arr.length - 1` to compute the index of the last element of the given array and returning it. - +### last + +Returns the last element in an array. + +Use `arr.length - 1` to compute the index of the last element of the given array and returning it. + ```js const last = arr => arr[arr.length - 1]; -``` - +``` +
    Examples ```js last([1, 2, 3]); // 3 -``` +```

    [⬆ Back to top](#table-of-contents) -### mapObject - -Maps the values of an array to an object using a function, where the key-value pairs consist of the original value as the key and the mapped value. - -Use an anonymous inner function scope to declare an undefined memory space, using closures to store a return value. Use a new `Array` to store the array with a map of the function over its data set and a comma operator to return a second step, without needing to move from one context to another (due to closures and order of operations). - +### mapObject + +Maps the values of an array to an object using a function, where the key-value pairs consist of the original value as the key and the mapped value. + +Use an anonymous inner function scope to declare an undefined memory space, using closures to store a return value. Use a new `Array` to store the array with a map of the function over its data set and a comma operator to return a second step, without needing to move from one context to another (due to closures and order of operations). + ```js const mapObject = (arr, fn) => (a => ( (a = [arr, arr.map(fn)]), a[0].reduce((acc, val, ind) => ((acc[val] = a[1][ind]), acc), {}) ))(); -``` - +``` +
    Examples ```js const squareIt = arr => mapObject(arr, a => a * a); squareIt([1, 2, 3]); // { 1: 1, 2: 4, 3: 9 } -``` +```

    [⬆ Back to top](#table-of-contents) -### nthElement - -Returns the nth element of an array. - -Use `Array.slice()` to get an array containing the nth element at the first place. -If the index is out of bounds, return `[]`. -Omit the second argument, `n`, to get the first element of the array. - +### nthElement + +Returns the nth element of an array. + +Use `Array.slice()` to get an array containing the nth element at the first place. +If the index is out of bounds, return `[]`. +Omit the second argument, `n`, to get the first element of the array. + ```js const nthElement = (arr, n = 0) => (n > 0 ? arr.slice(n, n + 1) : arr.slice(n))[0]; -``` - +``` +
    Examples ```js nthElement(['a', 'b', 'c'], 1); // 'b' nthElement(['a', 'b', 'b'], -3); // 'a' -``` +```

    [⬆ Back to top](#table-of-contents) -### pick - -Picks the key-value pairs corresponding to the given keys from an object. - -Use `Array.reduce()` to convert the filtered/picked keys back to an object with the corresponding key-value pair if the key exists in the obj. - +### pick + +Picks the key-value pairs corresponding to the given keys from an object. + +Use `Array.reduce()` to convert the filtered/picked keys back to an object with the corresponding key-value pair if the key exists in the obj. + ```js const pick = (obj, arr) => arr.reduce((acc, curr) => (curr in obj && (acc[curr] = obj[curr]), acc), {}); -``` - +``` +
    Examples ```js pick({ a: 1, b: '2', c: 3 }, ['a', 'c']); // { 'a': 1, 'c': 3 } -``` +```

    [⬆ Back to top](#table-of-contents) -### pull - -Mutates the original array to filter out the values specified. - -Use `Array.filter()` and `Array.includes()` to pull out the values that are not needed. -Use `Array.length = 0` to mutate the passed in an array by resetting it's length to zero and `Array.push()` to re-populate it with only the pulled values. - -_(For a snippet that does not mutate the original array see [`without`](#without))_ - +### pull + +Mutates the original array to filter out the values specified. + +Use `Array.filter()` and `Array.includes()` to pull out the values that are not needed. +Use `Array.length = 0` to mutate the passed in an array by resetting it's length to zero and `Array.push()` to re-populate it with only the pulled values. + +_(For a snippet that does not mutate the original array see [`without`](#without))_ + ```js const pull = (arr, ...args) => { let argState = Array.isArray(args[0]) ? args[0] : args; @@ -1105,8 +1105,8 @@ const pull = (arr, ...args) => { arr.length = 0; pulled.forEach(v => arr.push(v)); }; -``` - +``` +
    Examples @@ -1118,21 +1118,21 @@ console.log(myArray1); // [ 'b', 'b' ] let myArray2 = ['a', 'b', 'c', 'a', 'b', 'c']; pull(myArray2, ['a', 'c']); console.log(myArray2); // [ 'b', 'b' ] -``` +```

    [⬆ Back to top](#table-of-contents) -### pullAtIndex - -Mutates the original array to filter out the values at the specified indexes. - -Use `Array.filter()` and `Array.includes()` to pull out the values that are not needed. -Use `Array.length = 0` to mutate the passed in an array by resetting it's length to zero and `Array.push()` to re-populate it with only the pulled values. -Use `Array.push()` to keep track of pulled values - +### pullAtIndex + +Mutates the original array to filter out the values at the specified indexes. + +Use `Array.filter()` and `Array.includes()` to pull out the values that are not needed. +Use `Array.length = 0` to mutate the passed in an array by resetting it's length to zero and `Array.push()` to re-populate it with only the pulled values. +Use `Array.push()` to keep track of pulled values + ```js const pullAtIndex = (arr, pullArr) => { let removed = []; @@ -1143,8 +1143,8 @@ const pullAtIndex = (arr, pullArr) => { pulled.forEach(v => arr.push(v)); return removed; }; -``` - +``` +
    Examples @@ -1154,21 +1154,21 @@ let pulled = pullAtIndex(myArray, [1, 3]); console.log(myArray); // [ 'a', 'c' ] console.log(pulled); // [ 'b', 'd' ] -``` +```

    [⬆ Back to top](#table-of-contents) -### pullAtValue - -Mutates the original array to filter out the values specified. Returns the removed elements. - -Use `Array.filter()` and `Array.includes()` to pull out the values that are not needed. -Use `Array.length = 0` to mutate the passed in an array by resetting it's length to zero and `Array.push()` to re-populate it with only the pulled values. -Use `Array.push()` to keep track of pulled values - +### pullAtValue + +Mutates the original array to filter out the values specified. Returns the removed elements. + +Use `Array.filter()` and `Array.includes()` to pull out the values that are not needed. +Use `Array.length = 0` to mutate the passed in an array by resetting it's length to zero and `Array.push()` to re-populate it with only the pulled values. +Use `Array.push()` to keep track of pulled values + ```js const pullAtValue = (arr, pullArr) => { let removed = [], @@ -1178,8 +1178,8 @@ const pullAtValue = (arr, pullArr) => { mutateTo.forEach(v => arr.push(v)); return removed; }; -``` - +``` +
    Examples @@ -1188,21 +1188,21 @@ let myArray = ['a', 'b', 'c', 'd']; let pulled = pullAtValue(myArray, ['b', 'd']); console.log(myArray); // [ 'a', 'c' ] console.log(pulled); // [ 'b', 'd' ] -``` +```

    [⬆ Back to top](#table-of-contents) -### quickSort - -QuickSort an Array (ascending sort by default). - -Use recursion. -Use `Array.filter` and spread operator (`...`) to create an array that all elements with values less than the pivot come before the pivot, and all elements with values greater than the pivot come after it. -If the parameter `desc` is truthy, return array sorts in descending order. - +### quickSort + +QuickSort an Array (ascending sort by default). + +Use recursion. +Use `Array.filter` and spread operator (`...`) to create an array that all elements with values less than the pivot come before the pivot, and all elements with values greater than the pivot come after it. +If the parameter `desc` is truthy, return array sorts in descending order. + ```js const quickSort = ([n, ...nums], desc) => isNaN(n) @@ -1212,70 +1212,70 @@ const quickSort = ([n, ...nums], desc) => n, ...quickSort(nums.filter(v => (!desc ? v > n : v <= n)), desc) ]; -``` - +``` +
    Examples ```js quickSort([4, 1, 3, 2]); // [1,2,3,4] quickSort([4, 1, 3, 2], true); // [4,3,2,1] -``` +```

    [⬆ Back to top](#table-of-contents) -### reducedFilter - -Filter an array of objects based on a condition while also filtering out unspecified keys. - -Use `Array.filter()` to filter the array based on the predicate `fn` so that it returns the objects for which the condition returned a truthy value. -On the filtered array, use `Array.map()` to return the new object using `Array.reduce()` to filter out the keys which were not supplied as the `keys` argument. - +### reducedFilter + +Filter an array of objects based on a condition while also filtering out unspecified keys. + +Use `Array.filter()` to filter the array based on the predicate `fn` so that it returns the objects for which the condition returned a truthy value. +On the filtered array, use `Array.map()` to return the new object using `Array.reduce()` to filter out the keys which were not supplied as the `keys` argument. + ```js -const reducedFilter = (data, keys, fn) => - data.filter(fn).map(el => - keys.reduce((acc, key) => { - acc[key] = el[key]; - return acc; - }, {}) - ); -``` - +const reducedFilter = (data, keys, fn) => + data.filter(fn).map(el => + keys.reduce((acc, key) => { + acc[key] = el[key]; + return acc; + }, {}) + ); +``` +
    Examples ```js -const data = [ - { - id: 1, - name: 'john', - age: 24 - }, - { - id: 2, - name: 'mike', - age: 50 - } -]; - -reducedFilter(data, ['id', 'name'], item => item.age > 24); // [{ id: 2, name: 'mike'}] -``` +const data = [ + { + id: 1, + name: 'john', + age: 24 + }, + { + id: 2, + name: 'mike', + age: 50 + } +]; + +reducedFilter(data, ['id', 'name'], item => item.age > 24); // [{ id: 2, name: 'mike'}] +```

    [⬆ Back to top](#table-of-contents) -### remove - -Removes elements from an array for which the given function returns `false`. - -Use `Array.filter()` to find array elements that return truthy values and `Array.reduce()` to remove elements using `Array.splice()`. -The `func` is invoked with three arguments (`value, index, array`). - +### remove + +Removes elements from an array for which the given function returns `false`. + +Use `Array.filter()` to find array elements that return truthy values and `Array.reduce()` to remove elements using `Array.splice()`. +The `func` is invoked with three arguments (`value, index, array`). + ```js const remove = (arr, func) => Array.isArray(arr) @@ -1284,305 +1284,305 @@ const remove = (arr, func) => return acc.concat(val); }, []) : []; -``` - +``` +
    Examples ```js remove([1, 2, 3, 4], n => n % 2 == 0); // [2, 4] -``` +```

    [⬆ Back to top](#table-of-contents) -### sample - -Returns a random element from an array. - -Use `Math.random()` to generate a random number, multiply it by `length` and round it of to the nearest whole number using `Math.floor()`. -This method also works with strings. - +### sample + +Returns a random element from an array. + +Use `Math.random()` to generate a random number, multiply it by `length` and round it of to the nearest whole number using `Math.floor()`. +This method also works with strings. + ```js const sample = arr => arr[Math.floor(Math.random() * arr.length)]; -``` - +``` +
    Examples ```js sample([3, 7, 9, 11]); // 9 -``` +```

    [⬆ Back to top](#table-of-contents) -### sampleSize - -Gets `n` random elements at unique keys from `array` up to the size of `array`. - -Shuffle the array using the [Fisher-Yates algorithm](https://github.com/chalarangelo/30-seconds-of-code#shuffle). -Use `Array.slice()` to get the first `n` elements. -Omit the second argument, `n` to get only one element at random from the array. - +### sampleSize + +Gets `n` random elements at unique keys from `array` up to the size of `array`. + +Shuffle the array using the [Fisher-Yates algorithm](https://github.com/chalarangelo/30-seconds-of-code#shuffle). +Use `Array.slice()` to get the first `n` elements. +Omit the second argument, `n` to get only one element at random from the array. + ```js -const sampleSize = ([...arr], n = 1) => { - let m = arr.length; - while (m) { - const i = Math.floor(Math.random() * m--); - [arr[m], arr[i]] = [arr[i], arr[m]]; - } - return arr.slice(0, n); -}; -``` - +const sampleSize = ([...arr], n = 1) => { + let m = arr.length; + while (m) { + const i = Math.floor(Math.random() * m--); + [arr[m], arr[i]] = [arr[i], arr[m]]; + } + return arr.slice(0, n); +}; +``` +
    Examples ```js -sampleSize([1, 2, 3], 2); // [3,1] -sampleSize([1, 2, 3], 4); // [2,3,1] -``` +sampleSize([1, 2, 3], 2); // [3,1] +sampleSize([1, 2, 3], 4); // [2,3,1] +```

    [⬆ Back to top](#table-of-contents) -### shuffle - -Randomizes the order of the values of an array, returning a new array. - -Uses the Fisher-Yates algorithm to reorder the elements of the array, based on the [Lodash implementation](https://github.com/lodash/lodash/blob/b2ea6b1cd251796dcb5f9700c4911a7b6223920b/shuffle.js), but as a pure function. - +### shuffle + +Randomizes the order of the values of an array, returning a new array. + +Uses the Fisher-Yates algorithm to reorder the elements of the array, based on the [Lodash implementation](https://github.com/lodash/lodash/blob/b2ea6b1cd251796dcb5f9700c4911a7b6223920b/shuffle.js), but as a pure function. + ```js -const shuffle = ([...arr]) => { - let m = arr.length; - while (m) { - const i = Math.floor(Math.random() * m--); - [arr[m], arr[i]] = [arr[i], arr[m]]; - } - return arr; -}; -``` - +const shuffle = ([...arr]) => { + let m = arr.length; + while (m) { + const i = Math.floor(Math.random() * m--); + [arr[m], arr[i]] = [arr[i], arr[m]]; + } + return arr; +}; +``` +
    Examples ```js -const foo = [1, 2, 3]; -shuffle(foo); // [2,3,1] -console.log(foo); // [1,2,3] -``` +const foo = [1, 2, 3]; +shuffle(foo); // [2,3,1] +console.log(foo); // [1,2,3] +```

    [⬆ Back to top](#table-of-contents) -### similarity - -Returns an array of elements that appear in both arrays. - -Use `filter()` to remove values that are not part of `values`, determined using `includes()`. - +### similarity + +Returns an array of elements that appear in both arrays. + +Use `filter()` to remove values that are not part of `values`, determined using `includes()`. + ```js const similarity = (arr, values) => arr.filter(v => values.includes(v)); -``` - +``` +
    Examples ```js similarity([1, 2, 3], [1, 2, 4]); // [1,2] -``` +```

    [⬆ Back to top](#table-of-contents) -### sortedIndex - -Returns the lowest index at which value should be inserted into array in order to maintain its sort order. - -Check if the array is sorted in descending order (loosely). -Use `Array.findIndex()` to find the appropriate index where the element should be inserted. - +### sortedIndex + +Returns the lowest index at which value should be inserted into array in order to maintain its sort order. + +Check if the array is sorted in descending order (loosely). +Use `Array.findIndex()` to find the appropriate index where the element should be inserted. + ```js -const sortedIndex = (arr, n) => { - const isDescending = arr[0] > arr[arr.length - 1]; - const index = arr.findIndex(el => (isDescending ? n >= el : n <= el)); - return index === -1 ? arr.length : index; -}; -``` - +const sortedIndex = (arr, n) => { + const isDescending = arr[0] > arr[arr.length - 1]; + const index = arr.findIndex(el => (isDescending ? n >= el : n <= el)); + return index === -1 ? arr.length : index; +}; +``` +
    Examples ```js -sortedIndex([5, 3, 2, 1], 4); // 1 -sortedIndex([30, 50], 40); // 1 -``` +sortedIndex([5, 3, 2, 1], 4); // 1 +sortedIndex([30, 50], 40); // 1 +```

    [⬆ Back to top](#table-of-contents) -### symmetricDifference - -Returns the symmetric difference between two arrays. - -Create a `Set` from each array, then use `Array.filter()` on each of them to only keep values not contained in the other. - +### symmetricDifference + +Returns the symmetric difference between two arrays. + +Create a `Set` from each array, then use `Array.filter()` on each of them to only keep values not contained in the other. + ```js const symmetricDifference = (a, b) => { const sA = new Set(a), sB = new Set(b); return [...a.filter(x => !sB.has(x)), ...b.filter(x => !sA.has(x))]; }; -``` - +``` +
    Examples ```js symmetricDifference([1, 2, 3], [1, 2, 4]); // [3,4] -``` +```

    [⬆ Back to top](#table-of-contents) -### tail - -Returns all elements in an array except for the first one. - -Return `arr.slice(1)` if the array's `length` is more than `1`, otherwise, return the whole array. - +### tail + +Returns all elements in an array except for the first one. + +Return `arr.slice(1)` if the array's `length` is more than `1`, otherwise, return the whole array. + ```js const tail = arr => (arr.length > 1 ? arr.slice(1) : arr); -``` - +``` +
    Examples ```js tail([1, 2, 3]); // [2,3] tail([1]); // [1] -``` +```

    [⬆ Back to top](#table-of-contents) -### take - -Returns an array with n elements removed from the beginning. - -Use `Array.slice()` to create a slice of the array with `n` elements taken from the beginning. - +### take + +Returns an array with n elements removed from the beginning. + +Use `Array.slice()` to create a slice of the array with `n` elements taken from the beginning. + ```js const take = (arr, n = 1) => arr.slice(0, n); -``` - +``` +
    Examples ```js take([1, 2, 3], 5); // [1, 2, 3] take([1, 2, 3], 0); // [] -``` +```

    [⬆ Back to top](#table-of-contents) -### takeRight - -Returns an array with n elements removed from the end. - -Use `Array.slice()` to create a slice of the array with `n` elements taken from the end. - +### takeRight + +Returns an array with n elements removed from the end. + +Use `Array.slice()` to create a slice of the array with `n` elements taken from the end. + ```js const takeRight = (arr, n = 1) => arr.slice(arr.length - n, arr.length); -``` - +``` +
    Examples ```js takeRight([1, 2, 3], 2); // [ 2, 3 ] takeRight([1, 2, 3]); // [3] -``` +```

    [⬆ Back to top](#table-of-contents) -### union - -Returns every element that exists in any of the two arrays once. - -Create a `Set` with all values of `a` and `b` and convert to an array. - +### union + +Returns every element that exists in any of the two arrays once. + +Create a `Set` with all values of `a` and `b` and convert to an array. + ```js const union = (a, b) => Array.from(new Set([...a, ...b])); -``` - +``` +
    Examples ```js union([1, 2, 3], [4, 3, 2]); // [1,2,3,4] -``` +```

    [⬆ Back to top](#table-of-contents) -### without - -Filters out the elements of an array, that have one of the specified values. - -Use `Array.filter()` to create an array excluding(using `!Array.includes()`) all given values. - -_(For a snippet that mutates the original array see [`pull`](#pull))_ - +### without + +Filters out the elements of an array, that have one of the specified values. + +Use `Array.filter()` to create an array excluding(using `!Array.includes()`) all given values. + +_(For a snippet that mutates the original array see [`pull`](#pull))_ + ```js const without = (arr, ...args) => arr.filter(v => !args.includes(v)); -``` - +``` +
    Examples ```js without([2, 1, 2, 3], 1, 2); // [3] -``` +```

    [⬆ Back to top](#table-of-contents) -### zip - -Creates an array of elements, grouped based on the position in the original arrays. - -Use `Math.max.apply()` to get the longest array in the arguments. -Creates an array with that length as return value and use `Array.from()` with a map-function to create an array of grouped elements. -If lengths of the argument-arrays vary, `undefined` is used where no value could be found. - +### zip + +Creates an array of elements, grouped based on the position in the original arrays. + +Use `Math.max.apply()` to get the longest array in the arguments. +Creates an array with that length as return value and use `Array.from()` with a map-function to create an array of grouped elements. +If lengths of the argument-arrays vary, `undefined` is used where no value could be found. + ```js const zip = (...arrays) => { const maxLength = Math.max(...arrays.map(x => x.length)); @@ -1590,39 +1590,39 @@ const zip = (...arrays) => { return Array.from({ length: arrays.length }, (_, k) => arrays[k][i]); }); }; -``` - +``` +
    Examples ```js zip(['a', 'b'], [1, 2], [true, false]); // [['a', 1, true], ['b', 2, false]] zip(['a'], [1, 2], [true, false]); // [['a', 1, true], [undefined, 2, false]] -``` +```

    [⬆ Back to top](#table-of-contents) -### zipObject - -Given an array of valid property identifiers and an array of values, return an object associating the properties to the values. - -Since an object can have undefined values but not undefined property pointers, the array of properties is used to decide the structure of the resulting object using `Array.reduce()`. - +### zipObject + +Given an array of valid property identifiers and an array of values, return an object associating the properties to the values. + +Since an object can have undefined values but not undefined property pointers, the array of properties is used to decide the structure of the resulting object using `Array.reduce()`. + ```js const zipObject = (props, values) => props.reduce((obj, prop, index) => ((obj[prop] = values[index]), obj), {}); -``` - +``` +
    Examples ```js zipObject(['a', 'b', 'c'], [1, 2]); // {a: 1, b: 2, c: undefined} zipObject(['a', 'b'], [1, 2, 3]); // {a: 1, b: 2} -``` +```
    @@ -1631,152 +1631,152 @@ zipObject(['a', 'b'], [1, 2, 3]); // {a: 1, b: 2} --- ## 🌐 Browser -### arrayToHtmlList - -Converts the given array elements into `
  • ` tags and appends them to the list of the given id. - -Use `Array.map()` and `document.querySelector()` to create a list of html tags. - +### arrayToHtmlList + +Converts the given array elements into `
  • ` tags and appends them to the list of the given id. + +Use `Array.map()` and `document.querySelector()` to create a list of html tags. + ```js const arrayToHtmlList = (arr, listID) => arr.map(item => (document.querySelector('#' + listID).innerHTML += `
  • ${item}
  • `)); -``` - +``` +
    Examples ```js arrayToHtmlList(['item 1', 'item 2'], 'myListID'); -``` +```

    [⬆ Back to top](#table-of-contents) -### bottomVisible - -Returns `true` if the bottom of the page is visible, `false` otherwise. - -Use `scrollY`, `scrollHeight` and `clientHeight` to determine if the bottom of the page is visible. - +### bottomVisible + +Returns `true` if the bottom of the page is visible, `false` otherwise. + +Use `scrollY`, `scrollHeight` and `clientHeight` to determine if the bottom of the page is visible. + ```js const bottomVisible = () => document.documentElement.clientHeight + window.scrollY >= (document.documentElement.scrollHeight || document.documentElement.clientHeight); -``` - +``` +
    Examples ```js bottomVisible(); // true -``` +```

    [⬆ Back to top](#table-of-contents) -### copyToClipboard - -Copy a string to the clipboard. Only works as a result of user action (i.e. inside a `click` event listener). - -Create a new `