├── .gitignore ├── README.md ├── crawl ├── crawler.js ├── db.js ├── package.json └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/node 3 | 4 | ### Node ### 5 | # Logs 6 | logs 7 | *.log 8 | npm-debug.log* 9 | yarn-debug.log* 10 | yarn-error.log* 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | 24 | # nyc test coverage 25 | .nyc_output 26 | 27 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 28 | .grunt 29 | 30 | # Bower dependency directory (https://bower.io/) 31 | bower_components 32 | 33 | # node-waf configuration 34 | .lock-wscript 35 | 36 | # Compiled binary addons (http://nodejs.org/api/addons.html) 37 | build/Release 38 | 39 | # Dependency directories 40 | node_modules/ 41 | jspm_packages/ 42 | 43 | # Typescript v1 declaration files 44 | typings/ 45 | 46 | # Optional npm cache directory 47 | .npm 48 | 49 | # Optional eslint cache 50 | .eslintcache 51 | 52 | # Optional REPL history 53 | .node_repl_history 54 | 55 | # Output of 'npm pack' 56 | *.tgz 57 | 58 | # Yarn Integrity file 59 | .yarn-integrity 60 | 61 | # dotenv environment variables file 62 | .env 63 | 64 | 65 | # End of https://www.gitignore.io/api/node 66 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Chromium / [Puppeteer](https://github.com/GoogleChrome/puppeteer) site crawler 2 | 3 | [![styled with prettier](https://img.shields.io/badge/styled_with-prettier-ff69b4.svg)](https://github.com/prettier/prettier) 4 | 5 | This crawler does a BFS starting from a given site entry point. It will not leave the entry point domain and it will not crawl a page more than once. Given a shared redis host/cluster this crawler can be distributed across multiple machines or processes. Discovered pages will be stored in mongo collection, each with a url, outbound urls, and a radius from the origin. 6 | 7 | ## Installation 8 | ``` 9 | yarn 10 | ``` 11 | 12 | ## Usage 13 | ### Basic 14 | ```bash 15 | ./crawl -u https://www.dadoune.com 16 | ``` 17 | ### Distributed 18 | ```bash 19 | # Terminal 1 20 | ./crawl -u https://www.dadoune.com 21 | ``` 22 | 23 | ```bash 24 | # Terminal 2 25 | ./crawl -r 26 | ``` 27 | ### Debug 28 | ```bash 29 | DEBUG=crawler:* ./crawl -u https://www.dadoune.com 30 | ``` 31 | 32 | ### Options 33 | - `--maxRadius` or `-m` the maximum link depth the crawler will explore from the entry url. 34 | - `--resume` or `-r` to resume crawling after prematurely exiting a process or to add additional crawlers to an existing crawl. 35 | - `--url` or `-u` the entry point URL to kick the crawler off. 36 | -------------------------------------------------------------------------------- /crawl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | require('dotenv').config(); 3 | const argv = require('yargs') 4 | .usage('Usage: $0 [options]') 5 | .option('url', { 6 | alias: 'u', 7 | describe: 'The URL the crawler should enter the site from', 8 | }) 9 | .option('resume', { 10 | alias: 'r', 11 | boolean: true, 12 | describe: 'Resume crawler from existing queue', 13 | }) 14 | .option('max-radius', { 15 | alias: 'm', 16 | number: true, 17 | describe: 'The maximum radius from the entry URL to crawl', 18 | default: Infinity, 19 | }) 20 | .check(({ url, resume }) => { 21 | if (url && resume) { 22 | throw new Error('--url and --resume are mutually exclusive'); 23 | } 24 | return true; 25 | }) 26 | .help().argv; 27 | 28 | const db = require('./db'); 29 | const crawl = require('./crawler'); 30 | 31 | (async () => { 32 | await db.connect(); 33 | if (!argv.resume) { 34 | await db.flush(); 35 | } 36 | await crawl(argv.url, { maxRadius: argv.maxRadius }); 37 | db.close(); 38 | })(); 39 | -------------------------------------------------------------------------------- /crawler.js: -------------------------------------------------------------------------------- 1 | const _ = require('lodash'); 2 | const db = require('./db'); 3 | const puppeteer = require('puppeteer'); 4 | const url = require('url'); 5 | 6 | const debug = { 7 | crawl: require('debug')('crawler:crawl'), 8 | page: require('debug')('crawler:page'), 9 | }; 10 | 11 | const crawl = async (entry, options = {}) => { 12 | debug.crawl('Crawler started'); 13 | let target = (await db.popUrl()) || { url: entry, radius: 0 }; 14 | const { maxRadius = Infinity } = options; 15 | if (!target.url) { 16 | debug.crawl('Nothing to crawl'); 17 | return; 18 | } 19 | 20 | const entryUrl = url.parse(target.url); 21 | const browser = await puppeteer.launch(); 22 | const page = await browser.newPage(); 23 | debug.crawl('Puppeteer started'); 24 | 25 | let count = 0; 26 | while (target) { 27 | if (target.radius >= maxRadius) { 28 | debug.page(`Max radius reached ${target.url} not scraped`); 29 | } else { 30 | count++; 31 | debug.page(`Crawling: ${target.url}`); 32 | await page.goto(target.url); 33 | debug.page(`Page loaded`); 34 | const links = await page.evaluate(() => { 35 | return Array.from(document.querySelectorAll('a')).map( 36 | link => link.href 37 | ); 38 | }); 39 | const outboundUrls = _.chain(links) 40 | .filter(link => { 41 | return url.parse(link).host === entryUrl.host; 42 | }) 43 | .value(); 44 | debug.page(`Scraped ${outboundUrls.length} urls`); 45 | await db.store({ 46 | outboundUrls, 47 | radius: ++target.radius, 48 | url: target.url, 49 | }); 50 | } 51 | target = await db.popUrl(); 52 | } 53 | debug.crawl(`Crawler finished after crawling ${count} pages`); 54 | 55 | browser.close(); 56 | }; 57 | 58 | module.exports = crawl; 59 | -------------------------------------------------------------------------------- /db.js: -------------------------------------------------------------------------------- 1 | const bluebird = require('bluebird'); 2 | const redis = require('redis'); 3 | const MongoClient = require('mongodb').MongoClient; 4 | 5 | bluebird.promisifyAll(redis.RedisClient.prototype); 6 | bluebird.promisifyAll(redis.Multi.prototype); 7 | 8 | const debug = { 9 | db: require('debug')('crawler:db'), 10 | redis: require('debug')('crawler:redis'), 11 | mongo: require('debug')('crawler:mongo'), 12 | }; 13 | 14 | module.exports = { 15 | connect: async () => { 16 | this.db = await MongoClient.connect('mongodb://localhost:27017/crawler'); 17 | this.client = redis.createClient( 18 | process.env.REDIS_PORT || 6379, 19 | process.env.REDIS_HOST || 'localhost' 20 | ); 21 | }, 22 | store: async page => { 23 | debug.db(`Store page ${page.url}`); 24 | 25 | // We don't need to wait for this 26 | (async () => { 27 | debug.mongo('Add page to mongo'); 28 | await this.db.collection('pages').insertOne(page); 29 | debug.mongo('Mongo save complete'); 30 | })(); 31 | 32 | debug.redis('Add scraped urls to redis'); 33 | const multi = this.client.multi(); 34 | page.outboundUrls.forEach(url => { 35 | multi.sadd('discoveredPages', url); 36 | }); 37 | const result = await multi.execAsync(); 38 | debug.redis('Added urls to discovered set'); 39 | 40 | let count = 0; 41 | result.forEach((notDiscovered, i) => { 42 | if (notDiscovered) { 43 | count++; 44 | const url = page.outboundUrls[i]; 45 | multi.rpush('pageQueue', `${url} ${page.radius}`); 46 | } 47 | }); 48 | await multi.execAsync(); 49 | debug.redis(`Added ${count} new urls to queue`); 50 | debug.redis(`${page.outboundUrls.length - count} duplicates found`); 51 | debug.db('Page stored'); 52 | }, 53 | 54 | popUrl: async () => { 55 | debug.redis('Pop url from queue'); 56 | const reply = await this.client.lpopAsync('pageQueue'); 57 | if (reply) { 58 | debug.redis('Url popped'); 59 | if (debug.redis.enabled) { 60 | const length = await this.client.llenAsync('pageQueue'); 61 | debug.redis(`${length} urls in queue`); 62 | } 63 | const parts = reply.match(/(.+) ([0-9]+)$/); 64 | return { 65 | url: parts[1], 66 | radius: parseInt(parts[2]), 67 | }; 68 | } 69 | debug.redis('Queue empty'); 70 | return null; 71 | }, 72 | 73 | getNodes: async () => { 74 | const pages = await this.db.collection('pages').find().toArray(); 75 | 76 | const nodes = []; 77 | pages.forEach(page => { 78 | page.outboundUrls.forEach(url => { 79 | nodes.push({ source: page.url, target: url }); 80 | }); 81 | }); 82 | 83 | console.log(JSON.stringify(nodes)); 84 | }, 85 | 86 | flush: async () => { 87 | debug.mongo('Drop page collection'); 88 | const pages = await this.db.collection('pages'); 89 | if (pages) { 90 | await pages.drop(); 91 | } 92 | debug.mongo('Page collection dropped'); 93 | debug.redis('Flush db'); 94 | await this.client.del('discoveredPages', 'pageQueue'); 95 | debug.redis('Redis flushed'); 96 | }, 97 | 98 | close: () => { 99 | this.client.end(true); 100 | this.db.close(); 101 | }, 102 | }; 103 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "crawler", 3 | "version": "1.0.0", 4 | "main": "crawl", 5 | "license": "MIT", 6 | "author": { 7 | "email": "reed@dadoune.com", 8 | "name": "Reed Dadoune", 9 | "url": "https://www.dadoune.com" 10 | }, 11 | "scripts": { 12 | "precommit": "lint-staged" 13 | }, 14 | "lint-staged": { 15 | "*.{js, jsx}": [ 16 | "prettier --single-quote --trailing-comma es5 --write", 17 | "git add" 18 | ] 19 | }, 20 | "dependencies": { 21 | "bluebird": "^3.5.0", 22 | "debug": "^3.0.0", 23 | "dotenv": "^4.0.0", 24 | "lodash": "^4.17.13", 25 | "mongodb": "^2.2.31", 26 | "puppeteer": "^0.9.0", 27 | "redis": "^2.8.0", 28 | "yargs": "^8.0.2" 29 | }, 30 | "devDependencies": { 31 | "husky": "^0.14.3", 32 | "lint-staged": "^4.0.3", 33 | "prettier": "^1.5.3" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | ansi-escapes@^1.0.0: 6 | version "1.4.0" 7 | resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" 8 | 9 | ansi-regex@^2.0.0: 10 | version "2.1.1" 11 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" 12 | 13 | ansi-regex@^3.0.0: 14 | version "3.0.0" 15 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" 16 | 17 | ansi-styles@^2.2.1: 18 | version "2.2.1" 19 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" 20 | 21 | app-root-path@^2.0.0: 22 | version "2.0.1" 23 | resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-2.0.1.tgz#cd62dcf8e4fd5a417efc664d2e5b10653c651b46" 24 | 25 | argparse@^1.0.7: 26 | version "1.0.9" 27 | resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" 28 | dependencies: 29 | sprintf-js "~1.0.2" 30 | 31 | async-limiter@~1.0.0: 32 | version "1.0.1" 33 | resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" 34 | 35 | balanced-match@^1.0.0: 36 | version "1.0.0" 37 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" 38 | 39 | bluebird@^3.5.0: 40 | version "3.5.0" 41 | resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.0.tgz#791420d7f551eea2897453a8a77653f96606d67c" 42 | 43 | brace-expansion@^1.1.7: 44 | version "1.1.8" 45 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" 46 | dependencies: 47 | balanced-match "^1.0.0" 48 | concat-map "0.0.1" 49 | 50 | bson@~1.0.4: 51 | version "1.0.4" 52 | resolved "https://registry.yarnpkg.com/bson/-/bson-1.0.4.tgz#93c10d39eaa5b58415cbc4052f3e53e562b0b72c" 53 | 54 | buffer-shims@~1.0.0: 55 | version "1.0.0" 56 | resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51" 57 | 58 | builtin-modules@^1.0.0: 59 | version "1.1.1" 60 | resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" 61 | 62 | camelcase@^4.1.0: 63 | version "4.1.0" 64 | resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" 65 | 66 | chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: 67 | version "1.1.3" 68 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" 69 | dependencies: 70 | ansi-styles "^2.2.1" 71 | escape-string-regexp "^1.0.2" 72 | has-ansi "^2.0.0" 73 | strip-ansi "^3.0.0" 74 | supports-color "^2.0.0" 75 | 76 | ci-info@^1.0.0: 77 | version "1.0.0" 78 | resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.0.0.tgz#dc5285f2b4e251821683681c381c3388f46ec534" 79 | 80 | cli-cursor@^1.0.2: 81 | version "1.0.2" 82 | resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" 83 | dependencies: 84 | restore-cursor "^1.0.1" 85 | 86 | cli-spinners@^0.1.2: 87 | version "0.1.2" 88 | resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-0.1.2.tgz#bb764d88e185fb9e1e6a2a1f19772318f605e31c" 89 | 90 | cli-truncate@^0.2.1: 91 | version "0.2.1" 92 | resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-0.2.1.tgz#9f15cfbb0705005369216c626ac7d05ab90dd574" 93 | dependencies: 94 | slice-ansi "0.0.4" 95 | string-width "^1.0.1" 96 | 97 | cliui@^3.2.0: 98 | version "3.2.0" 99 | resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" 100 | dependencies: 101 | string-width "^1.0.1" 102 | strip-ansi "^3.0.1" 103 | wrap-ansi "^2.0.0" 104 | 105 | code-point-at@^1.0.0: 106 | version "1.1.0" 107 | resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" 108 | 109 | commander@^2.9.0: 110 | version "2.11.0" 111 | resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563" 112 | 113 | concat-map@0.0.1: 114 | version "0.0.1" 115 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 116 | 117 | concat-stream@1.6.0: 118 | version "1.6.0" 119 | resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" 120 | dependencies: 121 | inherits "^2.0.3" 122 | readable-stream "^2.2.2" 123 | typedarray "^0.0.6" 124 | 125 | core-util-is@~1.0.0: 126 | version "1.0.2" 127 | resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" 128 | 129 | cosmiconfig@^1.1.0: 130 | version "1.1.0" 131 | resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-1.1.0.tgz#0dea0f9804efdfb929fbb1b188e25553ea053d37" 132 | dependencies: 133 | graceful-fs "^4.1.2" 134 | js-yaml "^3.4.3" 135 | minimist "^1.2.0" 136 | object-assign "^4.0.1" 137 | os-homedir "^1.0.1" 138 | parse-json "^2.2.0" 139 | pinkie-promise "^2.0.0" 140 | require-from-string "^1.1.0" 141 | 142 | cross-spawn@^5.0.1: 143 | version "5.1.0" 144 | resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" 145 | dependencies: 146 | lru-cache "^4.0.1" 147 | shebang-command "^1.2.0" 148 | which "^1.2.9" 149 | 150 | date-fns@^1.27.2: 151 | version "1.28.5" 152 | resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.28.5.tgz#257cfc45d322df45ef5658665967ee841cd73faf" 153 | 154 | debug@2.2.0: 155 | version "2.2.0" 156 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" 157 | dependencies: 158 | ms "0.7.1" 159 | 160 | debug@^2.6.8: 161 | version "2.6.8" 162 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" 163 | dependencies: 164 | ms "2.0.0" 165 | 166 | debug@^3.0.0: 167 | version "3.0.0" 168 | resolved "https://registry.yarnpkg.com/debug/-/debug-3.0.0.tgz#1d2feae53349047b08b264ec41906ba17a8516e4" 169 | dependencies: 170 | ms "2.0.0" 171 | 172 | decamelize@^1.1.1: 173 | version "1.2.0" 174 | resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" 175 | 176 | dotenv@^4.0.0: 177 | version "4.0.0" 178 | resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-4.0.0.tgz#864ef1379aced55ce6f95debecdce179f7a0cd1d" 179 | 180 | double-ended-queue@^2.1.0-0: 181 | version "2.1.0-0" 182 | resolved "https://registry.yarnpkg.com/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz#103d3527fd31528f40188130c841efdd78264e5c" 183 | 184 | elegant-spinner@^1.0.1: 185 | version "1.0.1" 186 | resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e" 187 | 188 | error-ex@^1.2.0: 189 | version "1.3.1" 190 | resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc" 191 | dependencies: 192 | is-arrayish "^0.2.1" 193 | 194 | es6-promise@3.2.1: 195 | version "3.2.1" 196 | resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.2.1.tgz#ec56233868032909207170c39448e24449dd1fc4" 197 | 198 | escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: 199 | version "1.0.5" 200 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 201 | 202 | esprima@^4.0.0: 203 | version "4.0.0" 204 | resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" 205 | 206 | execa@^0.7.0: 207 | version "0.7.0" 208 | resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" 209 | dependencies: 210 | cross-spawn "^5.0.1" 211 | get-stream "^3.0.0" 212 | is-stream "^1.1.0" 213 | npm-run-path "^2.0.0" 214 | p-finally "^1.0.0" 215 | signal-exit "^3.0.0" 216 | strip-eof "^1.0.0" 217 | 218 | execa@^0.8.0: 219 | version "0.8.0" 220 | resolved "https://registry.yarnpkg.com/execa/-/execa-0.8.0.tgz#d8d76bbc1b55217ed190fd6dd49d3c774ecfc8da" 221 | dependencies: 222 | cross-spawn "^5.0.1" 223 | get-stream "^3.0.0" 224 | is-stream "^1.1.0" 225 | npm-run-path "^2.0.0" 226 | p-finally "^1.0.0" 227 | signal-exit "^3.0.0" 228 | strip-eof "^1.0.0" 229 | 230 | exit-hook@^1.0.0: 231 | version "1.1.1" 232 | resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" 233 | 234 | extract-zip@^1.6.5: 235 | version "1.6.5" 236 | resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.6.5.tgz#99a06735b6ea20ea9b705d779acffcc87cff0440" 237 | dependencies: 238 | concat-stream "1.6.0" 239 | debug "2.2.0" 240 | mkdirp "0.5.0" 241 | yauzl "2.4.1" 242 | 243 | fd-slicer@~1.0.1: 244 | version "1.0.1" 245 | resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.0.1.tgz#8b5bcbd9ec327c5041bf9ab023fd6750f1177e65" 246 | dependencies: 247 | pend "~1.2.0" 248 | 249 | figures@^1.7.0: 250 | version "1.7.0" 251 | resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" 252 | dependencies: 253 | escape-string-regexp "^1.0.5" 254 | object-assign "^4.1.0" 255 | 256 | find-up@^2.0.0: 257 | version "2.1.0" 258 | resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" 259 | dependencies: 260 | locate-path "^2.0.0" 261 | 262 | fs.realpath@^1.0.0: 263 | version "1.0.0" 264 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 265 | 266 | get-caller-file@^1.0.1: 267 | version "1.0.2" 268 | resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" 269 | 270 | get-stream@^3.0.0: 271 | version "3.0.0" 272 | resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" 273 | 274 | glob@^7.0.5: 275 | version "7.1.2" 276 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" 277 | dependencies: 278 | fs.realpath "^1.0.0" 279 | inflight "^1.0.4" 280 | inherits "2" 281 | minimatch "^3.0.4" 282 | once "^1.3.0" 283 | path-is-absolute "^1.0.0" 284 | 285 | graceful-fs@^4.1.2: 286 | version "4.1.11" 287 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" 288 | 289 | has-ansi@^2.0.0: 290 | version "2.0.0" 291 | resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" 292 | dependencies: 293 | ansi-regex "^2.0.0" 294 | 295 | hosted-git-info@^2.1.4: 296 | version "2.5.0" 297 | resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c" 298 | 299 | husky@^0.14.3: 300 | version "0.14.3" 301 | resolved "https://registry.yarnpkg.com/husky/-/husky-0.14.3.tgz#c69ed74e2d2779769a17ba8399b54ce0b63c12c3" 302 | dependencies: 303 | is-ci "^1.0.10" 304 | normalize-path "^1.0.0" 305 | strip-indent "^2.0.0" 306 | 307 | indent-string@^2.1.0: 308 | version "2.1.0" 309 | resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" 310 | dependencies: 311 | repeating "^2.0.0" 312 | 313 | indent-string@^3.0.0: 314 | version "3.2.0" 315 | resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" 316 | 317 | inflight@^1.0.4: 318 | version "1.0.6" 319 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 320 | dependencies: 321 | once "^1.3.0" 322 | wrappy "1" 323 | 324 | inherits@2, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: 325 | version "2.0.3" 326 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" 327 | 328 | invert-kv@^1.0.0: 329 | version "1.0.0" 330 | resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" 331 | 332 | is-arrayish@^0.2.1: 333 | version "0.2.1" 334 | resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" 335 | 336 | is-builtin-module@^1.0.0: 337 | version "1.0.0" 338 | resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" 339 | dependencies: 340 | builtin-modules "^1.0.0" 341 | 342 | is-ci@^1.0.10: 343 | version "1.0.10" 344 | resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.0.10.tgz#f739336b2632365061a9d48270cd56ae3369318e" 345 | dependencies: 346 | ci-info "^1.0.0" 347 | 348 | is-finite@^1.0.0: 349 | version "1.0.2" 350 | resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" 351 | dependencies: 352 | number-is-nan "^1.0.0" 353 | 354 | is-fullwidth-code-point@^1.0.0: 355 | version "1.0.0" 356 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" 357 | dependencies: 358 | number-is-nan "^1.0.0" 359 | 360 | is-fullwidth-code-point@^2.0.0: 361 | version "2.0.0" 362 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" 363 | 364 | is-promise@^2.1.0: 365 | version "2.1.0" 366 | resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" 367 | 368 | is-stream@^1.1.0: 369 | version "1.1.0" 370 | resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" 371 | 372 | isarray@~1.0.0: 373 | version "1.0.0" 374 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" 375 | 376 | isexe@^2.0.0: 377 | version "2.0.0" 378 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" 379 | 380 | js-yaml@^3.4.3: 381 | version "3.9.1" 382 | resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.9.1.tgz#08775cebdfdd359209f0d2acd383c8f86a6904a0" 383 | dependencies: 384 | argparse "^1.0.7" 385 | esprima "^4.0.0" 386 | 387 | lcid@^1.0.0: 388 | version "1.0.0" 389 | resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" 390 | dependencies: 391 | invert-kv "^1.0.0" 392 | 393 | lint-staged@^4.0.3: 394 | version "4.0.3" 395 | resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-4.0.3.tgz#1ce55591bc2c83a781a90b69a0a0c8aa0fc6370b" 396 | dependencies: 397 | app-root-path "^2.0.0" 398 | cosmiconfig "^1.1.0" 399 | execa "^0.8.0" 400 | listr "^0.12.0" 401 | lodash.chunk "^4.2.0" 402 | minimatch "^3.0.0" 403 | npm-which "^3.0.1" 404 | p-map "^1.1.1" 405 | staged-git-files "0.0.4" 406 | 407 | listr-silent-renderer@^1.1.1: 408 | version "1.1.1" 409 | resolved "https://registry.yarnpkg.com/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz#924b5a3757153770bf1a8e3fbf74b8bbf3f9242e" 410 | 411 | listr-update-renderer@^0.2.0: 412 | version "0.2.0" 413 | resolved "https://registry.yarnpkg.com/listr-update-renderer/-/listr-update-renderer-0.2.0.tgz#ca80e1779b4e70266807e8eed1ad6abe398550f9" 414 | dependencies: 415 | chalk "^1.1.3" 416 | cli-truncate "^0.2.1" 417 | elegant-spinner "^1.0.1" 418 | figures "^1.7.0" 419 | indent-string "^3.0.0" 420 | log-symbols "^1.0.2" 421 | log-update "^1.0.2" 422 | strip-ansi "^3.0.1" 423 | 424 | listr-verbose-renderer@^0.4.0: 425 | version "0.4.0" 426 | resolved "https://registry.yarnpkg.com/listr-verbose-renderer/-/listr-verbose-renderer-0.4.0.tgz#44dc01bb0c34a03c572154d4d08cde9b1dc5620f" 427 | dependencies: 428 | chalk "^1.1.3" 429 | cli-cursor "^1.0.2" 430 | date-fns "^1.27.2" 431 | figures "^1.7.0" 432 | 433 | listr@^0.12.0: 434 | version "0.12.0" 435 | resolved "https://registry.yarnpkg.com/listr/-/listr-0.12.0.tgz#6bce2c0f5603fa49580ea17cd6a00cc0e5fa451a" 436 | dependencies: 437 | chalk "^1.1.3" 438 | cli-truncate "^0.2.1" 439 | figures "^1.7.0" 440 | indent-string "^2.1.0" 441 | is-promise "^2.1.0" 442 | is-stream "^1.1.0" 443 | listr-silent-renderer "^1.1.1" 444 | listr-update-renderer "^0.2.0" 445 | listr-verbose-renderer "^0.4.0" 446 | log-symbols "^1.0.2" 447 | log-update "^1.0.2" 448 | ora "^0.2.3" 449 | p-map "^1.1.1" 450 | rxjs "^5.0.0-beta.11" 451 | stream-to-observable "^0.1.0" 452 | strip-ansi "^3.0.1" 453 | 454 | load-json-file@^2.0.0: 455 | version "2.0.0" 456 | resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" 457 | dependencies: 458 | graceful-fs "^4.1.2" 459 | parse-json "^2.2.0" 460 | pify "^2.0.0" 461 | strip-bom "^3.0.0" 462 | 463 | locate-path@^2.0.0: 464 | version "2.0.0" 465 | resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" 466 | dependencies: 467 | p-locate "^2.0.0" 468 | path-exists "^3.0.0" 469 | 470 | lodash.chunk@^4.2.0: 471 | version "4.2.0" 472 | resolved "https://registry.yarnpkg.com/lodash.chunk/-/lodash.chunk-4.2.0.tgz#66e5ce1f76ed27b4303d8c6512e8d1216e8106bc" 473 | 474 | lodash@^4.17.13: 475 | version "4.17.13" 476 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.13.tgz#0bdc3a6adc873d2f4e0c4bac285df91b64fc7b93" 477 | 478 | log-symbols@^1.0.2: 479 | version "1.0.2" 480 | resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18" 481 | dependencies: 482 | chalk "^1.0.0" 483 | 484 | log-update@^1.0.2: 485 | version "1.0.2" 486 | resolved "https://registry.yarnpkg.com/log-update/-/log-update-1.0.2.tgz#19929f64c4093d2d2e7075a1dad8af59c296b8d1" 487 | dependencies: 488 | ansi-escapes "^1.0.0" 489 | cli-cursor "^1.0.2" 490 | 491 | lru-cache@^4.0.1: 492 | version "4.1.1" 493 | resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.1.tgz#622e32e82488b49279114a4f9ecf45e7cd6bba55" 494 | dependencies: 495 | pseudomap "^1.0.2" 496 | yallist "^2.1.2" 497 | 498 | mem@^1.1.0: 499 | version "1.1.0" 500 | resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" 501 | dependencies: 502 | mimic-fn "^1.0.0" 503 | 504 | mime@^1.3.4: 505 | version "1.3.6" 506 | resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.6.tgz#591d84d3653a6b0b4a3b9df8de5aa8108e72e5e0" 507 | 508 | mimic-fn@^1.0.0: 509 | version "1.1.0" 510 | resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18" 511 | 512 | minimatch@^3.0.0, minimatch@^3.0.4: 513 | version "3.0.4" 514 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" 515 | dependencies: 516 | brace-expansion "^1.1.7" 517 | 518 | minimist@0.0.8: 519 | version "0.0.8" 520 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" 521 | 522 | minimist@^1.2.0: 523 | version "1.2.0" 524 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" 525 | 526 | mkdirp@0.5.0: 527 | version "0.5.0" 528 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.0.tgz#1d73076a6df986cd9344e15e71fcc05a4c9abf12" 529 | dependencies: 530 | minimist "0.0.8" 531 | 532 | mongodb-core@2.1.15: 533 | version "2.1.15" 534 | resolved "https://registry.yarnpkg.com/mongodb-core/-/mongodb-core-2.1.15.tgz#841f53b87ffff4c7458189c35c8ae827e1169764" 535 | dependencies: 536 | bson "~1.0.4" 537 | require_optional "~1.0.0" 538 | 539 | mongodb@^2.2.31: 540 | version "2.2.31" 541 | resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-2.2.31.tgz#1940445c661e19217bb3bf8245d9854aaef548db" 542 | dependencies: 543 | es6-promise "3.2.1" 544 | mongodb-core "2.1.15" 545 | readable-stream "2.2.7" 546 | 547 | ms@0.7.1: 548 | version "0.7.1" 549 | resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098" 550 | 551 | ms@2.0.0: 552 | version "2.0.0" 553 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" 554 | 555 | normalize-package-data@^2.3.2: 556 | version "2.4.0" 557 | resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" 558 | dependencies: 559 | hosted-git-info "^2.1.4" 560 | is-builtin-module "^1.0.0" 561 | semver "2 || 3 || 4 || 5" 562 | validate-npm-package-license "^3.0.1" 563 | 564 | normalize-path@^1.0.0: 565 | version "1.0.0" 566 | resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-1.0.0.tgz#32d0e472f91ff345701c15a8311018d3b0a90379" 567 | 568 | npm-path@^2.0.2: 569 | version "2.0.3" 570 | resolved "https://registry.yarnpkg.com/npm-path/-/npm-path-2.0.3.tgz#15cff4e1c89a38da77f56f6055b24f975dfb2bbe" 571 | dependencies: 572 | which "^1.2.10" 573 | 574 | npm-run-path@^2.0.0: 575 | version "2.0.2" 576 | resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" 577 | dependencies: 578 | path-key "^2.0.0" 579 | 580 | npm-which@^3.0.1: 581 | version "3.0.1" 582 | resolved "https://registry.yarnpkg.com/npm-which/-/npm-which-3.0.1.tgz#9225f26ec3a285c209cae67c3b11a6b4ab7140aa" 583 | dependencies: 584 | commander "^2.9.0" 585 | npm-path "^2.0.2" 586 | which "^1.2.10" 587 | 588 | number-is-nan@^1.0.0: 589 | version "1.0.1" 590 | resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" 591 | 592 | object-assign@^4.0.1, object-assign@^4.1.0: 593 | version "4.1.1" 594 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" 595 | 596 | once@^1.3.0: 597 | version "1.4.0" 598 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 599 | dependencies: 600 | wrappy "1" 601 | 602 | onetime@^1.0.0: 603 | version "1.1.0" 604 | resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" 605 | 606 | ora@^0.2.3: 607 | version "0.2.3" 608 | resolved "https://registry.yarnpkg.com/ora/-/ora-0.2.3.tgz#37527d220adcd53c39b73571d754156d5db657a4" 609 | dependencies: 610 | chalk "^1.1.1" 611 | cli-cursor "^1.0.2" 612 | cli-spinners "^0.1.2" 613 | object-assign "^4.0.1" 614 | 615 | os-homedir@^1.0.1: 616 | version "1.0.2" 617 | resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" 618 | 619 | os-locale@^2.0.0: 620 | version "2.1.0" 621 | resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" 622 | dependencies: 623 | execa "^0.7.0" 624 | lcid "^1.0.0" 625 | mem "^1.1.0" 626 | 627 | p-finally@^1.0.0: 628 | version "1.0.0" 629 | resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" 630 | 631 | p-limit@^1.1.0: 632 | version "1.1.0" 633 | resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.1.0.tgz#b07ff2d9a5d88bec806035895a2bab66a27988bc" 634 | 635 | p-locate@^2.0.0: 636 | version "2.0.0" 637 | resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" 638 | dependencies: 639 | p-limit "^1.1.0" 640 | 641 | p-map@^1.1.1: 642 | version "1.1.1" 643 | resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.1.1.tgz#05f5e4ae97a068371bc2a5cc86bfbdbc19c4ae7a" 644 | 645 | parse-json@^2.2.0: 646 | version "2.2.0" 647 | resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" 648 | dependencies: 649 | error-ex "^1.2.0" 650 | 651 | path-exists@^3.0.0: 652 | version "3.0.0" 653 | resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" 654 | 655 | path-is-absolute@^1.0.0: 656 | version "1.0.1" 657 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 658 | 659 | path-key@^2.0.0: 660 | version "2.0.1" 661 | resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" 662 | 663 | path-type@^2.0.0: 664 | version "2.0.0" 665 | resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" 666 | dependencies: 667 | pify "^2.0.0" 668 | 669 | pend@~1.2.0: 670 | version "1.2.0" 671 | resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" 672 | 673 | pify@^2.0.0: 674 | version "2.3.0" 675 | resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" 676 | 677 | pinkie-promise@^2.0.0: 678 | version "2.0.1" 679 | resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" 680 | dependencies: 681 | pinkie "^2.0.0" 682 | 683 | pinkie@^2.0.0: 684 | version "2.0.4" 685 | resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" 686 | 687 | prettier@^1.5.3: 688 | version "1.5.3" 689 | resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.5.3.tgz#59dadc683345ec6b88f88b94ed4ae7e1da394bfe" 690 | 691 | process-nextick-args@~1.0.6: 692 | version "1.0.7" 693 | resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" 694 | 695 | progress@^2.0.0: 696 | version "2.0.0" 697 | resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f" 698 | 699 | pseudomap@^1.0.2: 700 | version "1.0.2" 701 | resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" 702 | 703 | puppeteer@^0.9.0: 704 | version "0.9.0" 705 | resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-0.9.0.tgz#d65997ff83e24eb569e5577d2f75695dcbe5be4a" 706 | dependencies: 707 | debug "^2.6.8" 708 | extract-zip "^1.6.5" 709 | mime "^1.3.4" 710 | progress "^2.0.0" 711 | rimraf "^2.6.1" 712 | ws "^3.0.0" 713 | 714 | read-pkg-up@^2.0.0: 715 | version "2.0.0" 716 | resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" 717 | dependencies: 718 | find-up "^2.0.0" 719 | read-pkg "^2.0.0" 720 | 721 | read-pkg@^2.0.0: 722 | version "2.0.0" 723 | resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" 724 | dependencies: 725 | load-json-file "^2.0.0" 726 | normalize-package-data "^2.3.2" 727 | path-type "^2.0.0" 728 | 729 | readable-stream@2.2.7: 730 | version "2.2.7" 731 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.7.tgz#07057acbe2467b22042d36f98c5ad507054e95b1" 732 | dependencies: 733 | buffer-shims "~1.0.0" 734 | core-util-is "~1.0.0" 735 | inherits "~2.0.1" 736 | isarray "~1.0.0" 737 | process-nextick-args "~1.0.6" 738 | string_decoder "~1.0.0" 739 | util-deprecate "~1.0.1" 740 | 741 | readable-stream@^2.2.2: 742 | version "2.3.3" 743 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c" 744 | dependencies: 745 | core-util-is "~1.0.0" 746 | inherits "~2.0.3" 747 | isarray "~1.0.0" 748 | process-nextick-args "~1.0.6" 749 | safe-buffer "~5.1.1" 750 | string_decoder "~1.0.3" 751 | util-deprecate "~1.0.1" 752 | 753 | redis-commands@^1.2.0: 754 | version "1.3.1" 755 | resolved "https://registry.yarnpkg.com/redis-commands/-/redis-commands-1.3.1.tgz#81d826f45fa9c8b2011f4cd7a0fe597d241d442b" 756 | 757 | redis-parser@^2.6.0: 758 | version "2.6.0" 759 | resolved "https://registry.yarnpkg.com/redis-parser/-/redis-parser-2.6.0.tgz#52ed09dacac108f1a631c07e9b69941e7a19504b" 760 | 761 | redis@^2.8.0: 762 | version "2.8.0" 763 | resolved "https://registry.yarnpkg.com/redis/-/redis-2.8.0.tgz#202288e3f58c49f6079d97af7a10e1303ae14b02" 764 | dependencies: 765 | double-ended-queue "^2.1.0-0" 766 | redis-commands "^1.2.0" 767 | redis-parser "^2.6.0" 768 | 769 | repeating@^2.0.0: 770 | version "2.0.1" 771 | resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" 772 | dependencies: 773 | is-finite "^1.0.0" 774 | 775 | require-directory@^2.1.1: 776 | version "2.1.1" 777 | resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" 778 | 779 | require-from-string@^1.1.0: 780 | version "1.2.1" 781 | resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-1.2.1.tgz#529c9ccef27380adfec9a2f965b649bbee636418" 782 | 783 | require-main-filename@^1.0.1: 784 | version "1.0.1" 785 | resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" 786 | 787 | require_optional@~1.0.0: 788 | version "1.0.1" 789 | resolved "https://registry.yarnpkg.com/require_optional/-/require_optional-1.0.1.tgz#4cf35a4247f64ca3df8c2ef208cc494b1ca8fc2e" 790 | dependencies: 791 | resolve-from "^2.0.0" 792 | semver "^5.1.0" 793 | 794 | resolve-from@^2.0.0: 795 | version "2.0.0" 796 | resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-2.0.0.tgz#9480ab20e94ffa1d9e80a804c7ea147611966b57" 797 | 798 | restore-cursor@^1.0.1: 799 | version "1.0.1" 800 | resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541" 801 | dependencies: 802 | exit-hook "^1.0.0" 803 | onetime "^1.0.0" 804 | 805 | rimraf@^2.6.1: 806 | version "2.6.1" 807 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.1.tgz#c2338ec643df7a1b7fe5c54fa86f57428a55f33d" 808 | dependencies: 809 | glob "^7.0.5" 810 | 811 | rxjs@^5.0.0-beta.11: 812 | version "5.4.3" 813 | resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.4.3.tgz#0758cddee6033d68e0fd53676f0f3596ce3d483f" 814 | dependencies: 815 | symbol-observable "^1.0.1" 816 | 817 | safe-buffer@~5.1.0, safe-buffer@~5.1.1: 818 | version "5.1.2" 819 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" 820 | 821 | "semver@2 || 3 || 4 || 5", semver@^5.1.0: 822 | version "5.4.1" 823 | resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" 824 | 825 | set-blocking@^2.0.0: 826 | version "2.0.0" 827 | resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" 828 | 829 | shebang-command@^1.2.0: 830 | version "1.2.0" 831 | resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" 832 | dependencies: 833 | shebang-regex "^1.0.0" 834 | 835 | shebang-regex@^1.0.0: 836 | version "1.0.0" 837 | resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" 838 | 839 | signal-exit@^3.0.0: 840 | version "3.0.2" 841 | resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" 842 | 843 | slice-ansi@0.0.4: 844 | version "0.0.4" 845 | resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" 846 | 847 | spdx-correct@~1.0.0: 848 | version "1.0.2" 849 | resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40" 850 | dependencies: 851 | spdx-license-ids "^1.0.2" 852 | 853 | spdx-expression-parse@~1.0.0: 854 | version "1.0.4" 855 | resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz#9bdf2f20e1f40ed447fbe273266191fced51626c" 856 | 857 | spdx-license-ids@^1.0.2: 858 | version "1.2.2" 859 | resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57" 860 | 861 | sprintf-js@~1.0.2: 862 | version "1.0.3" 863 | resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" 864 | 865 | staged-git-files@0.0.4: 866 | version "0.0.4" 867 | resolved "https://registry.yarnpkg.com/staged-git-files/-/staged-git-files-0.0.4.tgz#d797e1b551ca7a639dec0237dc6eb4bb9be17d35" 868 | 869 | stream-to-observable@^0.1.0: 870 | version "0.1.0" 871 | resolved "https://registry.yarnpkg.com/stream-to-observable/-/stream-to-observable-0.1.0.tgz#45bf1d9f2d7dc09bed81f1c307c430e68b84cffe" 872 | 873 | string-width@^1.0.1: 874 | version "1.0.2" 875 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" 876 | dependencies: 877 | code-point-at "^1.0.0" 878 | is-fullwidth-code-point "^1.0.0" 879 | strip-ansi "^3.0.0" 880 | 881 | string-width@^2.0.0: 882 | version "2.1.1" 883 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" 884 | dependencies: 885 | is-fullwidth-code-point "^2.0.0" 886 | strip-ansi "^4.0.0" 887 | 888 | string_decoder@~1.0.0, string_decoder@~1.0.3: 889 | version "1.0.3" 890 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab" 891 | dependencies: 892 | safe-buffer "~5.1.0" 893 | 894 | strip-ansi@^3.0.0, strip-ansi@^3.0.1: 895 | version "3.0.1" 896 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" 897 | dependencies: 898 | ansi-regex "^2.0.0" 899 | 900 | strip-ansi@^4.0.0: 901 | version "4.0.0" 902 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" 903 | dependencies: 904 | ansi-regex "^3.0.0" 905 | 906 | strip-bom@^3.0.0: 907 | version "3.0.0" 908 | resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" 909 | 910 | strip-eof@^1.0.0: 911 | version "1.0.0" 912 | resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" 913 | 914 | strip-indent@^2.0.0: 915 | version "2.0.0" 916 | resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" 917 | 918 | supports-color@^2.0.0: 919 | version "2.0.0" 920 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" 921 | 922 | symbol-observable@^1.0.1: 923 | version "1.0.4" 924 | resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.4.tgz#29bf615d4aa7121bdd898b22d4b3f9bc4e2aa03d" 925 | 926 | typedarray@^0.0.6: 927 | version "0.0.6" 928 | resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" 929 | 930 | ultron@~1.1.0: 931 | version "1.1.1" 932 | resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c" 933 | 934 | util-deprecate@~1.0.1: 935 | version "1.0.2" 936 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" 937 | 938 | validate-npm-package-license@^3.0.1: 939 | version "3.0.1" 940 | resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc" 941 | dependencies: 942 | spdx-correct "~1.0.0" 943 | spdx-expression-parse "~1.0.0" 944 | 945 | which-module@^2.0.0: 946 | version "2.0.0" 947 | resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" 948 | 949 | which@^1.2.10, which@^1.2.9: 950 | version "1.3.0" 951 | resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a" 952 | dependencies: 953 | isexe "^2.0.0" 954 | 955 | wrap-ansi@^2.0.0: 956 | version "2.1.0" 957 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" 958 | dependencies: 959 | string-width "^1.0.1" 960 | strip-ansi "^3.0.1" 961 | 962 | wrappy@1: 963 | version "1.0.2" 964 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 965 | 966 | ws@^3.0.0: 967 | version "3.3.3" 968 | resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2" 969 | dependencies: 970 | async-limiter "~1.0.0" 971 | safe-buffer "~5.1.0" 972 | ultron "~1.1.0" 973 | 974 | y18n@^3.2.1: 975 | version "3.2.1" 976 | resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" 977 | 978 | yallist@^2.1.2: 979 | version "2.1.2" 980 | resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" 981 | 982 | yargs-parser@^7.0.0: 983 | version "7.0.0" 984 | resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-7.0.0.tgz#8d0ac42f16ea55debd332caf4c4038b3e3f5dfd9" 985 | dependencies: 986 | camelcase "^4.1.0" 987 | 988 | yargs@^8.0.2: 989 | version "8.0.2" 990 | resolved "https://registry.yarnpkg.com/yargs/-/yargs-8.0.2.tgz#6299a9055b1cefc969ff7e79c1d918dceb22c360" 991 | dependencies: 992 | camelcase "^4.1.0" 993 | cliui "^3.2.0" 994 | decamelize "^1.1.1" 995 | get-caller-file "^1.0.1" 996 | os-locale "^2.0.0" 997 | read-pkg-up "^2.0.0" 998 | require-directory "^2.1.1" 999 | require-main-filename "^1.0.1" 1000 | set-blocking "^2.0.0" 1001 | string-width "^2.0.0" 1002 | which-module "^2.0.0" 1003 | y18n "^3.2.1" 1004 | yargs-parser "^7.0.0" 1005 | 1006 | yauzl@2.4.1: 1007 | version "2.4.1" 1008 | resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.4.1.tgz#9528f442dab1b2284e58b4379bb194e22e0c4005" 1009 | dependencies: 1010 | fd-slicer "~1.0.1" 1011 | --------------------------------------------------------------------------------