diff --git a/app/browser/api/ledger.js b/app/browser/api/ledger.js
index b96c0b1c619..17d0ec0c4a1 100644
--- a/app/browser/api/ledger.js
+++ b/app/browser/api/ledger.js
@@ -1408,6 +1408,77 @@ const clientprep = () => {
   _internal.verboseP = ledgerClient.prototype.boolion(process.env.LEDGER_PUBLISHER_VERBOSE)
 }
 
+/**
+ * This callback that we do it in roundtrips
+ *
+ * @callback roundtripCallback
+ * @param {Error|null} error - error when doing a request, null if no errors
+ * @param {object} response - response object that we get from request.request
+ * @param {any} payload - data that we get from the request
+ */
+
+/**
+ * Round trip for fetching data (scrap data from html) inside window process
+ * @param {object} params - contains params from roundtrip
+ * @param {string} params.url - url of the site that we want to scrap
+ * @param {string} params.verboseP - tells us if we want to log the process or not
+ * @param {roundtripCallback} callback - The callback that handles the response
+ */
+const roundTripFromWindow = (params, callback) => {
+  if (!callback) {
+    return
+  }
+
+  if (!params || !params.url) {
+    if (params && params.verboseP) {
+      console.log(`We are missing url. Params ${JSON.stringify(params)}`)
+    }
+
+    callback(new Error('Url is missing'))
+    return
+  }
+
+  request.fetchPublisherInfo(params.url, {
+    method: 'GET',
+    responseType: 'text',
+    headers: {
+      'content-type': 'application/json; charset=utf-8'
+    }
+  }, (error, body) => {
+    if (error) {
+      if (params.verboseP) {
+        console.log(`roundTripFromWindow error: ${error.toString()}`)
+      }
+      return callback(error)
+    }
+
+    if (params.verboseP) {
+      console.log(`roundTripFromWindow success: ${JSON.stringify(body)}`)
+    }
+
+    return callback(null, null, body)
+  })
+}
+
+/**
+ * Round trip function for executing actions
+ * from the bat libraries (mostly server calls)
+ * @param {object} params - params that are directly tied to request.request
+ * @param {string} params.server - server url
+ * @param {string} params.method - HTTP method (GET, PUT, etc)
+ * @param {object} params.payload - payload that we want to send to the server
+ * @param {object} params.headers - HTTP headers
+ * @param {string} params.path - relative path to requested url
+ * @param {object} options
+ * @param {boolean} options.verboseP - tells us if we want to log the process or not
+ * @param {object} options.headers - headers that are used in the request.request
+ * @param {string} options.server - server url
+ * @param {boolean} options.binaryP - are we receiving binary payload back
+ * @param {boolean} options.rawP - are we receiving raw payload back
+ * @param {boolean} options.scrapeP - are we doping scraping
+ * @param {boolean} options.windowP - do we want to run this request in the window process
+ * @param {roundtripCallback} callback - The callback that handles the response
+ */
 const roundtrip = (params, options, callback) => {
   let parts = typeof params.server === 'string' ? urlParse(params.server)
     : typeof params.server !== 'undefined' ? params.server
@@ -1436,6 +1507,11 @@ const roundtrip = (params, options, callback) => {
     parts.pathname = parts.path
   }
 
+  if (options.windowP) {
+    roundTripFromWindow({url: urlFormat(parts), verboseP: options.verboseP}, callback)
+    return
+  }
+
   options = {
     url: urlFormat(parts),
     method: params.method,
@@ -2863,6 +2939,7 @@ const getMethods = () => {
       activityRoundTrip,
       pathName,
       onReferralInit,
+      roundTripFromWindow,
       onReferralCodeRead,
       onVerifiedPStatus
     }
diff --git a/app/extensions.js b/app/extensions.js
index e7815a33525..eb71cb897ac 100644
--- a/app/extensions.js
+++ b/app/extensions.js
@@ -38,7 +38,7 @@ let generateBraveManifest = () => {
     manifest_version: 2,
     version: '1.0',
     background: {
-      scripts: [ 'content/scripts/idleHandler.js' ],
+      scripts: [ 'content/scripts/metaScraper.js', 'content/scripts/requestHandler.js', 'content/scripts/idleHandler.js' ],
       persistent: true
     },
     content_scripts: [
@@ -187,6 +187,7 @@ let generateBraveManifest = () => {
     'style-src': '\'self\' \'unsafe-inline\'',
     'font-src': '\'self\' data:',
     'img-src': '* data: file://*',
+    'connect-src': 'https://www.youtube.com',
     'frame-src': '\'self\' https://brave.com'
   }
 
@@ -194,9 +195,11 @@ let generateBraveManifest = () => {
     // allow access to webpack dev server resources
     let devServer = 'localhost:' + process.env.npm_package_config_port
     cspDirectives['default-src'] = '\'self\' http://' + devServer
-    cspDirectives['connect-src'] = ['\'self\'',
+    cspDirectives['connect-src'] = cspDirectives['connect-src'] + [
+      ' \'self\'',
       'http://' + devServer,
-      'ws://' + devServer].join(' ')
+      'ws://' + devServer
+    ].join(' ')
     cspDirectives['style-src'] = '\'self\' \'unsafe-inline\' http://' + devServer
     cspDirectives['font-src'] += ` http://${devServer}`
   }
diff --git a/app/extensions/brave/content/scripts/metaScraper.js b/app/extensions/brave/content/scripts/metaScraper.js
new file mode 100644
index 00000000000..e8855b2ff04
--- /dev/null
+++ b/app/extensions/brave/content/scripts/metaScraper.js
@@ -0,0 +1,102 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+ // Main repository
+ // Version 3.9.2
+// https://github.com/microlinkhq/metascraper
+
+// Image
+// https://github.com/microlinkhq/metascraper/tree/master/packages/metascraper-image
+
+// Author
+// https://github.com/microlinkhq/metascraper/tree/master/packages/metascraper-author
+
+// Title
+// https://github.com/microlinkhq/metascraper/tree/master/packages/metascraper-title
+
+// YouTube
+// https://github.com/microlinkhq/metascraper/tree/master/packages/metascraper-youtube
+
+const metaScraperRules = {
+  // Rules
+  getImageRules: () => {
+    const wrap = rule => ({htmlDom,url}) => {
+      const value = rule(htmlDom)
+      return requestHandlerApi.isUrl(value) && requestHandlerApi.getUrl(url, value)
+    }
+
+    return [
+      // Youtube
+      ({htmlDom,url}) => {
+        const {id,service} = requestHandlerApi.getVideoId(url)
+        return service === 'youtube' && id && requestHandlerApi.getThumbnailUrl(id)
+      },
+      // Regular
+      wrap(html => requestHandlerApi.getContent(html.querySelector('meta[property="og:image:secure_url"]'))),
+      wrap(html => requestHandlerApi.getContent(html.querySelector('meta[property="og:image:url"]'))),
+      wrap(html => requestHandlerApi.getContent(html.querySelector('meta[property="og:image"]'))),
+      wrap(html => requestHandlerApi.getContent(html.querySelector('meta[name="twitter:image:src"]'))),
+      wrap(html => requestHandlerApi.getContent(html.querySelector('meta[name="twitter:image"]'))),
+      wrap(html => requestHandlerApi.getContent(html.querySelector('meta[name="sailthru.image.thumb"]'))),
+      wrap(html => requestHandlerApi.getContent(html.querySelector('meta[name="sailthru.image.full"]'))),
+      wrap(html => requestHandlerApi.getContent(html.querySelector('meta[name="sailthru.image"]'))),
+      wrap(html => requestHandlerApi.getValue(html.querySelectorAll('article img[src]'), requestHandlerApi.getSrc)),
+      wrap(html => requestHandlerApi.getValue(html.querySelectorAll('#content img[src]'), requestHandlerApi.getSrc)),
+      wrap(html => requestHandlerApi.getSrc(html.querySelector('img[alt*="author"]'))),
+      wrap(html => requestHandlerApi.getSrc(html.querySelector('img[src]')))
+    ]
+  },
+
+  getTitleRules: () => {
+    const wrap = rule => ({htmlDom}) => {
+      const value = rule(htmlDom)
+      return requestHandlerApi.isString(value) && requestHandlerApi.titleize(value)
+    }
+
+    return [
+      // Regular
+      wrap(html => requestHandlerApi.getContent(html.querySelector('meta[property="og:title"]'))),
+      wrap(html => requestHandlerApi.getContent(html.querySelector('meta[name="twitter:title"]'))),
+      wrap(html => requestHandlerApi.getContent(html.querySelector('meta[name="sailthru.title"]'))),
+      wrap(html => requestHandlerApi.getText(html.querySelector('.post-title'))),
+      wrap(html => requestHandlerApi.getText(html.querySelector('.entry-title'))),
+      wrap(html => requestHandlerApi.getText(html.querySelector('[itemtype="http://schema.org/BlogPosting"] [itemprop="name"]'))),
+      wrap(html => requestHandlerApi.getText(html.querySelector('h1[class*="title"] a'))),
+      wrap(html => requestHandlerApi.getText(html.querySelector('h1[class*="title"]'))),
+      wrap(html => requestHandlerApi.getText(html.querySelector('title')))
+    ]
+  },
+
+  getAuthorRules: () => {
+    const wrap = rule => ({htmlDom}) => {
+      const value = rule(htmlDom)
+
+      return requestHandlerApi.isString(value) &&
+        !requestHandlerApi.isUrl(value, {relative: false}) &&
+        requestHandlerApi.titleize(value, {removeBy: true})
+    }
+
+    return [
+      // Youtube
+      wrap(html => requestHandlerApi.getText(html.querySelector('#owner-name'))),
+      wrap(html => requestHandlerApi.getText(html.querySelector('#channel-title'))),
+      wrap(html => requestHandlerApi.getValue(html.querySelectorAll('[class*="user-info"]'))),
+      // Regular
+      wrap(html => requestHandlerApi.getContent(html.querySelector('meta[property="author"]'))),
+      wrap(html => requestHandlerApi.getContent(html.querySelector('meta[property="article:author"]'))),
+      wrap(html => requestHandlerApi.getContent(html.querySelector('meta[name="author"]'))),
+      wrap(html => requestHandlerApi.getContent(html.querySelector('meta[name="sailthru.author"]'))),
+      wrap(html => requestHandlerApi.getValue(html.querySelectorAll('[rel="author"]'))),
+      wrap(html => requestHandlerApi.getValue(html.querySelectorAll('[itemprop*="author"] [itemprop="name"]'))),
+      wrap(html => requestHandlerApi.getValue(html.querySelectorAll('[itemprop*="author"]'))),
+      wrap(html => requestHandlerApi.getContent(html.querySelector('meta[property="book:author"]'))),
+      requestHandlerApi.strict(wrap(html => requestHandlerApi.getValue(html.querySelectorAll('a[class*="author"]')))),
+      requestHandlerApi.strict(wrap(html => requestHandlerApi.getValue(html.querySelectorAll('[class*="author"] a')))),
+      requestHandlerApi.strict(wrap(html => requestHandlerApi.getValue(html.querySelectorAll('a[href*="/author/"]')))),
+      wrap(html => requestHandlerApi.getValue(html.querySelectorAll('a[class*="screenname"]'))),
+      requestHandlerApi.strict(wrap(html => requestHandlerApi.getValue(html.querySelectorAll('[class*="author"]')))),
+      requestHandlerApi.strict(wrap(html => requestHandlerApi.getValue(html.querySelectorAll('[class*="byline"]'))))
+    ]
+  }
+}
diff --git a/app/extensions/brave/content/scripts/requestHandler.js b/app/extensions/brave/content/scripts/requestHandler.js
new file mode 100644
index 00000000000..16afec1ee48
--- /dev/null
+++ b/app/extensions/brave/content/scripts/requestHandler.js
@@ -0,0 +1,374 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+const ipc = chrome.ipcRenderer
+
+ipc.send('got-background-page-webcontents')
+const domParser = new DOMParser()
+
+ipc.on('fetch-publisher-info', (e, url, options) => {
+  let finalUrl = url
+  window.fetch(url, options).then((response) => {
+    finalUrl = response.url
+    return response.text()
+  }).then((text) => {
+    const html = domParser.parseFromString(text, 'text/html')
+    requestHandlerApi.getMetaData(html, url, finalUrl)
+  }).catch((err) => {
+    requestHandlerApi.onError(err, url, finalUrl)
+  })
+})
+
+const requestHandlerApi = {
+  onError: (err, url, finalUrl) => {
+    console.error('fetch error', err)
+    ipc.send(`got-publisher-info-${url}`, {
+      error: err.message,
+      body: {
+        url: finalUrl
+      }
+    })
+  },
+
+  getMetaData: async (htmlDom, url, finalUrl) => {
+    try {
+      const result = {
+        image: await requestHandlerApi.getData({ htmlDom, finalUrl, conditions: metaScraperRules.getImageRules() }),
+        title: await requestHandlerApi.getData({ htmlDom, finalUrl, conditions: metaScraperRules.getTitleRules() }),
+        author: await requestHandlerApi.getData({ htmlDom, finalUrl, conditions: metaScraperRules.getAuthorRules() })
+      }
+
+      ipc.send(`got-publisher-info-${url}`, {
+        error: null,
+        body: {
+          url: finalUrl,
+          title: result.title || '',
+          image: result.image || '',
+          author: result.author || ''
+        }
+      })
+    } catch (err) {
+      requestHandlerApi.onError(err, url, finalUrl)
+    }
+  },
+
+  // Basic logic
+  getData: async ({htmlDom,url,conditions}) => {
+    const size = conditions.length
+    let index = -1
+    let value
+
+    while (!value && index++ < size - 1) {
+      value = await conditions[index]({htmlDom,url})
+    }
+
+    return value
+  },
+
+  // Helpers
+  getText: (node) => {
+    if (!node) {
+      return ''
+    }
+
+    const html = (node.outerHTML || new XMLSerializer().serializeToString(node)) || ''
+    return html.replace(/([\s\n]*<[^>]*>[\s\n]*)+/g, ' ')
+  },
+
+  urlCheck: (url) => {
+    try {
+      new URL(url)
+      return true
+    } catch (e) {
+      return false
+    }
+  },
+
+  getContent: (selector) => {
+    if (!selector) {
+      return null
+    }
+
+    return selector.content
+  },
+
+  getSrc: (selector) => {
+    if (!selector) {
+      return null
+    }
+
+    return selector.src
+  },
+
+  urlTest: (url, opts) => {
+    let relative
+    if (opts == null) {
+      relative = true
+    } else {
+      relative = opts.relative == null ? true : opts.relative
+    }
+
+    return relative
+      ? requestHandlerApi.isAbsoluteUrl(url) === false || requestHandlerApi.urlCheck(url)
+      : requestHandlerApi.urlCheck(url)
+  },
+
+  isEmpty: (value) => {
+    return value == null || value.length === 0
+  },
+
+  isUrl: (url, opts = {}) => {
+    return !requestHandlerApi.isEmpty(url) && requestHandlerApi.urlTest(url, opts)
+  },
+
+  getUrl: (baseUrl, relativePath = '') => {
+    return requestHandlerApi.isAbsoluteUrl(relativePath) === false
+      ? requestHandlerApi.resolveUrl(baseUrl, relativePath)
+      : relativePath
+  },
+
+  strict: rule => htmlDom => {
+    const value = rule(htmlDom)
+    return requestHandlerApi.isStrictString(value)
+  },
+
+  isStrictString: value => {
+    return /^\S+\s+\S+/.test(value) && value
+  },
+
+  titleize: (src, {removeBy = false} = {}) => {
+    if (!src) {
+      return ''
+    }
+
+    let title = requestHandlerApi.createTitle(src)
+    if (removeBy) title = requestHandlerApi.removeByPrefix(title).trim()
+    return title
+  },
+
+  defaultFn: (el) => {
+    if (!el) {
+      return ''
+    }
+
+    const text = requestHandlerApi.getText(el) || ''
+    return text.trim()
+  },
+
+  getValue: (collection, fn = requestHandlerApi.defaultFn) => {
+    if (!collection || !fn) {
+      return null
+    }
+
+    if (!NodeList.prototype.isPrototypeOf(collection)) {
+      return fn(collection)
+    }
+
+    for (const ele of collection) {
+      const value = fn(ele)
+      if (value) {
+        return value
+      }
+    }
+
+    return null
+  },
+
+  getThumbnailUrl: (id) => {
+    if (id == null) {
+      return null
+    }
+
+    return `https://img.youtube.com/vi/${id}/sddefault.jpg`
+  },
+
+  getVideoId: (str) => {
+    let metadata = {}
+
+    if (typeof str !== 'string') {
+      return metadata
+    }
+
+    // remove surrounding white spaces or line feeds
+    str = str.trim()
+
+    // remove the '-nocookie' flag from youtube urls
+    str = str.replace('-nocookie', '')
+
+    // remove any leading `www.`
+    str = str.replace('/www.', '/')
+
+    if (/youtube|youtu\.be|i.ytimg\./.test(str)) {
+      metadata = {
+        id: requestHandlerApi.getYouTubeId(str),
+        service: 'youtube'
+      }
+    }
+
+    return metadata
+  },
+
+  // https://github.com/radiovisual/get-video-id
+  getYouTubeId: (str) => {
+    if (str == null) {
+      return ''
+    }
+
+    // short code
+    const shortCode = /youtube:\/\/|https?:\/\/youtu\.be\//g
+    if (shortCode.test(str)) {
+      const shortCodeId = str.split(shortCode)[1]
+      return requestHandlerApi.stripParameters(shortCodeId)
+    }
+
+    // /v/ or /vi/
+    const inlineV = /\/v\/|\/vi\//g
+    if (inlineV.test(str)) {
+      const inlineId = str.split(inlineV)[1]
+      return requestHandlerApi.stripParameters(inlineId)
+    }
+
+    // v= or vi=
+    const parameterV = /v=|vi=/g
+    if (parameterV.test(str)) {
+      const arr = str.split(parameterV)
+      return arr[1].split('&')[0]
+    }
+
+    // v= or vi=
+    const parameterWebP = /\/an_webp\//g
+    if (parameterWebP.test(str)) {
+      const webP = str.split(parameterWebP)[1]
+      return requestHandlerApi.stripParameters(webP)
+    }
+
+    // embed
+    const embedReg = /\/embed\//g
+    if (embedReg.test(str)) {
+      const embedId = str.split(embedReg)[1]
+      return requestHandlerApi.stripParameters(embedId)
+    }
+
+    // user
+    const userReg = /\/user\//g
+    if (userReg.test(str)) {
+      const elements = str.split('/')
+      return requestHandlerApi.stripParameters(elements.pop())
+    }
+
+    // attribution_link
+    const attrReg = /\/attribution_link\?.*v%3D([^%&]*)(%26|&|$)/
+    if (attrReg.test(str)) {
+      return str.match(attrReg)[1]
+    }
+  },
+
+  stripParameters: (str) => {
+    if (str == null) {
+      return ''
+    }
+
+    // Split parameters
+    if (str.includes('?')) {
+      return str.split('?')[0]
+    }
+
+    // Split folder separator
+    if (str.includes('/')) {
+      return str.split('/')[0]
+    }
+
+    return str
+  },
+
+  // https://github.com/kellym/smartquotesjs
+  getReplacements: () => {
+    return [
+      // triple prime
+      [/'''/g, retainLength => '\u2034' + (retainLength ? '\u2063\u2063' : '')],
+      // beginning "
+      [/(\W|^)"(\w)/g, '$1\u201c$2'],
+      // ending "
+      [/(\u201c[^"]*)"([^"]*$|[^\u201c"]*\u201c)/g, '$1\u201d$2'],
+      // remaining " at end of word
+      [/([^0-9])"/g, '$1\u201d'],
+      // double prime as two single quotes
+      [/''/g, retainLength => '\u2033' + (retainLength ? '\u2063' : '')],
+      // beginning '
+      [/(\W|^)'(\S)/g, '$1\u2018$2'],
+      // conjunction's possession
+      [/([a-z])'([a-z])/ig, '$1\u2019$2'],
+      // abbrev. years like '93
+      [/(\u2018)([0-9]{2}[^\u2019]*)(\u2018([^0-9]|$)|$|\u2019[a-z])/ig, '\u2019$2$3'],
+      // ending '
+      [/((\u2018[^']*)|[a-z])'([^0-9]|$)/ig, '$1\u2019$3'],
+      // backwards apostrophe
+      [/(\B|^)\u2018(?=([^\u2018\u2019]*\u2019\b)*([^\u2018\u2019]*\B\W[\u2018\u2019]\b|[^\u2018\u2019]*$))/ig, '$1\u2019'],
+      // double prime
+      [/"/g, '\u2033'],
+      // prime
+      [/'/g, '\u2032']
+    ]
+  },
+
+  smartQuotes: (str) => {
+    const replacements = requestHandlerApi.getReplacements()
+    if (!replacements || !str) {
+      return ''
+    }
+
+    replacements.forEach(replace => {
+      const replacement = typeof replace[1] === 'function' ? replace[1]({}) : replace[1]
+      str = str.replace(replace[0], replacement)
+    })
+
+    return str
+  },
+
+  removeByPrefix: (str = '') => {
+    if (str == null) {
+      return ''
+    }
+
+    return str.replace(/^[\s\n]*by|@[\s\n]*/i, '').trim()
+  },
+
+  createTitle: (str = '') => {
+    if (str == null) {
+      return ''
+    }
+
+    str = str.trim().replace(/\s{2,}/g, ' ')
+    return requestHandlerApi.smartQuotes(str)
+  },
+
+  // https://github.com/sindresorhus/is-absolute-url
+  isAbsoluteUrl: (url) => {
+    if (!requestHandlerApi.isString(url)) {
+      return
+    }
+
+    return /^[a-z][a-z0-9+.-]*:/.test(url)
+  },
+
+  resolveUrl: (baseUrl, relativePath) => {
+    let url = baseUrl
+
+    if (!relativePath) {
+      return url
+    }
+
+    try {
+      url = new URL(relativePath, [baseUrl])
+    } catch (e) {}
+
+    return url
+  },
+
+  isString: (str) => {
+    return typeof str === 'string'
+  }
+}
+
+if (module) module.exports = requestHandlerApi
diff --git a/js/lib/request.js b/js/lib/request.js
index b7cc6420daa..af5cfba1cbc 100644
--- a/js/lib/request.js
+++ b/js/lib/request.js
@@ -8,8 +8,16 @@ const electron = require('electron')
 const session = electron.session
 const underscore = require('underscore')
 const urlParse = require('../../app/common/urlParse')
+const ipc = electron.ipcMain
 
 var cachedDefaultSession = null
+var backgroundPageWebContents = null
+
+if (ipc) {
+  ipc.on('got-background-page-webcontents', (e) => {
+    backgroundPageWebContents = e.sender
+  })
+}
 
 const getDefaultSession = () => {
   if (!cachedDefaultSession) {
@@ -84,3 +92,22 @@ module.exports.requestDataFile = (url, headers, path, reject, resolve) => {
     })
   }
 }
+
+/**
+ * Fetches url, title, and image for a publishers site (Youtube, Twitch, etc.)
+ * See
+ * https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch
+ * @param {string} url - url to fetch
+ * @param {Object} options - options to pass to window.fetch
+ * @param {Function({url: string, title: string, image: string, error: string})} callback
+ */
+module.exports.fetchPublisherInfo = (url, options, callback) => {
+  if (!backgroundPageWebContents) {
+    callback(new Error('Background page web contents not initialized.'), { url })
+    return
+  }
+  backgroundPageWebContents.send('fetch-publisher-info', url, options)
+  ipc.once('got-publisher-info-' + url, (e, response) => {
+    callback(response.error, response.body)
+  })
+}
diff --git a/package-lock.json b/package-lock.json
index eb275b2a9a0..33de4127300 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -28,8 +28,7 @@
     "abbrev": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
-      "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
-      "dev": true
+      "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
     },
     "abstract-leveldown": {
       "version": "2.6.3",
@@ -247,11 +246,6 @@
       "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=",
       "dev": true
     },
-    "any-promise": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
-      "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8="
-    },
     "anymatch": {
       "version": "1.3.2",
       "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz",
@@ -538,7 +532,6 @@
       "version": "0.13.1",
       "resolved": "https://registry.npmjs.org/asar/-/asar-0.13.1.tgz",
       "integrity": "sha512-HJnZadTbDVDhBDv3tMyDov3ZnwMYYmz80/+a7S6cFPvulUyRz55UG5hOyHeWSP1iZud6vjFq8GOYM6xxtxJECQ==",
-      "dev": true,
       "requires": {
         "chromium-pickle-js": "0.2.0",
         "commander": "2.14.1",
@@ -554,7 +547,6 @@
           "version": "6.0.4",
           "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz",
           "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=",
-          "dev": true,
           "requires": {
             "inflight": "1.0.6",
             "inherits": "2.0.3",
@@ -567,7 +559,6 @@
           "version": "0.0.28",
           "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.28.tgz",
           "integrity": "sha1-Fyc1t/YU6nrzlmT6hM8N5OUV0SA=",
-          "dev": true,
           "requires": {
             "os-tmpdir": "1.0.2"
           }
@@ -666,6 +657,12 @@
       "integrity": "sha1-GcenYEc3dEaPILLS0DNyrX1Mv10=",
       "dev": true
     },
+    "author-regex": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/author-regex/-/author-regex-1.0.0.tgz",
+      "integrity": "sha1-0IiFvmubv5Q5/gh8dihyRfCoFFA=",
+      "optional": true
+    },
     "autoprefixer": {
       "version": "6.7.7",
       "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-6.7.7.tgz",
@@ -801,7 +798,6 @@
       "version": "6.26.0",
       "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.0.tgz",
       "integrity": "sha1-rzL3izGm/O8RnIew/Y2XU/A6C7g=",
-      "dev": true,
       "requires": {
         "babel-code-frame": "6.26.0",
         "babel-generator": "6.26.1",
@@ -840,7 +836,6 @@
       "version": "6.26.1",
       "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz",
       "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==",
-      "dev": true,
       "requires": {
         "babel-messages": "6.23.0",
         "babel-runtime": "6.26.0",
@@ -994,7 +989,6 @@
       "version": "6.24.1",
       "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz",
       "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=",
-      "dev": true,
       "requires": {
         "babel-runtime": "6.26.0",
         "babel-template": "6.26.0"
@@ -1004,7 +998,6 @@
       "version": "7.1.3",
       "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-7.1.3.tgz",
       "integrity": "sha512-PeN29YvOynPMvNk7QCzsHqxpmfXwKAC+uxkiSNFQsmXBBVltzEkVWmv/Ip3tx7yk149dQUwk497bTXNu+DZjLA==",
-      "dev": true,
       "requires": {
         "find-cache-dir": "1.0.0",
         "loader-utils": "1.1.0",
@@ -1015,7 +1008,6 @@
       "version": "6.23.0",
       "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz",
       "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=",
-      "dev": true,
       "requires": {
         "babel-runtime": "6.26.0"
       }
@@ -1522,7 +1514,6 @@
       "version": "6.26.0",
       "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz",
       "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=",
-      "dev": true,
       "requires": {
         "babel-core": "6.26.0",
         "babel-runtime": "6.26.0",
@@ -1546,7 +1537,6 @@
       "version": "6.26.0",
       "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz",
       "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=",
-      "dev": true,
       "requires": {
         "babel-runtime": "6.26.0",
         "babel-traverse": "6.26.0",
@@ -1559,7 +1549,6 @@
       "version": "6.26.0",
       "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz",
       "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=",
-      "dev": true,
       "requires": {
         "babel-code-frame": "6.26.0",
         "babel-messages": "6.23.0",
@@ -1575,8 +1564,7 @@
         "globals": {
           "version": "9.18.0",
           "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz",
-          "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==",
-          "dev": true
+          "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ=="
         }
       }
     },
@@ -1584,7 +1572,6 @@
       "version": "6.26.0",
       "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz",
       "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=",
-      "dev": true,
       "requires": {
         "babel-runtime": "6.26.0",
         "esutils": "2.0.2",
@@ -1595,8 +1582,7 @@
     "babylon": {
       "version": "6.18.0",
       "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz",
-      "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==",
-      "dev": true
+      "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ=="
     },
     "balanced-match": {
       "version": "1.0.0",
@@ -1681,7 +1667,7 @@
       "requires": {
         "@ambassify/backoff-strategies": "1.0.0",
         "bat-balance": "1.0.7",
-        "bat-publisher": "2.0.11",
+        "bat-publisher": "2.0.13",
         "bitgo": "4.20.0",
         "brave-crypto": "0.0.1",
         "http-request-signature": "0.0.2",
@@ -1707,9 +1693,9 @@
       }
     },
     "bat-publisher": {
-      "version": "2.0.11",
-      "resolved": "https://registry.npmjs.org/bat-publisher/-/bat-publisher-2.0.11.tgz",
-      "integrity": "sha512-zXYPS208qBOhzWaMPx5hkU96kZuPVgjhqigJy/MtMGavOuKIAW2RgzJES140PM2QHPwTfLsWS5zQhOotNbv65Q==",
+      "version": "2.0.13",
+      "resolved": "https://registry.npmjs.org/bat-publisher/-/bat-publisher-2.0.13.tgz",
+      "integrity": "sha512-Ij4D+DtpIBv7glLH+FyS8asxILwgR+nkFsFL9G3NF8wS797dikzFQif6AlzvcXjeU1VVoSSQLrPIE+enmGxKAQ==",
       "requires": {
         "@ambassify/backoff-strategies": "1.0.0",
         "async": "2.6.0",
@@ -1718,7 +1704,6 @@
         "jimp": "0.2.28",
         "joi": "13.1.2",
         "jsdom": "11.2.0",
-        "metascraper": "1.0.7",
         "node-cache": "4.1.1",
         "parse-cache-control": "1.0.1",
         "random-lib": "2.1.0",
@@ -1805,7 +1790,6 @@
       "version": "0.3.0",
       "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz",
       "integrity": "sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=",
-      "dev": true,
       "requires": {
         "buffers": "0.1.1",
         "chainsaw": "0.1.0"
@@ -2174,6 +2158,99 @@
         "readable-stream": "2.3.4"
       }
     },
+    "bloodhound-js": {
+      "version": "github:brave/bloodhound#03555132b049adcb5a09138aa911acc3b4d3af7c",
+      "requires": {
+        "babel-core": "6.26.0",
+        "babel-loader": "7.1.3",
+        "es6-promise": "3.3.1",
+        "immutable": "3.8.2",
+        "object-assign": "4.1.1",
+        "storage2": "0.1.0",
+        "superagent": "1.8.5"
+      },
+      "dependencies": {
+        "async": {
+          "version": "1.5.2",
+          "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+          "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo="
+        },
+        "cookiejar": {
+          "version": "2.0.6",
+          "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.0.6.tgz",
+          "integrity": "sha1-Cr81atANHFohnYjURRgEbdAmrP4="
+        },
+        "extend": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz",
+          "integrity": "sha1-WkdDU7nzNT3dgXbf03uRyDpG8dQ="
+        },
+        "form-data": {
+          "version": "1.0.0-rc3",
+          "resolved": "https://registry.npmjs.org/form-data/-/form-data-1.0.0-rc3.tgz",
+          "integrity": "sha1-01vGLn+8KTeuePlIqqDTjZBgdXc=",
+          "requires": {
+            "async": "1.5.2",
+            "combined-stream": "1.0.6",
+            "mime-types": "2.1.18"
+          }
+        },
+        "formidable": {
+          "version": "1.0.17",
+          "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.0.17.tgz",
+          "integrity": "sha1-71SRSQ+UM7cF+qdyScmQKa40hVk="
+        },
+        "isarray": {
+          "version": "0.0.1",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+          "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
+        },
+        "mime": {
+          "version": "1.3.4",
+          "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz",
+          "integrity": "sha1-EV+eO2s9rylZmDyzjxSaLUDrXVM="
+        },
+        "qs": {
+          "version": "2.3.3",
+          "resolved": "https://registry.npmjs.org/qs/-/qs-2.3.3.tgz",
+          "integrity": "sha1-6eha2+ddoLvkyOBHaghikPhjtAQ="
+        },
+        "readable-stream": {
+          "version": "1.0.27-1",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.27-1.tgz",
+          "integrity": "sha1-a2eYPCA1fO/QfwFlABoW1xDZEHg=",
+          "requires": {
+            "core-util-is": "1.0.2",
+            "inherits": "2.0.3",
+            "isarray": "0.0.1",
+            "string_decoder": "0.10.31"
+          }
+        },
+        "string_decoder": {
+          "version": "0.10.31",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+          "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
+        },
+        "superagent": {
+          "version": "1.8.5",
+          "resolved": "https://registry.npmjs.org/superagent/-/superagent-1.8.5.tgz",
+          "integrity": "sha1-HA3cOvMOgOuE68BcshItqP6UC1U=",
+          "requires": {
+            "component-emitter": "1.2.1",
+            "cookiejar": "2.0.6",
+            "debug": "2.6.9",
+            "extend": "3.0.0",
+            "form-data": "1.0.0-rc3",
+            "formidable": "1.0.17",
+            "methods": "1.1.2",
+            "mime": "1.3.4",
+            "qs": "2.3.3",
+            "readable-stream": "1.0.27-1",
+            "reduce-component": "1.0.1"
+          }
+        }
+      }
+    },
     "bluebird": {
       "version": "3.5.1",
       "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
@@ -2240,7 +2317,8 @@
     "boolbase": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
-      "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24="
+      "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=",
+      "dev": true
     },
     "boom": {
       "version": "4.3.1",
@@ -2527,6 +2605,43 @@
       "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==",
       "dev": true
     },
+    "buffer-to-vinyl": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/buffer-to-vinyl/-/buffer-to-vinyl-1.1.0.tgz",
+      "integrity": "sha1-APFfruOreh3aLN5tkSG//dB7ImI=",
+      "dev": true,
+      "requires": {
+        "file-type": "3.9.0",
+        "readable-stream": "2.3.4",
+        "uuid": "2.0.3",
+        "vinyl": "1.2.0"
+      },
+      "dependencies": {
+        "clone": {
+          "version": "1.0.3",
+          "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.3.tgz",
+          "integrity": "sha1-KY1+IjFmD0DAA8LtMUDezz9TCF8=",
+          "dev": true
+        },
+        "uuid": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz",
+          "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=",
+          "dev": true
+        },
+        "vinyl": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz",
+          "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=",
+          "dev": true,
+          "requires": {
+            "clone": "1.0.3",
+            "clone-stats": "0.0.1",
+            "replace-ext": "0.0.1"
+          }
+        }
+      }
+    },
     "buffer-xor": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
@@ -2535,8 +2650,7 @@
     "buffers": {
       "version": "0.1.1",
       "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz",
-      "integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s=",
-      "dev": true
+      "integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s="
     },
     "bufferutil": {
       "version": "3.0.3",
@@ -2675,8 +2789,7 @@
     "builtin-modules": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
-      "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
-      "dev": true
+      "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8="
     },
     "builtin-status-codes": {
       "version": "3.0.0",
@@ -2898,7 +3011,6 @@
       "version": "0.1.0",
       "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz",
       "integrity": "sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=",
-      "dev": true,
       "requires": {
         "traverse": "0.3.9"
       }
@@ -2936,70 +3048,6 @@
       "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz",
       "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I="
     },
-    "cheerio": {
-      "version": "0.20.0",
-      "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.20.0.tgz",
-      "integrity": "sha1-XHEPK6uVZTJyhCugHG6mGzVF7DU=",
-      "requires": {
-        "css-select": "1.2.0",
-        "dom-serializer": "0.1.0",
-        "entities": "1.1.1",
-        "htmlparser2": "3.8.3",
-        "jsdom": "7.2.2",
-        "lodash": "4.17.5"
-      },
-      "dependencies": {
-        "acorn": {
-          "version": "2.7.0",
-          "resolved": "https://registry.npmjs.org/acorn/-/acorn-2.7.0.tgz",
-          "integrity": "sha1-q259nYhqrKiwhbwzEreaGYQz8Oc="
-        },
-        "acorn-globals": {
-          "version": "1.0.9",
-          "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-1.0.9.tgz",
-          "integrity": "sha1-VbtemGkVB7dFedBRNBMhfDgMVM8=",
-          "optional": true,
-          "requires": {
-            "acorn": "2.7.0"
-          }
-        },
-        "jsdom": {
-          "version": "7.2.2",
-          "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-7.2.2.tgz",
-          "integrity": "sha1-QLQCdwwr2iNGkJa+6Rq2deOx/G4=",
-          "optional": true,
-          "requires": {
-            "abab": "1.0.4",
-            "acorn": "2.7.0",
-            "acorn-globals": "1.0.9",
-            "cssom": "0.3.2",
-            "cssstyle": "0.2.37",
-            "escodegen": "1.9.0",
-            "nwmatcher": "1.4.3",
-            "parse5": "1.5.1",
-            "request": "2.83.0",
-            "sax": "1.2.4",
-            "symbol-tree": "3.2.2",
-            "tough-cookie": "2.3.3",
-            "webidl-conversions": "2.0.1",
-            "whatwg-url-compat": "0.6.5",
-            "xml-name-validator": "2.0.1"
-          }
-        },
-        "parse5": {
-          "version": "1.5.1",
-          "resolved": "https://registry.npmjs.org/parse5/-/parse5-1.5.1.tgz",
-          "integrity": "sha1-m387DeMr543CQBsXVzzK8Pb1nZQ=",
-          "optional": true
-        },
-        "webidl-conversions": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-2.0.1.tgz",
-          "integrity": "sha1-O/glj30xjHRDw28uFpQCoaZwNQY=",
-          "optional": true
-        }
-      }
-    },
     "chokidar": {
       "version": "1.7.0",
       "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz",
@@ -3051,16 +3099,7 @@
     "chromium-pickle-js": {
       "version": "0.2.0",
       "resolved": "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz",
-      "integrity": "sha1-BKEGZywYsIWrd02YPfo+oTjyIgU=",
-      "dev": true
-    },
-    "chrono-node": {
-      "version": "1.3.5",
-      "resolved": "https://registry.npmjs.org/chrono-node/-/chrono-node-1.3.5.tgz",
-      "integrity": "sha1-oklSmKMtqCvMAa2b59d++l4kQSI=",
-      "requires": {
-        "moment": "2.18.1"
-      }
+      "integrity": "sha1-BKEGZywYsIWrd02YPfo+oTjyIgU="
     },
     "chunk-store-stream": {
       "version": "2.0.2",
@@ -3396,14 +3435,12 @@
     "commander": {
       "version": "2.14.1",
       "resolved": "https://registry.npmjs.org/commander/-/commander-2.14.1.tgz",
-      "integrity": "sha512-+YR16o3rK53SmWHU3rEM3tPAh2rwb1yPcQX5irVn7mb0gXbwuCCrnkbV5+PBfETdfg1vui07nM6PCG1zndcjQw==",
-      "dev": true
+      "integrity": "sha512-+YR16o3rK53SmWHU3rEM3tPAh2rwb1yPcQX5irVn7mb0gXbwuCCrnkbV5+PBfETdfg1vui07nM6PCG1zndcjQw=="
     },
     "commondir": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
-      "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
-      "dev": true
+      "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs="
     },
     "compact2string": {
       "version": "1.4.0",
@@ -3544,8 +3581,7 @@
     "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=",
-      "dev": true
+      "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU="
     },
     "cookie": {
       "version": "0.3.1",
@@ -4400,6 +4436,7 @@
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz",
       "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=",
+      "dev": true,
       "requires": {
         "boolbase": "1.0.0",
         "css-what": "2.1.0",
@@ -4425,7 +4462,8 @@
     "css-what": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.0.tgz",
-      "integrity": "sha1-lGfQMsOM+u+58teVASUwYvh/ob0="
+      "integrity": "sha1-lGfQMsOM+u+58teVASUwYvh/ob0=",
+      "dev": true
     },
     "cssesc": {
       "version": "0.1.0",
@@ -4502,8 +4540,7 @@
     "cuint": {
       "version": "0.2.2",
       "resolved": "https://registry.npmjs.org/cuint/-/cuint-0.2.2.tgz",
-      "integrity": "sha1-QICG1AlVDCYxFVYZ6fp7ytw7mRs=",
-      "dev": true
+      "integrity": "sha1-QICG1AlVDCYxFVYZ6fp7ytw7mRs="
     },
     "currently-unhandled": {
       "version": "0.4.1",
@@ -4616,89 +4653,495 @@
       "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
       "dev": true
     },
-    "decompress-response": {
-      "version": "3.3.0",
-      "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
-      "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
-      "requires": {
-        "mimic-response": "1.0.0"
-      }
-    },
-    "decompress-zip": {
-      "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/decompress-zip/-/decompress-zip-0.3.0.tgz",
-      "integrity": "sha1-rjvLfjTGWHmt/nfhnDD4ZgK0vbA=",
+    "decompress": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/decompress/-/decompress-3.0.0.tgz",
+      "integrity": "sha1-rx3VDQbjv8QyRh033hGzjA2ZG+0=",
       "dev": true,
       "requires": {
-        "binary": "0.3.0",
-        "graceful-fs": "4.1.11",
-        "mkpath": "0.1.0",
-        "nopt": "3.0.6",
-        "q": "1.5.1",
-        "readable-stream": "1.1.14",
-        "touch": "0.0.3"
+        "buffer-to-vinyl": "1.1.0",
+        "concat-stream": "1.6.0",
+        "decompress-tar": "3.1.0",
+        "decompress-tarbz2": "3.1.0",
+        "decompress-targz": "3.1.0",
+        "decompress-unzip": "3.4.0",
+        "stream-combiner2": "1.1.1",
+        "vinyl-assign": "1.2.1",
+        "vinyl-fs": "2.4.4"
       },
       "dependencies": {
-        "isarray": {
-          "version": "0.0.1",
-          "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
-          "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+        "arr-diff": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz",
+          "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=",
+          "dev": true,
+          "requires": {
+            "arr-flatten": "1.1.0"
+          }
+        },
+        "array-unique": {
+          "version": "0.2.1",
+          "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz",
+          "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=",
           "dev": true
         },
-        "readable-stream": {
-          "version": "1.1.14",
-          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
-          "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
+        "braces": {
+          "version": "1.8.5",
+          "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz",
+          "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=",
           "dev": true,
           "requires": {
-            "core-util-is": "1.0.2",
-            "inherits": "2.0.3",
-            "isarray": "0.0.1",
-            "string_decoder": "0.10.31"
+            "expand-range": "1.8.2",
+            "preserve": "0.2.0",
+            "repeat-element": "1.1.2"
           }
         },
-        "string_decoder": {
-          "version": "0.10.31",
-          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
-          "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
+        "clone": {
+          "version": "1.0.3",
+          "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.3.tgz",
+          "integrity": "sha1-KY1+IjFmD0DAA8LtMUDezz9TCF8=",
           "dev": true
-        }
-      }
-    },
-    "deep-eql": {
-      "version": "0.1.3",
-      "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz",
-      "integrity": "sha1-71WKyrjeJSBs1xOQbXTlaTDrafI=",
-      "dev": true,
-      "requires": {
-        "type-detect": "0.1.1"
-      },
-      "dependencies": {
-        "type-detect": {
-          "version": "0.1.1",
-          "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz",
-          "integrity": "sha1-C6XsKohWQORw6k6FBZcZANrFiCI=",
+        },
+        "expand-brackets": {
+          "version": "0.1.5",
+          "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz",
+          "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=",
+          "dev": true,
+          "requires": {
+            "is-posix-bracket": "0.1.1"
+          }
+        },
+        "extend": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
+          "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=",
           "dev": true
-        }
-      }
-    },
-    "deep-equal": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz",
-      "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=",
-      "dev": true
-    },
-    "deep-extend": {
-      "version": "0.4.2",
-      "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz",
-      "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8="
-    },
-    "deep-is": {
-      "version": "0.1.3",
-      "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
-      "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ="
-    },
-    "deepmerge": {
+        },
+        "extglob": {
+          "version": "0.3.2",
+          "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz",
+          "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=",
+          "dev": true,
+          "requires": {
+            "is-extglob": "1.0.0"
+          }
+        },
+        "glob": {
+          "version": "5.0.15",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz",
+          "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=",
+          "dev": true,
+          "requires": {
+            "inflight": "1.0.6",
+            "inherits": "2.0.3",
+            "minimatch": "3.0.4",
+            "once": "1.4.0",
+            "path-is-absolute": "1.0.1"
+          }
+        },
+        "glob-stream": {
+          "version": "5.3.5",
+          "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-5.3.5.tgz",
+          "integrity": "sha1-pVZlqajM3EGRWofHAeMtTgFvrSI=",
+          "dev": true,
+          "requires": {
+            "extend": "3.0.1",
+            "glob": "5.0.15",
+            "glob-parent": "3.1.0",
+            "micromatch": "2.3.11",
+            "ordered-read-streams": "0.3.0",
+            "through2": "0.6.5",
+            "to-absolute-glob": "0.1.1",
+            "unique-stream": "2.2.1"
+          },
+          "dependencies": {
+            "readable-stream": {
+              "version": "1.0.34",
+              "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
+              "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
+              "dev": true,
+              "requires": {
+                "core-util-is": "1.0.2",
+                "inherits": "2.0.3",
+                "isarray": "0.0.1",
+                "string_decoder": "0.10.31"
+              }
+            },
+            "through2": {
+              "version": "0.6.5",
+              "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz",
+              "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=",
+              "dev": true,
+              "requires": {
+                "readable-stream": "1.0.34",
+                "xtend": "4.0.1"
+              }
+            }
+          }
+        },
+        "is-extglob": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
+          "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
+          "dev": true
+        },
+        "is-glob": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
+          "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
+          "dev": true,
+          "requires": {
+            "is-extglob": "1.0.0"
+          }
+        },
+        "isarray": {
+          "version": "0.0.1",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+          "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+          "dev": true
+        },
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "1.1.6"
+          }
+        },
+        "micromatch": {
+          "version": "2.3.11",
+          "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz",
+          "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=",
+          "dev": true,
+          "requires": {
+            "arr-diff": "2.0.0",
+            "array-unique": "0.2.1",
+            "braces": "1.8.5",
+            "expand-brackets": "0.1.5",
+            "extglob": "0.3.2",
+            "filename-regex": "2.0.1",
+            "is-extglob": "1.0.0",
+            "is-glob": "2.0.1",
+            "kind-of": "3.2.2",
+            "normalize-path": "2.1.1",
+            "object.omit": "2.0.1",
+            "parse-glob": "3.0.4",
+            "regex-cache": "0.4.4"
+          }
+        },
+        "ordered-read-streams": {
+          "version": "0.3.0",
+          "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.3.0.tgz",
+          "integrity": "sha1-cTfmmzKYuzQiR6G77jiByA4v14s=",
+          "dev": true,
+          "requires": {
+            "is-stream": "1.1.0",
+            "readable-stream": "2.3.4"
+          }
+        },
+        "string_decoder": {
+          "version": "0.10.31",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+          "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
+          "dev": true
+        },
+        "through2": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz",
+          "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=",
+          "dev": true,
+          "requires": {
+            "readable-stream": "2.3.4",
+            "xtend": "4.0.1"
+          }
+        },
+        "unique-stream": {
+          "version": "2.2.1",
+          "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.2.1.tgz",
+          "integrity": "sha1-WqADz76Uxf+GbE59ZouxxNuts2k=",
+          "dev": true,
+          "requires": {
+            "json-stable-stringify": "1.0.1",
+            "through2-filter": "2.0.0"
+          }
+        },
+        "vinyl": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz",
+          "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=",
+          "dev": true,
+          "requires": {
+            "clone": "1.0.3",
+            "clone-stats": "0.0.1",
+            "replace-ext": "0.0.1"
+          }
+        },
+        "vinyl-fs": {
+          "version": "2.4.4",
+          "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-2.4.4.tgz",
+          "integrity": "sha1-vm/zJwy1Xf19MGNkDegfJddTIjk=",
+          "dev": true,
+          "requires": {
+            "duplexify": "3.5.3",
+            "glob-stream": "5.3.5",
+            "graceful-fs": "4.1.11",
+            "gulp-sourcemaps": "1.6.0",
+            "is-valid-glob": "0.3.0",
+            "lazystream": "1.0.0",
+            "lodash.isequal": "4.5.0",
+            "merge-stream": "1.0.1",
+            "mkdirp": "0.5.1",
+            "object-assign": "4.1.1",
+            "readable-stream": "2.3.4",
+            "strip-bom": "2.0.0",
+            "strip-bom-stream": "1.0.0",
+            "through2": "2.0.3",
+            "through2-filter": "2.0.0",
+            "vali-date": "1.0.0",
+            "vinyl": "1.2.0"
+          }
+        }
+      }
+    },
+    "decompress-response": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
+      "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
+      "requires": {
+        "mimic-response": "1.0.0"
+      }
+    },
+    "decompress-tar": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-3.1.0.tgz",
+      "integrity": "sha1-IXx4n5uURQ76rcXF5TeXj8MzxGY=",
+      "dev": true,
+      "requires": {
+        "is-tar": "1.0.0",
+        "object-assign": "2.1.1",
+        "strip-dirs": "1.1.1",
+        "tar-stream": "1.5.5",
+        "through2": "0.6.5",
+        "vinyl": "0.4.6"
+      },
+      "dependencies": {
+        "clone": {
+          "version": "0.2.0",
+          "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz",
+          "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=",
+          "dev": true
+        },
+        "object-assign": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz",
+          "integrity": "sha1-Q8NuXVaf+OSBbE76i+AtJpZ8GKo=",
+          "dev": true
+        },
+        "vinyl": {
+          "version": "0.4.6",
+          "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz",
+          "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=",
+          "dev": true,
+          "requires": {
+            "clone": "0.2.0",
+            "clone-stats": "0.0.1"
+          }
+        }
+      }
+    },
+    "decompress-tarbz2": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-3.1.0.tgz",
+      "integrity": "sha1-iyOTVoE1X58YnYclag+L3ZbZZm0=",
+      "dev": true,
+      "requires": {
+        "is-bzip2": "1.0.0",
+        "object-assign": "2.1.1",
+        "seek-bzip": "1.0.5",
+        "strip-dirs": "1.1.1",
+        "tar-stream": "1.5.5",
+        "through2": "0.6.5",
+        "vinyl": "0.4.6"
+      },
+      "dependencies": {
+        "clone": {
+          "version": "0.2.0",
+          "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz",
+          "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=",
+          "dev": true
+        },
+        "object-assign": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz",
+          "integrity": "sha1-Q8NuXVaf+OSBbE76i+AtJpZ8GKo=",
+          "dev": true
+        },
+        "vinyl": {
+          "version": "0.4.6",
+          "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz",
+          "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=",
+          "dev": true,
+          "requires": {
+            "clone": "0.2.0",
+            "clone-stats": "0.0.1"
+          }
+        }
+      }
+    },
+    "decompress-targz": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-3.1.0.tgz",
+      "integrity": "sha1-ssE9+YFmJomRtxXWRH9kLpaW9aA=",
+      "dev": true,
+      "requires": {
+        "is-gzip": "1.0.0",
+        "object-assign": "2.1.1",
+        "strip-dirs": "1.1.1",
+        "tar-stream": "1.5.5",
+        "through2": "0.6.5",
+        "vinyl": "0.4.6"
+      },
+      "dependencies": {
+        "clone": {
+          "version": "0.2.0",
+          "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz",
+          "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=",
+          "dev": true
+        },
+        "object-assign": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz",
+          "integrity": "sha1-Q8NuXVaf+OSBbE76i+AtJpZ8GKo=",
+          "dev": true
+        },
+        "vinyl": {
+          "version": "0.4.6",
+          "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz",
+          "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=",
+          "dev": true,
+          "requires": {
+            "clone": "0.2.0",
+            "clone-stats": "0.0.1"
+          }
+        }
+      }
+    },
+    "decompress-unzip": {
+      "version": "3.4.0",
+      "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-3.4.0.tgz",
+      "integrity": "sha1-YUdbQVIGa74/7hL51inRX+ZHjus=",
+      "dev": true,
+      "requires": {
+        "is-zip": "1.0.0",
+        "read-all-stream": "3.1.0",
+        "stat-mode": "0.2.2",
+        "strip-dirs": "1.1.1",
+        "through2": "2.0.3",
+        "vinyl": "1.2.0",
+        "yauzl": "2.4.1"
+      },
+      "dependencies": {
+        "clone": {
+          "version": "1.0.3",
+          "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.3.tgz",
+          "integrity": "sha1-KY1+IjFmD0DAA8LtMUDezz9TCF8=",
+          "dev": true
+        },
+        "through2": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz",
+          "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=",
+          "dev": true,
+          "requires": {
+            "readable-stream": "2.3.4",
+            "xtend": "4.0.1"
+          }
+        },
+        "vinyl": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz",
+          "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=",
+          "dev": true,
+          "requires": {
+            "clone": "1.0.3",
+            "clone-stats": "0.0.1",
+            "replace-ext": "0.0.1"
+          }
+        }
+      }
+    },
+    "decompress-zip": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/decompress-zip/-/decompress-zip-0.3.0.tgz",
+      "integrity": "sha1-rjvLfjTGWHmt/nfhnDD4ZgK0vbA=",
+      "requires": {
+        "binary": "0.3.0",
+        "graceful-fs": "4.1.11",
+        "mkpath": "0.1.0",
+        "nopt": "3.0.6",
+        "q": "1.5.1",
+        "readable-stream": "1.1.14",
+        "touch": "0.0.3"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "0.0.1",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+          "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
+        },
+        "readable-stream": {
+          "version": "1.1.14",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+          "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
+          "requires": {
+            "core-util-is": "1.0.2",
+            "inherits": "2.0.3",
+            "isarray": "0.0.1",
+            "string_decoder": "0.10.31"
+          }
+        },
+        "string_decoder": {
+          "version": "0.10.31",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+          "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
+        }
+      }
+    },
+    "deep-eql": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz",
+      "integrity": "sha1-71WKyrjeJSBs1xOQbXTlaTDrafI=",
+      "dev": true,
+      "requires": {
+        "type-detect": "0.1.1"
+      },
+      "dependencies": {
+        "type-detect": {
+          "version": "0.1.1",
+          "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz",
+          "integrity": "sha1-C6XsKohWQORw6k6FBZcZANrFiCI=",
+          "dev": true
+        }
+      }
+    },
+    "deep-equal": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz",
+      "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=",
+      "dev": true
+    },
+    "deep-extend": {
+      "version": "0.4.2",
+      "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz",
+      "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8="
+    },
+    "deep-is": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
+      "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ="
+    },
+    "deepmerge": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.0.1.tgz",
       "integrity": "sha512-VIPwiMJqJ13ZQfaCsIFnp5Me9tnjURiaIFxfz7EH0Ci0dTSQpZtSLrqOicXqEd/z2r+z+Klk9GzmnRsgpgbOsQ=="
@@ -4855,7 +5298,6 @@
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz",
       "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=",
-      "dev": true,
       "requires": {
         "repeating": "2.0.1"
       }
@@ -4871,6 +5313,12 @@
       "integrity": "sha1-ogM8CcyOFY03dI+951B4Mr1s4Sc=",
       "dev": true
     },
+    "dev-null": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/dev-null/-/dev-null-0.1.1.tgz",
+      "integrity": "sha1-WiBc48Ky73e2I41roXnrdMag6Bg=",
+      "dev": true
+    },
     "dezalgo": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.3.tgz",
@@ -5326,6 +5774,55 @@
         }
       }
     },
+    "electron-download": {
+      "version": "github:brave/electron-download#409b65caff14edeef1daa36a7445ba6334658d7c",
+      "dev": true,
+      "requires": {
+        "debug": "2.6.9",
+        "home-path": "1.0.5",
+        "minimist": "1.2.0",
+        "mkdirp": "0.5.1",
+        "mv": "2.1.1",
+        "nugget": "1.6.2",
+        "path-exists": "1.0.0",
+        "rc": "1.2.5"
+      },
+      "dependencies": {
+        "nugget": {
+          "version": "1.6.2",
+          "resolved": "https://registry.npmjs.org/nugget/-/nugget-1.6.2.tgz",
+          "integrity": "sha1-iMpuA7pXBqmRc/XaCQJZPWvK4Qc=",
+          "dev": true,
+          "requires": {
+            "debug": "2.6.9",
+            "minimist": "1.2.0",
+            "pretty-bytes": "1.0.4",
+            "progress-stream": "1.2.0",
+            "request": "2.83.0",
+            "single-line-log": "0.4.1",
+            "throttleit": "0.0.2"
+          }
+        },
+        "path-exists": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-1.0.0.tgz",
+          "integrity": "sha1-1aiZjrce83p0w06w2eum6HjuoIE=",
+          "dev": true
+        },
+        "single-line-log": {
+          "version": "0.4.1",
+          "resolved": "https://registry.npmjs.org/single-line-log/-/single-line-log-0.4.1.tgz",
+          "integrity": "sha1-h6VWSfdJ14PsDc2AToFA2Yc8fO4=",
+          "dev": true
+        },
+        "throttleit": {
+          "version": "0.0.2",
+          "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-0.0.2.tgz",
+          "integrity": "sha1-z+34jmDADdlpe2H90qg0OptoDq8=",
+          "dev": true
+        }
+      }
+    },
     "electron-download-tf": {
       "version": "4.3.4",
       "resolved": "https://registry.npmjs.org/electron-download-tf/-/electron-download-tf-4.3.4.tgz",
@@ -5352,45 +5849,264 @@
             "ms": "2.0.0"
           }
         },
-        "fs-extra": {
-          "version": "4.0.3",
-          "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz",
-          "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==",
+        "fs-extra": {
+          "version": "4.0.3",
+          "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz",
+          "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==",
+          "dev": true,
+          "requires": {
+            "graceful-fs": "4.1.11",
+            "jsonfile": "4.0.0",
+            "universalify": "0.1.1"
+          }
+        },
+        "jsonfile": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
+          "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
+          "dev": true,
+          "requires": {
+            "graceful-fs": "4.1.11"
+          }
+        }
+      }
+    },
+    "electron-installer-debian": {
+      "version": "github:brave/electron-installer-debian#5f37713f52437678e5cbf9b17500fba4ae7cb5ad",
+      "optional": true,
+      "requires": {
+        "asar": "0.13.1",
+        "async": "2.6.0",
+        "debug": "2.6.9",
+        "fs-extra": "1.0.0",
+        "get-folder-size": "1.0.1",
+        "glob": "7.1.2",
+        "lodash": "4.17.5",
+        "temp": "0.8.3",
+        "word-wrap": "1.2.3",
+        "yargs": "7.1.0"
+      },
+      "dependencies": {
+        "camelcase": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
+          "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=",
+          "optional": true
+        },
+        "fs-extra": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz",
+          "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=",
+          "optional": true,
+          "requires": {
+            "graceful-fs": "4.1.11",
+            "jsonfile": "2.4.0",
+            "klaw": "1.3.1"
+          }
+        },
+        "yargs": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz",
+          "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=",
+          "optional": true,
+          "requires": {
+            "camelcase": "3.0.0",
+            "cliui": "3.2.0",
+            "decamelize": "1.2.0",
+            "get-caller-file": "1.0.2",
+            "os-locale": "1.4.0",
+            "read-pkg-up": "1.0.1",
+            "require-directory": "2.1.1",
+            "require-main-filename": "1.0.1",
+            "set-blocking": "2.0.0",
+            "string-width": "1.0.2",
+            "which-module": "1.0.0",
+            "y18n": "3.2.1",
+            "yargs-parser": "5.0.0"
+          }
+        }
+      }
+    },
+    "electron-installer-redhat": {
+      "version": "github:brave/electron-installer-redhat#442d0c83fa3cfea853d69857e6806e2bb5e8fe72",
+      "optional": true,
+      "requires": {
+        "asar": "0.13.1",
+        "async": "2.6.0",
+        "debug": "2.6.9",
+        "fs-extra": "2.1.2",
+        "glob": "7.1.2",
+        "lodash": "4.17.5",
+        "parse-author": "2.0.0",
+        "temp": "0.8.3",
+        "word-wrap": "1.2.3",
+        "yargs": "7.0.2"
+      },
+      "dependencies": {
+        "camelcase": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
+          "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=",
+          "optional": true
+        },
+        "yargs": {
+          "version": "7.0.2",
+          "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.0.2.tgz",
+          "integrity": "sha1-EVuX3xMhgj6Lhkjolox4JSEiH2c=",
+          "optional": true,
+          "requires": {
+            "camelcase": "3.0.0",
+            "cliui": "3.2.0",
+            "decamelize": "1.2.0",
+            "get-caller-file": "1.0.2",
+            "os-locale": "1.4.0",
+            "read-pkg-up": "1.0.1",
+            "require-directory": "2.1.1",
+            "require-main-filename": "1.0.1",
+            "set-blocking": "2.0.0",
+            "string-width": "1.0.2",
+            "which-module": "1.0.0",
+            "y18n": "3.2.1",
+            "yargs-parser": "5.0.0"
+          }
+        }
+      }
+    },
+    "electron-localshortcut": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/electron-localshortcut/-/electron-localshortcut-0.6.1.tgz",
+      "integrity": "sha1-xOJow4puQvQN5WGPyQbR7WCPEao="
+    },
+    "electron-osx-sign": {
+      "version": "0.4.8",
+      "resolved": "https://registry.npmjs.org/electron-osx-sign/-/electron-osx-sign-0.4.8.tgz",
+      "integrity": "sha1-8Ln63e2eHlTsNfqJh3tcbDTHvEA=",
+      "dev": true,
+      "requires": {
+        "bluebird": "3.5.1",
+        "compare-version": "0.1.2",
+        "debug": "2.6.9",
+        "isbinaryfile": "3.0.2",
+        "minimist": "1.2.0",
+        "plist": "2.1.0"
+      }
+    },
+    "electron-packager": {
+      "version": "github:brave/electron-packager#0dcbc2d5b56b058e8ee9a2ec1f43f96d94f4925e",
+      "dev": true,
+      "requires": {
+        "asar": "0.11.0",
+        "electron-download": "github:brave/electron-download#409b65caff14edeef1daa36a7445ba6334658d7c",
+        "electron-osx-sign": "0.3.2",
+        "extract-zip": "1.6.6",
+        "fs-extra": "0.28.0",
+        "get-package-info": "0.0.2",
+        "minimist": "1.2.0",
+        "plist": "1.2.0",
+        "rcedit": "0.5.1",
+        "resolve": "1.5.0",
+        "run-series": "1.1.4"
+      },
+      "dependencies": {
+        "asar": {
+          "version": "0.11.0",
+          "resolved": "https://registry.npmjs.org/asar/-/asar-0.11.0.tgz",
+          "integrity": "sha1-uSbnksMV+MBIxDNx4yWwnJenZGQ=",
+          "dev": true,
+          "requires": {
+            "chromium-pickle-js": "0.1.0",
+            "commander": "2.14.1",
+            "cuint": "0.2.2",
+            "glob": "6.0.4",
+            "minimatch": "3.0.4",
+            "mkdirp": "0.5.1",
+            "mksnapshot": "0.3.1"
+          }
+        },
+        "base64-js": {
+          "version": "0.0.8",
+          "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-0.0.8.tgz",
+          "integrity": "sha1-EQHpVE9KdrG8OybUUsqW16NeeXg=",
+          "dev": true
+        },
+        "chromium-pickle-js": {
+          "version": "0.1.0",
+          "resolved": "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.1.0.tgz",
+          "integrity": "sha1-HUixB9ghJqLz4hHC6iX4A7pVGyE=",
+          "dev": true
+        },
+        "electron-osx-sign": {
+          "version": "0.3.2",
+          "resolved": "https://registry.npmjs.org/electron-osx-sign/-/electron-osx-sign-0.3.2.tgz",
+          "integrity": "sha1-iPp9brrbXZx5NouWSRoNjEYwFG4=",
+          "dev": true,
+          "requires": {
+            "debug": "2.6.9",
+            "minimist": "1.2.0",
+            "run-series": "1.1.4"
+          }
+        },
+        "fs-extra": {
+          "version": "0.28.0",
+          "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.28.0.tgz",
+          "integrity": "sha1-mhwHCOqMUWkperBv2MuRT1ZHsnI=",
+          "dev": true,
+          "requires": {
+            "graceful-fs": "4.1.11",
+            "jsonfile": "2.4.0",
+            "klaw": "1.3.1",
+            "path-is-absolute": "1.0.1",
+            "rimraf": "2.4.5"
+          }
+        },
+        "glob": {
+          "version": "6.0.4",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz",
+          "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=",
+          "dev": true,
+          "requires": {
+            "inflight": "1.0.6",
+            "inherits": "2.0.3",
+            "minimatch": "3.0.4",
+            "once": "1.4.0",
+            "path-is-absolute": "1.0.1"
+          }
+        },
+        "lodash": {
+          "version": "3.10.1",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
+          "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=",
+          "dev": true
+        },
+        "plist": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/plist/-/plist-1.2.0.tgz",
+          "integrity": "sha1-CEtQk93JJQbiWfh0uNmxr7jHlZM=",
           "dev": true,
           "requires": {
-            "graceful-fs": "4.1.11",
-            "jsonfile": "4.0.0",
-            "universalify": "0.1.1"
+            "base64-js": "0.0.8",
+            "util-deprecate": "1.0.2",
+            "xmlbuilder": "4.0.0",
+            "xmldom": "0.1.27"
           }
         },
-        "jsonfile": {
+        "xmlbuilder": {
           "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
-          "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
+          "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-4.0.0.tgz",
+          "integrity": "sha1-mLj2UcowqmJANvEn0RzGbce5B6M=",
           "dev": true,
           "requires": {
-            "graceful-fs": "4.1.11"
+            "lodash": "3.10.1"
           }
         }
       }
     },
-    "electron-localshortcut": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/electron-localshortcut/-/electron-localshortcut-0.6.1.tgz",
-      "integrity": "sha1-xOJow4puQvQN5WGPyQbR7WCPEao="
-    },
-    "electron-osx-sign": {
-      "version": "0.4.8",
-      "resolved": "https://registry.npmjs.org/electron-osx-sign/-/electron-osx-sign-0.4.8.tgz",
-      "integrity": "sha1-8Ln63e2eHlTsNfqJh3tcbDTHvEA=",
+    "electron-prebuilt": {
+      "version": "github:brave/electron-prebuilt#e65e72f4bc7a8e7de160667f3eb3c2b22e3e395e",
       "dev": true,
       "requires": {
-        "bluebird": "3.5.1",
-        "compare-version": "0.1.2",
-        "debug": "2.6.9",
-        "isbinaryfile": "3.0.2",
-        "minimist": "1.2.0",
-        "plist": "2.1.0"
+        "electron-download": "github:brave/electron-download#409b65caff14edeef1daa36a7445ba6334658d7c",
+        "extract-zip": "1.6.6"
       }
     },
     "electron-publish": {
@@ -5415,6 +6131,12 @@
         }
       }
     },
+    "electron-squirrel-startup": {
+      "version": "github:brave/electron-squirrel-startup#88d78fee0079d7bfce7e5238658e54e2e75550ef",
+      "requires": {
+        "debug": "2.6.9"
+      }
+    },
     "electron-to-chromium": {
       "version": "1.3.34",
       "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.34.tgz",
@@ -5571,7 +6293,6 @@
       "version": "1.3.1",
       "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz",
       "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=",
-      "dev": true,
       "requires": {
         "is-arrayish": "0.2.1"
       }
@@ -5695,11 +6416,6 @@
       "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
       "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
     },
-    "escape-regexp-component": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/escape-regexp-component/-/escape-regexp-component-1.0.2.tgz",
-      "integrity": "sha1-nGO20LJf8qiMOtvRjFthrMO5+qI="
-    },
     "escape-string-regexp": {
       "version": "1.0.5",
       "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
@@ -6609,7 +7325,6 @@
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-1.0.0.tgz",
       "integrity": "sha1-kojj6ePMN0hxfTnq3hfPcfww7m8=",
-      "dev": true,
       "requires": {
         "commondir": "1.0.1",
         "make-dir": "1.2.0",
@@ -6632,7 +7347,6 @@
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
       "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
-      "dev": true,
       "requires": {
         "locate-path": "2.0.0"
       }
@@ -7884,6 +8598,12 @@
       "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
       "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc="
     },
+    "gar": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/gar/-/gar-1.0.3.tgz",
+      "integrity": "sha512-zDpwk/l3HbhjVAvdxNUTJFzgXiNy0a7EmE/50XT38o1z+7NJbFhp+8CDsv1Qgy2adBAwUVYlMpIX2fZUbmlUJw==",
+      "optional": true
+    },
     "gather-stream": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/gather-stream/-/gather-stream-1.0.0.tgz",
@@ -7936,8 +8656,36 @@
     "get-caller-file": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz",
-      "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=",
-      "dev": true
+      "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U="
+    },
+    "get-folder-size": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/get-folder-size/-/get-folder-size-1.0.1.tgz",
+      "integrity": "sha1-gC+kIIQ03nEgUYKxWrfxNSCI5YA=",
+      "optional": true,
+      "requires": {
+        "async": "1.5.2",
+        "gar": "1.0.3"
+      },
+      "dependencies": {
+        "async": {
+          "version": "1.5.2",
+          "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+          "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
+          "optional": true
+        }
+      }
+    },
+    "get-package-info": {
+      "version": "0.0.2",
+      "resolved": "https://registry.npmjs.org/get-package-info/-/get-package-info-0.0.2.tgz",
+      "integrity": "sha1-csOPvuLnZyhCSgDcFOJN0aKMI5E=",
+      "dev": true,
+      "requires": {
+        "bluebird": "3.5.1",
+        "lodash.get": "4.4.2",
+        "resolve": "1.5.0"
+      }
     },
     "get-stdin": {
       "version": "5.0.1",
@@ -8049,6 +8797,16 @@
         }
       }
     },
+    "glob-parent": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
+      "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
+      "dev": true,
+      "requires": {
+        "is-glob": "3.1.0",
+        "path-dirname": "1.0.2"
+      }
+    },
     "glob-stream": {
       "version": "3.1.18",
       "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-3.1.18.tgz",
@@ -8263,6 +9021,12 @@
       "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
       "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg="
     },
+    "graceful-readlink": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz",
+      "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=",
+      "dev": true
+    },
     "growl": {
       "version": "1.9.2",
       "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz",
@@ -8317,6 +9081,48 @@
         }
       }
     },
+    "gulp-sourcemaps": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-1.6.0.tgz",
+      "integrity": "sha1-uG/zSdgBzrVuHZ59x7vLS33uYAw=",
+      "dev": true,
+      "requires": {
+        "convert-source-map": "1.5.1",
+        "graceful-fs": "4.1.11",
+        "strip-bom": "2.0.0",
+        "through2": "2.0.3",
+        "vinyl": "1.2.0"
+      },
+      "dependencies": {
+        "clone": {
+          "version": "1.0.3",
+          "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.3.tgz",
+          "integrity": "sha1-KY1+IjFmD0DAA8LtMUDezz9TCF8=",
+          "dev": true
+        },
+        "through2": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz",
+          "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=",
+          "dev": true,
+          "requires": {
+            "readable-stream": "2.3.4",
+            "xtend": "4.0.1"
+          }
+        },
+        "vinyl": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz",
+          "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=",
+          "dev": true,
+          "requires": {
+            "clone": "1.0.3",
+            "clone-stats": "0.0.1",
+            "replace-ext": "0.0.1"
+          }
+        }
+      }
+    },
     "gulp-util": {
       "version": "3.0.8",
       "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.8.tgz",
@@ -8564,12 +9370,17 @@
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz",
       "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=",
-      "dev": true,
       "requires": {
         "os-homedir": "1.0.2",
         "os-tmpdir": "1.0.2"
       }
     },
+    "home-path": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/home-path/-/home-path-1.0.5.tgz",
+      "integrity": "sha1-eIspgVsS1Tus9XVkhHbm+QQdEz8=",
+      "dev": true
+    },
     "homedir-polyfill": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz",
@@ -8582,8 +9393,7 @@
     "hosted-git-info": {
       "version": "2.5.0",
       "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz",
-      "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==",
-      "dev": true
+      "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg=="
     },
     "hpack.js": {
       "version": "2.1.6",
@@ -8617,46 +9427,6 @@
       "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=",
       "dev": true
     },
-    "htmlparser2": {
-      "version": "3.8.3",
-      "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz",
-      "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=",
-      "requires": {
-        "domelementtype": "1.3.0",
-        "domhandler": "2.3.0",
-        "domutils": "1.5.1",
-        "entities": "1.0.0",
-        "readable-stream": "1.1.14"
-      },
-      "dependencies": {
-        "entities": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz",
-          "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY="
-        },
-        "isarray": {
-          "version": "0.0.1",
-          "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
-          "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
-        },
-        "readable-stream": {
-          "version": "1.1.14",
-          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
-          "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
-          "requires": {
-            "core-util-is": "1.0.2",
-            "inherits": "2.0.3",
-            "isarray": "0.0.1",
-            "string_decoder": "0.10.31"
-          }
-        },
-        "string_decoder": {
-          "version": "0.10.31",
-          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
-          "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
-        }
-      }
-    },
     "http-deceiver": {
       "version": "1.2.7",
       "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz",
@@ -8975,6 +9745,12 @@
         "immutable": "3.8.2"
       }
     },
+    "immutablepatch": {
+      "version": "github:brave/immutable-js-patch#84e400e5419defd1f15928c3af8dbcd96364cbc1",
+      "requires": {
+        "immutable": "3.8.2"
+      }
+    },
     "import-lazy": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz",
@@ -9162,8 +9938,7 @@
     "is-arrayish": {
       "version": "0.2.1",
       "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
-      "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
-      "dev": true
+      "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0="
     },
     "is-ascii": {
       "version": "1.0.0",
@@ -9189,11 +9964,16 @@
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
       "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=",
-      "dev": true,
       "requires": {
         "builtin-modules": "1.1.1"
       }
     },
+    "is-bzip2": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-bzip2/-/is-bzip2-1.0.0.tgz",
+      "integrity": "sha1-XuWOqlounIDiFAe+3yOuWsCRs/w=",
+      "dev": true
+    },
     "is-callable": {
       "version": "1.1.3",
       "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz",
@@ -9271,7 +10051,6 @@
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz",
       "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=",
-      "dev": true,
       "requires": {
         "number-is-nan": "1.0.1"
       }
@@ -9304,6 +10083,12 @@
         "is-extglob": "2.1.1"
       }
     },
+    "is-gzip": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-gzip/-/is-gzip-1.0.0.tgz",
+      "integrity": "sha1-bKiwe5nHeZgCWQDlVc7Y7YCHmoM=",
+      "dev": true
+    },
     "is-installed-globally": {
       "version": "0.1.0",
       "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz",
@@ -9314,11 +10099,6 @@
         "is-path-inside": "1.0.1"
       }
     },
-    "is-isodate": {
-      "version": "0.0.1",
-      "resolved": "https://registry.npmjs.org/is-isodate/-/is-isodate-0.0.1.tgz",
-      "integrity": "sha1-T+LpN9UPO6aMe2mwIYAItiSqUDY="
-    },
     "is-my-ip-valid": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz",
@@ -9338,6 +10118,12 @@
         "xtend": "4.0.1"
       }
     },
+    "is-natural-number": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-2.1.1.tgz",
+      "integrity": "sha1-fUxXKDd+84bD4ZSpkRv1fG3DNec=",
+      "dev": true
+    },
     "is-npm": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz",
@@ -9506,6 +10292,12 @@
       "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=",
       "dev": true
     },
+    "is-tar": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-tar/-/is-tar-1.0.0.tgz",
+      "integrity": "sha1-L2suF5LB9bs2UZrKqdZcDSb+hT0=",
+      "dev": true
+    },
     "is-typedarray": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
@@ -9520,15 +10312,15 @@
         "unc-path-regex": "0.1.2"
       }
     },
-    "is-url": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.2.tgz",
-      "integrity": "sha1-SYkFpZO/R8wtnn9zg3K792lsfyY="
-    },
     "is-utf8": {
       "version": "0.2.1",
       "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
-      "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
+      "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI="
+    },
+    "is-valid-glob": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-0.3.0.tgz",
+      "integrity": "sha1-1LVcafUYhvm2XHDWwmItN+KfSP4=",
       "dev": true
     },
     "is-windows": {
@@ -9537,6 +10329,12 @@
       "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
       "dev": true
     },
+    "is-zip": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-zip/-/is-zip-1.0.0.tgz",
+      "integrity": "sha1-R7Co/004p2QxzP2ZqOFaTIa6IyU=",
+      "dev": true
+    },
     "isarray": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
@@ -9931,8 +10729,7 @@
     "jsesc": {
       "version": "1.3.0",
       "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz",
-      "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=",
-      "dev": true
+      "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s="
     },
     "json-loader": {
       "version": "0.5.7",
@@ -10083,7 +10880,6 @@
       "version": "1.3.1",
       "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz",
       "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=",
-      "dev": true,
       "requires": {
         "graceful-fs": "4.1.11"
       }
@@ -10530,7 +11326,6 @@
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
       "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
-      "dev": true,
       "requires": {
         "graceful-fs": "4.1.11",
         "parse-json": "2.2.0",
@@ -10559,7 +11354,6 @@
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
       "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
-      "dev": true,
       "requires": {
         "p-locate": "2.0.0",
         "path-exists": "3.0.0"
@@ -10686,6 +11480,12 @@
       "integrity": "sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM=",
       "dev": true
     },
+    "lodash.get": {
+      "version": "4.4.2",
+      "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
+      "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=",
+      "dev": true
+    },
     "lodash.isarguments": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz",
@@ -10698,6 +11498,12 @@
       "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=",
       "dev": true
     },
+    "lodash.isequal": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
+      "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=",
+      "dev": true
+    },
     "lodash.keys": {
       "version": "3.1.2",
       "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz",
@@ -10871,7 +11677,6 @@
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.2.0.tgz",
       "integrity": "sha512-aNUAa4UMg/UougV25bbrU4ZaaKNjJ/3/xnvg/twpmKROPdKZPZ9wGgI0opdZzO8q/zUFawoUuixuOv33eZ61Iw==",
-      "dev": true,
       "requires": {
         "pify": "3.0.0"
       },
@@ -10879,24 +11684,10 @@
         "pify": {
           "version": "3.0.0",
           "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
-          "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
-          "dev": true
+          "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY="
         }
       }
     },
-    "make-error": {
-      "version": "1.3.4",
-      "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.4.tgz",
-      "integrity": "sha512-0Dab5btKVPhibSalc9QGXb559ED7G7iLjFXBaj9Wq8O3vorueR5K5jaE3hkG6ZQINyhA/JgG6Qk4qdFQjsYV6g=="
-    },
-    "make-error-cause": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/make-error-cause/-/make-error-cause-1.2.2.tgz",
-      "integrity": "sha1-3wOI/NCzeBbf8KX7gQiTl3fcvJ0=",
-      "requires": {
-        "make-error": "1.3.4"
-      }
-    },
     "make-iterator": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.0.tgz",
@@ -11025,24 +11816,20 @@
       "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
       "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
     },
+    "merge-stream": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz",
+      "integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=",
+      "dev": true,
+      "requires": {
+        "readable-stream": "2.3.4"
+      }
+    },
     "merkle-lib": {
       "version": "2.0.10",
       "resolved": "https://registry.npmjs.org/merkle-lib/-/merkle-lib-2.0.10.tgz",
       "integrity": "sha1-grjbrnXieneFOItz+ddyXQ9vMyY="
     },
-    "metascraper": {
-      "version": "1.0.7",
-      "resolved": "https://registry.npmjs.org/metascraper/-/metascraper-1.0.7.tgz",
-      "integrity": "sha512-UPGR9eGM4u6iS3oWNS/KQoHrfINz8N33a1astWECiLz9st6e1PUc7+sGyHvQuzXDzYvc+Qu0/TrzOWUNuw+Fcg==",
-      "requires": {
-        "cheerio": "0.20.0",
-        "chrono-node": "1.3.5",
-        "is-isodate": "0.0.1",
-        "is-url": "1.2.2",
-        "popsicle": "6.2.2",
-        "to-title-case": "1.0.0"
-      }
-    },
     "methods": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
@@ -11207,14 +11994,12 @@
     "mkpath": {
       "version": "0.1.0",
       "resolved": "https://registry.npmjs.org/mkpath/-/mkpath-0.1.0.tgz",
-      "integrity": "sha1-dVSm+Nhxg0zJe1RisSLEwSTW3pE=",
-      "dev": true
+      "integrity": "sha1-dVSm+Nhxg0zJe1RisSLEwSTW3pE="
     },
     "mksnapshot": {
       "version": "0.3.1",
       "resolved": "https://registry.npmjs.org/mksnapshot/-/mksnapshot-0.3.1.tgz",
       "integrity": "sha1-JQHAVldDbXQs6Vik/5LHfkDdN+Y=",
-      "dev": true,
       "requires": {
         "decompress-zip": "0.3.0",
         "fs-extra": "0.26.7",
@@ -11225,7 +12010,6 @@
           "version": "0.26.7",
           "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.26.7.tgz",
           "integrity": "sha1-muH92UiXeY7at20JGM9C0MMYT6k=",
-          "dev": true,
           "requires": {
             "graceful-fs": "4.1.11",
             "jsonfile": "2.4.0",
@@ -11512,7 +12296,6 @@
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz",
       "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=",
-      "optional": true,
       "requires": {
         "mkdirp": "0.5.1",
         "ncp": "2.0.0",
@@ -11778,7 +12561,6 @@
       "version": "3.0.6",
       "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
       "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
-      "dev": true,
       "requires": {
         "abbrev": "1.1.1"
       }
@@ -11787,7 +12569,6 @@
       "version": "2.4.0",
       "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
       "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==",
-      "dev": true,
       "requires": {
         "hosted-git-info": "2.5.0",
         "is-builtin-module": "1.0.0",
@@ -12035,6 +12816,7 @@
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz",
       "integrity": "sha1-mSms32KPwsQQmN6rgqxYDPFJquQ=",
+      "dev": true,
       "requires": {
         "boolbase": "1.0.0"
       }
@@ -12437,6 +13219,12 @@
         "lcid": "1.0.0"
       }
     },
+    "os-shim": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/os-shim/-/os-shim-0.1.3.tgz",
+      "integrity": "sha1-a2LDeRz3kJ6jXtRuF2WLtBfLORc=",
+      "dev": true
+    },
     "os-tmpdir": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
@@ -12462,7 +13250,6 @@
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz",
       "integrity": "sha512-Y/OtIaXtUPr4/YpMv1pCL5L5ed0rumAaAeBSj12F+bSlMdys7i8oQF/GUJmfpTS/QoaRrS/k6pma29haJpsMng==",
-      "dev": true,
       "requires": {
         "p-try": "1.0.0"
       }
@@ -12471,7 +13258,6 @@
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
       "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
-      "dev": true,
       "requires": {
         "p-limit": "1.2.0"
       }
@@ -12485,8 +13271,7 @@
     "p-try": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
-      "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
-      "dev": true
+      "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M="
     },
     "pac-proxy-agent": {
       "version": "2.0.0",
@@ -12565,6 +13350,15 @@
         "pbkdf2": "3.0.14"
       }
     },
+    "parse-author": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/parse-author/-/parse-author-2.0.0.tgz",
+      "integrity": "sha1-00YL8d3Q367tQtp1QkLmX7aEqB8=",
+      "optional": true,
+      "requires": {
+        "author-regex": "1.0.0"
+      }
+    },
     "parse-bmfont-ascii": {
       "version": "1.0.6",
       "resolved": "https://registry.npmjs.org/parse-bmfont-ascii/-/parse-bmfont-ascii-1.0.6.tgz",
@@ -12659,7 +13453,6 @@
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
       "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
-      "dev": true,
       "requires": {
         "error-ex": "1.3.1"
       }
@@ -12717,11 +13510,16 @@
       "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=",
       "dev": true
     },
+    "path-dirname": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
+      "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=",
+      "dev": true
+    },
     "path-exists": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
-      "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
-      "dev": true
+      "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU="
     },
     "path-is-absolute": {
       "version": "1.0.1",
@@ -12769,7 +13567,6 @@
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
       "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
-      "dev": true,
       "requires": {
         "graceful-fs": "4.1.11",
         "pify": "2.3.0",
@@ -12895,7 +13692,6 @@
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz",
       "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=",
-      "dev": true,
       "requires": {
         "find-up": "2.1.0"
       }
@@ -12967,66 +13763,8 @@
     },
     "pngjs": {
       "version": "3.3.2",
-      "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.3.2.tgz",
-      "integrity": "sha512-bVNd3LMXRzdo6s4ehr4XW2wFMu9cb40nPgHEjSSppm8/++Xc+g0b2QQb+SeDesgfANXbjydOr1or9YQ+pcCZPQ=="
-    },
-    "popsicle": {
-      "version": "6.2.2",
-      "resolved": "https://registry.npmjs.org/popsicle/-/popsicle-6.2.2.tgz",
-      "integrity": "sha1-4nPIvUgYH3OlmxmeKl4ltpKz4jc=",
-      "requires": {
-        "any-promise": "1.3.0",
-        "arrify": "1.0.1",
-        "concat-stream": "1.6.0",
-        "form-data": "0.2.0",
-        "make-error-cause": "1.2.2",
-        "throwback": "1.1.1",
-        "tough-cookie": "2.3.3",
-        "xtend": "4.0.1"
-      },
-      "dependencies": {
-        "async": {
-          "version": "0.9.2",
-          "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz",
-          "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0="
-        },
-        "combined-stream": {
-          "version": "0.0.7",
-          "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz",
-          "integrity": "sha1-ATfmV7qlp1QcV6w3rF/AfXO03B8=",
-          "requires": {
-            "delayed-stream": "0.0.5"
-          }
-        },
-        "delayed-stream": {
-          "version": "0.0.5",
-          "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz",
-          "integrity": "sha1-1LH0OpPoKW3+AmlPRoC8N6MTxz8="
-        },
-        "form-data": {
-          "version": "0.2.0",
-          "resolved": "https://registry.npmjs.org/form-data/-/form-data-0.2.0.tgz",
-          "integrity": "sha1-Jvi8JtpkQOKZy9z7aQNcT3em5GY=",
-          "requires": {
-            "async": "0.9.2",
-            "combined-stream": "0.0.7",
-            "mime-types": "2.0.14"
-          }
-        },
-        "mime-db": {
-          "version": "1.12.0",
-          "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.12.0.tgz",
-          "integrity": "sha1-PQxjGA9FjrENMlqqN9fFiuMS6dc="
-        },
-        "mime-types": {
-          "version": "2.0.14",
-          "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.0.14.tgz",
-          "integrity": "sha1-MQ4VnbI+B3+Lsit0jav6SVcUCqY=",
-          "requires": {
-            "mime-db": "1.12.0"
-          }
-        }
-      }
+      "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.3.2.tgz",
+      "integrity": "sha512-bVNd3LMXRzdo6s4ehr4XW2wFMu9cb40nPgHEjSSppm8/++Xc+g0b2QQb+SeDesgfANXbjydOr1or9YQ+pcCZPQ=="
     },
     "portfinder": {
       "version": "1.0.13",
@@ -13892,6 +14630,46 @@
         "postcss": "4.1.16"
       }
     },
+    "pre-commit": {
+      "version": "github:brave/pre-commit#67aef1db3066f298a25e930c06a8c9f2b19f2a3e",
+      "dev": true,
+      "requires": {
+        "cross-spawn": "4.0.2",
+        "spawn-sync": "1.0.15",
+        "which": "1.2.14"
+      },
+      "dependencies": {
+        "cross-spawn": {
+          "version": "4.0.2",
+          "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz",
+          "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=",
+          "dev": true,
+          "requires": {
+            "lru-cache": "4.1.2",
+            "which": "1.2.14"
+          }
+        },
+        "lru-cache": {
+          "version": "4.1.2",
+          "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.2.tgz",
+          "integrity": "sha512-wgeVXhrDwAWnIF/yZARsFnMBtdFXOg1b8RIrhilp+0iDYN4mdQcNZElDZ0e4B64BhaxeQ5zN7PMyvu7we1kPeQ==",
+          "dev": true,
+          "requires": {
+            "pseudomap": "1.0.2",
+            "yallist": "2.1.2"
+          }
+        },
+        "which": {
+          "version": "1.2.14",
+          "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz",
+          "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=",
+          "dev": true,
+          "requires": {
+            "isexe": "2.0.0"
+          }
+        }
+      }
+    },
     "pre-push": {
       "version": "0.1.1",
       "resolved": "https://registry.npmjs.org/pre-push/-/pre-push-0.1.1.tgz",
@@ -13979,8 +14757,7 @@
     "private": {
       "version": "0.1.8",
       "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz",
-      "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==",
-      "dev": true
+      "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg=="
     },
     "process": {
       "version": "0.5.2",
@@ -14255,8 +15032,7 @@
     "q": {
       "version": "1.5.1",
       "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
-      "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=",
-      "dev": true
+      "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc="
     },
     "qr-image": {
       "version": "3.2.0",
@@ -14397,6 +15173,12 @@
         "strip-json-comments": "2.0.1"
       }
     },
+    "rcedit": {
+      "version": "0.5.1",
+      "resolved": "https://registry.npmjs.org/rcedit/-/rcedit-0.5.1.tgz",
+      "integrity": "sha1-0L3PXSgKnRwp2m8RjMzizhU87x0=",
+      "dev": true
+    },
     "react": {
       "version": "15.6.2",
       "resolved": "https://registry.npmjs.org/react/-/react-15.6.2.tgz",
@@ -14494,6 +15276,16 @@
         "warning": "3.0.0"
       }
     },
+    "read-all-stream": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/read-all-stream/-/read-all-stream-3.1.0.tgz",
+      "integrity": "sha1-NcPhd/IHjveJ7kv6+kNzB06u9Po=",
+      "dev": true,
+      "requires": {
+        "pinkie-promise": "2.0.1",
+        "readable-stream": "2.3.4"
+      }
+    },
     "read-chunk": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/read-chunk/-/read-chunk-1.0.1.tgz",
@@ -14536,7 +15328,6 @@
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
       "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
-      "dev": true,
       "requires": {
         "load-json-file": "1.1.0",
         "normalize-package-data": "2.4.0",
@@ -14547,7 +15338,6 @@
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
       "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
-      "dev": true,
       "requires": {
         "find-up": "1.1.2",
         "read-pkg": "1.1.0"
@@ -14557,7 +15347,6 @@
           "version": "1.1.2",
           "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
           "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
-          "dev": true,
           "requires": {
             "path-exists": "2.1.0",
             "pinkie-promise": "2.0.1"
@@ -14567,7 +15356,6 @@
           "version": "2.1.0",
           "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
           "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
-          "dev": true,
           "requires": {
             "pinkie-promise": "2.0.1"
           }
@@ -14643,6 +15431,11 @@
         "strip-indent": "1.0.1"
       }
     },
+    "reduce-component": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/reduce-component/-/reduce-component-1.0.1.tgz",
+      "integrity": "sha1-4Mk1QsV0UhvqE98PlIjtgqt3xdo="
+    },
     "reduce-css-calc": {
       "version": "1.3.0",
       "resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz",
@@ -14819,7 +15612,6 @@
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
       "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=",
-      "dev": true,
       "requires": {
         "is-finite": "1.0.2"
       }
@@ -14887,14 +15679,12 @@
     "require-directory": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
-      "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
-      "dev": true
+      "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I="
     },
     "require-main-filename": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
-      "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=",
-      "dev": true
+      "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE="
     },
     "require-uncached": {
       "version": "1.0.3",
@@ -15260,6 +16050,26 @@
       "resolved": "https://registry.npmjs.org/secrets.js-grempe/-/secrets.js-grempe-1.1.0.tgz",
       "integrity": "sha1-uztgbdaGN8okRoGhD97mxRIEkpQ="
     },
+    "seek-bzip": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.5.tgz",
+      "integrity": "sha1-z+kXyz0nS8/6x5J1ivUxc+sfq9w=",
+      "dev": true,
+      "requires": {
+        "commander": "2.8.1"
+      },
+      "dependencies": {
+        "commander": {
+          "version": "2.8.1",
+          "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz",
+          "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=",
+          "dev": true,
+          "requires": {
+            "graceful-readlink": "1.0.1"
+          }
+        }
+      }
+    },
     "select-hose": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
@@ -15572,8 +16382,7 @@
     "slash": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz",
-      "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=",
-      "dev": true
+      "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU="
     },
     "slice-ansi": {
       "version": "1.0.0",
@@ -15878,7 +16687,6 @@
       "version": "0.4.18",
       "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz",
       "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==",
-      "dev": true,
       "requires": {
         "source-map": "0.5.7"
       }
@@ -15895,11 +16703,20 @@
       "integrity": "sha1-Gsu/tZJDbRC76PeFt8xvgoFQEsM=",
       "dev": true
     },
+    "spawn-sync": {
+      "version": "1.0.15",
+      "resolved": "https://registry.npmjs.org/spawn-sync/-/spawn-sync-1.0.15.tgz",
+      "integrity": "sha1-sAeZVX63+wyDdsKdROih6mfldHY=",
+      "dev": true,
+      "requires": {
+        "concat-stream": "1.6.0",
+        "os-shim": "0.1.3"
+      }
+    },
     "spdx-correct": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz",
       "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=",
-      "dev": true,
       "requires": {
         "spdx-license-ids": "1.2.2"
       }
@@ -15907,14 +16724,12 @@
     "spdx-expression-parse": {
       "version": "1.0.4",
       "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz",
-      "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=",
-      "dev": true
+      "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw="
     },
     "spdx-license-ids": {
       "version": "1.2.2",
       "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz",
-      "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=",
-      "dev": true
+      "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc="
     },
     "spdy": {
       "version": "3.4.7",
@@ -15945,6 +16760,28 @@
         "wbuf": "1.7.2"
       }
     },
+    "spectron": {
+      "version": "github:brave/spectron#375698c8a4b8a2298e808d8e8714813b7636a834",
+      "dev": true,
+      "requires": {
+        "dev-null": "0.1.1",
+        "electron-chromedriver": "github:brave/electron-chromedriver#772ace180da97768478ce9683b871449c621205a",
+        "request": "2.83.0",
+        "split": "1.0.1",
+        "webdriverio": "4.7.1"
+      },
+      "dependencies": {
+        "electron-chromedriver": {
+          "version": "github:brave/electron-chromedriver#772ace180da97768478ce9683b871449c621205a",
+          "dev": true,
+          "requires": {
+            "decompress": "3.0.0",
+            "mkdirp": "0.5.1",
+            "request": "2.83.0"
+          }
+        }
+      }
+    },
     "speedometer": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/speedometer/-/speedometer-1.0.0.tgz",
@@ -16396,6 +17233,11 @@
       "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
       "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks="
     },
+    "storage2": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/storage2/-/storage2-0.1.0.tgz",
+      "integrity": "sha512-HNGFQFOr0+paYBbsAl9XO+YzM/LdS6CI9xI5aAfIu+9wL5NO3DK2YN8K0ha6LLJeYckSfyOA7jxWKHpyHF9zZw=="
+    },
     "stream-browserify": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz",
@@ -16406,6 +17248,27 @@
         "readable-stream": "2.3.4"
       }
     },
+    "stream-combiner2": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz",
+      "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=",
+      "dev": true,
+      "requires": {
+        "duplexer2": "0.1.4",
+        "readable-stream": "2.3.4"
+      },
+      "dependencies": {
+        "duplexer2": {
+          "version": "0.1.4",
+          "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz",
+          "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=",
+          "dev": true,
+          "requires": {
+            "readable-stream": "2.3.4"
+          }
+        }
+      }
+    },
     "stream-consume": {
       "version": "0.1.1",
       "resolved": "https://registry.npmjs.org/stream-consume/-/stream-consume-0.1.1.tgz",
@@ -16537,11 +17400,70 @@
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
       "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
-      "dev": true,
       "requires": {
         "is-utf8": "0.2.1"
       }
     },
+    "strip-bom-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/strip-bom-stream/-/strip-bom-stream-1.0.0.tgz",
+      "integrity": "sha1-5xRDmFd9Uaa+0PoZlPoF9D/ZiO4=",
+      "dev": true,
+      "requires": {
+        "first-chunk-stream": "1.0.0",
+        "strip-bom": "2.0.0"
+      }
+    },
+    "strip-dirs": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-1.1.1.tgz",
+      "integrity": "sha1-lgu9EoeETzl1pFWKoQOoJV4kVqA=",
+      "dev": true,
+      "requires": {
+        "chalk": "1.1.3",
+        "get-stdin": "4.0.1",
+        "is-absolute": "0.1.7",
+        "is-natural-number": "2.1.1",
+        "minimist": "1.2.0",
+        "sum-up": "1.0.3"
+      },
+      "dependencies": {
+        "chalk": {
+          "version": "1.1.3",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+          "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "2.2.1",
+            "escape-string-regexp": "1.0.5",
+            "has-ansi": "2.0.0",
+            "strip-ansi": "3.0.1",
+            "supports-color": "2.0.0"
+          }
+        },
+        "get-stdin": {
+          "version": "4.0.1",
+          "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
+          "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=",
+          "dev": true
+        },
+        "is-absolute": {
+          "version": "0.1.7",
+          "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-0.1.7.tgz",
+          "integrity": "sha1-hHSREZ/MtftDYhfMc39/qtUPYD8=",
+          "dev": true,
+          "requires": {
+            "is-relative": "0.1.3"
+          }
+        },
+        "is-relative": {
+          "version": "0.1.3",
+          "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-0.1.3.tgz",
+          "integrity": "sha1-kF/uiuhvRbPsYUvDwVyGnfCHboI=",
+          "dev": true
+        }
+      }
+    },
     "strip-eof": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
@@ -16580,6 +17502,30 @@
         "schema-utils": "0.3.0"
       }
     },
+    "sum-up": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/sum-up/-/sum-up-1.0.3.tgz",
+      "integrity": "sha1-HGYfZnBX9jvLeHWqFDi8FiUlFW4=",
+      "dev": true,
+      "requires": {
+        "chalk": "1.1.3"
+      },
+      "dependencies": {
+        "chalk": {
+          "version": "1.1.3",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+          "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "2.2.1",
+            "escape-string-regexp": "1.0.5",
+            "has-ansi": "2.0.0",
+            "strip-ansi": "3.0.1",
+            "supports-color": "2.0.0"
+          }
+        }
+      }
+    },
     "sumchecker": {
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-2.0.2.tgz",
@@ -16806,7 +17752,6 @@
       "version": "0.8.3",
       "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.3.tgz",
       "integrity": "sha1-4Ma8TSa5AxJEEOT+2BEDAU38H1k=",
-      "dev": true,
       "requires": {
         "os-tmpdir": "1.0.2",
         "rimraf": "2.2.8"
@@ -16815,8 +17760,7 @@
         "rimraf": {
           "version": "2.2.8",
           "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz",
-          "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=",
-          "dev": true
+          "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI="
         }
       }
     },
@@ -16893,12 +17837,26 @@
         }
       }
     },
-    "throwback": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/throwback/-/throwback-1.1.1.tgz",
-      "integrity": "sha1-8AfnwXYEptFtegfEGqDo/txhhKQ=",
+    "through2-filter": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-2.0.0.tgz",
+      "integrity": "sha1-YLxVoNrLdghdsfna6Zq0P4PWIuw=",
+      "dev": true,
       "requires": {
-        "any-promise": "1.3.0"
+        "through2": "2.0.3",
+        "xtend": "4.0.1"
+      },
+      "dependencies": {
+        "through2": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz",
+          "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=",
+          "dev": true,
+          "requires": {
+            "readable-stream": "2.3.4",
+            "xtend": "4.0.1"
+          }
+        }
       }
     },
     "thunkify": {
@@ -16946,11 +17904,6 @@
       "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.1.tgz",
       "integrity": "sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g="
     },
-    "title-case-minors": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/title-case-minors/-/title-case-minors-1.0.0.tgz",
-      "integrity": "sha1-UfFwN8KUdHodHNpCS1AEyG2OsRU="
-    },
     "tldjs": {
       "version": "1.6.2",
       "resolved": "https://registry.npmjs.org/tldjs/-/tldjs-1.6.2.tgz",
@@ -16964,24 +17917,35 @@
         "os-tmpdir": "1.0.2"
       }
     },
+    "to-absolute-glob": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-0.1.1.tgz",
+      "integrity": "sha1-HN+kcqnvUMI57maZm2YsoOs5k38=",
+      "dev": true,
+      "requires": {
+        "extend-shallow": "2.0.1"
+      },
+      "dependencies": {
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "0.1.1"
+          }
+        }
+      }
+    },
     "to-arraybuffer": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz",
       "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M="
     },
-    "to-capital-case": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/to-capital-case/-/to-capital-case-1.0.0.tgz",
-      "integrity": "sha1-pXxQFP1aNyF88FCZ/4pCG7+cm38=",
-      "requires": {
-        "to-space-case": "1.0.0"
-      }
-    },
     "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=",
-      "dev": true
+      "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc="
     },
     "to-iso-string": {
       "version": "0.0.2",
@@ -16989,11 +17953,6 @@
       "integrity": "sha1-TcGeZk38y+Jb2NtQiwDG2hWCVdE=",
       "dev": true
     },
-    "to-no-case": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/to-no-case/-/to-no-case-1.0.2.tgz",
-      "integrity": "sha1-xyKQcWTvaxeBMsjmmTAhLRtKoWo="
-    },
     "to-object-path": {
       "version": "0.3.0",
       "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
@@ -17036,33 +17995,6 @@
         "repeat-string": "1.6.1"
       }
     },
-    "to-sentence-case": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/to-sentence-case/-/to-sentence-case-1.0.0.tgz",
-      "integrity": "sha1-xIO/NkdzflxzjvcAb+Ng1fmcVy4=",
-      "requires": {
-        "to-no-case": "1.0.2"
-      }
-    },
-    "to-space-case": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/to-space-case/-/to-space-case-1.0.0.tgz",
-      "integrity": "sha1-sFLar7Gysp3HcM6gFj5ewOvJ/Bc=",
-      "requires": {
-        "to-no-case": "1.0.2"
-      }
-    },
-    "to-title-case": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/to-title-case/-/to-title-case-1.0.0.tgz",
-      "integrity": "sha1-rKiPidYGTeUBCKl86g20SCfoAGE=",
-      "requires": {
-        "escape-regexp-component": "1.0.2",
-        "title-case-minors": "1.0.0",
-        "to-capital-case": "1.0.0",
-        "to-sentence-case": "1.0.0"
-      }
-    },
     "topo": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/topo/-/topo-3.0.0.tgz",
@@ -17103,7 +18035,6 @@
       "version": "0.0.3",
       "resolved": "https://registry.npmjs.org/touch/-/touch-0.0.3.tgz",
       "integrity": "sha1-Ua7z1ElXHU8oel2Hyci0kYGg2x0=",
-      "dev": true,
       "requires": {
         "nopt": "1.0.10"
       },
@@ -17112,7 +18043,6 @@
           "version": "1.0.10",
           "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
           "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=",
-          "dev": true,
           "requires": {
             "abbrev": "1.1.1"
           }
@@ -17145,8 +18075,7 @@
     "traverse": {
       "version": "0.3.9",
       "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz",
-      "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=",
-      "dev": true
+      "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk="
     },
     "trim": {
       "version": "0.0.1",
@@ -17162,8 +18091,7 @@
     "trim-right": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz",
-      "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=",
-      "dev": true
+      "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM="
     },
     "truncate-utf8-bytes": {
       "version": "1.0.2",
@@ -17798,11 +18726,16 @@
         "user-home": "1.1.1"
       }
     },
+    "vali-date": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/vali-date/-/vali-date-1.0.0.tgz",
+      "integrity": "sha1-G5BKWWCfsyjvB4E4Qgk09rhnCaY=",
+      "dev": true
+    },
     "validate-npm-package-license": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz",
       "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=",
-      "dev": true,
       "requires": {
         "spdx-correct": "1.0.2",
         "spdx-expression-parse": "1.0.4"
@@ -17902,6 +18835,16 @@
         }
       }
     },
+    "vinyl-assign": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/vinyl-assign/-/vinyl-assign-1.2.1.tgz",
+      "integrity": "sha1-TRmIkbVRWRHXcajNnFSApGoHSkU=",
+      "dev": true,
+      "requires": {
+        "object-assign": "4.1.1",
+        "readable-stream": "2.3.4"
+      }
+    },
     "vinyl-fs": {
       "version": "0.3.14",
       "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-0.3.14.tgz",
@@ -18848,23 +19791,6 @@
         "webidl-conversions": "4.0.2"
       }
     },
-    "whatwg-url-compat": {
-      "version": "0.6.5",
-      "resolved": "https://registry.npmjs.org/whatwg-url-compat/-/whatwg-url-compat-0.6.5.tgz",
-      "integrity": "sha1-AImBEa9om7CXVBzVpFymyHmERb8=",
-      "optional": true,
-      "requires": {
-        "tr46": "0.0.3"
-      },
-      "dependencies": {
-        "tr46": {
-          "version": "0.0.3",
-          "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
-          "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=",
-          "optional": true
-        }
-      }
-    },
     "whet.extend": {
       "version": "0.9.9",
       "resolved": "https://registry.npmjs.org/whet.extend/-/whet.extend-0.9.9.tgz",
@@ -18882,8 +19808,7 @@
     "which-module": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz",
-      "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=",
-      "dev": true
+      "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8="
     },
     "which-pm-runs": {
       "version": "1.0.0",
@@ -18953,6 +19878,12 @@
       "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz",
       "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY="
     },
+    "word-wrap": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
+      "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
+      "optional": true
+    },
     "wordwrap": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
@@ -19139,6 +20070,23 @@
         "y18n": "3.2.1"
       }
     },
+    "yargs-parser": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz",
+      "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=",
+      "optional": true,
+      "requires": {
+        "camelcase": "3.0.0"
+      },
+      "dependencies": {
+        "camelcase": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
+          "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=",
+          "optional": true
+        }
+      }
+    },
     "yauzl": {
       "version": "2.4.1",
       "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz",
diff --git a/package.json b/package.json
index f30deffd88f..53cdca7627c 100644
--- a/package.json
+++ b/package.json
@@ -34,7 +34,7 @@
     "start-brk": "node ./tools/start.js --debug-brk=5858 -enable-logging --v=0 --enable-dcheck --user-data-dir-name=brave-development",
     "test": "cross-env NODE_ENV=test mocha \"test/**/*Test.js\"",
     "testsuite": "node ./tools/test.js",
-    "unittest": "cross-env NODE_ENV=test mocha \"test/unit/**/*Test.js\"",
+    "unittest": "cross-env NODE_ENV=test mocha \"test/unit/**/*Test.js\" --globals chrome,DOMParser,XMLSerializer",
     "unittest-cov": "node --harmony node_modules/istanbul/lib/cli.js cover ./node_modules/mocha/bin/_mocha --report lcovonly --report html --report text -x \"test/unit/**/*Test.js\" -- \"test/unit/**/*Test.js\"",
     "update-pdfjs": "rm -r app/extensions/pdfjs/; cp -r ../pdf.js/build/chromium/ app/extensions/pdfjs/",
     "update-psl": "./tools/updatepsl.sh",
@@ -90,7 +90,7 @@
     "async": "^2.0.1",
     "bat-balance": "^1.0.7",
     "bat-client": "^2.0.11",
-    "bat-publisher": "^2.0.11",
+    "bat-publisher": "^2.0.12",
     "bignumber.js": "^4.0.4",
     "bloodhound-js": "brave/bloodhound",
     "clipboard-copy": "^1.0.0",
diff --git a/test/unit/app/browser/api/ledgerTest.js b/test/unit/app/browser/api/ledgerTest.js
index 857f5003c0e..251947afda1 100644
--- a/test/unit/app/browser/api/ledgerTest.js
+++ b/test/unit/app/browser/api/ledgerTest.js
@@ -2663,4 +2663,35 @@ describe('ledger api unit tests', function () {
       assert.deepEqual(ledgerApi.getSynopsis(), expectedSynopsis)
     })
   })
+
+  describe('roundTripFromWindow', function () {
+    let fetchPublisherInfoSpy
+
+    before(() => {
+      fetchPublisherInfoSpy = sinon.spy(request, 'fetchPublisherInfo')
+    })
+
+    afterEach(() => {
+      fetchPublisherInfoSpy.reset()
+    })
+
+    after(() => {
+      fetchPublisherInfoSpy.restore()
+    })
+
+    it('null case', function () {
+      ledgerApi.roundTripFromWindow()
+      assert(fetchPublisherInfoSpy.notCalled)
+    })
+
+    it('url is missing', function () {
+      ledgerApi.roundTripFromWindow({})
+      assert(fetchPublisherInfoSpy.notCalled)
+    })
+
+    it('fetch is called', function () {
+      ledgerApi.roundTripFromWindow({url: 'test.com'}, () => true)
+      assert(fetchPublisherInfoSpy.withArgs('test.com', sinon.match.any, sinon.match.any))
+    })
+  })
 })
diff --git a/test/unit/app/extensions/brave/content/scripts/requestHandlerTest.js b/test/unit/app/extensions/brave/content/scripts/requestHandlerTest.js
new file mode 100644
index 00000000000..df7530a0f34
--- /dev/null
+++ b/test/unit/app/extensions/brave/content/scripts/requestHandlerTest.js
@@ -0,0 +1,619 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* global describe, it, before */
+const assert = require('assert')
+
+const fakeElectron = require('../../../../../lib/fakeElectron')
+require('../../../../../braveUnit')
+
+describe('requestHandler unit test', function () {
+  let requestHandler, parseFromStringHTML
+
+  before(() => {
+    global.chrome = {
+      ipcRenderer: fakeElectron.ipcRenderer
+    }
+
+    global.DOMParser = class {
+      parseFromString () {
+        return parseFromStringHTML
+      }
+    }
+
+    global.XMLSerializer = class {
+      serializeToString () {
+        return ''
+      }
+    }
+
+    requestHandler = require('../../../../../../../app/extensions/brave/content/scripts/requestHandler')
+  })
+
+  describe('getText', function () {
+    it('null case', function () {
+      const result = requestHandler.getText()
+      assert.equal(result, '')
+    })
+
+    it('node is actually number', function () {
+      const result = requestHandler.getText(123)
+      assert.equal(result, '')
+    })
+
+    it('span is provided', function () {
+      let span = document.createElement('span')
+      span.innerHTML = ('Span hello')
+      const result = requestHandler.getText(span)
+      assert.equal(result, ' Span hello ')
+    })
+  })
+
+  describe('urlCheck', function () {
+    it('null case', function () {
+      const result = requestHandler.urlCheck()
+      assert.equal(result, false)
+    })
+
+    it('is not url', function () {
+      const result = requestHandler.urlCheck(123)
+      assert.equal(result, false)
+    })
+
+    it('is http url', function () {
+      const result = requestHandler.urlCheck('http://test.com')
+      assert.equal(result, true)
+    })
+  })
+
+  describe('getContent', function () {
+    it('null case', function () {
+      const result = requestHandler.getContent()
+      assert.equal(result, null)
+    })
+
+    it('empty object', function () {
+      const result = requestHandler.getContent({})
+      assert.equal(result, null)
+    })
+
+    it('src is provided', function () {
+      const result = requestHandler.getContent({content: 'some text'})
+      assert.equal(result, 'some text')
+    })
+  })
+
+  describe('getSrc', function () {
+    it('null case', function () {
+      const result = requestHandler.getSrc()
+      assert.equal(result, null)
+    })
+
+    it('empty object', function () {
+      const result = requestHandler.getSrc({})
+      assert.equal(result, null)
+    })
+
+    it('src is provided', function () {
+      const result = requestHandler.getSrc({src: 'url'})
+      assert.equal(result, 'url')
+    })
+  })
+
+  describe('urlTest', function () {
+    it('null case', function () {
+      const result = requestHandler.urlTest()
+      assert.equal(result, false)
+    })
+
+    it('is not url', function () {
+      const result = requestHandler.urlTest(123)
+      assert.equal(result, false)
+    })
+
+    it('is simple url', function () {
+      const result = requestHandler.urlTest('test.com')
+      assert.equal(result, true)
+    })
+
+    it('is http url', function () {
+      const result = requestHandler.urlTest('http://test.com')
+      assert.equal(result, true)
+    })
+
+    it('is file url', function () {
+      const result = requestHandler.urlTest('file://test.png')
+      assert.equal(result, true)
+    })
+
+    it('relative url', function () {
+      const result = requestHandler.urlTest('/page', {relative: true})
+      assert.equal(result, true)
+    })
+
+    it('do not allow relative url', function () {
+      const result = requestHandler.urlTest('/page', {relative: false})
+      assert.equal(result, false)
+    })
+  })
+
+  describe('isEmpty', function () {
+    it('null case', function () {
+      const result = requestHandler.isEmpty()
+      assert.equal(result, true)
+    })
+
+    it('empty string', function () {
+      const result = requestHandler.isEmpty('')
+      assert.equal(result, true)
+    })
+
+    it('string is provided', function () {
+      const result = requestHandler.isEmpty('test.com')
+      assert.equal(result, false)
+    })
+  })
+
+  describe('isUrl', function () {
+    it('null case', function () {
+      const result = requestHandler.isUrl()
+      assert.equal(result, false)
+    })
+
+    it('emtpy string', function () {
+      const result = requestHandler.isUrl('')
+      assert.equal(result, false)
+    })
+
+    it('is not url', function () {
+      const result = requestHandler.isUrl(123)
+      assert.equal(result, false)
+    })
+
+    it('is simple url', function () {
+      const result = requestHandler.isUrl('test.com')
+      assert.equal(result, true)
+    })
+
+    it('is http url', function () {
+      const result = requestHandler.isUrl('http://test.com')
+      assert.equal(result, true)
+    })
+
+    it('is file url', function () {
+      const result = requestHandler.isUrl('file://test.png')
+      assert.equal(result, true)
+    })
+
+    it('relative url', function () {
+      const result = requestHandler.isUrl('/page', {relative: true})
+      assert.equal(result, true)
+    })
+
+    it('do not allow relative url', function () {
+      const result = requestHandler.isUrl('/page', {relative: false})
+      assert.equal(result, false)
+    })
+  })
+
+  describe('getUrl', function () {
+    it('null case', function () {
+      const result = requestHandler.getUrl()
+      assert.equal(result, undefined)
+    })
+
+    it('relative path is absolute link', function () {
+      const result = requestHandler.getUrl('https://youtube.com', '/page')
+      assert.equal(result, 'https://youtube.com/page')
+    })
+
+    it('relative path is relative link', function () {
+      const result = requestHandler.getUrl('https://youtube.com', '/page')
+      assert.equal(result, 'https://youtube.com/page')
+    })
+
+    it('relative path is absolute link', function () {
+      const result = requestHandler.getUrl('https://youtube.com', 'https://youtube.com/page')
+      assert.equal(result, 'https://youtube.com/page')
+    })
+  })
+
+  describe('isStrictString', function () {
+    it('null case', function () {
+      const result = requestHandler.isStrictString()
+      assert.equal(result, false)
+    })
+
+    it('value is no in correct format', function () {
+      const result = requestHandler.isStrictString('firstlast')
+      assert.equal(result, false)
+    })
+
+    it('value is in correct format', function () {
+      const result = requestHandler.isStrictString('first last')
+      assert.equal(result, 'first last')
+    })
+  })
+
+  describe('titleize', function () {
+    it('null case', function () {
+      const result = requestHandler.titleize()
+      assert.equal(result, '')
+    })
+
+    it('remove multiple spaces', function () {
+      const result = requestHandler.titleize('this is  long     title')
+      assert.equal(result, 'this is long title')
+    })
+
+    it('keep by by default', function () {
+      const result = requestHandler.titleize('by Author')
+      assert.equal(result, 'by Author')
+    })
+
+    it('keep by by default', function () {
+      const result = requestHandler.titleize('by Author', {removeBy: true})
+      assert.equal(result, 'Author')
+    })
+  })
+
+  describe('defaultFn', function () {
+    it('null case', function () {
+      const result = requestHandler.defaultFn()
+      assert.equal(result, '')
+    })
+
+    it('parameter is not HTML element', function () {
+      const result = requestHandler.defaultFn('something')
+      assert.equal(result, '')
+    })
+
+    it('text is trimmed', function () {
+      let span = document.createElement('span')
+      span.innerHTML = ('  Span as a child    ')
+
+      const result = requestHandler.defaultFn(span)
+      assert.equal(result, 'Span as a child')
+    })
+  })
+
+  describe('getValue', function () {
+    it('null case', function () {
+      const result = requestHandler.getValue()
+      assert.equal(result, null)
+    })
+
+    it('collection has only one element', function () {
+      let wrap = document.createElement('div')
+      let span = document.createElement('span')
+      span.innerHTML = ('Span as a child')
+      wrap.appendChild(span)
+      const result = requestHandler.getValue(wrap.querySelector('span'))
+      assert.equal(result, 'Span as a child')
+    })
+
+    it('collection has multiple elements', function () {
+      let wrap = document.createElement('div')
+      let span = document.createElement('span')
+      span.innerHTML = ('Span as a first child')
+      wrap.appendChild(span)
+      let span2 = document.createElement('span')
+      span2.innerHTML = ('Span as a second child')
+      wrap.appendChild(span2)
+      const result = requestHandler.getValue(wrap.querySelectorAll('span'))
+      assert.equal(result, 'Span as a first child')
+    })
+
+    it('first element has empty span', function () {
+      let wrap = document.createElement('div')
+      let span = document.createElement('span')
+      span.innerHTML = ('')
+      wrap.appendChild(span)
+      let span2 = document.createElement('span')
+      span2.innerHTML = ('Span as a second child')
+      wrap.appendChild(span2)
+      const result = requestHandler.getValue(wrap.querySelectorAll('span'))
+      assert.equal(result, 'Span as a second child')
+    })
+  })
+
+  describe('getThumbnailUrl', function () {
+    it('null case', function () {
+      const result = requestHandler.getThumbnailUrl()
+      assert.equal(result, null)
+    })
+
+    it('id is passed in', function () {
+      const result = requestHandler.getThumbnailUrl('ABC12302')
+      assert.equal(result, `https://img.youtube.com/vi/ABC12302/sddefault.jpg`)
+    })
+  })
+
+  describe('getVideoId', function () {
+    it('null case', function () {
+      const result = requestHandler.getVideoId()
+      assert.deepEqual(result, {})
+    })
+
+    it('strip white space', function () {
+      const result = requestHandler.getVideoId('   https://youtu.be/ABC12302    ')
+      assert.deepEqual(result, {
+        id: 'ABC12302',
+        service: 'youtube'
+      })
+    })
+
+    it('strip white space', function () {
+      const result = requestHandler.getVideoId('   https://youtu.be/ABC12302    ')
+      assert.deepEqual(result, {
+        id: 'ABC12302',
+        service: 'youtube'
+      })
+    })
+
+    it('nocookie ', function () {
+      const result = requestHandler.getVideoId('http://www.youtube-nocookie.com/ytscreeningroom?v=ABC12300')
+      assert.deepEqual(result, {
+        id: 'ABC12300',
+        service: 'youtube'
+      })
+    })
+
+    it('removes www', function () {
+      const result = requestHandler.getVideoId('https://www.youtu.be/ABC12302')
+      assert.deepEqual(result, {
+        id: 'ABC12302',
+        service: 'youtube'
+      })
+    })
+  })
+
+  // source https://github.com/radiovisual/get-video-id/blob/master/test.js
+  describe('getYouTubeId', function () {
+    it('null case', function () {
+      const result = requestHandler.getYouTubeId()
+      assert.equal(result, '')
+    })
+
+    it('gets metadata from youtube short code formats', () => {
+      assert.equal(requestHandler.getYouTubeId('youtube://ABC12301'), 'ABC12301')
+      assert.equal(requestHandler.getYouTubeId('https://youtu.be/ABC12302'), 'ABC12302')
+      assert.equal(requestHandler.getYouTubeId('http://youtu.be/ABC12303'), 'ABC12303')
+      assert.equal(requestHandler.getYouTubeId('http://youtu.be/ABC12304?feature=youtube_gdata_player'), 'ABC12304')
+    })
+
+    it('handles youtube v= and vi= formats', () => {
+      assert.equal(requestHandler.getYouTubeId('http://www.youtube.com/ytscreeningroom?v=ABC1230'), 'ABC1230')
+      assert.equal(requestHandler.getYouTubeId('https://www.youtube.com/watch?v=ABC12301'), 'ABC12301')
+      assert.equal(requestHandler.getYouTubeId('http://www.youtube.com/watch?v=ABC12302&list=abc123&index=2&feature=plpp_video'), 'ABC12302')
+      assert.equal(requestHandler.getYouTubeId('http://www.youtube.com/watch?v=ABC12303&feature=channel'), 'ABC12303')
+      assert.equal(requestHandler.getYouTubeId('http://www.youtube.com/watch?v=ABC12304&playnext_from=TL&videos=abc123&feature=sub'), 'ABC12304')
+      assert.equal(requestHandler.getYouTubeId('http://www.youtube.com/watch?v=ABC12305&feature=channel'), 'ABC12305')
+      assert.equal(requestHandler.getYouTubeId('http://www.youtube.com/watch?v=ABC12306&playnext_from=TL&videos=abc123&feature=sub'), 'ABC12306')
+      assert.equal(requestHandler.getYouTubeId('http://www.youtube.com/watch?v=ABC12307'), 'ABC12307')
+      assert.equal(requestHandler.getYouTubeId('http://youtube.com/?v=ABC12308&feature=youtube_gdata_player'), 'ABC12308')
+      assert.equal(requestHandler.getYouTubeId('http://youtube.com/?vi=ABC12309&feature=youtube_gdata_player'), 'ABC12309')
+      assert.equal(requestHandler.getYouTubeId('http://youtube.com/watch?v=ABC12310&feature=youtube_gdata_player'), 'ABC12310')
+      assert.equal(requestHandler.getYouTubeId('http://youtube.com/watch?vi=ABC12311&feature=youtube_gdata_player'), 'ABC12311')
+      assert.equal(requestHandler.getYouTubeId('http://www.youtube.com/watch?v=ABC12312&feature=youtube_gdata_player'), 'ABC12312')
+      assert.equal(requestHandler.getYouTubeId('http://www.youtube.com/watch?v=ABC12313&feature=youtu.be'), 'ABC12313')
+    })
+
+    it('handles youtube /v/ and /vi/ formats', () => {
+      assert.equal(requestHandler.getYouTubeId('http://www.youtube.com/v/ABC1230'), 'ABC1230')
+      assert.equal(requestHandler.getYouTubeId('http://youtube.com/v/ABC12301?feature=youtube_gdata_player'), 'ABC12301')
+      assert.equal(requestHandler.getYouTubeId('http://youtube.com/vi/ABC12302?feature=youtube_gdata_player'), 'ABC12302')
+      assert.equal(requestHandler.getYouTubeId('https://i.ytimg.com/vi/0okagl9U2eo/hqdefault.jpg'), '0okagl9U2eo')
+    })
+
+    it('handles youtube image /an_webp/{id}/ formats', () => {
+      assert.equal(requestHandler.getYouTubeId('https://i.ytimg.com/an_webp/MYDcdp-VNmQ/mqdefault_6s.webp'), 'MYDcdp-VNmQ')
+    })
+
+    it('handles youtube /embed/ formats', () => {
+      assert.equal(requestHandler.getYouTubeId('https://www.youtube.com/embed/ABC1230'), 'ABC1230')
+      assert.equal(requestHandler.getYouTubeId('www.youtube-nocookie.com/embed/ABC12301?rel=0'), 'ABC12301')
+      assert.equal(requestHandler.getYouTubeId('http://www.youtube.com/embed/ABC12302?rel=0'), 'ABC12302')
+    })
+
+    it('handles youtube /user/ formats', () => {
+      assert.equal(requestHandler.getYouTubeId('http://www.youtube.com/user/username#p/u/1/ABC1230'), 'ABC1230')
+      assert.equal(requestHandler.getYouTubeId('http://www.youtube.com/user/username#p/a/u/2/ABC12301'), 'ABC12301')
+      assert.equal(requestHandler.getYouTubeId('http://www.youtube.com/user/username#p/u/1/ABC12302?rel=0'), 'ABC12302')
+    })
+
+    it('handles youtube attribution_links', () => {
+      assert.equal(requestHandler.getYouTubeId('http://www.youtube.com/attribution_link?u=%2Fwatch%3Fv%3DABC12300%26feature%3Dshare&a=JdfC0C9V6ZI'), 'ABC12300')
+      assert.equal(requestHandler.getYouTubeId('https://www.youtube.com/attribution_link?a=JdfC0C9V6ZI&u=%2Fwatch%3Fv%3DABC12301%26feature%3Dshare'), 'ABC12301')
+      assert.equal(requestHandler.getYouTubeId('http://www.youtube.com/attribution_link?u=/watch?v=ABC12302&feature=share&list=UUsnCjinFcybOuyJU1NFOJmg&a=LjnCygXKl21WkJdyKu9O-w'), 'ABC12302')
+      assert.equal(requestHandler.getYouTubeId('http://www.youtube.com/attribution_link?u=/watch?v=ABC12303&feature=share&a=9QlmP1yvjcllp0h3l0NwuA'), 'ABC12303')
+      assert.equal(requestHandler.getYouTubeId('http://www.youtube.com/attribution_link?a=fF1CWYwxCQ4&u=/watch?v=ABC12304&feature=em-uploademail'), 'ABC12304')
+      assert.equal(requestHandler.getYouTubeId('http://www.youtube.com/attribution_link?a=fF1CWYwxCQ4&feature=em-uploademail&u=/watch?v=ABC12305'), 'ABC12305')
+    })
+  })
+
+  describe('stripParameters', function () {
+    it('null case', function () {
+      const result = requestHandler.stripParameters()
+      assert.equal(result, '')
+    })
+
+    it('string with parms', function () {
+      const result = requestHandler.stripParameters('this is test')
+      assert.equal(result, 'this is test')
+    })
+
+    it('string with /', function () {
+      const result = requestHandler.stripParameters('this is/test')
+      assert.equal(result, 'this is')
+    })
+
+    it('string with ?', function () {
+      const result = requestHandler.stripParameters('this is?test')
+      assert.equal(result, 'this is')
+    })
+  })
+
+  describe('smartQuotes', function () {
+    it('null case', function () {
+      const result = requestHandler.smartQuotes()
+      assert.equal(result, '')
+    })
+
+    it('regular quote', function () {
+      const result = requestHandler.smartQuotes(`'test'`)
+      assert.equal(result, `‘test’`)
+    })
+
+    it('double quote (start)', function () {
+      const result = requestHandler.smartQuotes(`'test'`)
+      assert.equal(result, `‘test’`)
+    })
+
+    it('double quote (start)', function () {
+      const result = requestHandler.smartQuotes(`this is "test"`)
+      assert.equal(result, `this is “test”`)
+    })
+
+    it('compilation 1', function () {
+      const result = requestHandler.smartQuotes(`Ma'am, this "test" is from '95`)
+      assert.equal(result, `Ma’am, this “test” is from ’95`)
+    })
+
+    it('compilation 2', function () {
+      const result = requestHandler.smartQuotes(`something of 'Something's`)
+      assert.equal(result, `something of ’Something’s`)
+    })
+  })
+
+  describe('removeByPrefix', function () {
+    it('null case', function () {
+      const result = requestHandler.removeByPrefix()
+      assert.equal(result, '')
+    })
+
+    it('case with param null', function () {
+      const result = requestHandler.removeByPrefix(null)
+      assert.equal(result, '')
+    })
+
+    it('removes @ prefix', function () {
+      const result = requestHandler.removeByPrefix('test @this')
+      assert.equal(result, 'test this')
+    })
+
+    it('removes by prefix', function () {
+      const result = requestHandler.removeByPrefix(' by me author')
+      assert.equal(result, 'me author')
+    })
+
+    it('removes BY prefix', function () {
+      const result = requestHandler.removeByPrefix(' BY me author')
+      assert.equal(result, 'me author')
+    })
+  })
+
+  describe('createTitle', function () {
+    it('null case', function () {
+      const result = requestHandler.createTitle()
+      assert.equal(result, '')
+    })
+
+    it('case with param null', function () {
+      const result = requestHandler.createTitle(null)
+      assert.equal(result, '')
+    })
+
+    it('trim string', function () {
+      const result = requestHandler.createTitle('   this is test ')
+      assert.equal(result, 'this is test')
+    })
+
+    it('remove double and more spaces', function () {
+      const result = requestHandler.createTitle('this     is  test     ')
+      assert.equal(result, 'this is test')
+    })
+
+    it('create smart quotes', function () {
+      const result = requestHandler.createTitle(`this "is" test which is 'ok'`)
+      assert.strictEqual(result, `this “is” test which is ‘ok’`)
+    })
+  })
+
+  describe('isAbsoluteUrl', function () {
+    it('null case', function () {
+      const result = requestHandler.isAbsoluteUrl()
+      assert.equal(result, undefined)
+    })
+
+    it('object was send in', function () {
+      const result = requestHandler.isAbsoluteUrl({})
+      assert.equal(result, undefined)
+    })
+
+    it('http url', function () {
+      const result = requestHandler.isAbsoluteUrl('http://clifton.io')
+      assert.equal(result, true)
+    })
+
+    it('http url', function () {
+      const result = requestHandler.isAbsoluteUrl('https://clifton.io')
+      assert.equal(result, true)
+    })
+
+    it('data url', function () {
+      const result = requestHandler.isAbsoluteUrl('data:text/plain;base64,31c4c5flv')
+      assert.equal(result, true)
+    })
+
+    it('file url', function () {
+      const result = requestHandler.isAbsoluteUrl('file://clifton.io')
+      assert.equal(result, true)
+    })
+  })
+
+  describe('resolveUrl', function () {
+    it('null case', function () {
+      const result = requestHandler.resolveUrl()
+      assert.equal(result, null)
+    })
+
+    it('args are not urls', function () {
+      const result = requestHandler.resolveUrl('brave', 'com')
+      assert.equal(result, 'brave')
+    })
+
+    it('we only have base url', function () {
+      const result = requestHandler.resolveUrl('https://brave.com')
+      assert.equal(result, 'https://brave.com')
+    })
+
+    it('relative path is added', function () {
+      const result = requestHandler.resolveUrl('https://brave.com', 'test')
+      assert.equal(result, 'https://brave.com/test')
+    })
+  })
+
+  describe('isString', function () {
+    it('null case', function () {
+      const result = requestHandler.isString()
+      assert.equal(result, false)
+    })
+
+    it('we send object in', function () {
+      const result = requestHandler.isString({})
+      assert.equal(result, false)
+    })
+
+    it('we send number in', function () {
+      const result = requestHandler.isString(10)
+      assert.equal(result, false)
+    })
+
+    it('we send string in', function () {
+      const result = requestHandler.isString('I am string')
+      assert.equal(result, true)
+    })
+  })
+})
diff --git a/tools/test.js b/tools/test.js
index 742d1fdcaa3..8e035b9327b 100644
--- a/tools/test.js
+++ b/tools/test.js
@@ -16,7 +16,7 @@ switch (TEST_DIR) {
     cmd.push('bash tools/codecov.sh')
     break
   default:
-    cmd.push(`mocha "test/${TEST_DIR}/**/*Test.js"`)
+    cmd.push(`mocha "test/${TEST_DIR}/**/*Test.js" --globals chrome,DOMParser,XMLSerializer`)
 }
 
 execute(cmd, process.env, (err) => {