diff --git a/.boostnoterc.sample b/.boostnoterc.sample new file mode 100644 index 00000000..2caa2c1a --- /dev/null +++ b/.boostnoterc.sample @@ -0,0 +1,33 @@ +{ + "amaEnabled": true, + "editor": { + "fontFamily": "Monaco, Consolas", + "fontSize": "14", + "indentSize": "2", + "indentType": "space", + "keyMap": "vim", + "switchPreview": "BLUR", + "theme": "monokai" + }, + "hotkey": { + "toggleFinder": "Cmd + Alt + S", + "toggleMain": "Cmd + Alt + L" + }, + "isSideNavFolded": false, + "listStyle": "DEFAULT", + "listWidth": 174, + "navWidth": 200, + "preview": { + "codeBlockTheme": "dracula", + "fontFamily": "Lato", + "fontSize": "14", + "lineNumber": true + }, + "sortBy": "UPDATED_AT", + "ui": { + "defaultNote": "ALWAYS_ASK", + "disableDirectWrite": false, + "theme": "default" + }, + "zoom": 1 +} diff --git a/.eslintrc b/.eslintrc index ac065a8b..9177344c 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,10 +1,16 @@ { - "extends": ["standard", "standard-jsx"], + "extends": ["standard", "standard-jsx", "plugin:react/recommended"], + "plugins": ["react"], "rules": { "no-useless-escape": 0, "prefer-const": "warn", "no-unused-vars": "warn", "no-undef": "warn", - "no-lone-blocks": "warn" + "no-lone-blocks": "warn", + "react/prop-types": 0, + "react/no-string-refs": 0, + "react/no-find-dom-node": "warn", + "react/no-render-return-value": "warn", + "react/no-deprecated": "warn" } } diff --git a/Backers.md b/Backers.md index 609b74b3..49d1a0ea 100644 --- a/Backers.md +++ b/Backers.md @@ -3,3 +3,7 @@ You can support Boostnote from $ 5 a month! # Backers [Kazu Yokomizo](https://twitter.com/kazup_bot) + +kolchan11 + +RonWalker22 diff --git a/browser/components/CodeEditor.js b/browser/components/CodeEditor.js index d32d3240..752c3f76 100644 --- a/browser/components/CodeEditor.js +++ b/browser/components/CodeEditor.js @@ -3,6 +3,7 @@ import _ from 'lodash' import CodeMirror from 'codemirror' import path from 'path' import copyImage from 'browser/main/lib/dataApi/copyImage' +import { findStorage } from 'browser/lib/findStorage' CodeMirror.modeURL = '../node_modules/codemirror/mode/%N/%N.js' @@ -39,6 +40,7 @@ export default class CodeEditor extends React.Component { } this.props.onBlur != null && this.props.onBlur(e) } + this.pasteHandler = (editor, e) => this.handlePaste(editor, e) this.loadStyleHandler = (e) => { this.editor.refresh() } @@ -98,14 +100,25 @@ export default class CodeEditor extends React.Component { this.editor.on('blur', this.blurHandler) this.editor.on('change', this.changeHandler) + this.editor.on('paste', this.pasteHandler) let editorTheme = document.getElementById('editorTheme') editorTheme.addEventListener('load', this.loadStyleHandler) + + CodeMirror.Vim.defineEx('quit', 'q', this.quitEditor) + CodeMirror.Vim.defineEx('q!', 'q!', this.quitEditor) + CodeMirror.Vim.defineEx('wq', 'wq', this.quitEditor) + CodeMirror.Vim.defineEx('qw', 'qw', this.quitEditor) + } + + quitEditor () { + document.querySelector('textarea').blur() } componentWillUnmount () { this.editor.off('blur', this.blurHandler) this.editor.off('change', this.changeHandler) + this.editor.off('paste', this.pasteHandler) let editorTheme = document.getElementById('editorTheme') editorTheme.removeEventListener('load', this.loadStyleHandler) } @@ -201,7 +214,30 @@ export default class CodeEditor extends React.Component { insertImageMd (imageMd) { const textarea = this.editor.getInputField() const cm = this.editor - textarea.value = `${textarea.value.substr(0, textarea.selectionStart)}${imageMd}${textarea.value.substr(textarea.selectionEnd)}` + cm.replaceSelection(`${textarea.value.substr(0, textarea.selectionStart)}${imageMd}${textarea.value.substr(textarea.selectionEnd)}`) + } + + handlePaste (editor, e) { + const dataTransferItem = e.clipboardData.items[0] + if (!dataTransferItem.type.match('image')) return + + const blob = dataTransferItem.getAsFile() + let reader = new FileReader() + let base64data + + reader.readAsDataURL(blob) + reader.onloadend = () => { + base64data = reader.result.replace(/^data:image\/png;base64,/, '') + base64data += base64data.replace('+', ' ') + const binaryData = new Buffer(base64data, 'base64').toString('binary') + const imageName = Math.random().toString(36).slice(-16) + const storagePath = findStorage(this.props.storageKey).path + const imagePath = path.join(`${storagePath}`, 'images', `${imageName}.png`) + + require('fs').writeFile(imagePath, binaryData, 'binary') + const imageMd = `![${imageName}](${path.join('/:storage', `${imageName}.png`)})` + this.insertImageMd(imageMd) + } } render () { diff --git a/browser/components/MarkdownEditor.js b/browser/components/MarkdownEditor.js index f20ec087..65b52f86 100644 --- a/browser/components/MarkdownEditor.js +++ b/browser/components/MarkdownEditor.js @@ -266,6 +266,7 @@ class MarkdownEditor extends React.Component { onMouseUp={(e) => this.handlePreviewMouseUp(e)} onMouseDown={(e) => this.handlePreviewMouseDown(e)} onCheckboxClick={(e) => this.handleCheckboxClick(e)} + showCopyNotification={config.ui.showCopyNotification} storagePath={storage.path} /> diff --git a/browser/components/MarkdownPreview.js b/browser/components/MarkdownPreview.js index a92fe68d..8bee23a5 100644 --- a/browser/components/MarkdownPreview.js +++ b/browser/components/MarkdownPreview.js @@ -40,7 +40,6 @@ body { code { font-family: ${codeBlockFontFamily.join(', ')}; background-color: rgba(0,0,0,0.04); - color: #CC305F; } .lineNumber { ${lineNumber && 'display: block !important;'} @@ -51,12 +50,12 @@ code { color: rgba(147,147,149,0.8);; fill: rgba(147,147,149,1);; border-radius: 50%; - margin: 7px; + margin: 0px 10px; border: none; background-color: transparent; outline: none; - height: 32px; - width: 32px; + height: 15px; + width: 15px; cursor: pointer; } @@ -224,6 +223,7 @@ export default class MarkdownPreview extends React.Component { prevProps.codeBlockFontFamily !== this.props.codeBlockFontFamily || prevProps.codeBlockTheme !== this.props.codeBlockTheme || prevProps.lineNumber !== this.props.lineNumber || + prevProps.showCopyNotification !== this.props.showCopyNotification || prevProps.theme !== this.props.theme) { this.applyStyle() this.rewriteIframe() @@ -262,7 +262,7 @@ export default class MarkdownPreview extends React.Component { el.removeEventListener('click', this.linkClickHandler) }) - let { value, theme, indentSize, codeBlockTheme, storagePath } = this.props + let { value, theme, indentSize, codeBlockTheme, showCopyNotification, storagePath } = this.props this.refs.root.contentWindow.document.body.setAttribute('data-theme', theme) @@ -291,8 +291,9 @@ export default class MarkdownPreview extends React.Component { }) _.forEach(this.refs.root.contentWindow.document.querySelectorAll('img'), (el) => { + el.src = markdown.normalizeLinkText(el.src) if (!/\/:storage/.test(el.src)) return - el.src = `file:///${path.join(storagePath, 'images', path.basename(el.src))}` + el.src = `file:///${markdown.normalizeLinkText(path.join(storagePath, 'images', path.basename(el.src)))}` }) codeBlockTheme = consts.THEMES.some((_theme) => _theme === codeBlockTheme) @@ -308,10 +309,12 @@ export default class MarkdownPreview extends React.Component { copyIcon.innerHTML = '' copyIcon.onclick = (e) => { copy(content) - this.notify('Saved to Clipboard!', { - body: 'Paste it wherever you want!', - silent: true - }) + if (showCopyNotification) { + this.notify('Saved to Clipboard!', { + body: 'Paste it wherever you want!', + silent: true + }) + } } el.parentNode.appendChild(copyIcon) el.innerHTML = '' @@ -425,5 +428,6 @@ MarkdownPreview.propTypes = { onMouseDown: PropTypes.func, className: PropTypes.string, value: PropTypes.string, + showCopyNotification: PropTypes.bool, storagePath: PropTypes.string } diff --git a/browser/components/ModalEscButton.js b/browser/components/ModalEscButton.js index 190b7ccd..42fe9100 100644 --- a/browser/components/ModalEscButton.js +++ b/browser/components/ModalEscButton.js @@ -6,7 +6,7 @@ const ModalEscButton = ({ handleEscButtonClick }) => ( ) diff --git a/browser/components/ModalEscButton.styl b/browser/components/ModalEscButton.styl index 378fac85..12cd56ed 100644 --- a/browser/components/ModalEscButton.styl +++ b/browser/components/ModalEscButton.styl @@ -11,4 +11,6 @@ height top-bar-height .esc-mark - font-size 15px + font-size 28px + margin-top -5px + margin-bottom -7px \ No newline at end of file diff --git a/browser/components/NoteItem.js b/browser/components/NoteItem.js index a4e9ca48..1652b02b 100644 --- a/browser/components/NoteItem.js +++ b/browser/components/NoteItem.js @@ -4,7 +4,9 @@ import React, { PropTypes } from 'react' import { isArray } from 'lodash' import CSSModules from 'browser/lib/CSSModules' +import { getTodoStatus } from 'browser/lib/getTodoStatus' import styles from './NoteItem.styl' +import TodoProcess from './TodoProcess' /** * @description Tag element component. @@ -68,6 +70,10 @@ const NoteItem = ({ isActive, note, dateDisplay, handleNoteClick, handleDragStar {note.isStarred ? : '' } + {note.type === 'MARKDOWN_NOTE' + ? + : '' + }
{note.tags.length > 0 diff --git a/browser/components/NoteItem.styl b/browser/components/NoteItem.styl index 12f8b193..d4b15dfd 100644 --- a/browser/components/NoteItem.styl +++ b/browser/components/NoteItem.styl @@ -39,6 +39,7 @@ $control-height = 30px .item-wrapper padding 15px 0 border-bottom $ui-border + position relative .item--active @extend .item @@ -116,8 +117,8 @@ $control-height = 30px .item-star position absolute - right 5px - bottom 0px + right -20px + bottom 2px width 34px height 34px color alpha($ui-favorite-star-button-color, 60%) diff --git a/browser/components/NoteItemSimple.styl b/browser/components/NoteItemSimple.styl index 15504384..2333353e 100644 --- a/browser/components/NoteItemSimple.styl +++ b/browser/components/NoteItemSimple.styl @@ -48,6 +48,7 @@ $control-height = 30px overflow ellipsis color $ui-inactive-text-color border-bottom $ui-border + position relative .item-simple-title-icon font-size 12px diff --git a/browser/components/RealtimeNotification.js b/browser/components/RealtimeNotification.js new file mode 100644 index 00000000..3a6bcc27 --- /dev/null +++ b/browser/components/RealtimeNotification.js @@ -0,0 +1,55 @@ +import React, { PropTypes } from 'react' +import CSSModules from 'browser/lib/CSSModules' +import styles from './RealtimeNotification.styl' + +const electron = require('electron') +const { shell } = electron + +class RealtimeNotification extends React.Component { + constructor (props) { + super(props) + + this.state = { + notifications: [] + } + } + + componentDidMount () { + this.fetchNotifications() + } + + fetchNotifications () { + const notificationsUrl = 'https://raw.githubusercontent.com/BoostIO/notification/master/notification.json' + fetch(notificationsUrl) + .then(response => { + return response.json() + }) + .then(json => { + this.setState({notifications: json.notifications}) + }) + } + + handleLinkClick (e) { + shell.openExternal(e.currentTarget.href) + e.preventDefault() + } + + render () { + const { notifications } = this.state + const link = notifications.length > 0 + ? this.handleLinkClick(e)} + > + {notifications[0].text} + + : '' + + return ( +
{link}
+ ) + } +} + +RealtimeNotification.propTypes = {} + +export default CSSModules(RealtimeNotification, styles) diff --git a/browser/components/RealtimeNotification.styl b/browser/components/RealtimeNotification.styl new file mode 100644 index 00000000..a49de536 --- /dev/null +++ b/browser/components/RealtimeNotification.styl @@ -0,0 +1,34 @@ +.notification-area + z-index 1000 + font-size 12px + position absolute + bottom 0px + right 0px + background-color #EBEBEB + height 30px + +.notification-link + position absolute + right 5px + top 5px + text-decoration none + color #282A36 + border 1px solid #6FA8E6 + background-color alpha(#6FA8E6, 0.2) + padding 3px 9px + border-radius 2px + transition 0.2s + &:hover + color #1378BD + +body[data-theme="dark"] + .notification-area + background-color #1E2124 + + .notification-link + color #fff + border 1px solid alpha(#5CB85C, 0.6) + background-color alpha(#5CB85C, 0.2) + transition 0.2s + &:hover + color #5CB85C diff --git a/browser/components/TodoProcess.js b/browser/components/TodoProcess.js new file mode 100644 index 00000000..64553fb6 --- /dev/null +++ b/browser/components/TodoProcess.js @@ -0,0 +1,33 @@ +/** + * @fileoverview Percentage of todo achievement. + */ + +import React, { PropTypes } from 'react' +import CSSModules from 'browser/lib/CSSModules' +import styles from './TodoProcess.styl' + +const TodoProcess = ({ + todoStatus: { + total: totalTodo, + completed: completedTodo + } +}) => ( +
0 ? '' : 'none'}}> +
+ + {completedTodo} of {totalTodo} +
+
+
+
+
+) + +TodoProcess.propTypes = { + todoStatus: { + total: PropTypes.number.isRequired, + completed: PropTypes.number.isRequired + } +} + +export default CSSModules(TodoProcess, styles) diff --git a/browser/components/TodoProcess.styl b/browser/components/TodoProcess.styl new file mode 100644 index 00000000..91aedaf8 --- /dev/null +++ b/browser/components/TodoProcess.styl @@ -0,0 +1,45 @@ +.todo-process + font-size 12px + display flex + padding-top 15px + width 85% + +.todo-process-text + display inline-block + padding-right 10px + white-space nowrap + text-overflow ellipsis + color $ui-inactive-text-color + i + color $ui-inactive-text-color + padding-right 5px + +.todo-process-bar + display inline-block + margin auto + height 4px + border-radius 10px + background-color #DADFE1 + border-radius 2px + flex-grow 1 + border 1px solid alpha(#6C7A89, 10%) + +.todo-process-bar--inner + height 100% + border-radius 5px + background-color #6C7A89 + transition 0.3s + + +body[data-theme="dark"] + .todo-process + color $ui-dark-text-color + + .todo-process-bar + background-color #363A3D + + .todo-process-text + color $ui-inactive-text-color + + .todo-process-bar--inner + background-color: alpha(#939395, 50%) diff --git a/browser/components/markdown.styl b/browser/components/markdown.styl index b19634ea..21894dde 100644 --- a/browser/components/markdown.styl +++ b/browser/components/markdown.styl @@ -193,6 +193,7 @@ ol &>li>ul, &>li>ol margin 0 code + color #CC305F padding 0.2em 0.4em background-color #f7f7f7 border-radius 3px diff --git a/browser/finder/FinderMain.styl b/browser/finder/FinderMain.styl index fb26b6c3..1fa396b9 100644 --- a/browser/finder/FinderMain.styl +++ b/browser/finder/FinderMain.styl @@ -64,7 +64,7 @@ $list-width = 250px .result-nav-storageList absolute bottom left right - top 80px + 32px + 10px + 10px + top 110px + 32px + 10px + 10px overflow-y auto .result-list diff --git a/browser/finder/NoteDetail.js b/browser/finder/NoteDetail.js index 2f3f1d30..6fda851e 100644 --- a/browser/finder/NoteDetail.js +++ b/browser/finder/NoteDetail.js @@ -146,6 +146,7 @@ class NoteDetail extends React.Component { config={config} value={snippet.content} ref={'code-' + index} + storageKey={note.storage} /> : ) diff --git a/browser/finder/NoteDetail.styl b/browser/finder/NoteDetail.styl index e46f291a..060902af 100644 --- a/browser/finder/NoteDetail.styl +++ b/browser/finder/NoteDetail.styl @@ -2,6 +2,7 @@ .root absolute top bottom left right + bottom 30px left $note-detail-left-margin right $note-detail-right-margin height 100% diff --git a/browser/lib/RcParser.js b/browser/lib/RcParser.js new file mode 100644 index 00000000..0df59476 --- /dev/null +++ b/browser/lib/RcParser.js @@ -0,0 +1,21 @@ +import path from 'path' +import sander from 'sander' + +const BOOSTNOTERC = '.boostnoterc' +const homePath = global.process.env.HOME || global.process.env.USERPROFILE +const _boostnotercPath = path.join(homePath, BOOSTNOTERC) + +export function parse (boostnotercPath = _boostnotercPath) { + if (!sander.existsSync(boostnotercPath)) return {} + try { + return JSON.parse(sander.readFileSync(boostnotercPath).toString()) + } catch (e) { + console.warn(e) + console.warn('Your .boostnoterc is broken so it\'s not used.') + return {} + } +} + +export default { + parse +} diff --git a/browser/lib/getTodoStatus.js b/browser/lib/getTodoStatus.js new file mode 100644 index 00000000..d65e4946 --- /dev/null +++ b/browser/lib/getTodoStatus.js @@ -0,0 +1,25 @@ +export function getTodoStatus (content) { + let splitted = content.split('\n') + let numberOfTodo = 0 + let numberOfCompletedTodo = 0 + + splitted.forEach((line) => { + let trimmedLine = line.trim() + if (trimmedLine.match(/^[\+\-\*] \[\s|x\] ./)) { + numberOfTodo++ + } + if (trimmedLine.match(/^[\+\-\*] \[x\] ./)) { + numberOfCompletedTodo++ + } + }) + + return { + total: numberOfTodo, + completed: numberOfCompletedTodo + } +} + +export function getTodoPercentageOfCompleted (content) { + const state = getTodoStatus(content) + return Math.floor(state.completed / state.total * 100) +} diff --git a/browser/lib/markdown.js b/browser/lib/markdown.js index f5d86a9b..ea30348e 100644 --- a/browser/lib/markdown.js +++ b/browser/lib/markdown.js @@ -59,6 +59,15 @@ md.use(math, { }) md.use(require('markdown-it-imsize')) md.use(require('markdown-it-footnote')) +md.use(require('markdown-it-multimd-table')) +md.use(require('markdown-it-named-headers'), { + slugify: (header) => { + return encodeURI(header.trim() + .replace(/[\]\[\!\"\#\$\%\&\'\(\)\*\+\,\.\/\:\;\<\=\>\?\@\\\^\_\{\|\}\~]/g, '') + .replace(/\s+/g, '-')) + .replace(/\-+$/, '') + } +}) // Override task item md.block.ruler.at('paragraph', function (state, startLine/*, endLine */) { let content, terminate, i, l, token @@ -156,12 +165,17 @@ function strip (input) { return output } +function normalizeLinkText (linkText) { + return md.normalizeLinkText(linkText) +} + const markdown = { render: function markdown (content) { if (!_.isString(content)) content = '' const renderedContent = md.render(content) - return md.normalizeLinkText(renderedContent) + return renderedContent }, - strip + strip, + normalizeLinkText } export default markdown diff --git a/browser/main/Detail/InfoPanel.js b/browser/main/Detail/InfoPanel.js index 99495ece..f228fb01 100644 --- a/browser/main/Detail/InfoPanel.js +++ b/browser/main/Detail/InfoPanel.js @@ -3,7 +3,7 @@ import CSSModules from 'browser/lib/CSSModules' import styles from './InfoPanel.styl' const InfoPanel = ({ - storageName, folderName, noteLink, updatedAt, createdAt, exportAsMd, exportAsTxt + storageName, folderName, noteLink, updatedAt, createdAt, exportAsMd, exportAsTxt, wordCount, letterCount, type }) => (
@@ -24,7 +24,7 @@ const InfoPanel = ({
- Created at + Created
{createdAt} @@ -32,7 +32,7 @@ const InfoPanel = ({
- Updated at + Updated
{updatedAt} @@ -46,6 +46,27 @@ const InfoPanel = ({ { e.target.select() }} />
+ {type === 'SNIPPET_NOTE' + ? '' + :
+
+
+ Words +
+
+ {wordCount} +
+
+
+
+ Letters +
+
+ {letterCount} +
+
+
+ }
+ + + + +
+
+) + +InfoPanelTrashed.propTypes = { + storageName: PropTypes.string.isRequired, + folderName: PropTypes.string.isRequired, + updatedAt: PropTypes.string.isRequired, + createdAt: PropTypes.string.isRequired, + exportAsMd: PropTypes.func.isRequired, + exportAsTxt: PropTypes.func.isRequired +} + +export default CSSModules(InfoPanelTrashed, styles) diff --git a/browser/main/Detail/MarkdownNoteDetail.js b/browser/main/Detail/MarkdownNoteDetail.js index 568292ad..f83d7164 100644 --- a/browser/main/Detail/MarkdownNoteDetail.js +++ b/browser/main/Detail/MarkdownNoteDetail.js @@ -17,7 +17,10 @@ import AwsMobileAnalyticsConfig from 'browser/main/lib/AwsMobileAnalyticsConfig' import TrashButton from './TrashButton' import InfoButton from './InfoButton' import InfoPanel from './InfoPanel' +import InfoPanelTrashed from './InfoPanelTrashed' import { formatDate } from 'browser/lib/date-formatter' +import { getTodoPercentageOfCompleted } from 'browser/lib/getTodoStatus' +import striptags from 'striptags' const electron = require('electron') const { remote } = electron @@ -69,30 +72,12 @@ class MarkdownNoteDetail extends React.Component { ee.off('topbar:togglelockbutton', this.toggleLockButton) } - getPercentageOfCompleteTodo (noteContent) { - let splitted = noteContent.split('\n') - let numberOfTodo = 0 - let numberOfCompletedTodo = 0 - - splitted.forEach((line) => { - let trimmedLine = line.trim() - if (trimmedLine.match(/^[\+\-\*] \[\s|x\] ./)) { - numberOfTodo++ - } - if (trimmedLine.match(/^[\+\-\*] \[x\] ./)) { - numberOfCompletedTodo++ - } - }) - - return Math.floor(numberOfCompletedTodo / numberOfTodo * 100) - } - handleChange (e) { let { note } = this.state note.content = this.refs.content.value if (this.refs.tags) note.tags = this.refs.tags.value - note.title = markdown.strip(findNoteTitle(note.content)) + note.title = markdown.strip(striptags(findNoteTitle(note.content))) note.updatedAt = new Date() this.setState({ @@ -190,8 +175,8 @@ class MarkdownNoteDetail extends React.Component { if (isTrashed) { let dialogueButtonIndex = dialog.showMessageBox(remote.getCurrentWindow(), { type: 'warning', - message: 'Delete a note', - detail: 'This work cannot be undone.', + message: 'Confirm note deletion', + detail: 'This will permanently remove this note.', buttons: ['Confirm', 'Cancel'] }) if (dialogueButtonIndex === 1) return @@ -300,10 +285,9 @@ class MarkdownNoteDetail extends React.Component { this.handleInfoButtonClick(e)} /> - this.handleChange(e)} />
@@ -357,7 +341,7 @@ class MarkdownNoteDetail extends React.Component { this.handleInfoButtonClick(e)} @@ -370,6 +354,9 @@ class MarkdownNoteDetail extends React.Component { createdAt={formatDate(note.createdAt)} exportAsMd={this.exportAsMd} exportAsTxt={this.exportAsTxt} + wordCount={note.content.split(' ').length} + letterCount={note.content.replace(/\r?\n/g, '').length} + type={note.type} />
diff --git a/browser/main/Detail/SnippetNoteDetail.js b/browser/main/Detail/SnippetNoteDetail.js index fd9e5087..baacc9f3 100644 --- a/browser/main/Detail/SnippetNoteDetail.js +++ b/browser/main/Detail/SnippetNoteDetail.js @@ -20,6 +20,7 @@ import AwsMobileAnalyticsConfig from 'browser/main/lib/AwsMobileAnalyticsConfig' import TrashButton from './TrashButton' import InfoButton from './InfoButton' import InfoPanel from './InfoPanel' +import InfoPanelTrashed from './InfoPanelTrashed' import { formatDate } from 'browser/lib/date-formatter' function pass (name) { @@ -176,8 +177,8 @@ class SnippetNoteDetail extends React.Component { if (isTrashed) { let dialogueButtonIndex = dialog.showMessageBox(remote.getCurrentWindow(), { type: 'warning', - message: 'Delete a note', - detail: 'This work cannot be undone.', + message: 'Confirm note deletion', + detail: 'This will permanently remove this note.', buttons: ['Confirm', 'Cancel'] }) if (dialogueButtonIndex === 1) return @@ -270,7 +271,7 @@ class SnippetNoteDetail extends React.Component { let syntax = CodeMirror.findModeByFileName(name.trim()) let mode = syntax != null ? syntax.name : null if (mode != null) snippets[index].mode = mode - this.state.note.snippets = snippets + this.setState({note: Object.assign(this.state.note, {snippets: snippets})}) this.setState({ note: this.state.note @@ -283,7 +284,7 @@ class SnippetNoteDetail extends React.Component { return (e) => { let snippets = this.state.note.snippets.slice() snippets[index].mode = name - this.state.note.snippets = snippets + this.setState({note: Object.assign(this.state.note, {snippets: snippets})}) this.setState({ note: this.state.note @@ -297,7 +298,7 @@ class SnippetNoteDetail extends React.Component { return (e) => { let snippets = this.state.note.snippets.slice() snippets[index].content = this.refs['code-' + index].value - this.state.note.snippets = snippets + this.setState({note: Object.assign(this.state.note, {snippets: snippets})}) this.setState({ note: this.state.note }, () => { @@ -519,6 +520,7 @@ class SnippetNoteDetail extends React.Component { onChange={(e) => this.handleCodeChange(index)(e)} ref={'code-' + index} ignorePreviewPointerEvents={this.props.ignorePreviewPointerEvents} + storageKey={storageKey} /> : this.handleInfoButtonClick(e)} /> - this.handleFullScreenButton(e)} > - + this.handleInfoButtonClick(e)} @@ -610,6 +611,7 @@ class SnippetNoteDetail extends React.Component { createdAt={formatDate(note.createdAt)} exportAsMd={this.showWarning} exportAsTxt={this.showWarning} + type={note.type} />
diff --git a/browser/main/Detail/SnippetNoteDetail.styl b/browser/main/Detail/SnippetNoteDetail.styl index 5b6f15cf..e233755d 100644 --- a/browser/main/Detail/SnippetNoteDetail.styl +++ b/browser/main/Detail/SnippetNoteDetail.styl @@ -19,7 +19,7 @@ .body .description absolute top left right - height 80px + height 50px .body .description textarea outline none @@ -27,14 +27,14 @@ height 100% width 100% resize none - border none - padding 10px + border 1px solid $ui-borderColor + padding 2px 5px line-height 1.6 background-color $ui-noteDetail-backgroundColor .tabList absolute left right - top 80px + top 55px height 30px display flex background-color $ui-noteDetail-backgroundColor @@ -50,16 +50,17 @@ .tabView absolute left right bottom - top 130px + top 100px .tabView-content absolute top left right bottom .override absolute bottom left + bottom 30px left 60px height 23px - z-index 1 + z-index 101 button navButtonColor() height 24px @@ -83,6 +84,7 @@ body[data-theme="dark"] .body .description textarea background-color $ui-dark-noteDetail-backgroundColor color $ui-dark-text-color + border 1px solid $ui-dark-borderColor .tabList background-color $ui-button--active-backgroundColor diff --git a/browser/main/Detail/TagSelect.styl b/browser/main/Detail/TagSelect.styl index 06958a82..b5b8bb74 100644 --- a/browser/main/Detail/TagSelect.styl +++ b/browser/main/Detail/TagSelect.styl @@ -51,7 +51,7 @@ margin 2px 0 15px 2px vertical-align middle height 18px - box-sizing borde-box + box-sizing border-box border none background-color transparent outline none diff --git a/browser/main/Detail/index.js b/browser/main/Detail/index.js index d6c62e8a..884c6452 100644 --- a/browser/main/Detail/index.js +++ b/browser/main/Detail/index.js @@ -49,7 +49,7 @@ class Detail extends React.Component { tabIndex='0' >
-
{OSX ? 'Command(⌘)' : 'Ctrl(^)'} + N
to create a new post
+
{OSX ? 'Command(⌘)' : 'Ctrl(^)'} + N
to create a new note
+ ) } diff --git a/browser/main/NewNoteButton/NewNoteButton.styl b/browser/main/NewNoteButton/NewNoteButton.styl new file mode 100644 index 00000000..b53ff892 --- /dev/null +++ b/browser/main/NewNoteButton/NewNoteButton.styl @@ -0,0 +1,68 @@ +.root + position relative + background-color $ui-noteList-backgroundColor + height $topBar-height - 1 + margin-left: auto; + width: 64px; + margin-right: -15px; + +.root--expanded + @extend .root + +$control-height = 34px + +.control + position absolute + top 13px + left 8px + right 8px + height $control-height + overflow hidden + display flex + +.control-newNoteButton + display block + width 32px + height $control-height - 2 + navButtonColor() + font-size 16px + line-height 28px + padding 0 + &:active + border-color $ui-button--active-backgroundColor + &:hover .control-newNoteButton-tooltip + opacity 1 + +.control-newNoteButton-tooltip + tooltip() + position fixed + pointer-events none + top 50px + left 433px + z-index 200 + padding 5px + line-height normal + border-radius 2px + opacity 0 + transition 0.1s + +body[data-theme="dark"] + .root, .root--expanded + background-color $ui-dark-noteList-backgroundColor + + .control + border-color $ui-dark-borderColor + + .control-newNoteButton + color $ui-inactive-text-color + border-color $ui-dark-borderColor + background-color $ui-dark-noteList-backgroundColor + &:hover + transition 0.15s + color $ui-dark-text-color + &:active + background-color alpha($ui-dark-button--active-backgroundColor, 20%) + border-color $ui-dark-button--active-backgroundColor + + .control-newNoteButton-tooltip + darkTooltip() diff --git a/browser/main/NewNoteButton/index.js b/browser/main/NewNoteButton/index.js new file mode 100644 index 00000000..936bb146 --- /dev/null +++ b/browser/main/NewNoteButton/index.js @@ -0,0 +1,106 @@ +import React, { PropTypes } from 'react' +import CSSModules from 'browser/lib/CSSModules' +import styles from './NewNoteButton.styl' +import _ from 'lodash' +import modal from 'browser/main/lib/modal' +import NewNoteModal from 'browser/main/modals/NewNoteModal' +import { hashHistory } from 'react-router' +import eventEmitter from 'browser/main/lib/eventEmitter' +import dataApi from 'browser/main/lib/dataApi' + +const { remote } = require('electron') +const { dialog } = remote + +const OSX = window.process.platform === 'darwin' + +class NewNoteButton extends React.Component { + constructor (props) { + super(props) + + this.state = { + } + + this.newNoteHandler = () => { + this.handleNewNoteButtonClick() + } + } + + componentDidMount () { + eventEmitter.on('top:new-note', this.newNoteHandler) + } + + componentWillUnmount () { + eventEmitter.off('top:new-note', this.newNoteHandler) + } + + handleNewNoteButtonClick (e) { + const { config, location, dispatch } = this.props + const { storage, folder } = this.resolveTargetFolder() + + modal.open(NewNoteModal, { + storage: storage.key, + folder: folder.key, + dispatch, + location + }) + } + + resolveTargetFolder () { + const { data, params } = this.props + let storage = data.storageMap.get(params.storageKey) + + // Find first storage + if (storage == null) { + for (let kv of data.storageMap) { + storage = kv[1] + break + } + } + + if (storage == null) this.showMessageBox('No storage to create a note') + const folder = _.find(storage.folders, {key: params.folderKey}) || storage.folders[0] + if (folder == null) this.showMessageBox('No folder to create a note') + + return { + storage, + folder + } + } + + showMessageBox (message) { + dialog.showMessageBox(remote.getCurrentWindow(), { + type: 'warning', + message: message, + buttons: ['OK'] + }) + } + + render () { + const { config, style } = this.props + return ( +
+
+ +
+
+ ) + } +} + +NewNoteButton.propTypes = { + dispatch: PropTypes.func, + config: PropTypes.shape({ + isSideNavFolded: PropTypes.bool + }) +} + +export default CSSModules(NewNoteButton, styles) diff --git a/browser/main/NoteList/NoteList.styl b/browser/main/NoteList/NoteList.styl index 892ad3d8..c8023a38 100644 --- a/browser/main/NoteList/NoteList.styl +++ b/browser/main/NoteList/NoteList.styl @@ -2,6 +2,7 @@ $control-height = 30px .root absolute left bottom + bottom 30px top $topBar-height - 1 background-color $ui-noteList-backgroundColor diff --git a/browser/main/NoteList/index.js b/browser/main/NoteList/index.js index 9c0b3c2d..c1441322 100644 --- a/browser/main/NoteList/index.js +++ b/browser/main/NoteList/index.js @@ -13,6 +13,7 @@ import fs from 'fs' import { hashHistory } from 'react-router' import markdown from 'browser/lib/markdown' import { findNoteTitle } from 'browser/lib/findNoteTitle' +import stripgtags from 'striptags' const { remote } = require('electron') const { Menu, MenuItem, dialog } = remote @@ -347,6 +348,22 @@ class NoteList extends React.Component { properties: ['openFile', 'multiSelections'] } + dialog.showOpenDialog(remote.getCurrentWindow(), options, (filepaths) => { + this.addNotesFromFiles(filepaths) + }) + } + + handleDrop (e) { + e.preventDefault() + const { location } = this.props + const filepaths = Array.from(e.dataTransfer.files).map(file => { return file.path }) + if (!location.pathname.match(/\/trashed/)) this.addNotesFromFiles(filepaths) + } + + // Add notes to the current folder + addNotesFromFiles (filepaths) { + const { dispatch, location } = this.props + const targetIndex = _.findIndex(this.notes, (note) => { return note !== null && `${note.storage}-${note.key}` === location.query.key }) @@ -354,28 +371,26 @@ class NoteList extends React.Component { const storageKey = this.notes[targetIndex].storage const folderKey = this.notes[targetIndex].folder - dialog.showOpenDialog(remote.getCurrentWindow(), options, (filepaths) => { - if (filepaths === undefined) return - filepaths.forEach((filepath) => { - fs.readFile(filepath, (err, data) => { - if (err) throw Error('File reading error: ', err) - const content = data.toString() - const newNote = { - content: content, - folder: folderKey, - title: markdown.strip(findNoteTitle(content)), - type: 'MARKDOWN_NOTE' - } - dataApi.createNote(storageKey, newNote) - .then((note) => { - dispatch({ - type: 'UPDATE_NOTE', - note: note - }) - hashHistory.push({ - pathname: location.pathname, - query: {key: `${note.storage}-${note.key}`} - }) + if (filepaths === undefined) return + filepaths.forEach((filepath) => { + fs.readFile(filepath, (err, data) => { + if (err) throw Error('File reading error: ', err) + const content = data.toString() + const newNote = { + content: content, + folder: folderKey, + title: markdown.strip(findNoteTitle(content)), + type: 'MARKDOWN_NOTE' + } + dataApi.createNote(storageKey, newNote) + .then((note) => { + dispatch({ + type: 'UPDATE_NOTE', + note: note + }) + hashHistory.push({ + pathname: location.pathname, + query: {key: `${note.storage}-${note.key}`} }) }) }) @@ -438,6 +453,7 @@ class NoteList extends React.Component {
this.handleDrop(e)} >
@@ -446,9 +462,9 @@ class NoteList extends React.Component { value={config.sortBy} onChange={(e) => this.handleSortByChange(e)} > - - - + + +
diff --git a/browser/main/SideNav/StorageItem.js b/browser/main/SideNav/StorageItem.js index fefc5a60..c7985f75 100644 --- a/browser/main/SideNav/StorageItem.js +++ b/browser/main/SideNav/StorageItem.js @@ -114,7 +114,7 @@ class StorageItem extends React.Component { let index = dialog.showMessageBox(remote.getCurrentWindow(), { type: 'warning', message: 'Delete Folder', - detail: 'This work will deletes all notes in the folder and can not be undone.', + detail: 'This will delete all notes in the folder and can not be undone.', buttons: ['Confirm', 'Cancel'] }) diff --git a/browser/main/StatusBar/StatusBar.styl b/browser/main/StatusBar/StatusBar.styl index 8dd8dc99..df8df627 100644 --- a/browser/main/StatusBar/StatusBar.styl +++ b/browser/main/StatusBar/StatusBar.styl @@ -3,6 +3,8 @@ .root absolute bottom left right height $statusBar-height + bottom 16px + z-index 100 background-color $ui-noteDetail-backgroundColor display flex diff --git a/browser/main/StatusBar/index.js b/browser/main/StatusBar/index.js index f3748548..c1ec0e71 100644 --- a/browser/main/StatusBar/index.js +++ b/browser/main/StatusBar/index.js @@ -59,8 +59,6 @@ class StatusBar extends React.Component { {Math.floor(config.zoom * 100)}% -
- {status.updateReady ?
+ {location.pathname === '/trashed' ? '' + : }
) } diff --git a/browser/main/global.styl b/browser/main/global.styl index 552e0d6c..ef70fcb3 100644 --- a/browser/main/global.styl +++ b/browser/main/global.styl @@ -64,7 +64,7 @@ textarea.block-input fullsize() modalZIndex= 1000 -modalBackColor = transparentify(white, 65%) +modalBackColor = white .ace_focus outline-color rgb(59, 153, 252) outline-offset 0px @@ -86,12 +86,12 @@ modalBackColor = transparentify(white, 65%) body[data-theme="dark"] .ModalBase .modalBack - background-color alpha(black, 60%) + background-color $ui-dark-backgroundColor .CodeMirror font-family inherit !important line-height 1.4em - height 100% + height 96% .CodeMirror > div > textarea margin-bottom -1em .CodeMirror-focused .CodeMirror-selected diff --git a/browser/main/lib/AwsMobileAnalyticsConfig.js b/browser/main/lib/AwsMobileAnalyticsConfig.js index fad7ab9f..70df7b7d 100644 --- a/browser/main/lib/AwsMobileAnalyticsConfig.js +++ b/browser/main/lib/AwsMobileAnalyticsConfig.js @@ -18,9 +18,10 @@ function initAwsMobileAnalytics () { AWS.config.credentials.get((err) => { if (!err) { console.log('Cognito Identity ID: ' + AWS.config.credentials.identityId) + recordDynamicCustomEvent('APP_STARTED') + recordStaticCustomEvent() } }) - recordStaticCustomEvent() } function recordDynamicCustomEvent (type) { diff --git a/browser/main/lib/ConfigManager.js b/browser/main/lib/ConfigManager.js index 6752fc14..fd374cf1 100644 --- a/browser/main/lib/ConfigManager.js +++ b/browser/main/lib/ConfigManager.js @@ -1,10 +1,13 @@ import _ from 'lodash' +import RcParser from 'browser/lib/RcParser' const OSX = global.process.platform === 'darwin' const win = global.process.platform === 'win32' const electron = require('electron') const { ipcRenderer } = electron const consts = require('browser/lib/consts') +const path = require('path') +const fs = require('fs') let isInitialized = false @@ -22,6 +25,7 @@ export const DEFAULT_CONFIG = { }, ui: { theme: 'default', + showCopyNotification: true, disableDirectWrite: false, defaultNote: 'ALWAYS_ASK' // 'ALWAYS_ASK', 'SNIPPET_NOTE', 'MARKDOWN_NOTE' }, @@ -57,17 +61,17 @@ function _save (config) { } function get () { - let config = window.localStorage.getItem('config') + const rawStoredConfig = window.localStorage.getItem('config') + const storedConfig = Object.assign({}, DEFAULT_CONFIG, JSON.parse(rawStoredConfig)) + let config = storedConfig try { - config = Object.assign({}, DEFAULT_CONFIG, JSON.parse(config)) - config.hotkey = Object.assign({}, DEFAULT_CONFIG.hotkey, config.hotkey) - config.ui = Object.assign({}, DEFAULT_CONFIG.ui, config.ui) - config.editor = Object.assign({}, DEFAULT_CONFIG.editor, config.editor) - config.preview = Object.assign({}, DEFAULT_CONFIG.preview, config.preview) + const boostnotercConfig = RcParser.parse() + config = assignConfigValues(storedConfig, boostnotercConfig) + if (!validate(config)) throw new Error('INVALID CONFIG') } catch (err) { - console.warn('Boostnote resets the malformed configuration.') + console.warn('Boostnote resets the invalid configuration.') config = DEFAULT_CONFIG _save(config) } @@ -126,6 +130,15 @@ function set (updates) { }) } +function assignConfigValues (originalConfig, rcConfig) { + let config = Object.assign({}, DEFAULT_CONFIG, originalConfig, rcConfig) + config.hotkey = Object.assign({}, DEFAULT_CONFIG.hotkey, originalConfig.hotkey, rcConfig.hotkey) + config.ui = Object.assign({}, DEFAULT_CONFIG.ui, originalConfig.ui, rcConfig.ui) + config.editor = Object.assign({}, DEFAULT_CONFIG.editor, originalConfig.editor, rcConfig.editor) + config.preview = Object.assign({}, DEFAULT_CONFIG.preview, originalConfig.preview, rcConfig.preview) + return config +} + export default { get, set, diff --git a/browser/main/modals/CreateFolderModal.styl b/browser/main/modals/CreateFolderModal.styl index 16ca7fba..97fddec7 100644 --- a/browser/main/modals/CreateFolderModal.styl +++ b/browser/main/modals/CreateFolderModal.styl @@ -4,10 +4,9 @@ height 270px overflow hidden position relative - padding 0 40px .header - height 70px + height 80px margin-bottom 10px margin-top 20px font-size 18px @@ -15,23 +14,27 @@ background-color $ui-backgroundColor color $ui-text-color +.title + font-size 36px + font-weight 600 + .control-folder-label text-align left - font-size 12px + font-size 14px color $ui-text-color .control-folder-input display block - height 30px - width 420px + height 40px + width 490px padding 0 5px - margin 10px auto 15px + margin 10px 0 border 1px solid #C9C9C9 // TODO: use variable. border-radius 2px background-color transparent outline none vertical-align middle - font-size 14px + font-size 16px &:disabled background-color $ui-input--disabled-backgroundColor &:focus, &:active @@ -39,14 +42,13 @@ .control-confirmButton display block - float right - height 30px - width 100px + height 35px + width 140px border none border-radius 2px padding 0 25px margin 20px auto - font-size 12px + font-size 14px colorPrimaryButton() body[data-theme="dark"] @@ -56,7 +58,6 @@ body[data-theme="dark"] height 270px overflow hidden position relative - padding 0 40px .header background-color transparent diff --git a/browser/main/modals/DeleteArticleModal.js b/browser/main/modals/DeleteArticleModal.js deleted file mode 100644 index 5069cda0..00000000 --- a/browser/main/modals/DeleteArticleModal.js +++ /dev/null @@ -1,51 +0,0 @@ -import React, { PropTypes } from 'react' -import ReactDOM from 'react-dom' - -const electron = require('electron') -const ipc = electron.ipcRenderer - -export default class DeleteArticleModal extends React.Component { - constructor (props) { - super(props) - - this.confirmHandler = (e) => this.handleYesButtonClick() - } - - componentDidMount () { - ReactDOM.findDOMNode(this.refs.no).focus() - ipc.on('modal-confirm', this.confirmHandler) - } - - componentWillUnmount () { - ipc.removeListener('modal-confirm', this.confirmHandler) - } - - handleNoButtonClick (e) { - this.props.close() - } - - handleYesButtonClick (e) { - this.props.close() - } - - render () { - return ( -
-
Delete an article.
- -
Do you really want to delete?
- -
- - -
-
- ) - } -} - -DeleteArticleModal.propTypes = { - action: PropTypes.object, - articleKey: PropTypes.string, - close: PropTypes.func -} diff --git a/browser/main/modals/NewNoteModal.styl b/browser/main/modals/NewNoteModal.styl index b12a20cf..97b18816 100644 --- a/browser/main/modals/NewNoteModal.styl +++ b/browser/main/modals/NewNoteModal.styl @@ -9,16 +9,19 @@ font-size 18px line-height 50px padding 0 15px - background-color $ui-backgroundColor - border-bottom solid 1px $ui-borderColor color $ui-text-color + margin-bottom 20px + +.title + font-size 36px + font-weight 600 .control - padding 25px 15px 15px + padding 25px 0px text-align center .control-button - width 220px + width 240px height 220px margin 0 15px border $ui-border @@ -30,8 +33,8 @@ colorPrimaryButton() .control-button-icon - font-size 50px - margin-bottom 15px + font-size 48px + margin-bottom 25px .control-button-label font-size 18px @@ -49,8 +52,6 @@ body[data-theme="dark"] modalDark() .header - background-color $ui-dark-button--hover-backgroundColor - border-color $ui-dark-borderColor color $ui-dark-text-color .control-button diff --git a/browser/main/modals/PreferencesModal/ConfigTab.styl b/browser/main/modals/PreferencesModal/ConfigTab.styl index 11114272..101f2f33 100644 --- a/browser/main/modals/PreferencesModal/ConfigTab.styl +++ b/browser/main/modals/PreferencesModal/ConfigTab.styl @@ -31,10 +31,15 @@ .group-section-control flex 1 + margin-left 5px .group-section-control select outline none border 1px solid $ui-borderColor + font-size 16px + height 30px + width 250px + margin-bottom 5px background-color transparent .group-section-control-input @@ -77,14 +82,16 @@ margin-right 10px .group-control-rightButton - float right + position absolute + top 10px + right 20px colorPrimaryButton() border none border-radius 2px font-size $tab--button-font-size - height 35px - width 100px - margin-right 10px + height 40px + width 120px + padding 0 15px .group-hint border $ui-border diff --git a/browser/main/modals/PreferencesModal/InfoTab.js b/browser/main/modals/PreferencesModal/InfoTab.js index 496fcd71..5ac4245f 100644 --- a/browser/main/modals/PreferencesModal/InfoTab.js +++ b/browser/main/modals/PreferencesModal/InfoTab.js @@ -81,7 +81,7 @@ class InfoTab extends React.Component {
  • this.handleLinkClick(e)} - >GitHub Issues : We'd love to hear your feedback 🙌 + >GitHub Issues : We'd love to hear your feedback 🙌

  • Data collection policy
    -

    We collect only the number of DAU for Boostnote and DO NOT collect any detail information

    -

    such as your note content. You can see how it works on this.handleLinkClick(e)}>GitHub.

    -

    These data are only used for Boostnote improvements.

    +
    We collect only the number of DAU for Boostnote and **DO NOT collect** any detail information such as your note content.
    +
    You can see how it works on this.handleLinkClick(e)}>GitHub.
    +
    This data is only used for Boostnote improvements.
    this.handleConfigChange(e)} checked={this.state.config.amaEnabled} ref='amaEnabled' diff --git a/browser/main/modals/PreferencesModal/InfoTab.styl b/browser/main/modals/PreferencesModal/InfoTab.styl index 6158c634..176405f4 100644 --- a/browser/main/modals/PreferencesModal/InfoTab.styl +++ b/browser/main/modals/PreferencesModal/InfoTab.styl @@ -43,6 +43,7 @@ text-decoration none .policy + width 100% font-size 20px margin-bottom 10px diff --git a/browser/main/modals/PreferencesModal/PreferencesModal.styl b/browser/main/modals/PreferencesModal/PreferencesModal.styl index a0a670b5..a452ca91 100644 --- a/browser/main/modals/PreferencesModal/PreferencesModal.styl +++ b/browser/main/modals/PreferencesModal/PreferencesModal.styl @@ -4,9 +4,10 @@ top-bar--height = 50px .root modal() - max-width 800px - min-height 500px - height 80% + max-width 100vw + min-height 100vh + height 100vh + width 100vw overflow hidden position relative @@ -25,22 +26,22 @@ top-bar--height = 50px top top-bar--height left 0 width 140px - margin-left 30px + margin-left 10px margin-top 20px background-color $ui-backgroundColor .nav-button font-size 14px text-align left - width 100px - margin 4px 0 - padding 5px 0 + width 120px + margin 5px 0 + padding 7px 0 padding-left 10px border none border-radius 2px background-color transparent color $ui-text-color - font-size 14px + font-size 16px .nav-button--active @extend .nav-button diff --git a/browser/main/modals/PreferencesModal/StorageItem.js b/browser/main/modals/PreferencesModal/StorageItem.js index d8d18d6c..d3586f35 100644 --- a/browser/main/modals/PreferencesModal/StorageItem.js +++ b/browser/main/modals/PreferencesModal/StorageItem.js @@ -298,8 +298,8 @@ class StorageItem extends React.Component { let index = dialog.showMessageBox(remote.getCurrentWindow(), { type: 'warning', message: 'Unlink Storage', - detail: 'This work just detatches a storage from Boostnote. (Any data won\'t be deleted.)', - buttons: ['Confirm', 'Cancel'] + detail: 'Unlinking removes this linked storage from Boostnote. No data is removed, please manually delete the folder from your hard drive if needed.', + buttons: ['Unlink', 'Cancel'] }) if (index === 0) { diff --git a/browser/main/modals/PreferencesModal/StoragesTab.js b/browser/main/modals/PreferencesModal/StoragesTab.js index dc1f96f0..641e5e8c 100644 --- a/browser/main/modals/PreferencesModal/StoragesTab.js +++ b/browser/main/modals/PreferencesModal/StoragesTab.js @@ -5,7 +5,7 @@ import dataApi from 'browser/main/lib/dataApi' import StorageItem from './StorageItem' const electron = require('electron') -const remote = electron.remote +const { shell, remote } = electron function browseFolder () { let dialog = remote.dialog @@ -50,6 +50,11 @@ class StoragesTab extends React.Component { }) } + handleLinkClick (e) { + shell.openExternal(e.currentTarget.href) + e.preventDefault() + } + renderList () { let { data, boundingBox } = this.props @@ -161,7 +166,10 @@ class StoragesTab extends React.Component {
    - 3rd party cloud integration(such as Google Drive and Dropbox) will be available soon. + 3rd party cloud integration: + this.handleLinkClick(e)} + >Cloud-Syncing
  • diff --git a/browser/main/modals/PreferencesModal/Tab.styl b/browser/main/modals/PreferencesModal/Tab.styl index 7280407b..3b722cbf 100644 --- a/browser/main/modals/PreferencesModal/Tab.styl +++ b/browser/main/modals/PreferencesModal/Tab.styl @@ -10,8 +10,8 @@ $tab--button-font-size = 14px $tab--dark-text-color = #E5E5E5 .header - font-size 24px - margin-bottom 30px + font-size 36px + margin-bottom 60px body[data-theme="dark"] .header diff --git a/browser/main/modals/PreferencesModal/UiTab.js b/browser/main/modals/PreferencesModal/UiTab.js index 58dc0e65..217306f6 100644 --- a/browser/main/modals/PreferencesModal/UiTab.js +++ b/browser/main/modals/PreferencesModal/UiTab.js @@ -36,6 +36,7 @@ class UiTab extends React.Component { const newConfig = { ui: { theme: this.refs.uiTheme.value, + showCopyNotification: this.refs.showCopyNotification.checked, disableDirectWrite: this.refs.uiD2w != null ? this.refs.uiD2w.checked : false @@ -90,9 +91,8 @@ class UiTab extends React.Component {
    UI
    -
    Theme
    -
    + Color Theme
    +
    + +
    { global.process.platform === 'win32' ?
    @@ -192,7 +202,7 @@ class UiTab extends React.Component {
    - Switching Preview + Switch to Preview
    @@ -218,7 +228,7 @@ class UiTab extends React.Component { - Please reload boostnote after you change the keymap + Please restart boostnote after you change the keymap
    @@ -271,7 +281,7 @@ class UiTab extends React.Component { ref='previewLineNumber' type='checkbox' />  - Code block line numbering + Show line numbers for preview code blocks diff --git a/browser/styles/index.styl b/browser/styles/index.styl index 8df338c0..50cd8f7e 100644 --- a/browser/styles/index.styl +++ b/browser/styles/index.styl @@ -5,7 +5,7 @@ $danger-color = #c9302c $danger-lighten-color = lighten(#c9302c, 5%) // Layouts -$statusBar-height = 24px +$statusBar-height = 36px $sideNav-width = 200px $sideNav--folded-width = 44px $topBar-height = 60px @@ -150,10 +150,13 @@ modal() position relative z-index $modal-z-index width 100% + margin-left 80px + margin-right 80px + margin-bottom 80px + margin-top 100px background-color $modal-background overflow hidden border-radius $modal-border-radius - box-shadow 0 0 1px rgba(76,86,103,.15), 0 2px 18px rgba(31,37,50,.22) topBarButtonLight() width 34px @@ -260,4 +263,3 @@ modalDark() background-color $ui-dark-backgroundColor overflow hidden border-radius $modal-border-radius - box-shadow 2px 2px 10px black diff --git a/contributing.md b/contributing.md index 73a05ee7..066d53fa 100644 --- a/contributing.md +++ b/contributing.md @@ -69,3 +69,21 @@ Pull requestをすることはその変化分のコードの著作権をMaisin&C これはいずれかBoostnoteが有料の商用アプリになる可能性がある話ではありません。 もし、このアプリケーションに料金が発生する時は、Boostnote専用のCloud storageの提供やMobile appとの連動、何か特殊なプレミアム機能の提供など形になります。 現在考えられているのは、GPL v3の場合、他のライセンスとの互換が不可能であるため、もしより自由なLicense(BSD, MIT)に変える時に改めて著作権者としてライセンスし直す選択肢を残すイメージです。 + +--- + +# Contributing to Boostnote (Simplified Chinese) + +### 当您创建一个issue的时候 +我们对您的issue格式没有要求,但是我们有一个请求: + +**如果可能,请在开发者模式打开的情况下,为我们提供屏幕截图** + +(您可以通过`Ctrl+Shift+I`打开开发者模式)。 +感谢您对我们的支持。 + +### 关于您提供的Pull Request的著作权(版权)问题 +如果您提供了一个Pull Request,这表示您将您所修改的代码的著作权移交给Maisin&Co。 + +这并不表示Boostnote会成为一个需要付费的软件。如果我们想获得收益,我们会尝试一些其他的方法,比如说云存储、绑定手机软件等。 +因为GPLv3过于严格,不能和其他的一些协议兼容,所以我们有可能在将来会把BoostNote的协议改为一些较为宽松的协议,比如说BSD、MIT。 diff --git a/docs/build.md b/docs/build.md index 79a64324..6daaca18 100644 --- a/docs/build.md +++ b/docs/build.md @@ -1,10 +1,11 @@ # Build +This page is also available in [Japanese](https://github.com/BoostIO/Boostnote/blob/master/docs/jp/build.md), [Korean](https://github.com/BoostIO/Boostnote/blob/master/docs/ko/build.md), [Russain](https://github.com/BoostIO/Boostnote/blob/master/docs/ru/build.md), and [Simplified Chinese](https://github.com/BoostIO/Boostnote/blob/master/docs/zh_CN/build.md). ## Environments * npm: 4.x * node: 7.x -You should use `npm v4.x` because `$ grand pre-build` fails on `v5.x`. +You should use `npm v4.x` because `$ grunt pre-build` fails on `v5.x`. ## Development @@ -43,6 +44,8 @@ You can build the program by using `grunt`. However, we don't recommend this bec So, we've prepared a separate script which just makes an executable file. +This build doesn't work on npm v5.3.0. So you need to use v5.2.0 when you build it. + ``` grunt pre-build ``` diff --git a/docs/debug.md b/docs/debug.md index ce1e1226..6502cb51 100644 --- a/docs/debug.md +++ b/docs/debug.md @@ -1,4 +1,6 @@ # How to debug Boostnote (Electron app) +This page is also available in [Japanese](https://github.com/BoostIO/Boostnote/blob/master/docs/jp/debug.md), [Korean](https://github.com/BoostIO/Boostnote/blob/master/docs/ko/debug.md), [Russain](https://github.com/BoostIO/Boostnote/blob/master/docs/ru/debug.md), and [Simplified Chinese](https://github.com/BoostIO/Boostnote/blob/master/docs/zh_CN/debug.md) + Boostnote is an Electron app so it's based on Chromium; developers can use `Developer Tools` just like Google Chrome. You can toggle the `Developer Tools` like this: diff --git a/docs/jp/build.md b/docs/jp/build.md index 75275181..0e7270f1 100644 --- a/docs/jp/build.md +++ b/docs/jp/build.md @@ -37,6 +37,8 @@ Gruntを使います。 それで、実行ファイルを作るスクリプトを用意しておきました。 +このビルドはnpm v5.3.0では動かないのでv5.2.0で動かす必要があります。 + ``` grunt pre-build ``` diff --git a/docs/ko/build.md b/docs/ko/build.md index 59178c78..7bbe302f 100644 --- a/docs/ko/build.md +++ b/docs/ko/build.md @@ -1,42 +1,50 @@ # Build +## 환경 +* npm: 4.x +* node: 7.x + +`$ grunt pre-build`를 `npm v5.x`에서 실행할 수 없기 때문에, 반드시 `npm v4.x`를 사용하셔야 합니다. + ## 개발 -Webpack HRM을 개발을 위해 사용합니다. -다음 명령을 통해 저희가 해둔 설정을 사용 할 수 있습니다. +개발에 있어서 Webpack HRM을 사용합니다. +다음과 같은 명령을 프로젝트 디렉토리에서 실행하면, 기본 설정을 사용 할 수 있습니다. + +먼저, yarn을 이용해서 필요한 패키지들을 설치합니다. ``` -yarn run webpack +$ yarn ``` -몇 초 후, 다음 메세지를 보게 될겁니다. +그 다음, 아래의 명령으로 빌드를 끝내고 자동적으로 어플리케이션을 실행합니다. ``` -webpack: bundle is now VALID. +$ yarn run dev-start ``` -그럼 앱을 실행합시다. +이 명령은 `yarn run webpack` 과 `yarn run hot`을 동시에 실행합니다. 이는 두개의 터미널에서 각각의 명령을 동시에 실행하는 것과 같습니다. -``` -yarn run hot -``` +`Webpack`은 코드의 변화를 자동으로 탐지하여 적용시키는 역할을 합니다. -> 원래 앱은 `yarn start`로 실행가능합니다. 하지만 이 경우, 컴파일된 스크립트를 사용할 것입니다. +만약, `Failed to load resource: net::ERR_CONNECTION_REFUSED`과 같은 에러가 나타난다면 Boostnote를 리로드해주세요. -이로써 웹팩이 자동적으로 코드변경을 확인하고 적용해줄 것입니다. +![net::ERR_CONNECTION_REFUSED](https://cloud.githubusercontent.com/assets/11307908/24343004/081e66ae-1279-11e7-8d9e-7f478043d835.png) > ### 주의 > 가끔 직접 리프레쉬를 해주어야 하는 경우가 있습니다. -> 1. 콤포넌트의 컨스트럭터 함수를 수정할 경우샐 +> 1. 콤포넌트의 컨스트럭터 함수를 수정할 경우 > 2. 새로운 CSS코드를 추가할 경우(1.과 같은 이유: CSS클래스는 콤포넌트마다 다시 만들어 지는데, 이 작업은 컨스트럭터에서 일어납니다.) ## 배포 -그런트를 사용합니다. -실제 디플로이는 `grunt`로 실행할 수 있습니다. 하지만, 여기엔 Codesign과 Authenticode의 과정이 포함되어있기 때문에 사용 하셔선 안됩니다. +Boostnote에서는 배포 자동화를 위하여 그런트를 사용합니다. +실제 배포는 `grunt`로 실행할 수 있습니다. 하지만, 여기엔 Codesign과 Authenticode의 과정이 포함되어있기 때문에 사용 하셔선 안됩니다. 그래서, 실행파일만을 만드는 스크립트를 준비해 뒀습니다. +이 빌드는 npm v5.3.0에서는 작동하지 않습니다. 그러므로, 성공적으로 빌드하기 위해서는 v5.2.0을 사용해야 합니다. + ``` grunt pre-build ``` diff --git a/docs/ko/debug.md b/docs/ko/debug.md new file mode 100644 index 00000000..290eee9c --- /dev/null +++ b/docs/ko/debug.md @@ -0,0 +1,21 @@ +# Boostnote의 디버그 방법(Electron app) + +Boostnote는 Electron 애플리케이션이므로 Chromium위에서 작동합니다. 그렇기 때문에 개발자분들은 Google Chrome 브라우저에서 처럼 `Developer Tools`를 사용하실 수 있습니다. + +다음과 같이 `Developer Tools`를 실행할 수 있습니다: +![how_to_toggle_devTools](https://cloud.githubusercontent.com/assets/11307908/24343585/162187e2-127c-11e7-9c01-23578db03ecf.png) + +`Developer Tools`는 다음과 같이 나타납니다: +![Developer_Tools](https://cloud.githubusercontent.com/assets/11307908/24343545/eff9f3a6-127b-11e7-94cf-cb67bfda634a.png) + +에러가 발생할 때에는, 에러메시지가 `console`위에 표시 됩니다. + +## 디버깅 +예를들면 `debugger`를 사용하여 코드 안에서 다음과 같이 일시 정지지점을 설정할 수 있습니다: + +![debugger](https://cloud.githubusercontent.com/assets/11307908/24343879/9459efea-127d-11e7-9943-f60bf7f66d4a.png) + +이는 단순한 하나의 예시에 불과합니다. 자기자신에게 가장 잘 맞는 디버그 방법을 찾는 것도 좋을 것 입니다. + +## 참고 +* [디버그에 관한 Google Chrome의 공식 문서](https://developer.chrome.com/devtools) diff --git a/docs/ru/build.md b/docs/ru/build.md index c29eaba0..d106e482 100644 --- a/docs/ru/build.md +++ b/docs/ru/build.md @@ -4,7 +4,7 @@ * npm: 4.x * node: 7.x -Вы должны использовать `npm v4.x`, так как `$ grand pre-build` не работает в `v5.x`. +Вы должны использовать `npm v4.x`, так как `$ grunt pre-build` не работает в `v5.x`. ## Разработка @@ -43,6 +43,8 @@ $ yarn run dev-start Мы подготовили отдельный скрипт, который просто создает исполняемый файл: +This build doesn't work on npm v5.3.0. So you need to use v5.2.0 when you build it. + ``` grunt pre-build ``` diff --git a/docs/zh_CN/build.md b/docs/zh_CN/build.md new file mode 100644 index 00000000..9183ebb3 --- /dev/null +++ b/docs/zh_CN/build.md @@ -0,0 +1,56 @@ +# 构建Boostnote + +## 环境 +* npm: 4.x +* node: 7.x + +因为`$ grunt pre-build`的问题,您只能使用`npm v4.x`而不能使用`npm v5.x`。 + +## 开发 + +我们使用Webpack HMR来开发Boostnote。 +在代码根目录下运行下列指令可以以默认配置运行Boostnote。 + +### 首先使用yarn安装所需的依赖包。 + +``` +$ yarn +``` + +### 接着编译并且运行Boostnote。 + +``` +$ yarn run dev-start +``` + +这个指令相当于在两个终端内同时运行`yarn run webpack`和`yarn run hot`。 + +如果出现错误`Failed to load resource: net::ERR_CONNECTION_REFUSED`,请尝试重新运行Boostnote。 +![net::ERR_CONNECTION_REFUSED](https://cloud.githubusercontent.com/assets/11307908/24343004/081e66ae-1279-11e7-8d9e-7f478043d835.png) + +### 然后您就可以进行开发了 + +当您对代码作出更改的时候,`webpack`会自动抓取并应用所有代码更改。 + +> ### 提示 +> 在如下情况中,您可能需要重新运行Boostnote才能应用代码更改 +> 1. 当您在修改了一个组件的构造函数的时候When editing a constructor method of a component +> 2. 当您新建了一个CSS类的时候(其实这和第1项是相同的,因为每个CSS类都需在组件的构造函数中被重写) + +## 部署 + +我们使用Grunt来自动部署Boostnote。 +因为部署需要协同设计(codesign)与验证码(authenticode),所以您可以但我们不建议通过`grunt`来部署。 +所以我们准备了一个脚本文件来生成执行文件。 + +``` +grunt pre-build +``` + +您只能使用`npm v5.2.0`而不能使用`npm v5.3.0`。 + +接下来您就可以在`dist`目录中找到可执行文件。 + +> ### 提示 +> 因为此可执行文件并没有被注册,所以自动更新不可用。 +> 如果需要,您也可将协同设计(codesign)与验证码(authenticode)使用于这个可执行文件中。 diff --git a/docs/zh_CN/debug.md b/docs/zh_CN/debug.md new file mode 100644 index 00000000..5f44ecd8 --- /dev/null +++ b/docs/zh_CN/debug.md @@ -0,0 +1,15 @@ +# 在Boostnote上Debug + +Boostnote基于Electron,所以Boostnote上的开发者工具和Google Chrome相同。 + +您可以像这样或者按下快捷键`Ctrl+Shift+I`打开开发者工具: +![how_to_toggle_devTools](https://cloud.githubusercontent.com/assets/11307908/24343585/162187e2-127c-11e7-9c01-23578db03ecf.png) + +开发者工具大概形如这样: +![Developer_Tools](https://cloud.githubusercontent.com/assets/11307908/24343545/eff9f3a6-127b-11e7-94cf-cb67bfda634a.png) + +您可以在`console`选项卡中找到运行错误, +也可以像这样在`debugger`选项卡中设置断点去分步Debug: +![debugger](https://cloud.githubusercontent.com/assets/11307908/24343879/9459efea-127d-11e7-9943-f60bf7f66d4a.png) + +关于具体如何使用开发者工具,详见[Chrome 官档](https://developer.chrome.com/devtools)。(如果您在中国大陆,您可能需要一个VPN才能正常访问) diff --git a/lib/main-window.js b/lib/main-window.js index 62ce14ac..5b53448d 100644 --- a/lib/main-window.js +++ b/lib/main-window.js @@ -17,7 +17,8 @@ const mainWindow = new BrowserWindow({ webPreferences: { zoomFactor: 1.0, blinkFeatures: 'OverlayScrollbars' - } + }, + icon: path.resolve(__dirname, '../resources/app.png') }) const url = path.resolve(__dirname, './main.html') diff --git a/lib/main.html b/lib/main.html index c76d49e0..4c10fcac 100644 --- a/lib/main.html +++ b/lib/main.html @@ -20,6 +20,15 @@ font-weight: normal; text-rendering: optimizeLegibility; } + @font-face { + font-family: 'Lato'; + src: url('../resources/fonts/Lato-Regular.woff2') format('woff2'), /* Modern Browsers */ + url('../resources/fonts/Lato-Regular.woff') format('woff'), /* Modern Browsers */ + url('../resources/fonts/Lato-Regular.ttf') format('truetype'); + font-style: normal; + font-weight: normal; + text-rendering: optimizeLegibility; + } #loadingCover{ background-color: #f4f4f4; position: absolute; diff --git a/package.json b/package.json index 46f239ef..2370049b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,7 @@ { "name": "boost", - "version": "0.8.12", + "productName": "Boostnote", + "version": "0.8.15", "main": "index.js", "description": "Boostnote", "license": "GPL-3.0", @@ -65,6 +66,8 @@ "markdown-it-emoji": "^1.1.1", "markdown-it-footnote": "^3.0.0", "markdown-it-imsize": "^2.0.1", + "markdown-it-multimd-table": "^2.0.1", + "markdown-it-named-headers": "^0.0.4", "md5": "^2.0.0", "mixpanel": "^0.4.1", "moment": "^2.10.3", @@ -76,6 +79,7 @@ "react-redux": "^4.4.5", "redux": "^3.5.2", "sander": "^0.5.1", + "striptags": "^2.2.1", "superagent": "^1.2.0", "superagent-promise": "^1.0.3" }, @@ -99,6 +103,7 @@ "eslint": "^3.13.1", "eslint-config-standard": "^6.2.1", "eslint-config-standard-jsx": "^3.2.0", + "eslint-plugin-react": "^7.2.0", "faker": "^3.1.0", "grunt": "^0.4.5", "grunt-electron-installer": "^1.2.0", diff --git a/readme.md b/readme.md index 0799eba9..00b58719 100644 --- a/readme.md +++ b/readme.md @@ -1,16 +1,13 @@ -

    - Boostnote -
    - Boostnote -
    -
    -

    -

    Note-taking app for programmers.

    -
    macOS, Windows and Linux. Android and iOS apps will be released soon!
    -
    Built with Electron, React + Redux, Webpack and CSSModules
    +New:zap: + +[Android and iOS apps](https://github.com/BoostIO/Boostnote-mobile) are released! ![Boostnote app screenshot](./resources/repository/top.png) +

    Note-taking app for programmers.

    +
    Apps available for Mac, Windows, Linux, Android and iOS!
    +
    Built with Electron, React + Redux, Webpack and CSSModules
    + [![Build Status](https://travis-ci.org/BoostIO/Boostnote.svg?branch=master)](https://travis-ci.org/BoostIO/Boostnote) ## Authors & Maintainers @@ -25,11 +22,11 @@ ## Slack Group Let's talk about Boostnote's great features, new feature requests and things like Japanese gourmet. 🍣
    -[Join us](https://join.slack.com/t/boostnote-group/shared_invite/MjE3NDcwODQ3NTkwLTE1MDA4NjQ3ODktM2IxOTk4ZTNjYQ) +[Join us](https://join.slack.com/t/boostnote-group/shared_invite/enQtMjQ0MjYxNTMxNjY5LTI0NWFkZDEyYWYxYWE0YTMyYjI4NzA2YjBlNmFmOGVhNGFjY2I1MTNmZWJjYmMxYTdkM2VjNWNjYTFiYWQ3ZmQ) ## More Information * [Website](https://boostnote.io) -* [Boostnote Team](https://boostnote.io/team/) : Boostnote for the creative hacker teams. Share your markdown notes and snippets instantly with your team. **We will release it at August!** 🏃💨 +* [10hz](https://boostnote.io/team/) : Boostnote for the creative hacker teams. Share your markdown notes and snippets instantly with your team. **We will release it at October!** 🏃💨 * [Support us via Bountysource](https://salt.bountysource.com/teams/boostnote) : Thank you for your support 🎉 * [Development](https://github.com/BoostIO/Boostnote/blob/master/docs/build.md) : Development configurations for Boostnote 🚀 * Copyright (C) 2017 Maisin&Co. diff --git a/resources/repository/top.png b/resources/repository/top.png index dcd55e23..584aa1d6 100644 Binary files a/resources/repository/top.png and b/resources/repository/top.png differ diff --git a/tests/lib/boostnoterc/.boostnoterc.all b/tests/lib/boostnoterc/.boostnoterc.all new file mode 100644 index 00000000..2caa2c1a --- /dev/null +++ b/tests/lib/boostnoterc/.boostnoterc.all @@ -0,0 +1,33 @@ +{ + "amaEnabled": true, + "editor": { + "fontFamily": "Monaco, Consolas", + "fontSize": "14", + "indentSize": "2", + "indentType": "space", + "keyMap": "vim", + "switchPreview": "BLUR", + "theme": "monokai" + }, + "hotkey": { + "toggleFinder": "Cmd + Alt + S", + "toggleMain": "Cmd + Alt + L" + }, + "isSideNavFolded": false, + "listStyle": "DEFAULT", + "listWidth": 174, + "navWidth": 200, + "preview": { + "codeBlockTheme": "dracula", + "fontFamily": "Lato", + "fontSize": "14", + "lineNumber": true + }, + "sortBy": "UPDATED_AT", + "ui": { + "defaultNote": "ALWAYS_ASK", + "disableDirectWrite": false, + "theme": "default" + }, + "zoom": 1 +} diff --git a/tests/lib/boostnoterc/.boostnoterc.invalid b/tests/lib/boostnoterc/.boostnoterc.invalid new file mode 100644 index 00000000..500327cb --- /dev/null +++ b/tests/lib/boostnoterc/.boostnoterc.invalid @@ -0,0 +1,12 @@ +{ + "editor": { + "keyMap": "vim", + "switchPreview": "BLUR", + "theme": "monokai", + }, + "hotkey": { + "toggleMain": "Control + L" + }, + "listWidth": 135, + "navWidth": 135 +} diff --git a/tests/lib/boostnoterc/.boostnoterc.valid b/tests/lib/boostnoterc/.boostnoterc.valid new file mode 100644 index 00000000..23f50f15 --- /dev/null +++ b/tests/lib/boostnoterc/.boostnoterc.valid @@ -0,0 +1,12 @@ +{ + "editor": { + "keyMap": "vim", + "switchPreview": "BLUR", + "theme": "monokai" + }, + "hotkey": { + "toggleMain": "Control + L" + }, + "listWidth": 135, + "navWidth": 135 +} diff --git a/tests/lib/get-todo-status-test.js b/tests/lib/get-todo-status-test.js new file mode 100644 index 00000000..55f951f5 --- /dev/null +++ b/tests/lib/get-todo-status-test.js @@ -0,0 +1,23 @@ +const test = require('ava') +const { getTodoStatus } = require('browser/lib/getTodoStatus') + +// Unit test +test('getTodoStatus should return a correct hash object', t => { + // [input, expected] + const testCases = [ + ['', { total: 0, completed: 0 }], + ['* [ ] a\n', { total: 1, completed: 0 }], + ['* [ ] a\n* [x] a\n', { total: 2, completed: 1 }], + ['- [ ] a\n', { total: 1, completed: 0 }], + ['- [ ] a\n- [x] a\n', { total: 2, completed: 1 }], + ['+ [ ] a\n', { total: 1, completed: 0 }], + ['+ [ ] a\n+ [x] a\n', { total: 2, completed: 1 }] + ] + + testCases.forEach(testCase => { + const [input, expected] = testCase + t.is(getTodoStatus(input).total, expected.total, `Test for getTodoStatus() input: ${input} expected: ${expected.total}`) + t.is(getTodoStatus(input).completed, expected.completed, `Test for getTodoStatus() input: ${input} expected: ${expected.completed}`) + }) +}) + diff --git a/tests/lib/rc-parser-test.js b/tests/lib/rc-parser-test.js new file mode 100644 index 00000000..a0f6d2a8 --- /dev/null +++ b/tests/lib/rc-parser-test.js @@ -0,0 +1,33 @@ +const test = require('ava') +const path = require('path') +const { parse } = require('browser/lib/RcParser') + +// Unit test +test('RcParser should return a json object', t => { + const validJson = { 'editor': { 'keyMap': 'vim', 'switchPreview': 'BLUR', 'theme': 'monokai' }, 'hotkey': { 'toggleMain': 'Control + L' }, 'listWidth': 135, 'navWidth': 135 } + const allJson = { 'amaEnabled': true, 'editor': { 'fontFamily': 'Monaco, Consolas', 'fontSize': '14', 'indentSize': '2', 'indentType': 'space', 'keyMap': 'vim', 'switchPreview': 'BLUR', 'theme': 'monokai' }, 'hotkey': { 'toggleFinder': 'Cmd + Alt + S', 'toggleMain': 'Cmd + Alt + L' }, 'isSideNavFolded': false, 'listStyle': 'DEFAULT', 'listWidth': 174, 'navWidth': 200, 'preview': { 'codeBlockTheme': 'dracula', 'fontFamily': 'Lato', 'fontSize': '14', 'lineNumber': true }, 'sortBy': 'UPDATED_AT', 'ui': { 'defaultNote': 'ALWAYS_ASK', 'disableDirectWrite': false, 'theme': 'default' }, 'zoom': 1 } + + // [input, expected] + const validTestCases = [ + ['.boostnoterc.valid', validJson], + ['.boostnoterc.all', allJson] + ] + + const invalidTestCases = [ + ['.boostnoterc.invalid', {}] + ] + + validTestCases.forEach(validTestCase => { + const [input, expected] = validTestCase + t.is(parse(filePath(input)).editor.keyMap, expected.editor.keyMap, `Test for getTodoStatus() input: ${input} expected: ${expected.keyMap}`) + }) + + invalidTestCases.forEach(invalidTestCase => { + const [input, expected] = invalidTestCase + t.is(parse(filePath(input)).editor, expected.editor, `Test for getTodoStatus() input: ${input} expected: ${expected.editor}`) + }) +}) + +function filePath (filename) { + return path.join('boostnoterc', filename) +} diff --git a/yarn.lock b/yarn.lock index c7067c1b..157e2977 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1,7 +1,5 @@ # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. # yarn lockfile v1 - - "@rokt33r/markdown-it-math@^4.0.1": version "4.0.2" resolved "https://registry.yarnpkg.com/@rokt33r/markdown-it-math/-/markdown-it-math-4.0.2.tgz#87c7172f459833b05e406cfc846e0c0b7ebc24ef" @@ -132,7 +130,7 @@ are-we-there-yet@~1.1.2: delegates "^1.0.0" readable-stream "^2.0.6" -argparse@^1.0.7: +argparse@^1.0.7, argparse@~1.0.3: version "1.0.9" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" dependencies: @@ -175,6 +173,13 @@ array-flatten@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" +array-includes@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.0.3.tgz#184b48f62d92d7452bb31b323165c7f8bd02266d" + dependencies: + define-properties "^1.1.2" + es-abstract "^1.7.0" + array-union@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" @@ -233,17 +238,13 @@ asar@~0.8.0: mkdirp "^0.5.0" mksnapshot "0.1.0" -asn1@0.1.11: - version "0.1.11" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.1.11.tgz#559be18376d08a4ec4dbe80877d27818639b2df7" - asn1@~0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" +asn1@0.1.11: + version "0.1.11" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.1.11.tgz#559be18376d08a4ec4dbe80877d27818639b2df7" assert-plus@^0.1.5: version "0.1.5" @@ -253,6 +254,10 @@ assert-plus@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" +assert-plus@^1.0.0, assert-plus@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + assert@^1.1.1: version "1.4.1" resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91" @@ -398,7 +403,7 @@ aws-sdk-mobile-analytics@^0.9.2: dependencies: aws-sdk ">=2.2.37" -aws-sdk@>=2.2.37, aws-sdk@^2.48.0: +aws-sdk@^2.48.0, aws-sdk@>=2.2.37: version "2.48.0" resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.48.0.tgz#c89bbdbd71fdd33457cd65c46c4080e4e44b2702" dependencies: @@ -1100,14 +1105,14 @@ balanced-match@^0.4.1, balanced-match@^0.4.2: version "0.4.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" -base64-js@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-0.0.8.tgz#1101e9544f4a76b1bc3b26d452ca96d7a35e7978" - base64-js@^1.0.2: version "1.2.0" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.0.tgz#a39992d723584811982be5e290bb6a53d86700f1" +base64-js@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-0.0.8.tgz#1101e9544f4a76b1bc3b26d452ca96d7a35e7978" + batch@0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" @@ -1219,7 +1224,7 @@ buffer-shims@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51" -buffer@4.9.1, buffer@^4.9.0: +buffer@^4.9.0, buffer@4.9.1: version "4.9.1" resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" dependencies: @@ -1327,16 +1332,6 @@ chainsaw@~0.1.0: dependencies: traverse ">=0.3.0 <0.4" -chalk@0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.5.1.tgz#663b3a648b68b55d04690d49167aa837858f2174" - dependencies: - ansi-styles "^1.1.0" - escape-string-regexp "^1.0.0" - has-ansi "^0.1.0" - strip-ansi "^0.3.0" - supports-color "^0.2.0" - chalk@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.4.0.tgz#5199a3ddcd0c1efe23bc08c1b027b06176e0c64f" @@ -1355,6 +1350,16 @@ chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" +chalk@0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.5.1.tgz#663b3a648b68b55d04690d49167aa837858f2174" + dependencies: + ansi-styles "^1.1.0" + escape-string-regexp "^1.0.0" + has-ansi "^0.1.0" + strip-ansi "^0.3.0" + supports-color "^0.2.0" + charenc@~0.0.1: version "0.0.2" resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" @@ -1374,7 +1379,7 @@ chokidar@^1.0.0, chokidar@^1.4.2: optionalDependencies: fsevents "^1.0.0" -chromium-pickle-js@0.1.0, chromium-pickle-js@^0.1.0: +chromium-pickle-js@^0.1.0, chromium-pickle-js@0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/chromium-pickle-js/-/chromium-pickle-js-0.1.0.tgz#1d48b107d82126a2f3e211c2ea25f803ba551b21" @@ -1529,6 +1534,12 @@ combined-stream@~0.0.4, combined-stream@~0.0.5: dependencies: delayed-stream "0.0.5" +commander@^2.8.1, commander@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" + dependencies: + graceful-readlink ">= 1.0.0" + commander@2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.3.0.tgz#fd430e889832ec353b9acd1de217c11cb3eef873" @@ -1537,12 +1548,6 @@ commander@2.6.0: version "2.6.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.6.0.tgz#9df7e52fb2a0cb0fb89058ee80c3104225f37e1d" -commander@^2.8.1, commander@^2.9.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" - dependencies: - graceful-readlink ">= 1.0.0" - common-path-prefix@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/common-path-prefix/-/common-path-prefix-1.0.0.tgz#cd52f6f0712e0baab97d6f9732874f22f47752c0" @@ -1576,7 +1581,7 @@ concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" -concat-stream@1.6.0, concat-stream@^1.4.6, concat-stream@^1.5.2: +concat-stream@^1.4.6, concat-stream@^1.5.2, concat-stream@1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" dependencies: @@ -1817,7 +1822,7 @@ csso@~2.3.1: clap "^1.0.9" source-map "^0.5.3" -cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": +"cssom@>= 0.3.2 < 0.4.0", cssom@0.3.x: version "0.3.2" resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.2.tgz#b8036170c79f07a90ff2f16e22284027a243848b" @@ -1831,14 +1836,14 @@ ctype@0.5.3: version "0.5.3" resolved "https://registry.yarnpkg.com/ctype/-/ctype-0.5.3.tgz#82c18c2461f74114ef16c135224ad0b9144ca12f" -cuint@0.1.5: - version "0.1.5" - resolved "https://registry.yarnpkg.com/cuint/-/cuint-0.1.5.tgz#b848b18466f3f180f96d1eb6e07ccb7ecf126a2e" - cuint@^0.2.1: version "0.2.2" resolved "https://registry.yarnpkg.com/cuint/-/cuint-0.2.2.tgz#408086d409550c2631155619e9fa7bcadc3b991b" +cuint@0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/cuint/-/cuint-0.1.5.tgz#b848b18466f3f180f96d1eb6e07ccb7ecf126a2e" + currently-unhandled@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" @@ -1877,13 +1882,13 @@ debug-log@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/debug-log/-/debug-log-1.0.1.tgz#2307632d4c04382b8df8a32f70b895046d52745f" -debug@*, debug@2, debug@2.6.8, debug@^2.1.1, debug@^2.1.3, debug@^2.2.0, debug@^2.6.6: +debug@*, debug@^2.1.1, debug@^2.1.3, debug@^2.2.0, debug@^2.6.6, debug@2, debug@2.6.8: version "2.6.8" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" dependencies: ms "2.0.0" -debug@2.2.0, debug@~2.2.0: +debug@~2.2.0, debug@2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" dependencies: @@ -1935,6 +1940,13 @@ deep-is@~0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" +define-properties@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94" + dependencies: + foreach "^2.0.5" + object-keys "^1.0.8" + defined@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" @@ -1962,19 +1974,19 @@ del@^2.0.2: pinkie-promise "^2.0.0" rimraf "^2.2.8" -delayed-stream@0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-0.0.5.tgz#d4b1f43a93e8296dfe02694f4680bc37a313c73f" - delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" +delayed-stream@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-0.0.5.tgz#d4b1f43a93e8296dfe02694f4680bc37a313c73f" + delegates@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" -depd@1.1.0, depd@~1.1.0: +depd@~1.1.0, depd@1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.0.tgz#e1bd82c6aab6ced965b97b88b17ed3e528ca18c3" @@ -2202,6 +2214,24 @@ error-stack-parser@^1.3.6: dependencies: stackframe "^0.3.1" +es-abstract@^1.7.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.8.0.tgz#3b00385e85729932beffa9163bbea1234e932914" + dependencies: + es-to-primitive "^1.1.1" + function-bind "^1.1.0" + has "^1.0.1" + is-callable "^1.1.3" + is-regex "^1.0.4" + +es-to-primitive@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.1.1.tgz#45355248a88979034b6792e19bb81f2b7975dd0d" + dependencies: + is-callable "^1.1.1" + is-date-object "^1.0.1" + is-symbol "^1.0.1" + es5-ext@^0.10.14, es5-ext@^0.10.9, es5-ext@~0.10.14: version "0.10.21" resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.21.tgz#19a725f9e51d0300bbc1e8e821109fd9daf55925" @@ -2209,7 +2239,7 @@ es5-ext@^0.10.14, es5-ext@^0.10.9, es5-ext@~0.10.14: es6-iterator "2" es6-symbol "~3.1" -es6-iterator@2, es6-iterator@^2.0.1, es6-iterator@~2.0.1: +es6-iterator@^2.0.1, es6-iterator@~2.0.1, es6-iterator@2: version "2.0.1" resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.1.tgz#8e319c9f0453bf575d374940a655920e59ca5512" dependencies: @@ -2246,7 +2276,7 @@ es6-set@~0.1.5: es6-symbol "3.1.1" event-emitter "~0.3.5" -es6-symbol@3.1.1, es6-symbol@^3.1, es6-symbol@^3.1.1, es6-symbol@~3.1, es6-symbol@~3.1.1: +es6-symbol@^3.1, es6-symbol@^3.1.1, es6-symbol@~3.1, es6-symbol@~3.1.1, es6-symbol@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" dependencies: @@ -2290,15 +2320,15 @@ escope@^3.6.0: esrecurse "^4.1.0" estraverse "^4.1.1" -eslint-config-standard-jsx@3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/eslint-config-standard-jsx/-/eslint-config-standard-jsx-3.2.0.tgz#c240e26ed919a11a42aa4de8059472b38268d620" - eslint-config-standard-jsx@^3.2.0: version "3.3.0" resolved "https://registry.yarnpkg.com/eslint-config-standard-jsx/-/eslint-config-standard-jsx-3.3.0.tgz#cab0801a15a360bf63facb97ab22fbdd88d8a5e0" -eslint-config-standard@6.2.1, eslint-config-standard@^6.2.1: +eslint-config-standard-jsx@3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/eslint-config-standard-jsx/-/eslint-config-standard-jsx-3.2.0.tgz#c240e26ed919a11a42aa4de8059472b38268d620" + +eslint-config-standard@^6.2.1, eslint-config-standard@6.2.1: version "6.2.1" resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-6.2.1.tgz#d3a68aafc7191639e7ee441e7348739026354292" @@ -2306,6 +2336,14 @@ eslint-plugin-promise@~3.4.0: version "3.4.2" resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-3.4.2.tgz#1be2793eafe2d18b5b123b8136c269f804fe7122" +eslint-plugin-react@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.2.0.tgz#25c77a4ec307e3eebb248ea3350960e372ab6406" + dependencies: + doctrine "^2.0.0" + has "^1.0.1" + jsx-ast-utils "^2.0.0" + eslint-plugin-react@~6.7.1: version "6.7.1" resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-6.7.1.tgz#1af96aea545856825157d97c1b50d5a8fb64a5a7" @@ -2553,7 +2591,7 @@ express@^4.13.3: utils-merge "1.0.0" vary "~1.1.1" -extend@3.0.0, extend@~3.0.0: +extend@~3.0.0, extend@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.0.tgz#5a474353b9f3353ddd8176dfd37b91c83a46f1d4" @@ -2731,18 +2769,14 @@ for-own@^0.1.4: dependencies: for-in "^1.0.1" +foreach@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" + forever-agent@~0.6.0, forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" -form-data@1.0.0-rc3: - version "1.0.0-rc3" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-1.0.0-rc3.tgz#d35bc62e7fbc2937ae78f948aaa0d38d90607577" - dependencies: - async "^1.4.0" - combined-stream "^1.0.5" - mime-types "^2.1.3" - form-data@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/form-data/-/form-data-0.2.0.tgz#26f8bc26da6440e299cbdcfb69035c4f77a6e466" @@ -2759,6 +2793,14 @@ form-data@~2.1.1: combined-stream "^1.0.5" mime-types "^2.1.12" +form-data@1.0.0-rc3: + version "1.0.0-rc3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-1.0.0-rc3.tgz#d35bc62e7fbc2937ae78f948aaa0d38d90607577" + dependencies: + async "^1.4.0" + combined-stream "^1.0.5" + mime-types "^2.1.3" + formidable@~1.0.14: version "1.0.17" resolved "https://registry.yarnpkg.com/formidable/-/formidable-1.0.17.tgz#ef5491490f9433b705faa77249c99029ae348559" @@ -2771,15 +2813,7 @@ fresh@0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.0.tgz#f474ca5e6a9246d6fd8e0953cfa9b9c805afa78e" -fs-extra@0.18.2: - version "0.18.2" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.18.2.tgz#af05ca702b0b6dfa7de803a1f7ab479ec5c21525" - dependencies: - graceful-fs "^3.0.5" - jsonfile "^2.0.0" - rimraf "^2.2.8" - -fs-extra@0.26.7, fs-extra@^0.26.0, fs-extra@^0.26.5: +fs-extra@^0.26.0, fs-extra@^0.26.5, fs-extra@0.26.7: version "0.26.7" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.26.7.tgz#9ae1fdd94897798edab76d0918cf42d0c3184fa9" dependencies: @@ -2799,6 +2833,14 @@ fs-extra@^0.30.0: path-is-absolute "^1.0.0" rimraf "^2.2.8" +fs-extra@0.18.2: + version "0.18.2" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.18.2.tgz#af05ca702b0b6dfa7de803a1f7ab479ec5c21525" + dependencies: + graceful-fs "^3.0.5" + jsonfile "^2.0.0" + rimraf "^2.2.8" + fs-plus@2.x: version "2.10.1" resolved "https://registry.yarnpkg.com/fs-plus/-/fs-plus-2.10.1.tgz#3204781d7840611e6364e7b6fb058c96327c5aa5" @@ -2836,7 +2878,7 @@ fstream@^1.0.0, fstream@^1.0.10, fstream@^1.0.2: mkdirp ">=0.5 0" rimraf "2" -function-bind@^1.0.2: +function-bind@^1.0.2, function-bind@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.0.tgz#16176714c801798e4e8f2cf7f7529467bb4a5771" @@ -2909,24 +2951,6 @@ glob-parent@^2.0.0: dependencies: is-glob "^2.0.0" -glob@3.2.x, glob@~3.2.9: - version "3.2.11" - resolved "https://registry.yarnpkg.com/glob/-/glob-3.2.11.tgz#4a973f635b9190f715d10987d5c00fd2815ebe3d" - dependencies: - inherits "2" - minimatch "0.3" - -glob@7.0.x: - version "7.0.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.0.6.tgz#211bafaf49e525b8cd93260d14ab136152b3f57a" - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.2" - once "^1.3.0" - path-is-absolute "^1.0.0" - glob@^5.0.5: version "5.0.15" resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" @@ -2966,6 +2990,24 @@ glob@~3.1.21: inherits "1" minimatch "~0.2.11" +glob@~3.2.9, glob@3.2.x: + version "3.2.11" + resolved "https://registry.yarnpkg.com/glob/-/glob-3.2.11.tgz#4a973f635b9190f715d10987d5c00fd2815ebe3d" + dependencies: + inherits "2" + minimatch "0.3" + +glob@7.0.x: + version "7.0.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.0.6.tgz#211bafaf49e525b8cd93260d14ab136152b3f57a" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.2" + once "^1.3.0" + path-is-absolute "^1.0.0" + global@^4.3.0: version "4.3.2" resolved "https://registry.yarnpkg.com/global/-/global-4.3.2.tgz#e76989268a6c74c38908b1305b10fc0e394e9d0f" @@ -3275,14 +3317,14 @@ humanize-plus@^1.8.1: version "1.8.2" resolved "https://registry.yarnpkg.com/humanize-plus/-/humanize-plus-1.8.2.tgz#a65b34459ad6367adbb3707a82a3c9f916167030" -iconv-lite@0.4.13, iconv-lite@~0.4.13: - version "0.4.13" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.13.tgz#1f88aba4ab0b1508e8312acc39345f36e992e2f2" - iconv-lite@~0.2.11: version "0.2.11" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.2.11.tgz#1ce60a3a57864a292d1321ff4609ca4bb965adc8" +iconv-lite@~0.4.13, iconv-lite@0.4.13: + version "0.4.13" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.13.tgz#1f88aba4ab0b1508e8312acc39345f36e992e2f2" + ieee754@^1.1.4: version "1.1.8" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4" @@ -3324,14 +3366,14 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" +inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1, inherits@2, inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + inherits@1: version "1.0.2" resolved "https://registry.yarnpkg.com/inherits/-/inherits-1.0.2.tgz#ca4309dadee6b54cc0b8d247e8d7c7a0975bdc9b" -inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - inherits@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" @@ -3408,12 +3450,20 @@ is-builtin-module@^1.0.0: dependencies: builtin-modules "^1.0.0" +is-callable@^1.1.1, is-callable@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.3.tgz#86eb75392805ddc33af71c92a0eedf74ee7604b2" + is-ci@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.0.10.tgz#f739336b2632365061a9d48270cd56ae3369318e" dependencies: ci-info "^1.0.0" +is-date-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" + is-dotfile@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.2.tgz#2c132383f39199f8edc268ca01b9b007d205cc4d" @@ -3541,6 +3591,12 @@ is-redirect@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" +is-regex@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" + dependencies: + has "^1.0.1" + is-resolvable@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.0.0.tgz#8df57c61ea2e3c501408d100fb013cf8d6e0cc62" @@ -3561,6 +3617,10 @@ is-svg@^2.0.0: dependencies: html-comment-regex "^1.1.0" +is-symbol@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572" + is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" @@ -3573,14 +3633,14 @@ is-utf8@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" +isarray@^1.0.0, isarray@~1.0.0, isarray@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + isarray@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" -isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -3747,6 +3807,12 @@ jsx-ast-utils@^1.3.3: version "1.4.1" resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-1.4.1.tgz#3867213e8dd79bf1e8f2300c0cfc1efb182c0df1" +jsx-ast-utils@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-2.0.0.tgz#ec06a3d60cf307e5e119dac7bad81e89f096f0f8" + dependencies: + array-includes "^3.0.3" + katex@^0.7.1: version "0.7.1" resolved "https://registry.yarnpkg.com/katex/-/katex-0.7.1.tgz#06bb5298efad05e1e7228035ba8e1591f3061b8f" @@ -3798,7 +3864,7 @@ levn@^0.3.0, levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" -linkify-it@~1.2.2: +linkify-it@~1.2.0, linkify-it@~1.2.2: version "1.2.4" resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-1.2.4.tgz#0773526c317c8fd13bd534ee1d180ff88abf881a" dependencies: @@ -3916,10 +3982,6 @@ lowercase-keys@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" -lru-cache@2: - version "2.7.3" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.7.3.tgz#6d4524e8b955f95d4f5b58851ce21dd72fb4e952" - lru-cache@^4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.0.2.tgz#1d17679c069cda5d040991a09dbc2c0db377e55e" @@ -3927,6 +3989,10 @@ lru-cache@^4.0.1: pseudomap "^1.0.1" yallist "^2.0.0" +lru-cache@2: + version "2.7.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.7.3.tgz#6d4524e8b955f95d4f5b58851ce21dd72fb4e952" + macaddress@^0.2.8: version "0.2.8" resolved "https://registry.yarnpkg.com/macaddress/-/macaddress-0.2.8.tgz#5904dc537c39ec6dbefeae902327135fa8511f12" @@ -3953,6 +4019,28 @@ markdown-it-imsize: version "2.0.1" resolved "https://registry.yarnpkg.com/markdown-it-imsize/-/markdown-it-imsize-2.0.1.tgz#cca0427905d05338a247cb9ca9d968c5cddd5170" +markdown-it-multimd-table@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/markdown-it-multimd-table/-/markdown-it-multimd-table-2.0.1.tgz#2e246dc2ec4ca093cbf05d43c9c1cc64e31f255d" + dependencies: + markdown-it "^5.0.3" + +markdown-it-named-headers@^0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/markdown-it-named-headers/-/markdown-it-named-headers-0.0.4.tgz#82efc28324240a6b1e77b9aae501771d5f351c1f" + dependencies: + string "^3.0.1" + +markdown-it@^5.0.3: + version "5.1.0" + resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-5.1.0.tgz#25286b8465bac496f3f1b77eed544643e9bd718d" + dependencies: + argparse "~1.0.3" + entities "~1.1.1" + linkify-it "~1.2.0" + mdurl "~1.0.1" + uc.micro "^1.0.0" + markdown-it@^6.0.1: version "6.1.1" resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-6.1.1.tgz#ced037f4473ee9f5153ac414f77dc83c91ba927c" @@ -4096,7 +4184,7 @@ mime-types@~2.0.1, mime-types@~2.0.3: dependencies: mime-db "~1.12.0" -mime@1.3.4, mime@^1.3.4: +mime@^1.3.4, mime@1.3.4: version "1.3.4" resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.4.tgz#115f9e3b6b3daf2959983cb38f149a2d40eb5d53" @@ -4106,25 +4194,12 @@ min-document@^2.19.0: dependencies: dom-walk "^0.1.0" -minimatch@0.3: - version "0.3.0" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.3.0.tgz#275d8edaac4f1bb3326472089e7949c8394699dd" - dependencies: - lru-cache "2" - sigmund "~1.0.0" - -"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4: +minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4, "minimatch@2 || 3": version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" dependencies: brace-expansion "^1.1.7" -minimatch@2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-2.0.4.tgz#83bea115803e7a097a78022427287edb762fafed" - dependencies: - brace-expansion "^1.0.0" - minimatch@~0.2.11, minimatch@~0.2.12: version "0.2.14" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.2.14.tgz#c74e780574f63c6f9a090e90efbe6ef53a6a756a" @@ -4132,42 +4207,47 @@ minimatch@~0.2.11, minimatch@~0.2.12: lru-cache "2" sigmund "~1.0.0" -minimist@0.0.8, minimist@~0.0.1: - version "0.0.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" +minimatch@0.3: + version "0.3.0" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.3.0.tgz#275d8edaac4f1bb3326472089e7949c8394699dd" + dependencies: + lru-cache "2" + sigmund "~1.0.0" + +minimatch@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-2.0.4.tgz#83bea115803e7a097a78022427287edb762fafed" + dependencies: + brace-expansion "^1.0.0" minimist@^1.1.0, minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" +minimist@~0.0.1, minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + mixpanel@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/mixpanel/-/mixpanel-0.4.1.tgz#0e92ee336fb89a164f54830f093c9cae8517fb8f" +mkdirp@^0.5.0, mkdirp@^0.5.1, "mkdirp@>=0.5 0", mkdirp@~0.5.0, mkdirp@~0.5.1, mkdirp@0.5.x: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + dependencies: + minimist "0.0.8" + mkdirp@0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.0.tgz#1d73076a6df986cd9344e15e71fcc05a4c9abf12" dependencies: minimist "0.0.8" -mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" - dependencies: - minimist "0.0.8" - mkpath@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/mkpath/-/mkpath-0.1.0.tgz#7554a6f8d871834cc97b5462b122c4c124d6de91" -mksnapshot@0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/mksnapshot/-/mksnapshot-0.1.0.tgz#f7d09abca806ad8c3780da701bb18778d7ce69ac" - dependencies: - decompress-zip "0.1.0" - fs-extra "0.18.2" - request "2.55.0" - mksnapshot@^0.3.0: version "0.3.1" resolved "https://registry.yarnpkg.com/mksnapshot/-/mksnapshot-0.3.1.tgz#2501c05657436d742ce958a4ff92c77e40dd37e6" @@ -4176,10 +4256,22 @@ mksnapshot@^0.3.0: fs-extra "0.26.7" request "^2.79.0" +mksnapshot@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/mksnapshot/-/mksnapshot-0.1.0.tgz#f7d09abca806ad8c3780da701bb18778d7ce69ac" + dependencies: + decompress-zip "0.1.0" + fs-extra "0.18.2" + request "2.55.0" + moment@^2.10.3: version "2.18.1" resolved "https://registry.yarnpkg.com/moment/-/moment-2.18.1.tgz#c36193dd3ce1c2eed2adb7c802dbbc77a81b1c0f" +ms@^0.7.1: + version "0.7.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.3.tgz#708155a5e44e33f5fd0fc53e81d0d40a91be1fff" + ms@0.7.1: version "0.7.1" resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098" @@ -4188,10 +4280,6 @@ ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" -ms@^0.7.1: - version "0.7.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.3.tgz#708155a5e44e33f5fd0fc53e81d0d40a91be1fff" - multimatch@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b" @@ -4415,6 +4503,10 @@ object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" +object-keys@^1.0.8: + version "1.0.11" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d" + object-keys@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-0.4.0.tgz#28a6aae7428dd2c3a92f3d95f21335dd204e0336" @@ -5078,30 +5170,30 @@ pseudomap@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" -punycode@1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" - punycode@^1.2.4, punycode@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + q@^1.1.2: version "1.5.0" resolved "https://registry.yarnpkg.com/q/-/q-1.5.0.tgz#dd01bac9d06d30e6f219aecb8253ee9ebdc308f1" -qs@2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/qs/-/qs-2.3.3.tgz#e9e85adbe75da0bbe4c8e0476a086290f863b404" - -qs@6.4.0, qs@~6.4.0: - version "6.4.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" - qs@~2.4.0: version "2.4.2" resolved "https://registry.yarnpkg.com/qs/-/qs-2.4.2.tgz#f7ce788e5777df0b5010da7f7c4e73ba32470f5a" +qs@~6.4.0, qs@6.4.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" + +qs@2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-2.3.3.tgz#e9e85adbe75da0bbe4c8e0476a086290f863b404" + query-string@^3.0.0: version "3.0.3" resolved "https://registry.yarnpkg.com/query-string/-/query-string-3.0.3.tgz#ae2e14b4d05071d4e9b9eb4873c35b0dcd42e638" @@ -5123,14 +5215,14 @@ querystring@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" -querystringify@0.0.x: - version "0.0.4" - resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-0.0.4.tgz#0cf7f84f9463ff0ae51c4c4b142d95be37724d9c" - querystringify@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-1.0.0.tgz#6286242112c5b712fa654e526652bf6a13ff05cb" +querystringify@0.0.x: + version "0.0.4" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-0.0.4.tgz#0cf7f84f9463ff0ae51c4c4b142d95be37724d9c" + randomatic@^1.1.3: version "1.1.6" resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.6.tgz#110dcabff397e9dcff7c0789ccc0a49adf1ec5bb" @@ -5142,7 +5234,7 @@ range-parser@^1.0.3, range-parser@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" -raphael@2.2.7, raphael@^2.2.7: +raphael@^2.2.7, raphael@2.2.7: version "2.2.7" resolved "https://registry.yarnpkg.com/raphael/-/raphael-2.2.7.tgz#231b19141f8d086986d8faceb66f8b562ee2c810" dependencies: @@ -5293,15 +5385,6 @@ read-pkg@^1.0.0: normalize-package-data "^2.3.2" path-type "^1.0.0" -readable-stream@1.0.27-1: - version "1.0.27-1" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.27-1.tgz#6b67983c20357cefd07f0165001a16d710d91078" - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" - readable-stream@^1.1.8, readable-stream@~1.1.9: version "1.1.14" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" @@ -5332,6 +5415,15 @@ readable-stream@~1.0.26: isarray "0.0.1" string_decoder "~0.10.x" +readable-stream@1.0.27-1: + version "1.0.27-1" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.27-1.tgz#6b67983c20357cefd07f0165001a16d710d91078" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + readdirp@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78" @@ -5469,29 +5561,6 @@ repeating@^2.0.0: dependencies: is-finite "^1.0.0" -request@2.55.0: - version "2.55.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.55.0.tgz#d75c1cdf679d76bb100f9bffe1fe551b5c24e93d" - dependencies: - aws-sign2 "~0.5.0" - bl "~0.9.0" - caseless "~0.9.0" - combined-stream "~0.0.5" - forever-agent "~0.6.0" - form-data "~0.2.0" - har-validator "^1.4.0" - hawk "~2.3.0" - http-signature "~0.10.0" - isstream "~0.1.1" - json-stringify-safe "~5.0.0" - mime-types "~2.0.1" - node-uuid "~1.4.0" - oauth-sign "~0.6.0" - qs "~2.4.0" - stringstream "~0.0.4" - tough-cookie ">=0.12.0" - tunnel-agent "~0.4.0" - request@^2.45.0, request@^2.79.0, request@^2.81.0: version "2.81.0" resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" @@ -5519,6 +5588,29 @@ request@^2.45.0, request@^2.79.0, request@^2.81.0: tunnel-agent "^0.6.0" uuid "^3.0.0" +request@2.55.0: + version "2.55.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.55.0.tgz#d75c1cdf679d76bb100f9bffe1fe551b5c24e93d" + dependencies: + aws-sign2 "~0.5.0" + bl "~0.9.0" + caseless "~0.9.0" + combined-stream "~0.0.5" + forever-agent "~0.6.0" + form-data "~0.2.0" + har-validator "^1.4.0" + hawk "~2.3.0" + http-signature "~0.10.0" + isstream "~0.1.1" + json-stringify-safe "~5.0.0" + mime-types "~2.0.1" + node-uuid "~1.4.0" + oauth-sign "~0.6.0" + qs "~2.4.0" + stringstream "~0.0.4" + tough-cookie ">=0.12.0" + tunnel-agent "~0.4.0" + require-precompiled@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/require-precompiled/-/require-precompiled-0.1.0.tgz#5a1b52eb70ebed43eb982e974c85ab59571e56fa" @@ -5567,7 +5659,7 @@ right-align@^0.1.1: dependencies: align-text "^0.1.1" -rimraf@2, rimraf@^2.2.8, rimraf@^2.3.2, rimraf@^2.5.1, rimraf@^2.5.2, rimraf@^2.6.1: +rimraf@^2.2.8, rimraf@^2.3.2, rimraf@^2.5.1, rimraf@^2.5.2, rimraf@^2.6.1, rimraf@2: version "2.6.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.1.tgz#c2338ec643df7a1b7fe5c54fa86f57428a55f33d" dependencies: @@ -5622,21 +5714,21 @@ sander@^0.5.1: mkdirp "^0.5.1" rimraf "^2.5.2" +sax@^1.2.1, sax@>=0.6.0, sax@~1.2.1, sax@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a" + sax@0.5.x: version "0.5.8" resolved "https://registry.yarnpkg.com/sax/-/sax-0.5.8.tgz#d472db228eb331c2506b0e8c15524adb939d12c1" -sax@1.2.1, sax@>=0.6.0, sax@^1.2.1, sax@~1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a" - semver-diff@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" dependencies: semver "^5.0.3" -"semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.3.0: +semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, "semver@2 || 3 || 4 || 5": version "5.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" @@ -5777,12 +5869,6 @@ source-map-support@^0.4.0, source-map-support@^0.4.2: dependencies: source-map "^0.5.6" -source-map@0.1.x: - version "0.1.43" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346" - dependencies: - amdefine ">=0.0.4" - source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1: version "0.5.6" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" @@ -5799,6 +5885,12 @@ source-map@~0.4.1: dependencies: amdefine ">=0.0.4" +source-map@0.1.x: + version "0.1.43" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346" + dependencies: + amdefine ">=0.0.4" + spawn-command@^0.0.2-1: version "0.0.2" resolved "https://registry.yarnpkg.com/spawn-command/-/spawn-command-0.0.2.tgz#9544e1a43ca045f8531aac1a48cb29bdae62338e" @@ -5900,6 +5992,16 @@ strict-uri-encode@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" +string_decoder@^0.10.25, string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + +string_decoder@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.1.tgz#62e200f039955a6810d8df0a33ffc0f013662d98" + dependencies: + safe-buffer "^5.0.1" + string-width@^1.0.1, string-width@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" @@ -5915,15 +6017,9 @@ string-width@^2.0.0: is-fullwidth-code-point "^2.0.0" strip-ansi "^3.0.0" -string_decoder@^0.10.25, string_decoder@~0.10.x: - version "0.10.31" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" - -string_decoder@~1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.1.tgz#62e200f039955a6810d8df0a33ffc0f013662d98" - dependencies: - safe-buffer "^5.0.1" +string@^3.0.1: + version "3.3.3" + resolved "https://registry.yarnpkg.com/string/-/string-3.3.3.tgz#5ea211cd92d228e184294990a6cc97b366a77cb0" stringifier@^1.3.0: version "1.3.0" @@ -5977,6 +6073,10 @@ strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" +striptags@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/striptags/-/striptags-2.2.1.tgz#4c450b708d41b8bf39cf24c49ff234fc6aabfd32" + style-loader@^0.12.4: version "0.12.4" resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.12.4.tgz#ae7d0665dc4dc653daa2fe97bb90914bc1d22d9b" @@ -5991,17 +6091,6 @@ stylus-loader@^2.3.1: lodash.clonedeep "^4.5.0" when "~3.6.x" -stylus@0.54.5: - version "0.54.5" - resolved "https://registry.yarnpkg.com/stylus/-/stylus-0.54.5.tgz#42b9560931ca7090ce8515a798ba9e6aa3d6dc79" - dependencies: - css-parse "1.7.x" - debug "*" - glob "7.0.x" - mkdirp "0.5.x" - sax "0.5.x" - source-map "0.1.x" - stylus@^0.52.4: version "0.52.4" resolved "https://registry.yarnpkg.com/stylus/-/stylus-0.52.4.tgz#6551b5f0bfdcf29ee7f0fe0a59b7eb6ff26d2539" @@ -6013,6 +6102,17 @@ stylus@^0.52.4: sax "0.5.x" source-map "0.1.x" +stylus@0.54.5: + version "0.54.5" + resolved "https://registry.yarnpkg.com/stylus/-/stylus-0.54.5.tgz#42b9560931ca7090ce8515a798ba9e6aa3d6dc79" + dependencies: + css-parse "1.7.x" + debug "*" + glob "7.0.x" + mkdirp "0.5.x" + sax "0.5.x" + source-map "0.1.x" + sumchecker@^1.2.0: version "1.3.1" resolved "https://registry.yarnpkg.com/sumchecker/-/sumchecker-1.3.1.tgz#79bb3b4456dd04f18ebdbc0d703a1d1daec5105d" @@ -6137,6 +6237,10 @@ throttleit@0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-0.0.2.tgz#cfedf88e60c00dd9697b61fdd2a8343a9b680eaf" +through@^2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + through2@^2.0.0: version "2.0.3" resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" @@ -6151,10 +6255,6 @@ through2@~0.2.3: readable-stream "~1.1.9" xtend "~2.1.1" -through@^2.3.6: - version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - time-require@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/time-require/-/time-require-0.1.2.tgz#f9e12cb370fc2605e11404582ba54ef5ca2b2d98" @@ -6196,7 +6296,7 @@ touch@0.0.3: dependencies: nopt "~1.0.10" -tough-cookie@>=0.12.0, tough-cookie@^2.3.2, tough-cookie@~2.3.0: +tough-cookie@^2.3.2, tough-cookie@>=0.12.0, tough-cookie@~2.3.0: version "2.3.2" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.2.tgz#f081f76e4c85720e6c37a5faced737150d84072a" dependencies: @@ -6206,14 +6306,14 @@ tr46@~0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" -"traverse@>=0.3.0 <0.4": - version "0.3.9" - resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.3.9.tgz#717b8f220cc0bb7b44e40514c22b2e8bbc70d8b9" - traverse@^0.6.6: version "0.6.6" resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.6.6.tgz#cbdf560fd7b9af632502fed40f918c157ea97137" +"traverse@>=0.3.0 <0.4": + version "0.3.9" + resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.3.9.tgz#717b8f220cc0bb7b44e40514c22b2e8bbc70d8b9" + tree-kill@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.1.0.tgz#c963dcf03722892ec59cba569e940b71954d1729" @@ -6273,7 +6373,7 @@ ua-parser-js@^0.7.9: version "0.7.12" resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.12.tgz#04c81a99bdd5dc52263ea29d24c6bf8d4818a4bb" -uc.micro@^1.0.1: +uc.micro@^1.0.0, uc.micro@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.3.tgz#7ed50d5e0f9a9fb0a573379259f2a77458d50192" @@ -6381,13 +6481,6 @@ url-parse-lax@^1.0.0: dependencies: prepend-http "^1.0.1" -url-parse@1.0.x: - version "1.0.5" - resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.0.5.tgz#0854860422afdcfefeb6c965c662d4800169927b" - dependencies: - querystringify "0.0.x" - requires-port "1.0.x" - url-parse@^1.1.8: version "1.1.9" resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.1.9.tgz#c67f1d775d51f0a18911dd7b3ffad27bb9e5bd19" @@ -6395,12 +6488,12 @@ url-parse@^1.1.8: querystringify "~1.0.0" requires-port "1.0.x" -url@0.10.3: - version "0.10.3" - resolved "https://registry.yarnpkg.com/url/-/url-0.10.3.tgz#021e4d9c7705f21bbf37d03ceb58767402774c64" +url-parse@1.0.x: + version "1.0.5" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.0.5.tgz#0854860422afdcfefeb6c965c662d4800169927b" dependencies: - punycode "1.3.2" - querystring "0.2.0" + querystringify "0.0.x" + requires-port "1.0.x" url@^0.11.0: version "0.11.0" @@ -6409,17 +6502,24 @@ url@^0.11.0: punycode "1.3.2" querystring "0.2.0" +url@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/url/-/url-0.10.3.tgz#021e4d9c7705f21bbf37d03ceb58767402774c64" + dependencies: + punycode "1.3.2" + querystring "0.2.0" + user-home@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/user-home/-/user-home-2.0.0.tgz#9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f" dependencies: os-homedir "^1.0.0" -util-deprecate@1.0.2, util-deprecate@~1.0.1: +util-deprecate@~1.0.1, util-deprecate@1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" -util@0.10.3, util@^0.10.3: +util@^0.10.3, util@0.10.3: version "0.10.3" resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" dependencies: @@ -6429,14 +6529,14 @@ utils-merge@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.0.tgz#0294fb922bb9375153541c4f7096231f287c8af8" -uuid@3.0.1, uuid@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.1.tgz#6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1" - uuid@^2.0.1, uuid@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.3.tgz#67e2e863797215530dff318e5bf9dcebfd47b21a" +uuid@^3.0.0, uuid@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.1.tgz#6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1" + validate-npm-package-license@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc" @@ -6603,22 +6703,18 @@ widest-line@^1.0.0: dependencies: string-width "^1.0.1" -window-size@0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" - window-size@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.4.tgz#f8e1aa1ee5a53ec5bf151ffa09742a6ad7697876" +window-size@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" + word-wrap@^1.1.0: version "1.2.2" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.2.tgz#8fa78c3bda3e3138c7797fabceae709968814b41" -wordwrap@0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" - wordwrap@~0.0.2: version "0.0.3" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" @@ -6627,6 +6723,10 @@ wordwrap@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" +wordwrap@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" + wrap-ansi@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" @@ -6687,18 +6787,18 @@ xml2js@0.4.17: sax ">=0.6.0" xmlbuilder "^4.1.0" +xmlbuilder@^4.1.0, xmlbuilder@4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-4.2.1.tgz#aa58a3041a066f90eaa16c2f5389ff19f3f461a5" + dependencies: + lodash "^4.0.0" + xmlbuilder@4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-4.0.0.tgz#98b8f651ca30aa624036f127d11cc66dc7b907a3" dependencies: lodash "^3.5.0" -xmlbuilder@4.2.1, xmlbuilder@^4.1.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-4.2.1.tgz#aa58a3041a066f90eaa16c2f5389ff19f3f461a5" - dependencies: - lodash "^4.0.0" - xmldom@0.1.x: version "0.1.27" resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.1.27.tgz#d501f97b3bdb403af8ef9ecc20573187aadac0e9" @@ -6747,3 +6847,4 @@ yauzl@2.4.1: resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.4.1.tgz#9528f442dab1b2284e58b4379bb194e22e0c4005" dependencies: fd-slicer "~1.0.1" +