commit 934b2069174d007b7d75faa8bcdf6baafac1ef76 Author: Orzu Ionut Date: Thu May 6 10:58:51 2021 +0300 Initial commit. Render CommonMark. WIP Definitions diff --git a/.coffeelintignore b/.coffeelintignore new file mode 100644 index 0000000..1db51fe --- /dev/null +++ b/.coffeelintignore @@ -0,0 +1 @@ +spec/fixtures diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d4f3de9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +node_modules +npm-debug.log +.github +.idea diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..20cfe51 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,15 @@ +language: objective-c + +notifications: + email: + on_success: never + on_failure: change + +script: 'curl -s https://raw.githubusercontent.com/atom/ci/master/build-package.sh | sh' + +git: + depth: 10 + +branches: + only: + - master diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..0fd0ad6 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1 @@ +See the [Atom contributing guide](https://github.com/atom/atom/blob/master/CONTRIBUTING.md) diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..b60bb86 --- /dev/null +++ b/ISSUE_TEMPLATE.md @@ -0,0 +1,40 @@ + + +### Prerequisites + +* [ ] Put an X between the brackets on this line if you have done all of the following: + * Reproduced the problem in Safe Mode: http://flight-manual.atom.io/hacking-atom/sections/debugging/#using-safe-mode + * Followed all applicable steps in the debugging guide: http://flight-manual.atom.io/hacking-atom/sections/debugging/ + * Checked the FAQs on the message board for common solutions: https://discuss.atom.io/c/faq + * Checked that your issue isn't already filed: https://github.com/issues?utf8=✓&q=is%3Aissue+user%3Aatom + * Checked that there is not already an Atom package that provides the described functionality: https://atom.io/packages + +### Description + +[Description of the issue] + +### Steps to Reproduce + +1. [First Step] +2. [Second Step] +3. [and so on...] + +**Expected behavior:** [What you expect to happen] + +**Actual behavior:** [What actually happens] + +**Reproduces how often:** [What percentage of the time does it reproduce?] + +### Versions + +You can get this information from copy and pasting the output of `atom --version` and `apm --version` from the command line. Also, please include the OS and what version of the OS you're running. + +### Additional Information + +Any additional information, configuration or data that might be necessary to reproduce the issue. diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..204b93d --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,19 @@ +MIT License Copyright (c) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS +OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..cdaa94a --- /dev/null +++ b/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,28 @@ +### Requirements + +* Filling out the template is required. Any pull request that does not include enough information to be reviewed in a timely manner may be closed at the maintainers' discretion. +* All new code requires tests to ensure against regressions + +### Description of the Change + + + +### Alternate Designs + + + +### Benefits + + + +### Possible Drawbacks + + + +### Applicable Issues + + diff --git a/README.md b/README.md new file mode 100644 index 0000000..c8ad110 --- /dev/null +++ b/README.md @@ -0,0 +1,8 @@ +# LegAtom package +Developing a legal IDE based on Atom + +## This package is a fork of the [markdown-preview](https://github.com/atom/markdown-preview) package. + +Show the rendered HTML CommonMark to the right of the current editor using ctrl-shift-m. + +It is currently enabled for `.markdown`, `.md`, `.mdown`, `.mkd`, `.mkdown`, `.ron`, and `.txt` files. diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 0000000..6856fdc --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,27 @@ +platform: + - x64 + - x86 + +branches: + only: + - master + +clone_depth: 10 + +skip_tags: true + +environment: + APM_TEST_PACKAGES: + + matrix: + - ATOM_CHANNEL: stable + - ATOM_CHANNEL: beta + +install: + - ps: Install-Product node 6 + +build_script: + - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/atom/ci/master/build-package.ps1')) + +test: off +deploy: off diff --git a/assets/hr.png b/assets/hr.png new file mode 100644 index 0000000..3e0e9c9 Binary files /dev/null and b/assets/hr.png differ diff --git a/assets/primer-markdown.less b/assets/primer-markdown.less new file mode 100644 index 0000000..cea32ad --- /dev/null +++ b/assets/primer-markdown.less @@ -0,0 +1,448 @@ +// All of our block level items should have the same margin +@margin: 16px; + +// This is styling for generic markdownized text. Anything you put in a +// container with .markdown-body on it should render generally well. It also +// includes some GitHub Flavored Markdown specific styling (like @mentions) +.markdown-body { + overflow: hidden; + font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif; + font-size: 16px; + line-height: 1.6; + word-wrap: break-word; + + > *:first-child { + margin-top: 0 !important; + } + + > *:last-child { + margin-bottom: 0 !important; + } + + // Anchors like . These sometimes end up wrapped around + // text when users mistakenly forget to close the tag or use self-closing tag + // syntax. We don't want them to appear like links. + // FIXME: a:not(:link):not(:visited) would be a little clearer here (and + // possibly faster to match), but it breaks styling of elements due + // to https://bugs.webkit.org/show_bug.cgi?id=142737. + a:not([href]) { + color: inherit; + text-decoration: none; + } + + // Link Colors + .absent { + color: #c00; + } + + .anchor { + position: absolute; + top: 0; + left: 0; + display: block; + padding-right: 6px; + padding-left: 30px; + margin-left: -30px; + + &:focus { + outline: none; + } + } + + // Headings + h1, h2, h3, h4, h5, h6 { + position: relative; + margin-top: 1em; + margin-bottom: @margin; + font-weight: bold; + line-height: 1.4; + + .octicon-link { + display: none; + color: #000; + vertical-align: middle; + } + + &:hover .anchor { + padding-left: 8px; + margin-left: -30px; + text-decoration: none; + + .octicon-link { + display: inline-block; + } + } + + tt, + code { + font-size: inherit; + } + } + + h1 { + padding-bottom: 0.3em; + font-size: 2.25em; + line-height: 1.2; + border-bottom: 1px solid #eee; + + .anchor { + line-height: 1; + } + } + + h2 { + padding-bottom: 0.3em; + font-size: 1.75em; + line-height: 1.225; + border-bottom: 1px solid #eee; + + .anchor { + line-height: 1; + } + } + + h3 { + font-size: 1.5em; + line-height: 1.43; + + .anchor { + line-height: 1.2; + } + } + + h4 { + font-size: 1.25em; + + .anchor { + line-height: 1.2; + } + } + + h5 { + font-size: 1em; + + .anchor { + line-height: 1.1; + } + } + + h6 { + font-size: 1em; + color: #777; + + .anchor { + line-height: 1.1; + } + } + + p, + blockquote, + ul, ol, dl, + table, + pre { + margin-top: 0; + margin-bottom: @margin; + } + + hr { + height: 4px; + padding: 0; + margin: @margin 0; + background-color: #e7e7e7; + border: 0 none; + } + + // Lists, Blockquotes & Such + ul, + ol { + padding-left: 2em; + + &.no-list { + padding: 0; + list-style-type: none; + } + } + + // Did someone complain about list spacing? Encourage them + // to create the spacing with their markdown formatting. + // List behavior should be controled by the markup, not the css. + // + // For lists with padding between items, use blank + // lines between items. This will generate paragraphs with + // padding to space things out. + // + // - item + // + // - item + // + // - item + // + // For list without padding, don't use blank lines. + // + // - item + // - item + // - item + // + // Modifying the css to emulate these behaviors merely brakes + // one case in the process of solving another. Don't change + // this unless it's really really a bug. + ul ul, + ul ol, + ol ol, + ol ul { + margin-top: 0; + margin-bottom: 0; + } + + li > p { + margin-top: @margin; + } + + dl { + padding: 0; + } + + dl dt { + padding: 0; + margin-top: @margin; + font-size: 1em; + font-style: italic; + font-weight: bold; + } + + dl dd { + padding: 0 @margin; + margin-bottom: @margin; + } + + blockquote { + padding: 0 15px; + color: #777; + border-left: 4px solid #ddd; + + > :first-child { + margin-top: 0; + } + + > :last-child { + margin-bottom: 0; + } + } + + // Tables + table { + display: block; + width: 100%; + overflow: auto; + word-break: normal; + word-break: keep-all; // For Firefox to horizontally scroll wider tables. + + th { + font-weight: bold; + } + + th, td { + padding: 6px 13px; + border: 1px solid #ddd; + } + + tr { + background-color: #fff; + border-top: 1px solid #ccc; + + &:nth-child(2n) { + background-color: #f8f8f8; + } + } + } + + // Images & Stuff + img { + max-width: 100%; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + + .emoji { + max-width: none; + } + + // Gollum Image Tags + + // Framed + span.frame { + display: block; + overflow: hidden; + + & > span { + display: block; + float: left; + width: auto; + padding: 7px; + margin: 13px 0 0; + overflow: hidden; + border: 1px solid #ddd; + } + + span img { + display: block; + float: left; + } + + span span { + display: block; + padding: 5px 0 0; + clear: both; + color: #333; + } + } + + span.align-center { + display: block; + overflow: hidden; + clear: both; + + & > span { + display: block; + margin: 13px auto 0; + overflow: hidden; + text-align: center; + } + + span img { + margin: 0 auto; + text-align: center; + } + } + + span.align-right { + display: block; + overflow: hidden; + clear: both; + + & > span { + display: block; + margin: 13px 0 0; + overflow: hidden; + text-align: right; + } + + span img { + margin: 0; + text-align: right; + } + } + + span.float-left { + display: block; + float: left; + margin-right: 13px; + overflow: hidden; + + span { + margin: 13px 0 0; + } + } + + span.float-right { + display: block; + float: right; + margin-left: 13px; + overflow: hidden; + + & > span { + display: block; + margin: 13px auto 0; + overflow: hidden; + text-align: right; + } + } + + // Inline code snippets + code, + tt { + padding: 0; + padding-top: 0.2em; + padding-bottom: 0.2em; + margin: 0; + font-size: 85%; + background-color: rgba(0,0,0,0.04); + border-radius: 3px; // don't add padding, gives scrollbars + + &:before, + &:after { + letter-spacing: -0.2em; // this creates padding + content: "\00a0"; + } + + br { display: none; } + } + + del code { text-decoration: inherit; } + + // Code tags within code blocks (
s)
+  pre > code {
+    padding: 0;
+    margin: 0;
+    font-size: 100%;
+    word-break: normal;
+    white-space: pre;
+    background: transparent;
+    border: 0;
+  }
+
+  .highlight {
+    margin-bottom: @margin;
+  }
+
+  .highlight pre,
+  pre {
+    padding: @margin;
+    overflow: auto;
+    font-size: 85%;
+    line-height: 1.45;
+    background-color: #f7f7f7;
+    border-radius: 3px;
+  }
+
+  .highlight pre {
+    margin-bottom: 0;
+    word-break: normal;
+  }
+
+  pre {
+    word-wrap: normal;
+  }
+
+  pre code,
+  pre tt {
+    display: inline;
+    max-width: initial;
+    padding: 0;
+    margin: 0;
+    overflow: initial;
+    line-height: inherit;
+    word-wrap: normal;
+    background-color: transparent;
+    border: 0;
+
+    &:before,
+    &:after {
+      content: normal;
+    }
+  }
+
+  kbd {
+    display: inline-block;
+    padding: 3px 5px;
+    font-size: 11px;
+    line-height: 10px;
+    color: #555;
+    vertical-align: middle;
+    background-color: #fcfcfc;
+    border: solid 1px #ccc;
+    border-bottom-color: #bbb;
+    border-radius: 3px;
+    box-shadow: inset 0 -1px 0 #bbb;
+  }
+}
diff --git a/coffeelint.json b/coffeelint.json
new file mode 100644
index 0000000..a5dd715
--- /dev/null
+++ b/coffeelint.json
@@ -0,0 +1,37 @@
+{
+  "max_line_length": {
+    "level": "ignore"
+  },
+  "no_empty_param_list": {
+    "level": "error"
+  },
+  "arrow_spacing": {
+    "level": "error"
+  },
+  "no_interpolation_in_single_quotes": {
+    "level": "error"
+  },
+  "no_debugger": {
+    "level": "error"
+  },
+  "prefer_english_operator": {
+    "level": "error"
+  },
+  "colon_assignment_spacing": {
+    "spacing": {
+      "left": 0,
+      "right": 1
+    },
+    "level": "error"
+  },
+  "braces_spacing": {
+    "spaces": 0,
+    "level": "error"
+  },
+  "spacing_after_comma": {
+    "level": "error"
+  },
+  "no_stand_alone_at": {
+    "level": "error"
+  }
+}
diff --git a/keymaps/markdown-preview.cson b/keymaps/markdown-preview.cson
new file mode 100644
index 0000000..79a9fa3
--- /dev/null
+++ b/keymaps/markdown-preview.cson
@@ -0,0 +1,18 @@
+'atom-text-editor':
+  'ctrl-shift-m': 'markdown-preview:toggle'
+
+'.platform-darwin .markdown-preview':
+  'cmd-a': 'markdown-preview:select-all'
+  'cmd-+': 'markdown-preview:zoom-in'
+  'cmd-=': 'markdown-preview:zoom-in'
+  'cmd--': 'markdown-preview:zoom-out'
+  'cmd-_': 'markdown-preview:zoom-out'
+  'cmd-0': 'markdown-preview:reset-zoom'
+
+'.platform-win32 .markdown-preview, .platform-linux .markdown-preview':
+  'ctrl-a': 'markdown-preview:select-all'
+  'ctrl-+': 'markdown-preview:zoom-in'
+  'ctrl-=': 'markdown-preview:zoom-in'
+  'ctrl--': 'markdown-preview:zoom-out'
+  'ctrl-_': 'markdown-preview:zoom-out'
+  'ctrl-0': 'markdown-preview:reset-zoom'
diff --git a/lib/definitions.js b/lib/definitions.js
new file mode 100644
index 0000000..356d043
--- /dev/null
+++ b/lib/definitions.js
@@ -0,0 +1,203 @@
+module.exports = class Definitions {
+  constructor (editor) {
+    this.editor = editor
+    this.alreadyAlerted = ''
+
+    this.init()
+  }
+
+  init () {
+    this.definitions = {}
+    this.definitionParagraphsInClause = []
+    this.usedDefinitions = {}
+    this.definedDefinitions = {}
+    this.undefinedDefinitions = {}
+    this.otherDefinitions = {}
+    this.definitionClauseContent = ''
+    this.definitionClauseEndIndex = null
+  }
+
+  boot () {
+    this.init()
+
+    const success = this.getDefinitionClause()
+    if (!success) {
+      return
+    }
+
+    this.setUsedDefinitions()
+    this.setDefinitions()
+    this.setDefinedDefinitions()
+  }
+
+  getDefinitionClause () {
+    const content = this.editor.getText()
+    const reg = /(# Definitions)([a-z]*[A-Z]*[ ]*)*/g
+    const result = [...content.matchAll(reg)]
+
+    if (result.length === 0) {
+      const message = 'There is no definition clause defined.'
+
+      if (!this.alreadyAlerted || message !== this.alreadyAlerted) {
+        alert(message)
+        this.alreadyAlerted = 'message'
+      }
+
+      return false
+    }
+
+    if (result.length > 1) {
+      const message = `There are ${result.length} definition clauses. There should only be one.`
+
+      if (!this.alreadyAlerted || message !== this.alreadyAlerted) {
+        alert(message)
+        this.alreadyAlerted = message
+      }
+
+      return false
+    }
+
+    // Definition clause index
+    const index = result[0].index
+    let text = content.substring(index)
+    // Text containing the Definition clause heading
+    let startText = result[0][0]
+    this.definitionClauseEndIndex = index + startText.length
+    // Remove the text containing the Definition clause heading so we can look for the next clause
+    text = text.substring(startText.length)
+
+    const nextClauseReg = /[^#]# ([a-z]*[A-Z]*)*/g
+    const nextClauseResult = [...text.matchAll(nextClauseReg)]
+    let nextClauseIndex = nextClauseResult.length > 0 ? nextClauseResult[0].index : text.length
+
+    text = text.substring(0, nextClauseIndex)
+    // Build the full content of the Definition clause
+    this.definitionClauseContent = startText.concat(text)
+
+    return true
+  }
+
+  setUsedDefinitions () {
+    const content = this.editor.getText()
+    const reg = /_([^_\n]*)_/g
+
+    for (let match of content.matchAll(reg)) {
+      if (!match[1]) {
+        continue
+      }
+
+      if (!this.usedDefinitions.hasOwnProperty(match[1])) {
+        this.usedDefinitions[match[1]] = []
+      }
+
+      this.usedDefinitions[match[1]].push(match.index)
+    }
+  }
+
+  setDefinitions () {
+    const content = this.editor.getText()
+    const reg = /\*\*([^**\n]*)\*\*/g
+
+    for (let match of content.matchAll(reg)) {
+      if (!match[1]) {
+        continue
+      }
+
+      if (!this.definitions.hasOwnProperty(match[1])) {
+        this.definitions[match[1]] = []
+      }
+
+      this.definitions[match[1]].push(match.index)
+    }
+  }
+
+  setDefinedDefinitions () {
+    const regex = /## (.)*\n/g
+    const definitionParagraphsInClause = this.definitionClauseContent.matchAll(regex)
+    const definitionsMapper = JSON.parse(JSON.stringify(this.definitions))
+
+    for (let definitionParagraph of definitionParagraphsInClause) {
+      if (definitionParagraph && definitionParagraph[0]) {
+        this.definitionParagraphsInClause.push(definitionParagraph)
+
+        let definitionContent = definitionParagraph[0]
+        let found = false
+
+        for (let definition of Object.keys(definitionsMapper)) {
+          const definitionToSearch = `**${definition}** means `
+          let index = definitionContent.indexOf(definitionToSearch)
+
+          if (index !== -1) {
+            let definitionExtracted = definitionContent.substring(index + definitionToSearch.length)
+            definitionExtracted = definitionExtracted.replace('[', '')
+            definitionExtracted = definitionExtracted.replace(']', '')
+            definitionExtracted = definitionExtracted.trim()
+
+            if (definitionExtracted.length > 0) {
+              this.definedDefinitions[definition] = definitionExtracted
+            } else {
+              this.undefinedDefinitions[definition] = true
+            }
+
+            delete definitionsMapper[definition]
+
+            found = true
+            break
+          }
+          // let results = definitionContent.match(new RegExp(`(${definition} means )([[(.)*]])`))
+          // if (results && results[0]) {
+          //
+          //
+          // }
+        }
+
+        if (!found) {
+          this.otherDefinitions[definitionContent] = true
+        }
+      }
+    }
+
+    if (Object.keys(definitionsMapper).length > 0) {
+      this.insertDefinitions(Object.keys(definitionsMapper))
+
+      // Refresh this because it contains more definition paragraphs
+      this.getDefinitionClause()
+    }
+  }
+
+  insertDefinitions (definitions) {
+    let currentRow = this.getRowPositionToInsertDefinitions()
+    const currentPosition = this.editor.getCursorBufferPosition()
+
+    for (let definition of definitions) {
+      this.editor.setCursorBufferPosition([currentRow, 0])
+      this.editor.insertText(`## **${definition}** means []\n`)
+      currentRow = currentRow + 1
+
+      this.undefinedDefinitions[definition] = true
+    }
+
+    this.editor.setCursorBufferPosition(currentPosition)
+  }
+
+  getRowPositionToInsertDefinitions () {
+    const content = this.editor.getText()
+    const reg = /\n/g
+    const results = content.matchAll(reg)
+    let linesCount = 0
+
+    for (let result of results) {
+      if (result.index === this.definitionClauseEndIndex) {
+        return linesCount + 1 + this.definitionParagraphsInClause.length
+      } else {
+        linesCount = linesCount + 1
+      }
+    }
+
+    return linesCount
+  }
+
+  getDefinedDefinitions () {
+    return Object.keys(this.definedDefinitions)
+  }
+}
diff --git a/lib/extension-helper.js b/lib/extension-helper.js
new file mode 100644
index 0000000..a2a464e
--- /dev/null
+++ b/lib/extension-helper.js
@@ -0,0 +1,50 @@
+const scopesByFenceName = {
+  bash: 'source.shell',
+  sh: 'source.shell',
+  powershell: 'source.powershell',
+  ps1: 'source.powershell',
+  c: 'source.c',
+  'c++': 'source.cpp',
+  cpp: 'source.cpp',
+  coffee: 'source.coffee',
+  'coffee-script': 'source.coffee',
+  coffeescript: 'source.coffee',
+  cs: 'source.cs',
+  csharp: 'source.cs',
+  css: 'source.css',
+  sass: 'source.sass',
+  scss: 'source.css.scss',
+  erlang: 'source.erl',
+  go: 'source.go',
+  html: 'text.html.basic',
+  java: 'source.java',
+  javascript: 'source.js',
+  js: 'source.js',
+  json: 'source.json',
+  less: 'source.less',
+  mustache: 'text.html.mustache',
+  objc: 'source.objc',
+  'objective-c': 'source.objc',
+  php: 'text.html.php',
+  py: 'source.python',
+  python: 'source.python',
+  rb: 'source.ruby',
+  ruby: 'source.ruby',
+  text: 'text.plain',
+  toml: 'source.toml',
+  ts: 'source.ts',
+  typescript: 'source.ts',
+  xml: 'text.xml',
+  yaml: 'source.yaml',
+  yml: 'source.yaml'
+}
+
+module.exports = {
+  scopeForFenceName (fenceName) {
+    fenceName = fenceName.toLowerCase()
+
+    return scopesByFenceName.hasOwnProperty(fenceName)
+      ? scopesByFenceName[fenceName]
+      : `source.${fenceName}`
+  }
+}
diff --git a/lib/main.js b/lib/main.js
new file mode 100644
index 0000000..82dbc17
--- /dev/null
+++ b/lib/main.js
@@ -0,0 +1,279 @@
+const fs = require('fs-plus')
+const { CompositeDisposable } = require('atom')
+const SuggestedDefinition = require('./suggested-definition')
+
+let MarkdownPreviewView = null
+let renderer = null
+let Definitions = null
+let definitionsMapper = {}
+
+const isMarkdownPreviewView = function (object) {
+  if (MarkdownPreviewView == null) {
+    MarkdownPreviewView = require('./markdown-preview-view')
+  }
+
+  return object instanceof MarkdownPreviewView
+}
+
+const getDefinitionsHandler = function (editor) {
+  if (Definitions == null) {
+    Definitions = require('./definitions')
+  }
+
+  return new Definitions(editor)
+}
+
+module.exports = {
+  suggestedDefinitionView: null,
+  modalPanel: null,
+
+  activate (state) {
+    this.disposables = new CompositeDisposable()
+    this.commandSubscriptions = new CompositeDisposable()
+
+    this.disposables.add(
+      atom.config.observe('markdown-preview.grammars', grammars => {
+        this.commandSubscriptions.dispose()
+        this.commandSubscriptions = new CompositeDisposable()
+
+        if (grammars == null) {
+          grammars = []
+        }
+
+        for (const grammar of grammars.map(grammar =>
+          grammar.replace(/\./g, ' ')
+        )) {
+          this.commandSubscriptions.add(
+            atom.commands.add(`atom-text-editor[data-grammar='${grammar}']`, {
+              'markdown-preview:toggle': () => this.toggle(),
+              'markdown-preview:copy-html': {
+                displayName: 'Markdown Preview: Copy HTML',
+                didDispatch: () => this.copyHTML()
+              },
+              'markdown-preview:save-as-html': {
+                displayName: 'Markdown Preview: Save as HTML',
+                didDispatch: () => this.saveAsHTML()
+              },
+              'markdown-preview:toggle-break-on-single-newline': () => {
+                const keyPath = 'markdown-preview.breakOnSingleNewline'
+                atom.config.set(keyPath, !atom.config.get(keyPath))
+              },
+              'markdown-preview:toggle-github-style': () => {
+                const keyPath = 'markdown-preview.useGitHubStyle'
+                atom.config.set(keyPath, !atom.config.get(keyPath))
+              }
+            })
+          )
+        }
+      })
+    )
+
+    const previewFile = this.previewFile.bind(this)
+    for (const extension of [
+      'markdown',
+      'md',
+      'mdown',
+      'mkd',
+      'mkdown',
+      'ron',
+      'txt'
+    ]) {
+      this.disposables.add(
+        atom.commands.add(
+          `.tree-view .file .name[data-name$=\\.${extension}]`,
+          'markdown-preview:preview-file',
+          previewFile
+        )
+      )
+    }
+
+    this.disposables.add(
+      atom.workspace.addOpener(uriToOpen => {
+        let [protocol, path] = uriToOpen.split('://')
+        if (protocol !== 'markdown-preview') {
+          return
+        }
+
+        try {
+          path = decodeURI(path)
+        } catch (error) {
+          return
+        }
+
+        if (path.startsWith('editor/')) {
+          return this.createMarkdownPreviewView({ editorId: path.substring(7) })
+        } else {
+          return this.createMarkdownPreviewView({ filePath: path })
+        }
+      })
+    )
+
+    this.suggestedDefinitionView = new SuggestedDefinition()
+
+    this.disposables.add(
+      atom.workspace.observeTextEditors(editor => {
+        if (editor.buffer && editor.buffer.file) {
+          const path = editor.buffer.file.path.split('.').pop()
+
+          if (path === 'md') { // @TODO Custom extension? Otherwise all markdown files will be handled.
+            this.bootContractHandler(editor)
+          }
+        }
+      })
+    )
+  },
+
+  deactivate () {
+    this.modalPanel.destroy()
+    this.disposables.dispose()
+    this.commandSubscriptions.dispose()
+    this.suggestedDefinitionView.destroy()
+  },
+
+  serialize () {},
+
+  createMarkdownPreviewView (state) {
+    if (state.editorId || fs.isFileSync(state.filePath)) {
+      if (MarkdownPreviewView == null) {
+        MarkdownPreviewView = require('./markdown-preview-view')
+      }
+      return new MarkdownPreviewView(state)
+    }
+  },
+
+  toggle () {
+    if (isMarkdownPreviewView(atom.workspace.getActivePaneItem())) {
+      atom.workspace.destroyActivePaneItem()
+      return
+    }
+
+    const editor = atom.workspace.getActiveTextEditor()
+    if (editor == null) {
+      return
+    }
+
+    const grammars = atom.config.get('markdown-preview.grammars') || []
+    if (!grammars.includes(editor.getGrammar().scopeName)) {
+      return
+    }
+
+    if (!this.removePreviewForEditor(editor)) {
+      return this.addPreviewForEditor(editor)
+    }
+  },
+
+  uriForEditor (editor) {
+    return `markdown-preview://editor/${editor.id}`
+  },
+
+  removePreviewForEditor (editor) {
+    const uri = this.uriForEditor(editor)
+    const previewPane = atom.workspace.paneForURI(uri)
+    if (previewPane != null) {
+      previewPane.destroyItem(previewPane.itemForURI(uri))
+      return true
+    } else {
+      return false
+    }
+  },
+
+  addPreviewForEditor (editor) {
+    const uri = this.uriForEditor(editor)
+    const previousActivePane = atom.workspace.getActivePane()
+    const options = { searchAllPanes: true }
+    if (atom.config.get('markdown-preview.openPreviewInSplitPane')) {
+      options.split = 'right'
+    }
+
+    return atom.workspace
+      .open(uri, options)
+      .then(function (markdownPreviewView) {
+        if (isMarkdownPreviewView(markdownPreviewView)) {
+          previousActivePane.activate()
+        }
+      })
+  },
+
+  previewFile ({ target }) {
+    const filePath = target.dataset.path
+    if (!filePath) {
+      return
+    }
+
+    for (const editor of atom.workspace.getTextEditors()) {
+      if (editor.getPath() === filePath) {
+        return this.addPreviewForEditor(editor)
+      }
+    }
+
+    atom.workspace.open(`markdown-preview://${encodeURI(filePath)}`, {
+      searchAllPanes: true
+    })
+  },
+
+  async copyHTML () {
+    const editor = atom.workspace.getActiveTextEditor()
+    if (editor == null) {
+      return
+    }
+
+    if (renderer == null) {
+      renderer = require('./renderer')
+    }
+    const text = editor.getSelectedText() || editor.getText()
+    const html = await renderer.toHTML(
+      text,
+      editor.getPath(),
+      editor.getGrammar()
+    )
+
+    atom.clipboard.write(html)
+  },
+
+  saveAsHTML () {
+    const activePaneItem = atom.workspace.getActivePaneItem()
+    if (isMarkdownPreviewView(activePaneItem)) {
+      atom.workspace.getActivePane().saveItemAs(activePaneItem)
+      return
+    }
+
+    const editor = atom.workspace.getActiveTextEditor()
+    if (editor == null) {
+      return
+    }
+
+    const grammars = atom.config.get('markdown-preview.grammars') || []
+    if (!grammars.includes(editor.getGrammar().scopeName)) {
+      return
+    }
+
+    const uri = this.uriForEditor(editor)
+    const markdownPreviewPane = atom.workspace.paneForURI(uri)
+    const markdownPreviewPaneItem =
+      markdownPreviewPane != null
+        ? markdownPreviewPane.itemForURI(uri)
+        : undefined
+
+    if (isMarkdownPreviewView(markdownPreviewPaneItem)) {
+      return markdownPreviewPane.saveItemAs(markdownPreviewPaneItem)
+    }
+  },
+
+  bootContractHandler (editor) {
+    definitionsMapper[editor.id] = getDefinitionsHandler(editor)
+    definitionsMapper[editor.id].boot()
+
+    setInterval(() => {
+      definitionsMapper[editor.id].boot()
+    }, 5000)
+
+    const editorView = atom.views.getView(editor)
+    editorView.addEventListener('keypress', (event) => {
+      if (event.keyCode !== 95) {
+        return
+      }
+
+      this.suggestedDefinitionView.show(editor, definitionsMapper[editor.id].getDefinedDefinitions())
+    })
+  }
+}
diff --git a/lib/markdown-preview-view.js b/lib/markdown-preview-view.js
new file mode 100644
index 0000000..40ee87b
--- /dev/null
+++ b/lib/markdown-preview-view.js
@@ -0,0 +1,513 @@
+const path = require('path')
+
+const { Emitter, Disposable, CompositeDisposable, File } = require('atom')
+const _ = require('underscore-plus')
+const fs = require('fs-plus')
+
+const renderer = require('./renderer')
+
+module.exports = class MarkdownPreviewView {
+  static deserialize (params) {
+    return new MarkdownPreviewView(params)
+  }
+
+  constructor ({ editorId, filePath }) {
+    this.editorId = editorId
+    this.filePath = filePath
+    this.element = document.createElement('div')
+    this.element.classList.add('markdown-preview')
+    this.element.tabIndex = -1
+    this.emitter = new Emitter()
+    this.loaded = false
+    this.disposables = new CompositeDisposable()
+    this.registerScrollCommands()
+    if (this.editorId != null) {
+      this.resolveEditor(this.editorId)
+    } else if (atom.packages.hasActivatedInitialPackages()) {
+      this.subscribeToFilePath(this.filePath)
+    } else {
+      this.disposables.add(
+        atom.packages.onDidActivateInitialPackages(() => {
+          this.subscribeToFilePath(this.filePath)
+        })
+      )
+    }
+  }
+
+  serialize () {
+    return {
+      deserializer: 'MarkdownPreviewView',
+      filePath: this.getPath() != null ? this.getPath() : this.filePath,
+      editorId: this.editorId
+    }
+  }
+
+  copy () {
+    return new MarkdownPreviewView({
+      editorId: this.editorId,
+      filePath: this.getPath() != null ? this.getPath() : this.filePath
+    })
+  }
+
+  destroy () {
+    this.disposables.dispose()
+    this.element.remove()
+  }
+
+  registerScrollCommands () {
+    this.disposables.add(
+      atom.commands.add(this.element, {
+        'core:move-up': () => {
+          this.element.scrollTop -= document.body.offsetHeight / 20
+        },
+        'core:move-down': () => {
+          this.element.scrollTop += document.body.offsetHeight / 20
+        },
+        'core:page-up': () => {
+          this.element.scrollTop -= this.element.offsetHeight
+        },
+        'core:page-down': () => {
+          this.element.scrollTop += this.element.offsetHeight
+        },
+        'core:move-to-top': () => {
+          this.element.scrollTop = 0
+        },
+        'core:move-to-bottom': () => {
+          this.element.scrollTop = this.element.scrollHeight
+        }
+      })
+    )
+  }
+
+  onDidChangeTitle (callback) {
+    return this.emitter.on('did-change-title', callback)
+  }
+
+  onDidChangeModified (callback) {
+    // No op to suppress deprecation warning
+    return new Disposable()
+  }
+
+  onDidChangeMarkdown (callback) {
+    return this.emitter.on('did-change-markdown', callback)
+  }
+
+  subscribeToFilePath (filePath) {
+    this.file = new File(filePath)
+    this.emitter.emit('did-change-title')
+    this.disposables.add(
+      this.file.onDidRename(() => this.emitter.emit('did-change-title'))
+    )
+    this.handleEvents()
+    return this.renderMarkdown()
+  }
+
+  resolveEditor (editorId) {
+    const resolve = () => {
+      this.editor = this.editorForId(editorId)
+
+      if (this.editor != null) {
+        this.emitter.emit('did-change-title')
+        this.disposables.add(
+          this.editor.onDidDestroy(() =>
+            this.subscribeToFilePath(this.getPath())
+          )
+        )
+        this.handleEvents()
+        this.renderMarkdown()
+      } else {
+        this.subscribeToFilePath(this.filePath)
+      }
+    }
+
+    if (atom.packages.hasActivatedInitialPackages()) {
+      resolve()
+    } else {
+      this.disposables.add(atom.packages.onDidActivateInitialPackages(resolve))
+    }
+  }
+
+  editorForId (editorId) {
+    for (const editor of atom.workspace.getTextEditors()) {
+      if (editor.id != null && editor.id.toString() === editorId.toString()) {
+        return editor
+      }
+    }
+    return null
+  }
+
+  handleEvents () {
+    const lazyRenderMarkdown = _.debounce(() => this.renderMarkdown(), 250)
+    this.disposables.add(
+      atom.grammars.onDidAddGrammar(() => lazyRenderMarkdown())
+    )
+    if (typeof atom.grammars.onDidRemoveGrammar === 'function') {
+      this.disposables.add(
+        atom.grammars.onDidRemoveGrammar(() => lazyRenderMarkdown())
+      )
+    } else {
+      // TODO: Remove onDidUpdateGrammar hook once onDidRemoveGrammar is released
+      this.disposables.add(
+        atom.grammars.onDidUpdateGrammar(() => lazyRenderMarkdown())
+      )
+    }
+
+    atom.commands.add(this.element, {
+      'core:copy': event => {
+        event.stopPropagation()
+        return this.copyToClipboard()
+      },
+      'markdown-preview:select-all': () => {
+        this.selectAll()
+      },
+      'markdown-preview:zoom-in': () => {
+        const zoomLevel = parseFloat(getComputedStyle(this.element).zoom)
+        this.element.style.zoom = zoomLevel + 0.1
+      },
+      'markdown-preview:zoom-out': () => {
+        const zoomLevel = parseFloat(getComputedStyle(this.element).zoom)
+        this.element.style.zoom = zoomLevel - 0.1
+      },
+      'markdown-preview:reset-zoom': () => {
+        this.element.style.zoom = 1
+      },
+      'markdown-preview:toggle-break-on-single-newline' () {
+        const keyPath = 'markdown-preview.breakOnSingleNewline'
+        atom.config.set(keyPath, !atom.config.get(keyPath))
+      },
+      'markdown-preview:toggle-github-style' () {
+        const keyPath = 'markdown-preview.useGitHubStyle'
+        atom.config.set(keyPath, !atom.config.get(keyPath))
+      }
+    })
+
+    const changeHandler = () => {
+      this.renderMarkdown()
+
+      const pane = atom.workspace.paneForItem(this)
+      if (pane != null && pane !== atom.workspace.getActivePane()) {
+        pane.activateItem(this)
+      }
+    }
+
+    if (this.file) {
+      this.disposables.add(this.file.onDidChange(changeHandler))
+    } else if (this.editor) {
+      this.disposables.add(
+        this.editor.getBuffer().onDidStopChanging(function () {
+          if (atom.config.get('markdown-preview.liveUpdate')) {
+            changeHandler()
+          }
+        })
+      )
+      this.disposables.add(
+        this.editor.onDidChangePath(() => this.emitter.emit('did-change-title'))
+      )
+      this.disposables.add(
+        this.editor.getBuffer().onDidSave(function () {
+          if (!atom.config.get('markdown-preview.liveUpdate')) {
+            changeHandler()
+          }
+        })
+      )
+      this.disposables.add(
+        this.editor.getBuffer().onDidReload(function () {
+          if (!atom.config.get('markdown-preview.liveUpdate')) {
+            changeHandler()
+          }
+        })
+      )
+    }
+
+    this.disposables.add(
+      atom.config.onDidChange(
+        'markdown-preview.breakOnSingleNewline',
+        changeHandler
+      )
+    )
+
+    this.disposables.add(
+      atom.config.observe('markdown-preview.useGitHubStyle', useGitHubStyle => {
+        if (useGitHubStyle) {
+          this.element.setAttribute('data-use-github-style', '')
+        } else {
+          this.element.removeAttribute('data-use-github-style')
+        }
+      })
+    )
+
+    document.onselectionchange = () => {
+      const selection = window.getSelection()
+      const selectedNode = selection.baseNode
+      if (
+        selectedNode === null ||
+        this.element === selectedNode ||
+        this.element.contains(selectedNode)
+      ) {
+        if (selection.isCollapsed) {
+          this.element.classList.remove('has-selection')
+        } else {
+          this.element.classList.add('has-selection')
+        }
+      }
+    }
+  }
+
+  renderMarkdown () {
+    if (!this.loaded) {
+      this.showLoading()
+    }
+    return this.getMarkdownSource()
+      .then(source => {
+        if (source != null) {
+          return this.renderMarkdownText(source)
+        }
+      })
+      .catch(reason => this.showError({ message: reason }))
+  }
+
+  getMarkdownSource () {
+    if (this.file && this.file.getPath()) {
+      return this.file
+        .read()
+        .then(source => {
+          if (source === null) {
+            return Promise.reject(
+              new Error(`${this.file.getBaseName()} could not be found`)
+            )
+          } else {
+            return Promise.resolve(source)
+          }
+        })
+        .catch(reason => Promise.reject(reason))
+    } else if (this.editor != null) {
+      return Promise.resolve(this.editor.getText())
+    } else {
+      return Promise.reject(new Error('No editor found'))
+    }
+  }
+
+  async getHTML () {
+    const source = await this.getMarkdownSource()
+
+    if (source == null) {
+      return
+    }
+
+    return renderer.toHTML(source, this.getPath(), this.getGrammar())
+  }
+
+  async renderMarkdownText (text) {
+    const { scrollTop } = this.element
+
+    try {
+      const domFragment = await renderer.toDOMFragment(
+        text,
+        this.getPath(),
+        this.getGrammar()
+      )
+
+      this.loading = false
+      this.loaded = true
+      this.element.textContent = ''
+      this.element.appendChild(domFragment)
+      this.emitter.emit('did-change-markdown')
+      this.element.scrollTop = scrollTop
+    } catch (error) {
+      this.showError(error)
+    }
+  }
+
+  getTitle () {
+    if (this.file != null && this.getPath() != null) {
+      return `${path.basename(this.getPath())} Preview`
+    } else if (this.editor != null) {
+      return `${this.editor.getTitle()} Preview`
+    } else {
+      return 'Markdown Preview'
+    }
+  }
+
+  getIconName () {
+    return 'markdown'
+  }
+
+  getURI () {
+    if (this.file != null) {
+      return `markdown-preview://${this.getPath()}`
+    } else {
+      return `markdown-preview://editor/${this.editorId}`
+    }
+  }
+
+  getPath () {
+    if (this.file != null) {
+      return this.file.getPath()
+    } else if (this.editor != null) {
+      return this.editor.getPath()
+    }
+  }
+
+  getGrammar () {
+    return this.editor != null ? this.editor.getGrammar() : undefined
+  }
+
+  getDocumentStyleSheets () {
+    // This function exists so we can stub it
+    return document.styleSheets
+  }
+
+  getTextEditorStyles () {
+    const textEditorStyles = document.createElement('atom-styles')
+    textEditorStyles.initialize(atom.styles)
+    textEditorStyles.setAttribute('context', 'atom-text-editor')
+    document.body.appendChild(textEditorStyles)
+
+    // Extract style elements content
+    return Array.prototype.slice
+      .apply(textEditorStyles.childNodes)
+      .map(styleElement => styleElement.innerText)
+  }
+
+  getMarkdownPreviewCSS () {
+    const markdownPreviewRules = []
+    const ruleRegExp = /\.markdown-preview/
+    const cssUrlRegExp = /url\(atom:\/\/markdown-preview\/assets\/(.*)\)/
+
+    for (const stylesheet of this.getDocumentStyleSheets()) {
+      if (stylesheet.rules != null) {
+        for (const rule of stylesheet.rules) {
+          // We only need `.markdown-review` css
+          if (rule.selectorText && rule.selectorText.match(ruleRegExp)) {
+            markdownPreviewRules.push(rule.cssText)
+          }
+        }
+      }
+    }
+
+    return markdownPreviewRules
+      .concat(this.getTextEditorStyles())
+      .join('\n')
+      .replace(/atom-text-editor/g, 'pre.editor-colors')
+      .replace(/:host/g, '.host') // Remove shadow-dom :host selector causing problem on FF
+      .replace(cssUrlRegExp, function (match, assetsName, offset, string) {
+        // base64 encode assets
+        const assetPath = path.join(__dirname, '../assets', assetsName)
+        const originalData = fs.readFileSync(assetPath, 'binary')
+        const base64Data = Buffer.from(originalData, 'binary').toString(
+          'base64'
+        )
+        return `url('data:image/jpeg;base64,${base64Data}')`
+      })
+  }
+
+  showError (result) {
+    this.element.textContent = ''
+    const h2 = document.createElement('h2')
+    h2.textContent = 'Previewing Markdown Failed'
+    this.element.appendChild(h2)
+    if (result) {
+      const h3 = document.createElement('h3')
+      h3.textContent = result.message
+      this.element.appendChild(h3)
+    }
+  }
+
+  showLoading () {
+    this.loading = true
+    this.element.textContent = ''
+    const div = document.createElement('div')
+    div.classList.add('markdown-spinner')
+    div.textContent = 'Loading Markdown\u2026'
+    this.element.appendChild(div)
+  }
+
+  selectAll () {
+    if (this.loading) {
+      return
+    }
+
+    const selection = window.getSelection()
+    selection.removeAllRanges()
+    const range = document.createRange()
+    range.selectNodeContents(this.element)
+    selection.addRange(range)
+  }
+
+  async copyToClipboard () {
+    if (this.loading) {
+      return
+    }
+
+    const selection = window.getSelection()
+    const selectedText = selection.toString()
+    const selectedNode = selection.baseNode
+
+    // Use default copy event handler if there is selected text inside this view
+    if (
+      selectedText &&
+      selectedNode != null &&
+      (this.element === selectedNode || this.element.contains(selectedNode))
+    ) {
+      atom.clipboard.write(selectedText)
+    } else {
+      try {
+        const html = await this.getHTML()
+
+        atom.clipboard.write(html)
+      } catch (error) {
+        atom.notifications.addError('Copying Markdown as HTML failed', {
+          dismissable: true,
+          detail: error.message
+        })
+      }
+    }
+  }
+
+  getSaveDialogOptions () {
+    let defaultPath = this.getPath()
+    if (defaultPath) {
+      defaultPath += '.html'
+    } else {
+      let projectPath
+      defaultPath = 'untitled.md.html'
+      if ((projectPath = atom.project.getPaths()[0])) {
+        defaultPath = path.join(projectPath, defaultPath)
+      }
+    }
+
+    return { defaultPath }
+  }
+
+  async saveAs (htmlFilePath) {
+    if (this.loading) {
+      atom.notifications.addWarning(
+        'Please wait until the Markdown Preview has finished loading before saving'
+      )
+      return
+    }
+
+    const filePath = this.getPath()
+    let title = 'Markdown to HTML'
+    if (filePath) {
+      title = path.parse(filePath).name
+    }
+
+    const htmlBody = await this.getHTML()
+
+    const html =
+      `\
+
+
+  
+      
+      ${title}
+      
+  
+  ${htmlBody}
+` + '\n' // Ensure trailing newline
+
+    fs.writeFileSync(htmlFilePath, html)
+    return atom.workspace.open(htmlFilePath)
+  }
+}
diff --git a/lib/renderer.js b/lib/renderer.js
new file mode 100644
index 0000000..7d2d3de
--- /dev/null
+++ b/lib/renderer.js
@@ -0,0 +1,245 @@
+const { TextEditor } = require('atom')
+const path = require('path')
+const createDOMPurify = require('dompurify')
+const emoji = require('emoji-images')
+const fs = require('fs-plus')
+let commonmark = null // Defer until used
+let renderer = null
+let cheerio = null
+let yamlFrontMatter = null
+
+const { scopeForFenceName } = require('./extension-helper')
+const { resourcePath } = atom.getLoadSettings()
+const packagePath = path.dirname(__dirname)
+
+const emojiFolder = path.join(
+  path.dirname(require.resolve('emoji-images')),
+  'pngs'
+)
+
+exports.toDOMFragment = async function (text, filePath, grammar, callback) {
+  if (text == null) {
+    text = ''
+  }
+
+  const domFragment = render(text, filePath)
+
+  await highlightCodeBlocks(domFragment, grammar, makeAtomEditorNonInteractive)
+
+  return domFragment
+}
+
+exports.toHTML = async function (text, filePath, grammar) {
+  if (text == null) {
+    text = ''
+  }
+
+  const domFragment = render(text, filePath)
+  const div = document.createElement('div')
+
+  div.appendChild(domFragment)
+  document.body.appendChild(div)
+
+  await highlightCodeBlocks(div, grammar, convertAtomEditorToStandardElement)
+
+  const result = div.innerHTML
+  div.remove()
+
+  return result
+}
+
+var render = function (text, filePath) {
+  if (commonmark == null || yamlFrontMatter == null || cheerio == null) {
+    commonmark = require('commonmark')
+    yamlFrontMatter = require('yaml-front-matter')
+    cheerio = require('cheerio')
+
+    renderer = new commonmark.Renderer()
+    renderer.listitem = function (text, isTask) {
+      const listAttributes = isTask ? ' class="task-list-item"' : ''
+
+      return `
  • ${text}
  • \n` + } + } + + // commonmark.setOptions({ + // sanitize: false, + // breaks: atom.config.get('markdown-preview.breakOnSingleNewline'), + // renderer + // }) + + const { __content, ...vars } = yamlFrontMatter.loadFront(text) + const parser = new commonmark.Parser() + const writer = new commonmark.HtmlRenderer() + const parsed = parser.parse(renderYamlTable(vars) + __content) + let html = writer.render(parsed) + + // emoji-images is too aggressive, so replace images in monospace tags with the actual emoji text. + const $ = cheerio.load(emoji(html, emojiFolder, 20)) + $('pre img').each((index, element) => + $(element).replaceWith($(element).attr('title')) + ) + $('code img').each((index, element) => + $(element).replaceWith($(element).attr('title')) + ) + + html = $.html() + + html = createDOMPurify().sanitize(html, { + ALLOW_UNKNOWN_PROTOCOLS: atom.config.get( + 'markdown-preview.allowUnsafeProtocols' + ) + }) + + const template = document.createElement('template') + template.innerHTML = html.trim() + const fragment = template.content.cloneNode(true) + + resolveImagePaths(fragment, filePath) + + return fragment +} + +function renderYamlTable (variables) { + const entries = Object.entries(variables) + + if (!entries.length) { + return '' + } + + const markdownRows = [ + entries.map(entry => entry[0]), + entries.map(entry => '--'), + entries.map(entry => entry[1]) + ] + + return ( + markdownRows.map(row => '| ' + row.join(' | ') + ' |').join('\n') + '\n' + ) +} + +var resolveImagePaths = function (element, filePath) { + const [rootDirectory] = atom.project.relativizePath(filePath) + + const result = [] + for (const img of element.querySelectorAll('img')) { + // We use the raw attribute instead of the .src property because the value + // of the property seems to be transformed in some cases. + let src + + if ((src = img.getAttribute('src'))) { + if (src.match(/^(https?|atom):\/\//)) { + continue + } + if (src.startsWith(process.resourcesPath)) { + continue + } + if (src.startsWith(resourcePath)) { + continue + } + if (src.startsWith(packagePath)) { + continue + } + + if (src[0] === '/') { + if (!fs.isFileSync(src)) { + if (rootDirectory) { + result.push((img.src = path.join(rootDirectory, src.substring(1)))) + } else { + result.push(undefined) + } + } else { + result.push(undefined) + } + } else { + result.push((img.src = path.resolve(path.dirname(filePath), src))) + } + } else { + result.push(undefined) + } + } + + return result +} + +var highlightCodeBlocks = function (domFragment, grammar, editorCallback) { + let defaultLanguage, fontFamily + if ( + (grammar != null ? grammar.scopeName : undefined) === 'source.litcoffee' + ) { + defaultLanguage = 'coffee' + } else { + defaultLanguage = 'text' + } + + if ((fontFamily = atom.config.get('editor.fontFamily'))) { + for (const codeElement of domFragment.querySelectorAll('code')) { + codeElement.style.fontFamily = fontFamily + } + } + + const promises = [] + for (const preElement of domFragment.querySelectorAll('pre')) { + const codeBlock = + preElement.firstElementChild != null + ? preElement.firstElementChild + : preElement + const className = codeBlock.getAttribute('class') + const fenceName = + className != null ? className.replace(/^language-/, '') : defaultLanguage + + const editor = new TextEditor({ + readonly: true, + keyboardInputEnabled: false + }) + const editorElement = editor.getElement() + + preElement.classList.add('editor-colors', `lang-${fenceName}`) + editorElement.setUpdatedSynchronously(true) + preElement.innerHTML = '' + preElement.parentNode.insertBefore(editorElement, preElement) + editor.setText(codeBlock.textContent.replace(/\r?\n$/, '')) + atom.grammars.assignLanguageMode(editor, scopeForFenceName(fenceName)) + editor.setVisible(true) + + promises.push(editorCallback(editorElement, preElement)) + } + return Promise.all(promises) +} + +var makeAtomEditorNonInteractive = function (editorElement, preElement) { + preElement.remove() + editorElement.setAttributeNode(document.createAttribute('gutter-hidden')) // Hide gutter + editorElement.removeAttribute('tabindex') // Make read-only + + // Remove line decorations from code blocks. + for (const cursorLineDecoration of editorElement.getModel() + .cursorLineDecorations) { + cursorLineDecoration.destroy() + } +} + +var convertAtomEditorToStandardElement = (editorElement, preElement) => { + return new Promise(function (resolve) { + const editor = editorElement.getModel() + const done = () => + editor.component.getNextUpdatePromise().then(function () { + for (const line of editorElement.querySelectorAll( + '.line:not(.dummy)' + )) { + const line2 = document.createElement('div') + line2.className = 'line' + line2.innerHTML = line.firstChild.innerHTML + preElement.appendChild(line2) + } + editorElement.remove() + resolve() + }) + const languageMode = editor.getBuffer().getLanguageMode() + if (languageMode.fullyTokenized || languageMode.tree) { + done() + } else { + editor.onDidTokenize(done) + } + }) +} diff --git a/lib/suggested-definition.js b/lib/suggested-definition.js new file mode 100644 index 0000000..e64a40e --- /dev/null +++ b/lib/suggested-definition.js @@ -0,0 +1,64 @@ +const {SelectListView} = require('atom-space-pen-views') + +module.exports = class SuggestedDefinition extends SelectListView { + constructor () { + super() + + this.editor = null + + this.addClass('overlay from-top') + + this.panel = atom.workspace.addModalPanel({ + item: this.getElement(), + visible: false + }) + } + + viewForItem (item) { + return `
  • ${item}
  • ` + } + + confirmed (item) { + this.hide() + + const position = this.editor.getCursorBufferPosition() + const definition = `${item}_ ` + + this.editor.insertText(definition) + + position.column = position.column + definition.length + this.editor.setCursorBufferPosition(position) + } + + cancelled () { + this.hide() + + this.editor.component.didFocus() + } + + // Returns an object that can be retrieved when package is activated + serialize () {} + + // Tear down any state and detach + destroy () { + this.element.remove() + } + + getElement () { + return this.element + } + + show (editor, items) { + this.editor = editor + + this.setItems(items) + + this.panel.show() + + this.focusFilterEditor() + } + + hide () { + this.panel.hide() + } +} diff --git a/menus/markdown-preview.cson b/menus/markdown-preview.cson new file mode 100644 index 0000000..a0966c8 --- /dev/null +++ b/menus/markdown-preview.cson @@ -0,0 +1,37 @@ +menu: [ + label: 'Packages' + submenu: [ + label: 'Markdown Preview' + submenu: [ + {label: 'Toggle Preview', command: 'markdown-preview:toggle'} + {label: 'Toggle Break on Single Newline', command: 'markdown-preview:toggle-break-on-single-newline'} + {label: 'Toggle GitHub Style', command: 'markdown-preview:toggle-github-style'} + ] + ] +] + +'context-menu': + '.markdown-preview': [ + {label: 'Select All', command: 'markdown-preview:select-all'} + {label: 'Save As HTML\u2026', command: 'core:save-as'} + ] + '.markdown-preview.has-selection': [ + {label: 'Copy', command: 'core:copy'} + ] + '.markdown-preview:not(.has-selection)': [ + {label: 'Copy As HTML', command: 'core:copy'} + ] + '.tree-view .file .name[data-name$=\\.markdown]': + [{label: 'Markdown Preview', command: 'markdown-preview:preview-file'}] + '.tree-view .file .name[data-name$=\\.md]': + [{label: 'Markdown Preview', command: 'markdown-preview:preview-file'}] + '.tree-view .file .name[data-name$=\\.mdown]': + [{label: 'Markdown Preview', command: 'markdown-preview:preview-file'}] + '.tree-view .file .name[data-name$=\\.mkd]': + [{label: 'Markdown Preview', command: 'markdown-preview:preview-file'}] + '.tree-view .file .name[data-name$=\\.mkdown]': + [{label: 'Markdown Preview', command: 'markdown-preview:preview-file'}] + '.tree-view .file .name[data-name$=\\.ron]': + [{label: 'Markdown Preview', command: 'markdown-preview:preview-file'}] + '.tree-view .file .name[data-name$=\\.txt]': + [{label: 'Markdown Preview', command: 'markdown-preview:preview-file'}] diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..05b9177 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,4480 @@ +{ + "name": "markdown-preview", + "version": "0.160.2", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "version": "0.160.2", + "license": "MIT", + "dependencies": { + "atom-space-pen-views": "^2.2.0", + "cheerio": "^1.0.0-rc.3", + "commonmark": "^0.29.3", + "dompurify": "^2.0.7", + "emoji-images": "^0.1.1", + "fs-plus": "^3.0.0", + "marked": "^0.7.0", + "underscore-plus": "^1.0.0", + "yaml-front-matter": "^4.0.0" + }, + "devDependencies": { + "coffeelint": "^1.9.7", + "standard": "^10.0.3", + "temp": "^0.8.1" + }, + "engines": { + "atom": "*" + } + }, + "node_modules/@types/node": { + "version": "11.13.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-11.13.7.tgz", + "integrity": "sha512-suFHr6hcA9mp8vFrZTgrmqW2ZU3mbWsryQtQlY/QvwTISCw7nw/j+bCQPPohqmskhmqa5wLNuMHTTsc+xf1MQg==" + }, + "node_modules/acorn": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", + "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", + "dev": true, + "dependencies": { + "acorn": "^3.0.4" + } + }, + "node_modules/acorn-jsx/node_modules/acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ajv": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", + "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "dev": true, + "dependencies": { + "co": "^4.6.0", + "json-stable-stringify": "^1.0.1" + } + }, + "node_modules/ajv-keywords": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", + "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=", + "dev": true + }, + "node_modules/ansi-escapes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", + "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/array.prototype.find": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/array.prototype.find/-/array.prototype.find-2.0.4.tgz", + "integrity": "sha1-VWpcU2LAhkgyPdrrnenRS8GGTJA=", + "dev": true, + "dependencies": { + "define-properties": "^1.1.2", + "es-abstract": "^1.7.0" + } + }, + "node_modules/async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" + }, + "node_modules/atom-space-pen-views": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/atom-space-pen-views/-/atom-space-pen-views-2.2.0.tgz", + "integrity": "sha1-plsskg7QL3JAFPp9Plw9ePv1mZc=", + "dependencies": { + "fuzzaldrin": "^2.1.0", + "space-pen": "^5.1.2" + } + }, + "node_modules/babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + } + }, + "node_modules/balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "node_modules/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/caller-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "dev": true, + "dependencies": { + "callsites": "^0.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/callsites": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cheerio": { + "version": "1.0.0-rc.3", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.3.tgz", + "integrity": "sha512-0td5ijfUPuubwLUu0OBoe98gZj8C/AA+RW3v67GPlGOrvxWjZmBXiBCRU+I8VEiNyJzjth40POfHiz2RB3gImA==", + "dependencies": { + "css-select": "~1.2.0", + "dom-serializer": "~0.1.1", + "entities": "~1.1.1", + "htmlparser2": "^3.9.1", + "lodash": "^4.15.0", + "parse5": "^3.0.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/circular-json": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", + "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", + "dev": true + }, + "node_modules/cli-cursor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", + "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", + "dev": true, + "dependencies": { + "restore-cursor": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/coffee-script": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.11.1.tgz", + "integrity": "sha1-vxxHrWREOg2V0S3ysUfMCk2q1uk=", + "dev": true, + "bin": { + "cake": "bin/cake", + "coffee": "bin/coffee" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/coffeelint": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/coffeelint/-/coffeelint-1.16.2.tgz", + "integrity": "sha512-6mzgOo4zb17WfdrSui/cSUEgQ0AQkW3gXDht+6lHkfkqGUtSYKwGdGcXsDfAyuScVzTlTtKdfwkAlJWfqul7zg==", + "dev": true, + "dependencies": { + "coffee-script": "~1.11.0", + "glob": "^7.0.6", + "ignore": "^3.0.9", + "optimist": "^0.6.1", + "resolve": "^0.6.3", + "strip-json-comments": "^1.0.2" + }, + "bin": { + "coffeelint": "bin/coffeelint" + }, + "engines": { + "node": ">=0.8.0", + "npm": ">=1.3.7" + } + }, + "node_modules/commander": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-1.0.0.tgz", + "integrity": "sha1-XmqI5wcP9ZCINurRkWlUjDD5C80=", + "engines": { + "node": ">= 0.4.x" + } + }, + "node_modules/commonmark": { + "version": "0.29.3", + "resolved": "https://registry.npmjs.org/commonmark/-/commonmark-0.29.3.tgz", + "integrity": "sha512-fvt/NdOFKaL2gyhltSy6BC4LxbbxbnPxBMl923ittqO/JBM0wQHaoYZliE4tp26cRxX/ZZtRsJlZzQrVdUkXAA==", + "dependencies": { + "entities": "~2.0", + "mdurl": "~1.0.1", + "minimist": ">=1.2.2", + "string.prototype.repeat": "^0.2.0" + }, + "bin": { + "commonmark": "bin/commonmark" + }, + "engines": { + "node": "*" + } + }, + "node_modules/commonmark/node_modules/entities": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", + "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==" + }, + "node_modules/commonmark/node_modules/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "engines": [ + "node >= 0.8" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/concat-stream/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "node_modules/concat-stream/node_modules/readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/concat-stream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "node_modules/css-select": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", + "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", + "dependencies": { + "boolbase": "~1.0.0", + "css-what": "2.1", + "domutils": "1.5.1", + "nth-check": "~1.0.1" + } + }, + "node_modules/css-what": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", + "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==", + "engines": { + "node": "*" + } + }, + "node_modules/d": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "dependencies": { + "es5-ext": "^0.10.9" + } + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/debug-log": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/debug-log/-/debug-log-1.0.1.tgz", + "integrity": "sha1-IwdjLUwEOCuN+KMvcLiVBG1SdF8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/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=", + "dev": true + }, + "node_modules/define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "dependencies": { + "object-keys": "^1.0.12" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/deglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/deglob/-/deglob-2.1.1.tgz", + "integrity": "sha512-2kjwuGGonL7gWE1XU4Fv79+vVzpoQCl0V+boMwWtOQJV2AGDabCwez++nB1Nli/8BabAfZQ/UuHPlp6AymKdWw==", + "dev": true, + "dependencies": { + "find-root": "^1.0.0", + "glob": "^7.0.5", + "ignore": "^3.0.9", + "pkg-config": "^1.1.0", + "run-parallel": "^1.1.2", + "uniq": "^1.0.1" + } + }, + "node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/dom-serializer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", + "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==", + "dependencies": { + "domelementtype": "^1.3.0", + "entities": "^1.1.1" + } + }, + "node_modules/domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" + }, + "node_modules/domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "dependencies": { + "domelementtype": "1" + } + }, + "node_modules/dompurify": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.0.7.tgz", + "integrity": "sha512-S3O0lk6rFJtO01ZTzMollCOGg+WAtCwS3U5E2WSDY/x/sy7q70RjEC4Dmrih5/UqzLLB9XoKJ8KqwBxaNvBu4A==" + }, + "node_modules/domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "dependencies": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "node_modules/emissary": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/emissary/-/emissary-1.3.3.tgz", + "integrity": "sha1-phjZLWgrIy0xER3DYlpd9mF5lgY=", + "dependencies": { + "es6-weak-map": "^0.1.2", + "mixto": "1.x", + "property-accessors": "^1.1", + "underscore-plus": "1.x" + } + }, + "node_modules/emissary/node_modules/d": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/d/-/d-0.1.1.tgz", + "integrity": "sha1-2hhMU10Y2O57oqoim5FACfrhEwk=", + "dependencies": { + "es5-ext": "~0.10.2" + } + }, + "node_modules/emissary/node_modules/es6-iterator": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-0.1.3.tgz", + "integrity": "sha1-1vWLjE/EE8JJtLqhl2j45NfIlE4=", + "dependencies": { + "d": "~0.1.1", + "es5-ext": "~0.10.5", + "es6-symbol": "~2.0.1" + } + }, + "node_modules/emissary/node_modules/es6-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-2.0.1.tgz", + "integrity": "sha1-dhtcZ8/U8dGK+yNPaR1nhoLLO/M=", + "dependencies": { + "d": "~0.1.1", + "es5-ext": "~0.10.5" + } + }, + "node_modules/emissary/node_modules/es6-weak-map": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-0.1.4.tgz", + "integrity": "sha1-cGzvnpmqI2undmwjnIueKG6n0ig=", + "dependencies": { + "d": "~0.1.1", + "es5-ext": "~0.10.6", + "es6-iterator": "~0.1.3", + "es6-symbol": "~2.0.1" + } + }, + "node_modules/emoji-images": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/emoji-images/-/emoji-images-0.1.1.tgz", + "integrity": "sha1-+ZLccgksA/vgkoJ2MZh+s7Exm2c=" + }, + "node_modules/entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz", + "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==", + "dev": true, + "dependencies": { + "es-to-primitive": "^1.2.0", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "is-callable": "^1.1.4", + "is-regex": "^1.0.4", + "object-keys": "^1.0.12" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", + "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es5-ext": { + "version": "0.10.49", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.49.tgz", + "integrity": "sha512-3NMEhi57E31qdzmYp2jwRArIUsj1HI/RxbQ4bgnSB+AIKIxsAmTiK83bYMifIcpWvEc3P1X30DhUKOqEtF/kvg==", + "dependencies": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.1", + "next-tick": "^1.0.0" + } + }, + "node_modules/es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "dependencies": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/es6-map": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", + "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", + "dev": true, + "dependencies": { + "d": "1", + "es5-ext": "~0.10.14", + "es6-iterator": "~2.0.1", + "es6-set": "~0.1.5", + "es6-symbol": "~3.1.1", + "event-emitter": "~0.3.5" + } + }, + "node_modules/es6-set": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", + "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", + "dev": true, + "dependencies": { + "d": "1", + "es5-ext": "~0.10.14", + "es6-iterator": "~2.0.1", + "es6-symbol": "3.1.1", + "event-emitter": "~0.3.5" + } + }, + "node_modules/es6-symbol": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", + "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "dependencies": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "node_modules/es6-weak-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", + "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", + "dev": true, + "dependencies": { + "d": "1", + "es5-ext": "^0.10.14", + "es6-iterator": "^2.0.1", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/escope": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", + "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", + "dev": true, + "dependencies": { + "es6-map": "^0.1.3", + "es6-weak-map": "^2.0.1", + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/eslint": { + "version": "3.19.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz", + "integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=", + "dev": true, + "dependencies": { + "babel-code-frame": "^6.16.0", + "chalk": "^1.1.3", + "concat-stream": "^1.5.2", + "debug": "^2.1.1", + "doctrine": "^2.0.0", + "escope": "^3.6.0", + "espree": "^3.4.0", + "esquery": "^1.0.0", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "file-entry-cache": "^2.0.0", + "glob": "^7.0.3", + "globals": "^9.14.0", + "ignore": "^3.2.0", + "imurmurhash": "^0.1.4", + "inquirer": "^0.12.0", + "is-my-json-valid": "^2.10.0", + "is-resolvable": "^1.0.0", + "js-yaml": "^3.5.1", + "json-stable-stringify": "^1.0.0", + "levn": "^0.3.0", + "lodash": "^4.0.0", + "mkdirp": "^0.5.0", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.1", + "pluralize": "^1.2.1", + "progress": "^1.1.8", + "require-uncached": "^1.0.2", + "shelljs": "^0.7.5", + "strip-bom": "^3.0.0", + "strip-json-comments": "~2.0.1", + "table": "^3.7.8", + "text-table": "~0.2.0", + "user-home": "^2.0.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-config-standard": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-10.2.1.tgz", + "integrity": "sha1-wGHk0GbzedwXzVYsZOgZtN1FRZE=", + "dev": true + }, + "node_modules/eslint-config-standard-jsx": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/eslint-config-standard-jsx/-/eslint-config-standard-jsx-4.0.2.tgz", + "integrity": "sha512-F8fRh2WFnTek7dZH9ZaE0PCBwdVGkwVWZmizla/DDNOmg7Tx6B/IlK5+oYpiX29jpu73LszeJj5i1axEZv6VMw==", + "dev": true + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.2.3.tgz", + "integrity": "sha1-Wt2BBujJKNssuiMrzZ76hG49oWw=", + "dev": true, + "dependencies": { + "debug": "^2.2.0", + "object-assign": "^4.0.1", + "resolve": "^1.1.6" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/resolve": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", + "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", + "dev": true, + "dependencies": { + "path-parse": "^1.0.6" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.4.0.tgz", + "integrity": "sha512-14tltLm38Eu3zS+mt0KvILC3q8jyIAH518MlG+HO0p+yK885Lb1UHTY/UgR91eOyGdmxAPb+OLoW4znqIT6Ndw==", + "dev": true, + "dependencies": { + "debug": "^2.6.8", + "pkg-dir": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.2.0.tgz", + "integrity": "sha1-crowb60wXWfEgWNIpGmaQimsi04=", + "dev": true, + "dependencies": { + "builtin-modules": "^1.1.1", + "contains-path": "^0.1.0", + "debug": "^2.2.0", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.2.0", + "eslint-module-utils": "^2.0.0", + "has": "^1.0.1", + "lodash.cond": "^4.3.0", + "minimatch": "^3.0.3", + "pkg-up": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "dependencies": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "node_modules/eslint-plugin-node": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-4.2.3.tgz", + "integrity": "sha512-vIUQPuwbVYdz/CYnlTLsJrRy7iXHQjdEe5wz0XhhdTym3IInM/zZLlPf9nZ2mThsH0QcsieCOWs2vOeCy/22LQ==", + "dev": true, + "dependencies": { + "ignore": "^3.0.11", + "minimatch": "^3.0.2", + "object-assign": "^4.0.1", + "resolve": "^1.1.7", + "semver": "5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-node/node_modules/resolve": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", + "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", + "dev": true, + "dependencies": { + "path-parse": "^1.0.6" + } + }, + "node_modules/eslint-plugin-promise": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-3.5.0.tgz", + "integrity": "sha1-ePu2/+BHIBYnVp6FpsU3OvKmj8o=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-react": { + "version": "6.10.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-6.10.3.tgz", + "integrity": "sha1-xUNb6wZ3ThLH2y9qut3L+QDNP3g=", + "dev": true, + "dependencies": { + "array.prototype.find": "^2.0.1", + "doctrine": "^1.2.2", + "has": "^1.0.1", + "jsx-ast-utils": "^1.3.4", + "object.assign": "^4.0.4" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "dependencies": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "node_modules/eslint-plugin-standard": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-3.0.1.tgz", + "integrity": "sha1-NNDJFbRe3G8BA5PH7vOCOwhWXPI=", + "dev": true + }, + "node_modules/eslint/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/espree": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", + "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", + "dev": true, + "dependencies": { + "acorn": "^5.5.0", + "acorn-jsx": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/esquery": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", + "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "dev": true, + "dependencies": { + "estraverse": "^4.0.0" + }, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "dependencies": { + "estraverse": "^4.1.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", + "dev": true, + "dependencies": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "node_modules/exit-hook": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", + "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "node_modules/figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5", + "object-assign": "^4.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/file-entry-cache": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "dev": true, + "dependencies": { + "flat-cache": "^1.2.1", + "object-assign": "^4.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", + "dev": true + }, + "node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/flat-cache": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz", + "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==", + "dev": true, + "dependencies": { + "circular-json": "^0.3.1", + "graceful-fs": "^4.1.2", + "rimraf": "~2.6.2", + "write": "^0.2.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fs-plus": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fs-plus/-/fs-plus-3.1.1.tgz", + "integrity": "sha512-Se2PJdOWXqos1qVTkvqqjb0CSnfBnwwD+pq+z4ksT+e97mEShod/hrNg0TRCCsXPbJzcIq+NuzQhigunMWMJUA==", + "dependencies": { + "async": "^1.5.2", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.2", + "underscore-plus": "1.x" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/fuzzaldrin": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fuzzaldrin/-/fuzzaldrin-2.1.0.tgz", + "integrity": "sha1-kCBMPi/appQbso0WZF1BgGOpDps=" + }, + "node_modules/generate-function": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", + "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "dev": true, + "dependencies": { + "is-property": "^1.0.2" + } + }, + "node_modules/generate-object-property": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", + "dev": true, + "dependencies": { + "is-property": "^1.0.0" + } + }, + "node_modules/get-stdin": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz", + "integrity": "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g=", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/graceful-fs": { + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", + "dev": true + }, + "node_modules/grim": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/grim/-/grim-1.5.0.tgz", + "integrity": "sha1-sysI71Z88YUvgXWe2caLDXE5ajI=", + "dependencies": { + "emissary": "^1.2.0" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "dependencies": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + } + }, + "node_modules/ignore": { + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", + "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", + "dev": true + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "node_modules/inquirer": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", + "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", + "dev": true, + "dependencies": { + "ansi-escapes": "^1.1.0", + "ansi-regex": "^2.0.0", + "chalk": "^1.0.0", + "cli-cursor": "^1.0.1", + "cli-width": "^2.0.0", + "figures": "^1.3.5", + "lodash": "^4.3.0", + "readline2": "^1.0.1", + "run-async": "^0.1.0", + "rx-lite": "^3.1.2", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.0", + "through": "^2.3.6" + } + }, + "node_modules/interpret": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", + "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "node_modules/is-callable": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/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", + "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==", + "dev": true + }, + "node_modules/is-my-json-valid": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.19.0.tgz", + "integrity": "sha512-mG0f/unGX1HZ5ep4uhRaPOS8EkAY8/j6mDRMJrutq4CqhoJWYp7qAlonIPy3TV7p3ju4TK9fo/PbnoksWmsp5Q==", + "dev": true, + "dependencies": { + "generate-function": "^2.0.0", + "generate-object-property": "^1.1.0", + "is-my-ip-valid": "^1.0.0", + "jsonpointer": "^4.0.0", + "xtend": "^4.0.0" + } + }, + "node_modules/is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", + "dev": true + }, + "node_modules/is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "dev": true, + "dependencies": { + "has": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-resolvable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", + "dev": true + }, + "node_modules/is-symbol": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", + "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/jquery": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-2.1.4.tgz", + "integrity": "sha1-IoveaYoMYUMdwmMKahVPFYkNIxc=" + }, + "node_modules/js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "node_modules/js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/js-yaml/node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "node_modules/json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "dev": true, + "dependencies": { + "jsonify": "~0.0.0" + } + }, + "node_modules/jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "dev": true + }, + "node_modules/jsonpointer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", + "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jsx-ast-utils": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-1.4.1.tgz", + "integrity": "sha1-OGchPo3Xm/Ho8jAMDPwe+xgsDfE=", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" + }, + "node_modules/lodash.cond": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz", + "integrity": "sha1-9HGh2khr5g9quVXRcRVSPdHSVdU=", + "dev": true + }, + "node_modules/marked": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-0.7.0.tgz", + "integrity": "sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg==", + "bin": { + "marked": "bin/marked" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=" + }, + "node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "node_modules/mixto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mixto/-/mixto-1.0.0.tgz", + "integrity": "sha1-wyDvYbUvKJj1IuF9i7xtUG2EJbY=" + }, + "node_modules/mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dependencies": { + "minimist": "0.0.8" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/mute-stream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", + "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=", + "dev": true + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "node_modules/next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" + }, + "node_modules/nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "dependencies": { + "boolbase": "~1.0.0" + } + }, + "node_modules/number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "dev": true, + "dependencies": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + } + }, + "node_modules/optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/optionator/node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "node_modules/os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/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, + "engines": { + "node": ">=4" + } + }, + "node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/parse5": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz", + "integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/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, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "node_modules/path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "dependencies": { + "pinkie": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pkg-conf": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.1.0.tgz", + "integrity": "sha1-ISZRTKbyq/69FoWW3xi6V4Z/AFg=", + "dev": true, + "dependencies": { + "find-up": "^2.0.0", + "load-json-file": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-config": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pkg-config/-/pkg-config-1.1.1.tgz", + "integrity": "sha1-VX7yLXPaPIg3EHdmxS6tq94pj+Q=", + "dev": true, + "dependencies": { + "debug-log": "^1.0.0", + "find-root": "^1.0.0", + "xtend": "^4.0.1" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "dependencies": { + "find-up": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-up": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-1.0.0.tgz", + "integrity": "sha1-Pgj7RhUlxEIWJKM7n35tCvWwWiY=", + "dev": true, + "dependencies": { + "find-up": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pkg-up/node_modules/find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "dependencies": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pkg-up/node_modules/path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "dependencies": { + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pluralize": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", + "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=", + "dev": true + }, + "node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "dev": true + }, + "node_modules/progress": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", + "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/property-accessors": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/property-accessors/-/property-accessors-1.1.3.tgz", + "integrity": "sha1-Hd6EAkYxhlkJ7zBwM2VoDF+SixU=", + "dependencies": { + "es6-weak-map": "^0.1.2", + "mixto": "1.x" + } + }, + "node_modules/property-accessors/node_modules/d": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/d/-/d-0.1.1.tgz", + "integrity": "sha1-2hhMU10Y2O57oqoim5FACfrhEwk=", + "dependencies": { + "es5-ext": "~0.10.2" + } + }, + "node_modules/property-accessors/node_modules/es6-iterator": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-0.1.3.tgz", + "integrity": "sha1-1vWLjE/EE8JJtLqhl2j45NfIlE4=", + "dependencies": { + "d": "~0.1.1", + "es5-ext": "~0.10.5", + "es6-symbol": "~2.0.1" + } + }, + "node_modules/property-accessors/node_modules/es6-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-2.0.1.tgz", + "integrity": "sha1-dhtcZ8/U8dGK+yNPaR1nhoLLO/M=", + "dependencies": { + "d": "~0.1.1", + "es5-ext": "~0.10.5" + } + }, + "node_modules/property-accessors/node_modules/es6-weak-map": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-0.1.4.tgz", + "integrity": "sha1-cGzvnpmqI2undmwjnIueKG6n0ig=", + "dependencies": { + "d": "~0.1.1", + "es5-ext": "~0.10.6", + "es6-iterator": "~0.1.3", + "es6-symbol": "~2.0.1" + } + }, + "node_modules/readable-stream": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.3.0.tgz", + "integrity": "sha512-EsI+s3k3XsW+fU8fQACLN59ky34AZ14LoeVZpYwmZvldCFo0r0gnelwF2TcMjLor/BTL5aDJVBMkss0dthToPw==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readline2": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", + "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=", + "dev": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "mute-stream": "0.0.5" + } + }, + "node_modules/rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dev": true, + "dependencies": { + "resolve": "^1.1.6" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/rechoir/node_modules/resolve": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", + "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", + "dev": true, + "dependencies": { + "path-parse": "^1.0.6" + } + }, + "node_modules/require-uncached": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "dev": true, + "dependencies": { + "caller-path": "^0.1.0", + "resolve-from": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-0.6.3.tgz", + "integrity": "sha1-3ZV5gufnNt699TtYpN2RdUV13UY=", + "dev": true + }, + "node_modules/resolve-from": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", + "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/restore-cursor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", + "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", + "dev": true, + "dependencies": { + "exit-hook": "^1.0.0", + "onetime": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/run-async": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", + "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", + "dev": true, + "dependencies": { + "once": "^1.3.0" + } + }, + "node_modules/run-parallel": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", + "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", + "dev": true + }, + "node_modules/rx-lite": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", + "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=", + "dev": true + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/shelljs": { + "version": "0.7.8", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz", + "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", + "dev": true, + "dependencies": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "bin": { + "shjs": "bin/shjs" + }, + "engines": { + "iojs": "*", + "node": ">=0.11.0" + } + }, + "node_modules/slice-ansi": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", + "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/space-pen": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/space-pen/-/space-pen-5.1.2.tgz", + "integrity": "sha1-Ivu+EOCwROe3pHsCPamdlLWE748=", + "dependencies": { + "grim": "^1.0.0", + "jquery": "2.1.4", + "underscore-plus": "1.x" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "node_modules/standard": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/standard/-/standard-10.0.3.tgz", + "integrity": "sha512-JURZ+85ExKLQULckDFijdX5WHzN6RC7fgiZNSV4jFQVo+3tPoQGHyBrGekye/yf0aOfb4210EM5qPNlc2cRh4w==", + "dev": true, + "dependencies": { + "eslint": "~3.19.0", + "eslint-config-standard": "10.2.1", + "eslint-config-standard-jsx": "4.0.2", + "eslint-plugin-import": "~2.2.0", + "eslint-plugin-node": "~4.2.2", + "eslint-plugin-promise": "~3.5.0", + "eslint-plugin-react": "~6.10.0", + "eslint-plugin-standard": "~3.0.1", + "standard-engine": "~7.0.0" + }, + "bin": { + "standard": "bin/cmd.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/standard-engine": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/standard-engine/-/standard-engine-7.0.0.tgz", + "integrity": "sha1-67d7nI/CyBZf+jU72Rug3/Qa9pA=", + "dev": true, + "dependencies": { + "deglob": "^2.1.0", + "get-stdin": "^5.0.1", + "minimist": "^1.1.0", + "pkg-conf": "^2.0.0" + } + }, + "node_modules/standard-engine/node_modules/minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "node_modules/string_decoder": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.2.0.tgz", + "integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string.prototype.repeat": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-0.2.0.tgz", + "integrity": "sha1-q6Nt4I3O5qWjN9SbLqHaGyj8Ds8=" + }, + "node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-json-comments": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz", + "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=", + "dev": true, + "bin": { + "strip-json-comments": "cli.js" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/table": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", + "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=", + "dev": true, + "dependencies": { + "ajv": "^4.7.0", + "ajv-keywords": "^1.0.0", + "chalk": "^1.1.1", + "lodash": "^4.0.0", + "slice-ansi": "0.0.4", + "string-width": "^2.0.0" + } + }, + "node_modules/table/node_modules/ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/table/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/table/node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/table/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/temp": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.3.tgz", + "integrity": "sha1-4Ma8TSa5AxJEEOT+2BEDAU38H1k=", + "dev": true, + "engines": [ + "node >=0.8.0" + ], + "dependencies": { + "os-tmpdir": "^1.0.0", + "rimraf": "~2.2.6" + } + }, + "node_modules/temp/node_modules/rimraf": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", + "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=", + "dev": true, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "node_modules/underscore": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", + "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" + }, + "node_modules/underscore-plus": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/underscore-plus/-/underscore-plus-1.7.0.tgz", + "integrity": "sha512-A3BEzkeicFLnr+U/Q3EyWwJAQPbA19mtZZ4h+lLq3ttm9kn8WC4R3YpuJZEXmWdLjYP47Zc8aLZm9kwdv+zzvA==", + "dependencies": { + "underscore": "^1.9.1" + } + }, + "node_modules/uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", + "dev": true + }, + "node_modules/user-home": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", + "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", + "dev": true, + "dependencies": { + "os-homedir": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "node_modules/wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "node_modules/write": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", + "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "dev": true, + "dependencies": { + "mkdirp": "^0.5.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/yaml-front-matter": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yaml-front-matter/-/yaml-front-matter-4.0.0.tgz", + "integrity": "sha1-EcN4xU6sMGGoLLr2k6abTkxE9IQ=", + "dependencies": { + "commander": "1.0.0", + "js-yaml": "^3.10.0" + }, + "bin": { + "yaml-front-matter": "bin/js-yaml-front.js" + } + } + }, + "dependencies": { + "@types/node": { + "version": "11.13.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-11.13.7.tgz", + "integrity": "sha512-suFHr6hcA9mp8vFrZTgrmqW2ZU3mbWsryQtQlY/QvwTISCw7nw/j+bCQPPohqmskhmqa5wLNuMHTTsc+xf1MQg==" + }, + "acorn": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", + "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==", + "dev": true + }, + "acorn-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", + "dev": true, + "requires": { + "acorn": "^3.0.4" + }, + "dependencies": { + "acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", + "dev": true + } + } + }, + "ajv": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", + "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "dev": true, + "requires": { + "co": "^4.6.0", + "json-stable-stringify": "^1.0.1" + } + }, + "ajv-keywords": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", + "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=", + "dev": true + }, + "ansi-escapes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", + "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", + "dev": true + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array.prototype.find": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/array.prototype.find/-/array.prototype.find-2.0.4.tgz", + "integrity": "sha1-VWpcU2LAhkgyPdrrnenRS8GGTJA=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.7.0" + } + }, + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" + }, + "atom-space-pen-views": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/atom-space-pen-views/-/atom-space-pen-views-2.2.0.tgz", + "integrity": "sha1-plsskg7QL3JAFPp9Plw9ePv1mZc=", + "requires": { + "fuzzaldrin": "^2.1.0", + "space-pen": "^5.1.2" + } + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "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 + }, + "caller-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "dev": true, + "requires": { + "callsites": "^0.2.0" + } + }, + "callsites": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", + "dev": true + }, + "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.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "cheerio": { + "version": "1.0.0-rc.3", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.3.tgz", + "integrity": "sha512-0td5ijfUPuubwLUu0OBoe98gZj8C/AA+RW3v67GPlGOrvxWjZmBXiBCRU+I8VEiNyJzjth40POfHiz2RB3gImA==", + "requires": { + "css-select": "~1.2.0", + "dom-serializer": "~0.1.1", + "entities": "~1.1.1", + "htmlparser2": "^3.9.1", + "lodash": "^4.15.0", + "parse5": "^3.0.1" + } + }, + "circular-json": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", + "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", + "dev": true + }, + "cli-cursor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", + "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", + "dev": true, + "requires": { + "restore-cursor": "^1.0.1" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, + "coffee-script": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.11.1.tgz", + "integrity": "sha1-vxxHrWREOg2V0S3ysUfMCk2q1uk=", + "dev": true + }, + "coffeelint": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/coffeelint/-/coffeelint-1.16.2.tgz", + "integrity": "sha512-6mzgOo4zb17WfdrSui/cSUEgQ0AQkW3gXDht+6lHkfkqGUtSYKwGdGcXsDfAyuScVzTlTtKdfwkAlJWfqul7zg==", + "dev": true, + "requires": { + "coffee-script": "~1.11.0", + "glob": "^7.0.6", + "ignore": "^3.0.9", + "optimist": "^0.6.1", + "resolve": "^0.6.3", + "strip-json-comments": "^1.0.2" + } + }, + "commander": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-1.0.0.tgz", + "integrity": "sha1-XmqI5wcP9ZCINurRkWlUjDD5C80=" + }, + "commonmark": { + "version": "0.29.3", + "resolved": "https://registry.npmjs.org/commonmark/-/commonmark-0.29.3.tgz", + "integrity": "sha512-fvt/NdOFKaL2gyhltSy6BC4LxbbxbnPxBMl923ittqO/JBM0wQHaoYZliE4tp26cRxX/ZZtRsJlZzQrVdUkXAA==", + "requires": { + "entities": "~2.0", + "mdurl": "~1.0.1", + "minimist": ">=1.2.2", + "string.prototype.repeat": "^0.2.0" + }, + "dependencies": { + "entities": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", + "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==" + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + } + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "css-select": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", + "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", + "requires": { + "boolbase": "~1.0.0", + "css-what": "2.1", + "domutils": "1.5.1", + "nth-check": "~1.0.1" + } + }, + "css-what": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", + "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==" + }, + "d": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "requires": { + "es5-ext": "^0.10.9" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "debug-log": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/debug-log/-/debug-log-1.0.1.tgz", + "integrity": "sha1-IwdjLUwEOCuN+KMvcLiVBG1SdF8=", + "dev": true + }, + "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=", + "dev": true + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "deglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/deglob/-/deglob-2.1.1.tgz", + "integrity": "sha512-2kjwuGGonL7gWE1XU4Fv79+vVzpoQCl0V+boMwWtOQJV2AGDabCwez++nB1Nli/8BabAfZQ/UuHPlp6AymKdWw==", + "dev": true, + "requires": { + "find-root": "^1.0.0", + "glob": "^7.0.5", + "ignore": "^3.0.9", + "pkg-config": "^1.1.0", + "run-parallel": "^1.1.2", + "uniq": "^1.0.1" + } + }, + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "dom-serializer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", + "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==", + "requires": { + "domelementtype": "^1.3.0", + "entities": "^1.1.1" + } + }, + "domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" + }, + "domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "requires": { + "domelementtype": "1" + } + }, + "dompurify": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.0.7.tgz", + "integrity": "sha512-S3O0lk6rFJtO01ZTzMollCOGg+WAtCwS3U5E2WSDY/x/sy7q70RjEC4Dmrih5/UqzLLB9XoKJ8KqwBxaNvBu4A==" + }, + "domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "emissary": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/emissary/-/emissary-1.3.3.tgz", + "integrity": "sha1-phjZLWgrIy0xER3DYlpd9mF5lgY=", + "requires": { + "es6-weak-map": "^0.1.2", + "mixto": "1.x", + "property-accessors": "^1.1", + "underscore-plus": "1.x" + }, + "dependencies": { + "d": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/d/-/d-0.1.1.tgz", + "integrity": "sha1-2hhMU10Y2O57oqoim5FACfrhEwk=", + "requires": { + "es5-ext": "~0.10.2" + } + }, + "es6-iterator": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-0.1.3.tgz", + "integrity": "sha1-1vWLjE/EE8JJtLqhl2j45NfIlE4=", + "requires": { + "d": "~0.1.1", + "es5-ext": "~0.10.5", + "es6-symbol": "~2.0.1" + } + }, + "es6-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-2.0.1.tgz", + "integrity": "sha1-dhtcZ8/U8dGK+yNPaR1nhoLLO/M=", + "requires": { + "d": "~0.1.1", + "es5-ext": "~0.10.5" + } + }, + "es6-weak-map": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-0.1.4.tgz", + "integrity": "sha1-cGzvnpmqI2undmwjnIueKG6n0ig=", + "requires": { + "d": "~0.1.1", + "es5-ext": "~0.10.6", + "es6-iterator": "~0.1.3", + "es6-symbol": "~2.0.1" + } + } + } + }, + "emoji-images": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/emoji-images/-/emoji-images-0.1.1.tgz", + "integrity": "sha1-+ZLccgksA/vgkoJ2MZh+s7Exm2c=" + }, + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz", + "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.0", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "is-callable": "^1.1.4", + "is-regex": "^1.0.4", + "object-keys": "^1.0.12" + } + }, + "es-to-primitive": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", + "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "es5-ext": { + "version": "0.10.49", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.49.tgz", + "integrity": "sha512-3NMEhi57E31qdzmYp2jwRArIUsj1HI/RxbQ4bgnSB+AIKIxsAmTiK83bYMifIcpWvEc3P1X30DhUKOqEtF/kvg==", + "requires": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.1", + "next-tick": "^1.0.0" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "requires": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "es6-map": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", + "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "~0.10.14", + "es6-iterator": "~2.0.1", + "es6-set": "~0.1.5", + "es6-symbol": "~3.1.1", + "event-emitter": "~0.3.5" + } + }, + "es6-set": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", + "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "~0.10.14", + "es6-iterator": "~2.0.1", + "es6-symbol": "3.1.1", + "event-emitter": "~0.3.5" + } + }, + "es6-symbol": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", + "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "requires": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "es6-weak-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", + "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "^0.10.14", + "es6-iterator": "^2.0.1", + "es6-symbol": "^3.1.1" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "escope": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", + "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", + "dev": true, + "requires": { + "es6-map": "^0.1.3", + "es6-weak-map": "^2.0.1", + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint": { + "version": "3.19.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz", + "integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=", + "dev": true, + "requires": { + "babel-code-frame": "^6.16.0", + "chalk": "^1.1.3", + "concat-stream": "^1.5.2", + "debug": "^2.1.1", + "doctrine": "^2.0.0", + "escope": "^3.6.0", + "espree": "^3.4.0", + "esquery": "^1.0.0", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "file-entry-cache": "^2.0.0", + "glob": "^7.0.3", + "globals": "^9.14.0", + "ignore": "^3.2.0", + "imurmurhash": "^0.1.4", + "inquirer": "^0.12.0", + "is-my-json-valid": "^2.10.0", + "is-resolvable": "^1.0.0", + "js-yaml": "^3.5.1", + "json-stable-stringify": "^1.0.0", + "levn": "^0.3.0", + "lodash": "^4.0.0", + "mkdirp": "^0.5.0", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.1", + "pluralize": "^1.2.1", + "progress": "^1.1.8", + "require-uncached": "^1.0.2", + "shelljs": "^0.7.5", + "strip-bom": "^3.0.0", + "strip-json-comments": "~2.0.1", + "table": "^3.7.8", + "text-table": "~0.2.0", + "user-home": "^2.0.0" + }, + "dependencies": { + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + } + } + }, + "eslint-config-standard": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-10.2.1.tgz", + "integrity": "sha1-wGHk0GbzedwXzVYsZOgZtN1FRZE=", + "dev": true + }, + "eslint-config-standard-jsx": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/eslint-config-standard-jsx/-/eslint-config-standard-jsx-4.0.2.tgz", + "integrity": "sha512-F8fRh2WFnTek7dZH9ZaE0PCBwdVGkwVWZmizla/DDNOmg7Tx6B/IlK5+oYpiX29jpu73LszeJj5i1axEZv6VMw==", + "dev": true + }, + "eslint-import-resolver-node": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.2.3.tgz", + "integrity": "sha1-Wt2BBujJKNssuiMrzZ76hG49oWw=", + "dev": true, + "requires": { + "debug": "^2.2.0", + "object-assign": "^4.0.1", + "resolve": "^1.1.6" + }, + "dependencies": { + "resolve": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", + "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + } + } + }, + "eslint-module-utils": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.4.0.tgz", + "integrity": "sha512-14tltLm38Eu3zS+mt0KvILC3q8jyIAH518MlG+HO0p+yK885Lb1UHTY/UgR91eOyGdmxAPb+OLoW4znqIT6Ndw==", + "dev": true, + "requires": { + "debug": "^2.6.8", + "pkg-dir": "^2.0.0" + } + }, + "eslint-plugin-import": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.2.0.tgz", + "integrity": "sha1-crowb60wXWfEgWNIpGmaQimsi04=", + "dev": true, + "requires": { + "builtin-modules": "^1.1.1", + "contains-path": "^0.1.0", + "debug": "^2.2.0", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.2.0", + "eslint-module-utils": "^2.0.0", + "has": "^1.0.1", + "lodash.cond": "^4.3.0", + "minimatch": "^3.0.3", + "pkg-up": "^1.0.0" + }, + "dependencies": { + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + } + } + }, + "eslint-plugin-node": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-4.2.3.tgz", + "integrity": "sha512-vIUQPuwbVYdz/CYnlTLsJrRy7iXHQjdEe5wz0XhhdTym3IInM/zZLlPf9nZ2mThsH0QcsieCOWs2vOeCy/22LQ==", + "dev": true, + "requires": { + "ignore": "^3.0.11", + "minimatch": "^3.0.2", + "object-assign": "^4.0.1", + "resolve": "^1.1.7", + "semver": "5.3.0" + }, + "dependencies": { + "resolve": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", + "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + } + } + }, + "eslint-plugin-promise": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-3.5.0.tgz", + "integrity": "sha1-ePu2/+BHIBYnVp6FpsU3OvKmj8o=", + "dev": true + }, + "eslint-plugin-react": { + "version": "6.10.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-6.10.3.tgz", + "integrity": "sha1-xUNb6wZ3ThLH2y9qut3L+QDNP3g=", + "dev": true, + "requires": { + "array.prototype.find": "^2.0.1", + "doctrine": "^1.2.2", + "has": "^1.0.1", + "jsx-ast-utils": "^1.3.4", + "object.assign": "^4.0.4" + }, + "dependencies": { + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + } + } + }, + "eslint-plugin-standard": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-3.0.1.tgz", + "integrity": "sha1-NNDJFbRe3G8BA5PH7vOCOwhWXPI=", + "dev": true + }, + "espree": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", + "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", + "dev": true, + "requires": { + "acorn": "^5.5.0", + "acorn-jsx": "^3.0.0" + } + }, + "esquery": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", + "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "dev": true, + "requires": { + "estraverse": "^4.0.0" + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "exit-hook": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", + "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5", + "object-assign": "^4.1.0" + } + }, + "file-entry-cache": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "dev": true, + "requires": { + "flat-cache": "^1.2.1", + "object-assign": "^4.0.1" + } + }, + "find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", + "dev": true + }, + "find-up": { + "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" + } + }, + "flat-cache": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz", + "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==", + "dev": true, + "requires": { + "circular-json": "^0.3.1", + "graceful-fs": "^4.1.2", + "rimraf": "~2.6.2", + "write": "^0.2.1" + } + }, + "fs-plus": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fs-plus/-/fs-plus-3.1.1.tgz", + "integrity": "sha512-Se2PJdOWXqos1qVTkvqqjb0CSnfBnwwD+pq+z4ksT+e97mEShod/hrNg0TRCCsXPbJzcIq+NuzQhigunMWMJUA==", + "requires": { + "async": "^1.5.2", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.2", + "underscore-plus": "1.x" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "fuzzaldrin": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fuzzaldrin/-/fuzzaldrin-2.1.0.tgz", + "integrity": "sha1-kCBMPi/appQbso0WZF1BgGOpDps=" + }, + "generate-function": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", + "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "dev": true, + "requires": { + "is-property": "^1.0.2" + } + }, + "generate-object-property": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", + "dev": true, + "requires": { + "is-property": "^1.0.0" + } + }, + "get-stdin": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz", + "integrity": "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g=", + "dev": true + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "dev": true + }, + "graceful-fs": { + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", + "dev": true + }, + "grim": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/grim/-/grim-1.5.0.tgz", + "integrity": "sha1-sysI71Z88YUvgXWe2caLDXE5ajI=", + "requires": { + "emissary": "^1.2.0" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", + "dev": true + }, + "htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "requires": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + } + }, + "ignore": { + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", + "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "inquirer": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", + "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", + "dev": true, + "requires": { + "ansi-escapes": "^1.1.0", + "ansi-regex": "^2.0.0", + "chalk": "^1.0.0", + "cli-cursor": "^1.0.1", + "cli-width": "^2.0.0", + "figures": "^1.3.5", + "lodash": "^4.3.0", + "readline2": "^1.0.1", + "run-async": "^0.1.0", + "rx-lite": "^3.1.2", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.0", + "through": "^2.3.6" + } + }, + "interpret": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", + "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==", + "dev": true + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-callable": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", + "dev": true + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "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", + "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==", + "dev": true + }, + "is-my-json-valid": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.19.0.tgz", + "integrity": "sha512-mG0f/unGX1HZ5ep4uhRaPOS8EkAY8/j6mDRMJrutq4CqhoJWYp7qAlonIPy3TV7p3ju4TK9fo/PbnoksWmsp5Q==", + "dev": true, + "requires": { + "generate-function": "^2.0.0", + "generate-object-property": "^1.1.0", + "is-my-ip-valid": "^1.0.0", + "jsonpointer": "^4.0.0", + "xtend": "^4.0.0" + } + }, + "is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", + "dev": true + }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "dev": true, + "requires": { + "has": "^1.0.1" + } + }, + "is-resolvable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", + "dev": true + }, + "is-symbol": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", + "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.0" + } + }, + "jquery": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-2.1.4.tgz", + "integrity": "sha1-IoveaYoMYUMdwmMKahVPFYkNIxc=" + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "dependencies": { + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + } + } + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "dev": true, + "requires": { + "jsonify": "~0.0.0" + } + }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "dev": true + }, + "jsonpointer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", + "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", + "dev": true + }, + "jsx-ast-utils": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-1.4.1.tgz", + "integrity": "sha1-OGchPo3Xm/Ho8jAMDPwe+xgsDfE=", + "dev": true + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + } + }, + "locate-path": { + "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" + } + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" + }, + "lodash.cond": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz", + "integrity": "sha1-9HGh2khr5g9quVXRcRVSPdHSVdU=", + "dev": true + }, + "marked": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-0.7.0.tgz", + "integrity": "sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg==" + }, + "mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "mixto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mixto/-/mixto-1.0.0.tgz", + "integrity": "sha1-wyDvYbUvKJj1IuF9i7xtUG2EJbY=" + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "mute-stream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", + "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" + }, + "nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "requires": { + "boolbase": "~1.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", + "dev": true + }, + "optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "dev": true, + "requires": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + } + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" + }, + "dependencies": { + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + } + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "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.1.0" + } + }, + "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 + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "parse5": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz", + "integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==", + "requires": { + "@types/node": "*" + } + }, + "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 + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "^2.0.0" + } + }, + "pkg-conf": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.1.0.tgz", + "integrity": "sha1-ISZRTKbyq/69FoWW3xi6V4Z/AFg=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "load-json-file": "^4.0.0" + } + }, + "pkg-config": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pkg-config/-/pkg-config-1.1.1.tgz", + "integrity": "sha1-VX7yLXPaPIg3EHdmxS6tq94pj+Q=", + "dev": true, + "requires": { + "debug-log": "^1.0.0", + "find-root": "^1.0.0", + "xtend": "^4.0.1" + } + }, + "pkg-dir": { + "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" + } + }, + "pkg-up": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-1.0.0.tgz", + "integrity": "sha1-Pgj7RhUlxEIWJKM7n35tCvWwWiY=", + "dev": true, + "requires": { + "find-up": "^1.0.0" + }, + "dependencies": { + "find-up": { + "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.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "path-exists": { + "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.0" + } + } + } + }, + "pluralize": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", + "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=", + "dev": true + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "dev": true + }, + "progress": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", + "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", + "dev": true + }, + "property-accessors": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/property-accessors/-/property-accessors-1.1.3.tgz", + "integrity": "sha1-Hd6EAkYxhlkJ7zBwM2VoDF+SixU=", + "requires": { + "es6-weak-map": "^0.1.2", + "mixto": "1.x" + }, + "dependencies": { + "d": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/d/-/d-0.1.1.tgz", + "integrity": "sha1-2hhMU10Y2O57oqoim5FACfrhEwk=", + "requires": { + "es5-ext": "~0.10.2" + } + }, + "es6-iterator": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-0.1.3.tgz", + "integrity": "sha1-1vWLjE/EE8JJtLqhl2j45NfIlE4=", + "requires": { + "d": "~0.1.1", + "es5-ext": "~0.10.5", + "es6-symbol": "~2.0.1" + } + }, + "es6-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-2.0.1.tgz", + "integrity": "sha1-dhtcZ8/U8dGK+yNPaR1nhoLLO/M=", + "requires": { + "d": "~0.1.1", + "es5-ext": "~0.10.5" + } + }, + "es6-weak-map": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-0.1.4.tgz", + "integrity": "sha1-cGzvnpmqI2undmwjnIueKG6n0ig=", + "requires": { + "d": "~0.1.1", + "es5-ext": "~0.10.6", + "es6-iterator": "~0.1.3", + "es6-symbol": "~2.0.1" + } + } + } + }, + "readable-stream": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.3.0.tgz", + "integrity": "sha512-EsI+s3k3XsW+fU8fQACLN59ky34AZ14LoeVZpYwmZvldCFo0r0gnelwF2TcMjLor/BTL5aDJVBMkss0dthToPw==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "readline2": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", + "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "mute-stream": "0.0.5" + } + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dev": true, + "requires": { + "resolve": "^1.1.6" + }, + "dependencies": { + "resolve": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", + "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + } + } + }, + "require-uncached": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "dev": true, + "requires": { + "caller-path": "^0.1.0", + "resolve-from": "^1.0.0" + } + }, + "resolve": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-0.6.3.tgz", + "integrity": "sha1-3ZV5gufnNt699TtYpN2RdUV13UY=", + "dev": true + }, + "resolve-from": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", + "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", + "dev": true + }, + "restore-cursor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", + "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", + "dev": true, + "requires": { + "exit-hook": "^1.0.0", + "onetime": "^1.0.0" + } + }, + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "requires": { + "glob": "^7.1.3" + } + }, + "run-async": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", + "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", + "dev": true, + "requires": { + "once": "^1.3.0" + } + }, + "run-parallel": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", + "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", + "dev": true + }, + "rx-lite": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", + "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=", + "dev": true + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", + "dev": true + }, + "shelljs": { + "version": "0.7.8", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz", + "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", + "dev": true, + "requires": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + } + }, + "slice-ansi": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", + "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", + "dev": true + }, + "space-pen": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/space-pen/-/space-pen-5.1.2.tgz", + "integrity": "sha1-Ivu+EOCwROe3pHsCPamdlLWE748=", + "requires": { + "grim": "^1.0.0", + "jquery": "2.1.4", + "underscore-plus": "1.x" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "standard": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/standard/-/standard-10.0.3.tgz", + "integrity": "sha512-JURZ+85ExKLQULckDFijdX5WHzN6RC7fgiZNSV4jFQVo+3tPoQGHyBrGekye/yf0aOfb4210EM5qPNlc2cRh4w==", + "dev": true, + "requires": { + "eslint": "~3.19.0", + "eslint-config-standard": "10.2.1", + "eslint-config-standard-jsx": "4.0.2", + "eslint-plugin-import": "~2.2.0", + "eslint-plugin-node": "~4.2.2", + "eslint-plugin-promise": "~3.5.0", + "eslint-plugin-react": "~6.10.0", + "eslint-plugin-standard": "~3.0.1", + "standard-engine": "~7.0.0" + } + }, + "standard-engine": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/standard-engine/-/standard-engine-7.0.0.tgz", + "integrity": "sha1-67d7nI/CyBZf+jU72Rug3/Qa9pA=", + "dev": true, + "requires": { + "deglob": "^2.1.0", + "get-stdin": "^5.0.1", + "minimist": "^1.1.0", + "pkg-conf": "^2.0.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "string_decoder": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.2.0.tgz", + "integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string.prototype.repeat": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-0.2.0.tgz", + "integrity": "sha1-q6Nt4I3O5qWjN9SbLqHaGyj8Ds8=" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-json-comments": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz", + "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=", + "dev": true + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + }, + "table": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", + "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=", + "dev": true, + "requires": { + "ajv": "^4.7.0", + "ajv-keywords": "^1.0.0", + "chalk": "^1.1.1", + "lodash": "^4.0.0", + "slice-ansi": "0.0.4", + "string-width": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "temp": { + "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.0", + "rimraf": "~2.2.6" + }, + "dependencies": { + "rimraf": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", + "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=", + "dev": true + } + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "underscore": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", + "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" + }, + "underscore-plus": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/underscore-plus/-/underscore-plus-1.7.0.tgz", + "integrity": "sha512-A3BEzkeicFLnr+U/Q3EyWwJAQPbA19mtZZ4h+lLq3ttm9kn8WC4R3YpuJZEXmWdLjYP47Zc8aLZm9kwdv+zzvA==", + "requires": { + "underscore": "^1.9.1" + } + }, + "uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", + "dev": true + }, + "user-home": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", + "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", + "dev": true, + "requires": { + "os-homedir": "^1.0.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "write": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", + "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + }, + "yaml-front-matter": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yaml-front-matter/-/yaml-front-matter-4.0.0.tgz", + "integrity": "sha1-EcN4xU6sMGGoLLr2k6abTkxE9IQ=", + "requires": { + "commander": "1.0.0", + "js-yaml": "^3.10.0" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..f85f1e7 --- /dev/null +++ b/package.json @@ -0,0 +1,81 @@ +{ + "name": "markdown-preview", + "version": "0.160.2", + "main": "./lib/main", + "description": "Open a rendered version of the Markdown in the current editor with `ctrl-shift-m`.", + "repository": "https://github.com/atom/markdown-preview", + "license": "MIT", + "engines": { + "atom": "*" + }, + "dependencies": { + "atom-space-pen-views": "^2.2.0", + "cheerio": "^1.0.0-rc.3", + "commonmark": "^0.29.3", + "dompurify": "^2.0.7", + "emoji-images": "^0.1.1", + "fs-plus": "^3.0.0", + "marked": "^0.7.0", + "underscore-plus": "^1.0.0", + "yaml-front-matter": "^4.0.0" + }, + "devDependencies": { + "coffeelint": "^1.9.7", + "standard": "^10.0.3", + "temp": "^0.8.1" + }, + "deserializers": { + "MarkdownPreviewView": "createMarkdownPreviewView" + }, + "configSchema": { + "breakOnSingleNewline": { + "type": "boolean", + "default": false, + "description": "In Markdown, a single newline character doesn't cause a line break in the generated HTML. In GitHub Flavored Markdown, that is not true. Enable this config option to insert line breaks in rendered HTML for single newlines in Markdown source." + }, + "liveUpdate": { + "type": "boolean", + "default": true, + "description": "Re-render the preview as the contents of the source changes, without requiring the source buffer to be saved. If disabled, the preview is re-rendered only when the buffer is saved to disk." + }, + "openPreviewInSplitPane": { + "type": "boolean", + "default": true, + "description": "Open the preview in a split pane. If disabled, the preview is opened in a new tab in the same pane." + }, + "allowUnsafeProtocols": { + "type": "boolean", + "default": false, + "description": "Allow HTML attributes to use protocols normally considered unsafe such as `file://` and absolute paths on Windows." + }, + "grammars": { + "type": "array", + "default": [ + "source.gfm", + "source.litcoffee", + "text.html.basic", + "text.md", + "text.plain", + "text.plain.null-grammar" + ], + "description": "List of scopes for languages for which previewing is enabled. See [this README](https://github.com/atom/spell-check#spell-check-package-) for more information on finding the correct scope for a specific language." + }, + "useGitHubStyle": { + "title": "Use GitHub.com style", + "type": "boolean", + "default": false, + "description": "Use the same CSS styles for preview as the ones used on GitHub.com." + } + }, + "standard": { + "env": { + "atomtest": true, + "browser": true, + "jasmine": true, + "node": true + }, + "globals": [ + "atom" + ] + } +} diff --git a/spec/fixtures/subdir/áccéntéd.md b/spec/fixtures/subdir/áccéntéd.md new file mode 100644 index 0000000..f00b526 --- /dev/null +++ b/spec/fixtures/subdir/áccéntéd.md @@ -0,0 +1 @@ +# Testing diff --git a/spec/fixtures/subdir/code-block.md b/spec/fixtures/subdir/code-block.md new file mode 100644 index 0000000..4e88d46 --- /dev/null +++ b/spec/fixtures/subdir/code-block.md @@ -0,0 +1,9 @@ +# Code Block + +```javascript +if a === 3 { + b = 5 +} +``` + +encoding → issue diff --git a/spec/fixtures/subdir/doctype-tag.md b/spec/fixtures/subdir/doctype-tag.md new file mode 100644 index 0000000..ec44f34 --- /dev/null +++ b/spec/fixtures/subdir/doctype-tag.md @@ -0,0 +1,4 @@ + + +content + diff --git a/spec/fixtures/subdir/evil.md b/spec/fixtures/subdir/evil.md new file mode 100644 index 0000000..cb4fe4c --- /dev/null +++ b/spec/fixtures/subdir/evil.md @@ -0,0 +1,5 @@ +hello + + + +world diff --git a/spec/fixtures/subdir/file with space.md b/spec/fixtures/subdir/file with space.md new file mode 100644 index 0000000..f00b526 --- /dev/null +++ b/spec/fixtures/subdir/file with space.md @@ -0,0 +1 @@ +# Testing diff --git a/spec/fixtures/subdir/file.markdown b/spec/fixtures/subdir/file.markdown new file mode 100644 index 0000000..ac8dc01 --- /dev/null +++ b/spec/fixtures/subdir/file.markdown @@ -0,0 +1,51 @@ +--- +variable1: value1 +array: + - foo + - bar +--- + +## File.markdown + +:cool: + +``` +function f(x) { + return x++; +} +``` + +```Ruby +def func + x = 1 +end +``` + +* ```javascript +if a === 3 { + b = 5 +} +``` + +```kombucha +drink-that-stuff: + tastes-weird~ +``` + +```python +def foo() + + bar + + + baz +``` + +![Image1](image1.png) + +![Image2](/tmp/image2.png) + +![Image3](http://github.com/image3.png) + +lorem +ipsum diff --git a/spec/fixtures/subdir/html-tag.md b/spec/fixtures/subdir/html-tag.md new file mode 100644 index 0000000..94cb6d7 --- /dev/null +++ b/spec/fixtures/subdir/html-tag.md @@ -0,0 +1 @@ +content diff --git a/spec/fixtures/subdir/pre-tag.md b/spec/fixtures/subdir/pre-tag.md new file mode 100644 index 0000000..08bf251 --- /dev/null +++ b/spec/fixtures/subdir/pre-tag.md @@ -0,0 +1 @@ +
    hey
    diff --git a/spec/fixtures/subdir/simple.md b/spec/fixtures/subdir/simple.md new file mode 100644 index 0000000..20d93cc --- /dev/null +++ b/spec/fixtures/subdir/simple.md @@ -0,0 +1,5 @@ +*italic* + +**bold** + +encoding → issue diff --git a/spec/fixtures/subdir/áccéntéd.md b/spec/fixtures/subdir/áccéntéd.md new file mode 100644 index 0000000..f00b526 --- /dev/null +++ b/spec/fixtures/subdir/áccéntéd.md @@ -0,0 +1 @@ +# Testing diff --git a/spec/markdown-preview-spec.js b/spec/markdown-preview-spec.js new file mode 100644 index 0000000..6a90d8c --- /dev/null +++ b/spec/markdown-preview-spec.js @@ -0,0 +1,839 @@ +const path = require('path') +const fs = require('fs-plus') +const temp = require('temp').track() +const MarkdownPreviewView = require('../lib/markdown-preview-view') +const { TextEditor } = require('atom') +const TextMateLanguageMode = new TextEditor().getBuffer().getLanguageMode() + .constructor + +describe('Markdown Preview', function () { + let preview = null + + beforeEach(function () { + const fixturesPath = path.join(__dirname, 'fixtures') + const tempPath = temp.mkdirSync('atom') + fs.copySync(fixturesPath, tempPath) + atom.project.setPaths([tempPath]) + + jasmine.unspy(TextMateLanguageMode.prototype, 'tokenizeInBackground') + + jasmine.useRealClock() + jasmine.attachToDOM(atom.views.getView(atom.workspace)) + + waitsForPromise(() => atom.packages.activatePackage('markdown-preview')) + + waitsForPromise(() => atom.packages.activatePackage('language-gfm')) + + runs(() => + spyOn(atom.packages, 'hasActivatedInitialPackages').andReturn(true) + ) + }) + + const expectPreviewInSplitPane = function () { + waitsFor(() => atom.workspace.getCenter().getPanes().length === 2) + + waitsFor( + 'markdown preview to be created', + () => + (preview = atom.workspace + .getCenter() + .getPanes()[1] + .getActiveItem()) + ) + + runs(() => { + expect(preview).toBeInstanceOf(MarkdownPreviewView) + expect(preview.getPath()).toBe( + atom.workspace.getActivePaneItem().getPath() + ) + }) + } + + describe('when a preview has not been created for the file', function () { + it('displays a markdown preview in a split pane', function () { + waitsForPromise(() => atom.workspace.open('subdir/file.markdown')) + runs(() => + atom.commands.dispatch( + atom.workspace.getActiveTextEditor().getElement(), + 'markdown-preview:toggle' + ) + ) + expectPreviewInSplitPane() + + runs(() => { + const [editorPane] = atom.workspace.getCenter().getPanes() + expect(editorPane.getItems()).toHaveLength(1) + expect(editorPane.isActive()).toBe(true) + }) + }) + + describe("when the editor's path does not exist", function () { + it('splits the current pane to the right with a markdown preview for the file', function () { + waitsForPromise(() => atom.workspace.open('new.markdown')) + runs(() => + atom.commands.dispatch( + atom.workspace.getActiveTextEditor().getElement(), + 'markdown-preview:toggle' + ) + ) + expectPreviewInSplitPane() + }) + }) + + describe('when the editor does not have a path', function () { + it('splits the current pane to the right with a markdown preview for the file', function () { + waitsForPromise(() => atom.workspace.open('')) + runs(() => + atom.commands.dispatch( + atom.workspace.getActiveTextEditor().getElement(), + 'markdown-preview:toggle' + ) + ) + expectPreviewInSplitPane() + }) + }) + + describe('when the path contains a space', function () { + it('renders the preview', function () { + waitsForPromise(() => atom.workspace.open('subdir/file with space.md')) + runs(() => + atom.commands.dispatch( + atom.workspace.getActiveTextEditor().getElement(), + 'markdown-preview:toggle' + ) + ) + expectPreviewInSplitPane() + }) + }) + + describe('when the path contains accented characters', function () { + it('renders the preview', function () { + waitsForPromise(() => atom.workspace.open('subdir/áccéntéd.md')) + runs(() => + atom.commands.dispatch( + atom.workspace.getActiveTextEditor().getElement(), + 'markdown-preview:toggle' + ) + ) + expectPreviewInSplitPane() + }) + }) + }) + + describe('when a preview has been created for the file', function () { + beforeEach(function () { + waitsForPromise(() => atom.workspace.open('subdir/file.markdown')) + runs(() => + atom.commands.dispatch( + atom.workspace.getActiveTextEditor().getElement(), + 'markdown-preview:toggle' + ) + ) + expectPreviewInSplitPane() + }) + + it('closes the existing preview when toggle is triggered a second time on the editor', function () { + atom.commands.dispatch( + atom.workspace.getActiveTextEditor().getElement(), + 'markdown-preview:toggle' + ) + + const [editorPane, previewPane] = atom.workspace.getCenter().getPanes() + expect(editorPane.isActive()).toBe(true) + expect(previewPane.getActiveItem()).toBeUndefined() + }) + + it('closes the existing preview when toggle is triggered on it and it has focus', function () { + const [editorPane, previewPane] = atom.workspace.getCenter().getPanes() + previewPane.activate() + + atom.commands.dispatch( + editorPane.getActiveItem().getElement(), + 'markdown-preview:toggle' + ) + expect(previewPane.getActiveItem()).toBeUndefined() + }) + + describe('when the editor is modified', function () { + it('re-renders the preview', function () { + spyOn(preview, 'showLoading') + + const markdownEditor = atom.workspace.getActiveTextEditor() + markdownEditor.setText('Hey!') + + waitsFor(() => preview.element.textContent.includes('Hey!')) + + runs(() => expect(preview.showLoading).not.toHaveBeenCalled()) + }) + + it('invokes ::onDidChangeMarkdown listeners', function () { + let listener + const markdownEditor = atom.workspace.getActiveTextEditor() + preview.onDidChangeMarkdown( + (listener = jasmine.createSpy('didChangeMarkdownListener')) + ) + + runs(() => markdownEditor.setText('Hey!')) + + waitsFor( + '::onDidChangeMarkdown handler to be called', + () => listener.callCount > 0 + ) + }) + + describe('when the preview is in the active pane but is not the active item', function () { + it('re-renders the preview but does not make it active', function () { + const markdownEditor = atom.workspace.getActiveTextEditor() + const previewPane = atom.workspace.getCenter().getPanes()[1] + previewPane.activate() + + waitsForPromise(() => atom.workspace.open()) + + runs(() => markdownEditor.setText('Hey!')) + + waitsFor(() => preview.element.textContent.includes('Hey!')) + + runs(() => { + expect(previewPane.isActive()).toBe(true) + expect(previewPane.getActiveItem()).not.toBe(preview) + }) + }) + }) + + describe('when the preview is not the active item and not in the active pane', function () { + it('re-renders the preview and makes it active', function () { + const markdownEditor = atom.workspace.getActiveTextEditor() + const [ + editorPane, + previewPane + ] = atom.workspace.getCenter().getPanes() + previewPane.splitRight({ copyActiveItem: true }) + previewPane.activate() + + waitsForPromise(() => atom.workspace.open()) + + runs(() => { + editorPane.activate() + markdownEditor.setText('Hey!') + }) + + waitsFor(() => preview.element.textContent.includes('Hey!')) + + runs(() => { + expect(editorPane.isActive()).toBe(true) + expect(previewPane.getActiveItem()).toBe(preview) + }) + }) + }) + + describe('when the liveUpdate config is set to false', function () { + it('only re-renders the markdown when the editor is saved, not when the contents are modified', function () { + atom.config.set('markdown-preview.liveUpdate', false) + + const didStopChangingHandler = jasmine.createSpy( + 'didStopChangingHandler' + ) + atom.workspace + .getActiveTextEditor() + .getBuffer() + .onDidStopChanging(didStopChangingHandler) + atom.workspace.getActiveTextEditor().setText('ch ch changes') + + waitsFor(() => didStopChangingHandler.callCount > 0) + + runs(() => { + expect(preview.element.textContent).not.toMatch('ch ch changes') + atom.workspace.getActiveTextEditor().save() + }) + + waitsFor(() => preview.element.textContent.includes('ch ch changes')) + }) + }) + }) + + describe('when the original preview is split', function () { + it('renders another preview in the new split pane', function () { + atom.workspace + .getCenter() + .getPanes()[1] + .splitRight({ copyActiveItem: true }) + + expect(atom.workspace.getCenter().getPanes()).toHaveLength(3) + + waitsFor( + 'split markdown preview to be created', + () => + (preview = atom.workspace + .getCenter() + .getPanes()[2] + .getActiveItem()) + ) + + runs(() => { + expect(preview).toBeInstanceOf(MarkdownPreviewView) + expect(preview.getPath()).toBe( + atom.workspace.getActivePaneItem().getPath() + ) + }) + }) + }) + + describe('when the editor is destroyed', function () { + beforeEach(() => + atom.workspace + .getCenter() + .getPanes()[0] + .destroyActiveItem() + ) + + it('falls back to using the file path', function () { + atom.workspace + .getCenter() + .getPanes()[1] + .activate() + expect(preview.file.getPath()).toBe( + atom.workspace.getActivePaneItem().getPath() + ) + }) + + it('continues to update the preview if the file is changed on #win32 and #darwin', function () { + let listener + const titleChangedCallback = jasmine.createSpy('titleChangedCallback') + + runs(() => { + expect(preview.getTitle()).toBe('file.markdown Preview') + preview.onDidChangeTitle(titleChangedCallback) + fs.renameSync( + preview.getPath(), + path.join(path.dirname(preview.getPath()), 'file2.md') + ) + }) + + waitsFor( + 'title to update', + () => preview.getTitle() === 'file2.md Preview' + ) + + runs(() => expect(titleChangedCallback).toHaveBeenCalled()) + + spyOn(preview, 'showLoading') + + runs(() => fs.writeFileSync(preview.getPath(), 'Hey!')) + + waitsFor('contents to update', () => + preview.element.textContent.includes('Hey!') + ) + + runs(() => expect(preview.showLoading).not.toHaveBeenCalled()) + + preview.onDidChangeMarkdown( + (listener = jasmine.createSpy('didChangeMarkdownListener')) + ) + + runs(() => fs.writeFileSync(preview.getPath(), 'Hey!')) + + waitsFor( + '::onDidChangeMarkdown handler to be called', + () => listener.callCount > 0 + ) + }) + + it('allows a new split pane of the preview to be created', function () { + atom.workspace + .getCenter() + .getPanes()[1] + .splitRight({ copyActiveItem: true }) + + expect(atom.workspace.getCenter().getPanes()).toHaveLength(3) + + waitsFor( + 'split markdown preview to be created', + () => + (preview = atom.workspace + .getCenter() + .getPanes()[2] + .getActiveItem()) + ) + + runs(() => { + expect(preview).toBeInstanceOf(MarkdownPreviewView) + expect(preview.getPath()).toBe( + atom.workspace.getActivePaneItem().getPath() + ) + }) + }) + }) + }) + + describe('when the markdown preview view is requested by file URI', function () { + it('opens a preview editor and watches the file for changes', function () { + waitsForPromise('atom.workspace.open promise to be resolved', () => + atom.workspace.open( + `markdown-preview://${atom.project + .getDirectories()[0] + .resolve('subdir/file.markdown')}` + ) + ) + + runs(() => { + preview = atom.workspace.getActivePaneItem() + expect(preview).toBeInstanceOf(MarkdownPreviewView) + + spyOn(preview, 'renderMarkdownText') + preview.file.emitter.emit('did-change') + }) + + waitsFor( + 'markdown to be re-rendered after file changed', + () => preview.renderMarkdownText.callCount > 0 + ) + }) + }) + + describe("when the editor's grammar it not enabled for preview", function () { + it('does not open the markdown preview', function () { + atom.config.set('markdown-preview.grammars', []) + + waitsForPromise(() => atom.workspace.open('subdir/file.markdown')) + + runs(() => { + spyOn(atom.workspace, 'open').andCallThrough() + atom.commands.dispatch( + atom.workspace.getActiveTextEditor().getElement(), + 'markdown-preview:toggle' + ) + expect(atom.workspace.open).not.toHaveBeenCalled() + }) + }) + }) + + describe("when the editor's path changes on #win32 and #darwin", function () { + it("updates the preview's title", function () { + const titleChangedCallback = jasmine.createSpy('titleChangedCallback') + + waitsForPromise(() => atom.workspace.open('subdir/file.markdown')) + runs(() => + atom.commands.dispatch( + atom.workspace.getActiveTextEditor().getElement(), + 'markdown-preview:toggle' + ) + ) + + expectPreviewInSplitPane() + + runs(() => { + expect(preview.getTitle()).toBe('file.markdown Preview') + preview.onDidChangeTitle(titleChangedCallback) + fs.renameSync( + atom.workspace.getActiveTextEditor().getPath(), + path.join( + path.dirname(atom.workspace.getActiveTextEditor().getPath()), + 'file2.md' + ) + ) + }) + + waitsFor(() => preview.getTitle() === 'file2.md Preview') + + runs(() => expect(titleChangedCallback).toHaveBeenCalled()) + }) + }) + + describe('when the URI opened does not have a markdown-preview protocol', function () { + it('does not throw an error trying to decode the URI (regression)', function () { + waitsForPromise(() => atom.workspace.open('%')) + + runs(() => expect(atom.workspace.getActiveTextEditor()).toBeTruthy()) + }) + }) + + describe('markdown-preview:toggle', function () { + beforeEach(() => + waitsForPromise(() => atom.workspace.open('code-block.md')) + ) + + it('does not exist for text editors that are not set to a grammar defined in `markdown-preview.grammars`', function () { + atom.config.set('markdown-preview.grammars', ['source.weird-md']) + const editorElement = atom.workspace.getActiveTextEditor().getElement() + const commands = atom.commands + .findCommands({ target: editorElement }) + .map(command => command.name) + expect(commands).not.toContain('markdown-preview:toggle') + }) + + it('exists for text editors that are set to a grammar defined in `markdown-preview.grammars`', function () { + atom.config.set('markdown-preview.grammars', ['source.gfm']) + const editorElement = atom.workspace.getActiveTextEditor().getElement() + const commands = atom.commands + .findCommands({ target: editorElement }) + .map(command => command.name) + expect(commands).toContain('markdown-preview:toggle') + }) + + it('updates whenever the list of grammars changes', function () { + // Last two tests combined + atom.config.set('markdown-preview.grammars', ['source.gfm', 'text.plain']) + const editorElement = atom.workspace.getActiveTextEditor().getElement() + let commands = atom.commands + .findCommands({ target: editorElement }) + .map(command => command.name) + expect(commands).toContain('markdown-preview:toggle') + + atom.config.set('markdown-preview.grammars', [ + 'source.weird-md', + 'text.plain' + ]) + commands = atom.commands + .findCommands({ target: editorElement }) + .map(command => command.name) + expect(commands).not.toContain('markdown-preview:toggle') + }) + }) + + describe('when markdown-preview:copy-html is triggered', function () { + it('copies the HTML to the clipboard', function () { + waitsForPromise(() => atom.workspace.open('subdir/simple.md')) + + waitsForPromise(() => + atom.commands.dispatch( + atom.workspace.getActiveTextEditor().getElement(), + 'markdown-preview:copy-html' + ) + ) + + runs(() => { + expect(atom.clipboard.read()).toBe(`\ +

    italic

    +

    bold

    +

    encoding \u2192 issue

    \ +`) + + atom.workspace + .getActiveTextEditor() + .setSelectedBufferRange([[0, 0], [1, 0]]) + }) + + waitsForPromise(() => + atom.commands.dispatch( + atom.workspace.getActiveTextEditor().getElement(), + 'markdown-preview:copy-html' + ) + ) + + runs(() => + expect(atom.clipboard.read()).toBe(`\ +

    italic

    \ +`) + ) + }) + + describe('code block tokenization', function () { + beforeEach(function () { + waitsForPromise(() => atom.packages.activatePackage('language-ruby')) + + waitsForPromise(() => atom.packages.activatePackage('markdown-preview')) + + waitsForPromise(() => atom.workspace.open('subdir/file.markdown')) + + waitsForPromise(() => + atom.commands.dispatch( + atom.workspace.getActiveTextEditor().getElement(), + 'markdown-preview:copy-html' + ) + ) + + runs(() => { + preview = document.createElement('div') + preview.innerHTML = atom.clipboard.read() + }) + }) + + describe("when the code block's fence name has a matching grammar", function () { + it('tokenizes the code block with the grammar', function () { + expect( + preview.querySelector('pre span.entity.name.function.ruby') + ).toBeDefined() + }) + }) + + describe("when the code block's fence name doesn't have a matching grammar", function () { + it('does not tokenize the code block', function () { + expect( + preview.querySelectorAll( + 'pre.lang-kombucha .line .syntax--null-grammar' + ).length + ).toBe(2) + }) + }) + + describe('when the code block contains empty lines', function () { + it("doesn't remove the empty lines", function () { + expect(preview.querySelector('pre.lang-python').children.length).toBe( + 6 + ) + expect( + preview + .querySelector('pre.lang-python div:nth-child(2)') + .textContent.trim() + ).toBe('') + expect( + preview + .querySelector('pre.lang-python div:nth-child(4)') + .textContent.trim() + ).toBe('') + expect( + preview + .querySelector('pre.lang-python div:nth-child(5)') + .textContent.trim() + ).toBe('') + }) + }) + + describe('when the code block is nested in a list', function () { + it('detects and styles the block', function () { + expect(preview.querySelector('pre.lang-javascript')).toHaveClass( + 'editor-colors' + ) + }) + }) + }) + }) + + describe('sanitization', function () { + it('removes script tags and attributes that commonly contain inline scripts', function () { + waitsForPromise(() => atom.workspace.open('subdir/evil.md')) + runs(() => + atom.commands.dispatch( + atom.workspace.getActiveTextEditor().getElement(), + 'markdown-preview:toggle' + ) + ) + expectPreviewInSplitPane() + + runs(() => + expect(preview.element.innerHTML).toBe(`\ +

    hello

    + + + +world\ +`) + ) + }) + + it('remove any tag on markdown files', function () { + waitsForPromise(() => atom.workspace.open('subdir/doctype-tag.md')) + runs(() => + atom.commands.dispatch( + atom.workspace.getActiveTextEditor().getElement(), + 'markdown-preview:toggle' + ) + ) + expectPreviewInSplitPane() + + runs(() => + expect(preview.element.innerHTML).toBe(`\ +

    content +

    \ +`) + ) + }) + }) + + describe('when the markdown contains an tag', function () { + it('does not throw an exception', function () { + waitsForPromise(() => atom.workspace.open('subdir/html-tag.md')) + runs(() => + atom.commands.dispatch( + atom.workspace.getActiveTextEditor().getElement(), + 'markdown-preview:toggle' + ) + ) + expectPreviewInSplitPane() + + runs(() => expect(preview.element.innerHTML).toBe('content')) + }) + }) + + describe('when the markdown contains a
     tag', function () {
    +    it('does not throw an exception', function () {
    +      waitsForPromise(() => atom.workspace.open('subdir/pre-tag.md'))
    +      runs(() =>
    +        atom.commands.dispatch(
    +          atom.workspace.getActiveTextEditor().getElement(),
    +          'markdown-preview:toggle'
    +        )
    +      )
    +      expectPreviewInSplitPane()
    +
    +      runs(() =>
    +        expect(preview.element.querySelector('atom-text-editor')).toBeDefined()
    +      )
    +    })
    +  })
    +
    +  describe('when there is an image with a relative path and no directory', function () {
    +    it('does not alter the image src', function () {
    +      for (let projectPath of atom.project.getPaths()) {
    +        atom.project.removePath(projectPath)
    +      }
    +
    +      const filePath = path.join(temp.mkdirSync('atom'), 'bar.md')
    +      fs.writeFileSync(filePath, '![rel path](/foo.png)')
    +
    +      waitsForPromise(() => atom.workspace.open(filePath))
    +
    +      runs(() =>
    +        atom.commands.dispatch(
    +          atom.workspace.getActiveTextEditor().getElement(),
    +          'markdown-preview:toggle'
    +        )
    +      )
    +      expectPreviewInSplitPane()
    +
    +      runs(() =>
    +        expect(preview.element.innerHTML).toBe(`\
    +

    rel path

    \ +`) + ) + }) + }) + + describe('GitHub style markdown preview', function () { + beforeEach(() => atom.config.set('markdown-preview.useGitHubStyle', false)) + + it('renders markdown using the default style when GitHub styling is disabled', function () { + waitsForPromise(() => atom.workspace.open('subdir/simple.md')) + runs(() => + atom.commands.dispatch( + atom.workspace.getActiveTextEditor().getElement(), + 'markdown-preview:toggle' + ) + ) + expectPreviewInSplitPane() + + runs(() => + expect(preview.element.getAttribute('data-use-github-style')).toBeNull() + ) + }) + + it('renders markdown using the GitHub styling when enabled', function () { + atom.config.set('markdown-preview.useGitHubStyle', true) + + waitsForPromise(() => atom.workspace.open('subdir/simple.md')) + runs(() => + atom.commands.dispatch( + atom.workspace.getActiveTextEditor().getElement(), + 'markdown-preview:toggle' + ) + ) + expectPreviewInSplitPane() + + runs(() => + expect(preview.element.getAttribute('data-use-github-style')).toBe('') + ) + }) + + it('updates the rendering style immediately when the configuration is changed', function () { + waitsForPromise(() => atom.workspace.open('subdir/simple.md')) + runs(() => + atom.commands.dispatch( + atom.workspace.getActiveTextEditor().getElement(), + 'markdown-preview:toggle' + ) + ) + expectPreviewInSplitPane() + + runs(() => { + expect(preview.element.getAttribute('data-use-github-style')).toBeNull() + + atom.config.set('markdown-preview.useGitHubStyle', true) + expect( + preview.element.getAttribute('data-use-github-style') + ).not.toBeNull() + + atom.config.set('markdown-preview.useGitHubStyle', false) + expect(preview.element.getAttribute('data-use-github-style')).toBeNull() + }) + }) + }) + + describe('when markdown-preview:save-as-html is triggered', function () { + beforeEach(function () { + waitsForPromise(() => atom.workspace.open('subdir/simple.markdown')) + runs(() => + atom.commands.dispatch( + atom.workspace.getActiveTextEditor().getElement(), + 'markdown-preview:toggle' + ) + ) + expectPreviewInSplitPane() + }) + + it('saves the HTML when it is triggered and the editor has focus', function () { + const [editorPane] = atom.workspace.getCenter().getPanes() + editorPane.activate() + + const outputPath = temp.path({ suffix: '.html' }) + expect(fs.existsSync(outputPath)).toBe(false) + + runs(() => { + spyOn(preview, 'getSaveDialogOptions').andReturn({ + defaultPath: outputPath + }) + spyOn(atom.applicationDelegate, 'showSaveDialog').andCallFake(function ( + options, + callback + ) { + if (typeof callback === 'function') { + callback(options.defaultPath) + } + // TODO: When https://github.com/atom/atom/pull/16245 lands remove the return + // and the existence check on the callback + return options.defaultPath + }) + return atom.commands.dispatch( + atom.workspace.getActiveTextEditor().getElement(), + 'markdown-preview:save-as-html' + ) + }) + + waitsFor(() => fs.existsSync(outputPath)) + + runs(() => expect(fs.existsSync(outputPath)).toBe(true)) + }) + + it('saves the HTML when it is triggered and the preview pane has focus', function () { + const [editorPane, previewPane] = atom.workspace.getCenter().getPanes() + previewPane.activate() + + const outputPath = temp.path({ suffix: '.html' }) + expect(fs.existsSync(outputPath)).toBe(false) + + runs(() => { + spyOn(preview, 'getSaveDialogOptions').andReturn({ + defaultPath: outputPath + }) + spyOn(atom.applicationDelegate, 'showSaveDialog').andCallFake(function ( + options, + callback + ) { + if (typeof callback === 'function') { + callback(options.defaultPath) + } + // TODO: When https://github.com/atom/atom/pull/16245 lands remove the return + // and the existence check on the callback + return options.defaultPath + }) + return atom.commands.dispatch( + editorPane.getActiveItem().getElement(), + 'markdown-preview:save-as-html' + ) + }) + + waitsFor(() => fs.existsSync(outputPath)) + + runs(() => expect(fs.existsSync(outputPath)).toBe(true)) + }) + }) +}) diff --git a/spec/markdown-preview-view-spec.js b/spec/markdown-preview-view-spec.js new file mode 100644 index 0000000..45a81ea --- /dev/null +++ b/spec/markdown-preview-view-spec.js @@ -0,0 +1,604 @@ +/* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md + */ +const path = require('path') +const fs = require('fs-plus') +const temp = require('temp').track() +const url = require('url') +const { TextEditor } = require('atom') +const MarkdownPreviewView = require('../lib/markdown-preview-view') +const TextMateLanguageMode = new TextEditor().getBuffer().getLanguageMode() + .constructor + +describe('MarkdownPreviewView', function () { + let preview = null + + beforeEach(function () { + // Makes _.debounce work + jasmine.useRealClock() + + jasmine.unspy(TextMateLanguageMode.prototype, 'tokenizeInBackground') + + spyOn(atom.packages, 'hasActivatedInitialPackages').andReturn(true) + + const filePath = atom.project + .getDirectories()[0] + .resolve('subdir/file.markdown') + preview = new MarkdownPreviewView({ filePath }) + jasmine.attachToDOM(preview.element) + + waitsForPromise(() => atom.packages.activatePackage('language-ruby')) + + waitsForPromise(() => atom.packages.activatePackage('language-javascript')) + + waitsForPromise(() => atom.packages.activatePackage('markdown-preview')) + }) + + afterEach(() => preview.destroy()) + + describe('::constructor', function () { + it('shows a loading spinner and renders the markdown', function () { + preview.showLoading() + expect(preview.element.querySelector('.markdown-spinner')).toBeDefined() + + waitsForPromise(() => preview.renderMarkdown()) + + runs(() => expect(preview.element.querySelector('.emoji')).toBeDefined()) + }) + + it('shows an error message when there is an error', function () { + preview.showError('Not a real file') + expect(preview.element.textContent).toMatch('Failed') + }) + + it('rerenders the markdown and the scrollTop stays the same', function () { + waitsForPromise(() => preview.renderMarkdown()) + + runs(function () { + preview.element.style.maxHeight = '10px' + preview.element.scrollTop = 24 + expect(preview.element.scrollTop).toBe(24) + }) + + waitsForPromise(() => preview.renderMarkdown()) + + runs(() => expect(preview.element.scrollTop).toBe(24)) + }) + }) + + describe('serialization', function () { + let newPreview = null + + afterEach(function () { + if (newPreview) { + newPreview.destroy() + } + }) + + it('recreates the preview when serialized/deserialized', function () { + newPreview = atom.deserializers.deserialize(preview.serialize()) + jasmine.attachToDOM(newPreview.element) + expect(newPreview.getPath()).toBe(preview.getPath()) + }) + + it('does not recreate a preview when the file no longer exists', function () { + const filePath = path.join(temp.mkdirSync('markdown-preview-'), 'foo.md') + fs.writeFileSync(filePath, '# Hi') + + preview.destroy() + preview = new MarkdownPreviewView({ filePath }) + const serialized = preview.serialize() + fs.removeSync(filePath) + + newPreview = atom.deserializers.deserialize(serialized) + expect(newPreview).toBeUndefined() + }) + + it('serializes the editor id when opened for an editor', function () { + preview.destroy() + + waitsForPromise(() => atom.workspace.open('new.markdown')) + + runs(function () { + preview = new MarkdownPreviewView({ + editorId: atom.workspace.getActiveTextEditor().id + }) + + jasmine.attachToDOM(preview.element) + expect(preview.getPath()).toBe( + atom.workspace.getActiveTextEditor().getPath() + ) + + newPreview = atom.deserializers.deserialize(preview.serialize()) + jasmine.attachToDOM(newPreview.element) + expect(newPreview.getPath()).toBe(preview.getPath()) + }) + }) + }) + + describe('code block conversion to atom-text-editor tags', function () { + beforeEach(function () { + waitsForPromise(() => preview.renderMarkdown()) + }) + + it('removes line decorations on rendered code blocks', function () { + const editor = preview.element.querySelector( + "atom-text-editor[data-grammar='text plain null-grammar']" + ) + const decorations = editor + .getModel() + .getDecorations({ class: 'cursor-line', type: 'line' }) + expect(decorations.length).toBe(0) + }) + + it('sets the editors as read-only', function () { + preview.element + .querySelectorAll('atom-text-editor') + .forEach(editorElement => + expect(editorElement.getAttribute('tabindex')).toBeNull() + ) + }) + + describe("when the code block's fence name has a matching grammar", function () { + it('assigns the grammar on the atom-text-editor', function () { + const rubyEditor = preview.element.querySelector( + "atom-text-editor[data-grammar='source ruby']" + ) + expect(rubyEditor.getModel().getText()).toBe(`\ +def func + x = 1 +end\ +`) + + // nested in a list item + const jsEditor = preview.element.querySelector( + "atom-text-editor[data-grammar='source js']" + ) + expect(jsEditor.getModel().getText()).toBe(`\ +if a === 3 { +b = 5 +}\ +`) + }) + }) + + describe("when the code block's fence name doesn't have a matching grammar", function () { + it('does not assign a specific grammar', function () { + const plainEditor = preview.element.querySelector( + "atom-text-editor[data-grammar='text plain null-grammar']" + ) + expect(plainEditor.getModel().getText()).toBe(`\ +function f(x) { + return x++; +}\ +`) + }) + }) + + describe('when an editor cannot find the grammar that is later loaded', function () { + it('updates the editor grammar', function () { + let renderSpy = null + + if (typeof atom.grammars.onDidRemoveGrammar !== 'function') { + // TODO: Remove once atom.grammars.onDidRemoveGrammar is released + waitsForPromise(() => atom.packages.activatePackage('language-gfm')) + } + + runs( + () => (renderSpy = spyOn(preview, 'renderMarkdown').andCallThrough()) + ) + + waitsForPromise(() => atom.packages.deactivatePackage('language-ruby')) + + waitsFor( + 'renderMarkdown to be called after disabling a language', + () => renderSpy.callCount === 1 + ) + + runs(function () { + const rubyEditor = preview.element.querySelector( + "atom-text-editor[data-grammar='source ruby']" + ) + expect(rubyEditor).toBeNull() + }) + + waitsForPromise(() => atom.packages.activatePackage('language-ruby')) + + waitsFor( + 'renderMarkdown to be called after enabling a language', + () => renderSpy.callCount === 2 + ) + + runs(function () { + const rubyEditor = preview.element.querySelector( + "atom-text-editor[data-grammar='source ruby']" + ) + expect(rubyEditor.getModel().getText()).toBe(`\ +def func + x = 1 +end\ +`) + }) + }) + }) + }) + + describe('image resolving', function () { + beforeEach(function () { + waitsForPromise(() => preview.renderMarkdown()) + }) + + describe('when the image uses a relative path', function () { + it('resolves to a path relative to the file', function () { + const image = preview.element.querySelector('img[alt=Image1]') + expect(image.getAttribute('src')).toBe( + atom.project.getDirectories()[0].resolve('subdir/image1.png') + ) + }) + }) + + describe('when the image uses an absolute path that does not exist', function () { + it('resolves to a path relative to the project root', function () { + const image = preview.element.querySelector('img[alt=Image2]') + expect(image.src).toMatch( + url.parse(atom.project.getDirectories()[0].resolve('tmp/image2.png')) + ) + }) + }) + + describe('when the image uses an absolute path that exists', function () { + it("doesn't change the URL when allowUnsafeProtocols is true", function () { + preview.destroy() + + atom.config.set('markdown-preview.allowUnsafeProtocols', true) + + const filePath = path.join(temp.mkdirSync('atom'), 'foo.md') + fs.writeFileSync(filePath, `![absolute](${filePath})`) + preview = new MarkdownPreviewView({ filePath }) + jasmine.attachToDOM(preview.element) + + waitsForPromise(() => preview.renderMarkdown()) + + runs(() => + expect( + preview.element.querySelector('img[alt=absolute]').src + ).toMatch(url.parse(filePath)) + ) + }) + }) + + it('removes the URL when allowUnsafeProtocols is false', function () { + preview.destroy() + + atom.config.set('markdown-preview.allowUnsafeProtocols', false) + + const filePath = path.join(temp.mkdirSync('atom'), 'foo.md') + fs.writeFileSync(filePath, `![absolute](${filePath})`) + preview = new MarkdownPreviewView({ filePath }) + jasmine.attachToDOM(preview.element) + + waitsForPromise(() => preview.renderMarkdown()) + + runs(() => + expect(preview.element.querySelector('img[alt=absolute]').src).toMatch( + '' + ) + ) + }) + + describe('when the image uses a web URL', function () { + it("doesn't change the URL", function () { + const image = preview.element.querySelector('img[alt=Image3]') + expect(image.src).toBe('http://github.com/image3.png') + }) + }) + }) + + describe('gfm newlines', function () { + describe('when gfm newlines are not enabled', function () { + it('creates a single paragraph with
    ', function () { + atom.config.set('markdown-preview.breakOnSingleNewline', false) + + waitsForPromise(() => preview.renderMarkdown()) + + runs(() => + expect( + preview.element.querySelectorAll('p:last-child br').length + ).toBe(0) + ) + }) + }) + + describe('when gfm newlines are enabled', function () { + it('creates a single paragraph with no
    ', function () { + atom.config.set('markdown-preview.breakOnSingleNewline', true) + + waitsForPromise(() => preview.renderMarkdown()) + + runs(() => + expect( + preview.element.querySelectorAll('p:last-child br').length + ).toBe(1) + ) + }) + }) + }) + + describe('yaml front matter', function () { + it('creates a table with the YAML variables', function () { + atom.config.set('markdown-preview.breakOnSingleNewline', true) + + waitsForPromise(() => preview.renderMarkdown()) + + runs(() => { + expect( + [...preview.element.querySelectorAll('table th')].map( + el => el.textContent + ) + ).toEqual(['variable1', 'array']) + expect( + [...preview.element.querySelectorAll('table td')].map( + el => el.textContent + ) + ).toEqual(['value1', 'foo,bar']) + }) + }) + }) + + describe('text selections', function () { + it('adds the `has-selection` class to the preview depending on if there is a text selection', function () { + expect(preview.element.classList.contains('has-selection')).toBe(false) + + const selection = window.getSelection() + selection.removeAllRanges() + selection.selectAllChildren(document.querySelector('atom-text-editor')) + + waitsFor( + () => preview.element.classList.contains('has-selection') === true + ) + + runs(() => selection.removeAllRanges()) + + waitsFor( + () => preview.element.classList.contains('has-selection') === false + ) + }) + }) + + describe('when core:save-as is triggered', function () { + beforeEach(function () { + preview.destroy() + const filePath = atom.project + .getDirectories()[0] + .resolve('subdir/code-block.md') + preview = new MarkdownPreviewView({ filePath }) + // Add to workspace for core:save-as command to be propagated up to the workspace + waitsForPromise(() => atom.workspace.open(preview)) + runs(() => jasmine.attachToDOM(atom.views.getView(atom.workspace))) + }) + + it('saves the rendered HTML and opens it', function () { + const outputPath = fs.realpathSync(temp.mkdirSync()) + 'output.html' + + const createRule = (selector, css) => ({ + selectorText: selector, + cssText: `${selector} ${css}` + }) + const markdownPreviewStyles = [ + { + rules: [createRule('.markdown-preview', '{ color: orange; }')] + }, + { + rules: [ + createRule('.not-included', '{ color: green; }'), + createRule('.markdown-preview :host', '{ color: purple; }') + ] + } + ] + + const atomTextEditorStyles = [ + 'atom-text-editor .line { color: brown; }\natom-text-editor .number { color: cyan; }', + 'atom-text-editor :host .something { color: black; }', + 'atom-text-editor .hr { background: url(atom://markdown-preview/assets/hr.png); }' + ] + + waitsForPromise(() => preview.renderMarkdown()) + + runs(() => { + expect(fs.isFileSync(outputPath)).toBe(false) + spyOn(preview, 'getSaveDialogOptions').andReturn({ + defaultPath: outputPath + }) + spyOn(atom.applicationDelegate, 'showSaveDialog').andCallFake(function ( + options, + callback + ) { + if (typeof callback === 'function') { + callback(options.defaultPath) + } + // TODO: When https://github.com/atom/atom/pull/16245 lands remove the return + // and the existence check on the callback + return options.defaultPath + }) + spyOn(preview, 'getDocumentStyleSheets').andReturn( + markdownPreviewStyles + ) + spyOn(preview, 'getTextEditorStyles').andReturn(atomTextEditorStyles) + }) + + waitsForPromise(() => + atom.commands.dispatch(preview.element, 'core:save-as') + ) + + waitsFor(() => { + const activeEditor = atom.workspace.getActiveTextEditor() + return activeEditor && activeEditor.getPath() === outputPath + }) + + runs(() => { + const element = document.createElement('div') + element.innerHTML = fs.readFileSync(outputPath) + expect(element.querySelector('h1').innerText).toBe('Code Block') + expect( + element.querySelector( + '.line .syntax--source.syntax--js .syntax--constant.syntax--numeric' + ).innerText + ).toBe('3') + expect( + element.querySelector( + '.line .syntax--source.syntax--js .syntax--keyword.syntax--control' + ).innerText + ).toBe('if') + expect( + element.querySelector( + '.line .syntax--source.syntax--js .syntax--constant.syntax--numeric' + ).innerText + ).toBe('3') + }) + }) + + describe('text editor style extraction', function () { + let [extractedStyles] = [] + + const textEditorStyle = '.editor-style .extraction-test { color: blue; }' + const unrelatedStyle = '.something else { color: red; }' + + beforeEach(function () { + atom.styles.addStyleSheet(textEditorStyle, { + context: 'atom-text-editor' + }) + + atom.styles.addStyleSheet(unrelatedStyle, { + context: 'unrelated-context' + }) + + return (extractedStyles = preview.getTextEditorStyles()) + }) + + it('returns an array containing atom-text-editor css style strings', function () { + expect(extractedStyles.indexOf(textEditorStyle)).toBeGreaterThan(-1) + }) + + it('does not return other styles', function () { + expect(extractedStyles.indexOf(unrelatedStyle)).toBe(-1) + }) + }) + }) + + describe('when core:copy is triggered', function () { + beforeEach(function () { + preview.destroy() + preview.element.remove() + + const filePath = atom.project + .getDirectories()[0] + .resolve('subdir/code-block.md') + preview = new MarkdownPreviewView({ filePath }) + jasmine.attachToDOM(preview.element) + + waitsForPromise(() => preview.renderMarkdown()) + }) + + describe('when there is no text selected', function () { + it('copies the rendered HTML of the entire Markdown document to the clipboard', function () { + expect(atom.clipboard.read()).toBe('initial clipboard content') + + waitsForPromise(() => + atom.commands.dispatch(preview.element, 'core:copy') + ) + + runs(() => { + const element = document.createElement('div') + element.innerHTML = atom.clipboard.read() + expect(element.querySelector('h1').innerText).toBe('Code Block') + expect( + element.querySelector( + '.line .syntax--source.syntax--js .syntax--constant.syntax--numeric' + ).innerText + ).toBe('3') + expect( + element.querySelector( + '.line .syntax--source.syntax--js .syntax--keyword.syntax--control' + ).innerText + ).toBe('if') + expect( + element.querySelector( + '.line .syntax--source.syntax--js .syntax--constant.syntax--numeric' + ).innerText + ).toBe('3') + }) + }) + }) + + describe('when there is a text selection', function () { + it('directly copies the selection to the clipboard', function () { + const selection = window.getSelection() + selection.removeAllRanges() + const range = document.createRange() + range.setStart(document.querySelector('atom-text-editor'), 0) + range.setEnd(document.querySelector('p').firstChild, 3) + selection.addRange(range) + + atom.commands.dispatch(preview.element, 'core:copy') + const clipboardText = atom.clipboard.read() + + expect(clipboardText).toBe(`\ +if a === 3 { + b = 5 +} + +enc\ +`) + }) + }) + }) + + describe('when markdown-preview:select-all is triggered', function () { + it('selects the entire Markdown preview', function () { + const filePath = atom.project + .getDirectories()[0] + .resolve('subdir/code-block.md') + const preview2 = new MarkdownPreviewView({ filePath }) + jasmine.attachToDOM(preview2.element) + + waitsForPromise(() => preview.renderMarkdown()) + + runs(function () { + atom.commands.dispatch(preview.element, 'markdown-preview:select-all') + const { commonAncestorContainer } = window.getSelection().getRangeAt(0) + expect(commonAncestorContainer).toEqual(preview.element) + }) + + waitsForPromise(() => preview2.renderMarkdown()) + + runs(() => { + atom.commands.dispatch(preview2.element, 'markdown-preview:select-all') + const selection = window.getSelection() + expect(selection.rangeCount).toBe(1) + const { commonAncestorContainer } = selection.getRangeAt(0) + expect(commonAncestorContainer).toEqual(preview2.element) + }) + }) + }) + + describe('when markdown-preview:zoom-in or markdown-preview:zoom-out are triggered', function () { + it('increases or decreases the zoom level of the markdown preview element', function () { + jasmine.attachToDOM(preview.element) + + waitsForPromise(() => preview.renderMarkdown()) + + runs(function () { + const originalZoomLevel = getComputedStyle(preview.element).zoom + atom.commands.dispatch(preview.element, 'markdown-preview:zoom-in') + expect(getComputedStyle(preview.element).zoom).toBeGreaterThan( + originalZoomLevel + ) + atom.commands.dispatch(preview.element, 'markdown-preview:zoom-out') + expect(getComputedStyle(preview.element).zoom).toBe(originalZoomLevel) + }) + }) + }) +}) diff --git a/styles/markdown-preview-default.less b/styles/markdown-preview-default.less new file mode 100644 index 0000000..25f7ade --- /dev/null +++ b/styles/markdown-preview-default.less @@ -0,0 +1,156 @@ + +// Default Markdown Preview styles + +// These are the default Markdown Preview styles. +// They use the syntax-variables to adapt to the color scheme of syntax themes. + + +@import "syntax-variables"; + +.markdown-preview:not([data-use-github-style]) { + + @fg: @syntax-text-color; + @bg: @syntax-background-color; + + @fg-accent: @syntax-cursor-color; + @fg-strong: contrast(@bg, darken(@fg, 32%), lighten(@fg, 32%)); + @fg-subtle: contrast(@fg, lighten(@fg, 16%), darken(@fg, 16%)); + + @border: contrast(@bg, lighten(@bg, 16%), darken(@bg, 16%)); + + @margin: 1.5em; + + + padding: 2em; + font-size: 1.2em; + color: @fg; + background-color: @bg; + overflow: auto; + + & > :first-child { + margin-top: 0; + } + + + // Headings -------------------- + + h1, h2, h3, h4, h5, h6 { + line-height: 1.2; + margin-top: @margin; + margin-bottom: @margin/3; + color: @fg-strong; + } + + h1 { font-size: 2.4em; font-weight: 300; } + h2 { font-size: 1.8em; font-weight: 400; } + h3 { font-size: 1.5em; font-weight: 500; } + h4 { font-size: 1.2em; font-weight: 600; } + h5 { font-size: 1.1em; font-weight: 600; } + h6 { font-size: 1.0em; font-weight: 600; } + + + // Emphasis -------------------- + + strong { + color: @fg-strong; + } + + del { + color: @fg-subtle; + } + + + // Link -------------------- + + a, + a code { + color: @fg-accent; + } + + + // Images -------------------- + + img { + max-width: 100%; + } + + + // Paragraph -------------------- + + & > p { + margin-top: 0; + margin-bottom: @margin; + } + + + // List -------------------- + + & > ul, + & > ol { + margin-bottom: @margin; + } + + + // Blockquotes -------------------- + + blockquote { + margin: @margin 0; + font-size: inherit; + color: @fg-subtle; + border-color: @border; + border-width: 4px; + } + + + // HR -------------------- + + hr { + margin: @margin*2 0; + border-top: 2px dashed @border; + background: none; + } + + + // Table -------------------- + + table { + margin: @margin 0; + } + + th { + color: @fg-strong; + } + + th, + td { + padding: .66em 1em; + border: 1px solid @border; + } + + + // Code -------------------- + + code { + color: @fg-strong; + background-color: contrast(@syntax-background-color, lighten(@syntax-background-color, 8%), darken(@syntax-background-color, 6%)); + } + + atom-text-editor { + margin: @margin 0; + padding: 1em; + font-size: .92em; + border-radius: 3px; + background-color: contrast(@syntax-background-color, lighten(@syntax-background-color, 4%), darken(@syntax-background-color, 4%)); + } + + + // KBD -------------------- + + kbd { + color: @fg-strong; + border: 1px solid @border; + border-bottom: 2px solid darken(@border, 6%); + background-color: contrast(@syntax-background-color, lighten(@syntax-background-color, 8%), darken(@syntax-background-color, 6%)); + } + +} diff --git a/styles/markdown-preview-github.less b/styles/markdown-preview-github.less new file mode 100644 index 0000000..fedb5cb --- /dev/null +++ b/styles/markdown-preview-github.less @@ -0,0 +1,40 @@ + +// GitHub.com styles + +// These are the GitHub Flavored Markdown styles also found on github.com. +// They can be anabled in the markdown-preview settings by turning on "Use GitHub.com styles". + + +@import (reference) "../assets/primer-markdown"; + +.markdown-preview[data-use-github-style] { + + // Includes GitHub.com styles from `../assets/primer-markdown.less`. + // Source: https://github.com/primer/primer/tree/master/modules/primer-markdown + .markdown-body(); + + + // The styles below override/complement the GitHub.com styles + // It's needed because some markup or global styles are different + padding: 30px; + font-size: 16px; + color: #333; + background-color: #fff; + overflow: scroll; + + a { + color: #337ab7; + } + + code { + color: inherit; + } + + atom-text-editor { + padding: .8em 1em; + margin-bottom: 1em; + font-size: .85em; + border-radius: 4px; + overflow: auto; + } +} diff --git a/styles/markdown-preview.less b/styles/markdown-preview.less new file mode 100644 index 0000000..4ae621e --- /dev/null +++ b/styles/markdown-preview.less @@ -0,0 +1,129 @@ +// Global Markdown Preview styles + +.markdown-preview { + atom-text-editor { + // only show scrollbars on hover + .scrollbars-visible-always & { + .vertical-scrollbar, + .horizontal-scrollbar { + visibility: hidden; + } + } + + .scrollbars-visible-always &:hover { + .vertical-scrollbar, + .horizontal-scrollbar { + visibility: visible; + } + } + + user-select: auto; + } + + // move task list checkboxes + .task-list-item input[type=checkbox] { + position: absolute; + margin: .25em 0 0 -1.4em; + } + + .task-list-item { + list-style-type: none; + } +} + +.markdown-spinner { + margin: auto; + background-image: url(images/octocat-spinner-128.gif); + background-repeat: no-repeat; + background-size: 64px; + background-position: top center; + padding-top: 70px; + text-align: center; +} + +// style the background color of the tree view +.tree-view { + // background-color: whitesmoke; +} + +// style the background and foreground colors on the atom-text-editor-element itself +atom-text-editor { + // color: white; + // background-color: hsl(180, 24%, 12%); +} + +// To style other content in the text editor's shadow DOM, use the ::shadow expression +atom-text-editor::shadow .cursor { + // border-color: red; +} + +.markdown-preview-custom { + // please write your custom style here + // eg: + // color: blue; // change font color + // font-size: 14px; // change font size + // + + // custom pdf output style + + h1 { + counter-increment: h1counter; + counter-reset: h2counter; + } + + h2 { + counter-increment: h2counter; + counter-reset: h3counter; + } + + h3 { + counter-increment: h3counter; + counter-reset: h4counter; + } + + h4 { + counter-increment: h4counter; + counter-reset: h5counter; + } + + h1:before { + content: counter(h1counter) ". "; + } + + h2:before { + content: counter(h1counter) "." counter(h2counter) ". "; + } + + h3:before { + content: counter(h1counter) "." counter(h2counter) "." counter(h3counter) ". "; + } + + h4:before { + content: counter(h1counter) "." counter(h2counter) "." counter(h3counter) "." counter(h4counter) ". "; + } + + @media print { + + } + + // custom phantomjs png/jpeg export style + &.phantomjs-image { + + } + + //custom phantomjs pdf export style + &.phantomjs-pdf { + + } + + // custom presentation style + .preview-slides .slide, + &[data-presentation-mode] { + // eg + // background-color: #000; + } +} + +.markdown-preview { + .markdown-preview-custom() !important; +}