aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChi Kei Chan <chikeichan@gmail.com>2017-09-20 12:18:36 +0800
committerChi Kei Chan <chikeichan@gmail.com>2017-09-20 12:18:36 +0800
commit0204aa2001af25da01ba61aed32f36eac47079a1 (patch)
tree617053e69807f42bda05156855fca7e7236b7dc9
parente7f1fc44361829f05a713218f8b1837a8574c2f2 (diff)
downloadtangerine-wallet-browser-0204aa2001af25da01ba61aed32f36eac47079a1.tar.gz
tangerine-wallet-browser-0204aa2001af25da01ba61aed32f36eac47079a1.tar.zst
tangerine-wallet-browser-0204aa2001af25da01ba61aed32f36eac47079a1.zip
Add Add Token UI; Add Fuzzy search for tokens
-rw-r--r--package.json5
-rw-r--r--ui/app/add-token.js348
-rw-r--r--ui/app/css/itcss/components/add-token.scss173
-rw-r--r--ui/app/css/itcss/components/index.scss2
-rw-r--r--yarn.lock70
5 files changed, 458 insertions, 140 deletions
diff --git a/package.json b/package.json
index b615cab20..c6bd437f1 100644
--- a/package.json
+++ b/package.json
@@ -74,7 +74,7 @@
"end-of-stream": "^1.1.0",
"ensnare": "^1.0.0",
"eth-bin-to-ops": "^1.0.1",
- "eth-contract-metadata": "^1.1.4",
+ "eth-contract-metadata": "^1.1.5",
"eth-hd-keyring": "^1.1.1",
"eth-json-rpc-filters": "^1.1.0",
"eth-phishing-detect": "^1.1.4",
@@ -93,6 +93,7 @@
"extensionizer": "^1.0.0",
"fast-json-patch": "^2.0.4",
"fast-levenshtein": "^2.0.6",
+ "fuse.js": "^3.1.0",
"gulp": "github:gulpjs/gulp#4.0",
"gulp-autoprefixer": "^4.0.0",
"gulp-eslint": "^4.0.0",
@@ -212,8 +213,8 @@
"react-addons-test-utils": "^15.5.1",
"react-test-renderer": "^15.5.4",
"react-testutils-additions": "^15.2.0",
- "stylelint-config-standard": "^17.0.0",
"sinon": "^3.2.0",
+ "stylelint-config-standard": "^17.0.0",
"tape": "^4.5.1",
"testem": "^1.10.3",
"uglifyify": "^4.0.2",
diff --git a/ui/app/add-token.js b/ui/app/add-token.js
index 4374ee586..dbba8e4f1 100644
--- a/ui/app/add-token.js
+++ b/ui/app/add-token.js
@@ -2,8 +2,20 @@ const inherits = require('util').inherits
const Component = require('react').Component
const h = require('react-hyperscript')
const connect = require('react-redux').connect
-const actions = require('./actions')
-const Tooltip = require('./components/tooltip.js')
+const Fuse = require('fuse.js')
+const contractMap = require('eth-contract-metadata')
+const contractList = Object.entries(contractMap).map(([ _, tokenData]) => tokenData)
+const fuse = new Fuse(contractList, {
+ shouldSort: true,
+ threshold: 0.3,
+ location: 0,
+ distance: 100,
+ maxPatternLength: 32,
+ minMatchCharLength: 1,
+ keys: ['address', 'name', 'symbol'],
+})
+// const actions = require('./actions')
+// const Tooltip = require('./components/tooltip.js')
const ethUtil = require('ethereumjs-util')
@@ -24,146 +36,232 @@ function mapStateToProps (state) {
inherits(AddTokenScreen, Component)
function AddTokenScreen () {
this.state = {
- warning: null,
- address: null,
- symbol: 'TOKEN',
- decimals: 18,
+ // warning: null,
+ // address: null,
+ // symbol: 'TOKEN',
+ // decimals: 18,
+ searchQuery: '',
+ isCollapsed: true,
}
Component.call(this)
}
-AddTokenScreen.prototype.render = function () {
- const state = this.state
- const props = this.props
- const { warning, symbol, decimals } = state
-
- return (
- h('.flex-column.flex-grow', [
-
- // subtitle and nav
- h('.section-title.flex-row.flex-center', [
- h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', {
- onClick: (event) => {
- props.dispatch(actions.goHome())
- },
- }),
- h('h2.page-subtitle', 'Add Token'),
+AddTokenScreen.prototype.renderCustomForm = function () {
+ return !this.state.isCollapsed && (
+ h('div.add-token__add-custom-form', [
+ h('div.add-token__add-custom-field', [
+ h('div.add-token__add-custom-label', 'Token Address'),
+ h('input.add-token__add-custom-input', { type: 'text' }),
]),
+ h('div.add-token__add-custom-field', [
+ h('div.add-token__add-custom-label', 'Token Symbol'),
+ h('input.add-token__add-custom-input', { type: 'text', disabled: true }),
+ ]),
+ h('div.add-token__add-custom-field', [
+ h('div.add-token__add-custom-label', 'Decimals of Precision'),
+ h('input.add-token__add-custom-input', { type: 'text', disabled: true }),
+ ]),
+ ])
+ )
+}
- h('.error', {
- style: {
- display: warning ? 'block' : 'none',
- padding: '0 20px',
- textAlign: 'center',
- },
- }, warning),
-
- // conf view
- h('.flex-column.flex-justify-center.flex-grow.select-none', [
- h('.flex-space-around', {
- style: {
- padding: '20px',
- },
- }, [
-
- h('div', [
- h(Tooltip, {
- position: 'top',
- title: 'The contract of the actual token contract. Click for more info.',
- }, [
- h('a', {
- style: { fontWeight: 'bold', paddingRight: '10px'},
- href: 'https://consensyssupport.happyfox.com/staff/kb/article/24-what-is-a-token-contract-address',
- target: '_blank',
- }, [
- h('span', 'Token Contract Address '),
- h('i.fa.fa-question-circle'),
- ]),
- ]),
- ]),
-
- h('section.flex-row.flex-center', [
- h('input#token-address', {
- name: 'address',
- placeholder: 'Token Contract Address',
- onChange: this.tokenAddressDidChange.bind(this),
- style: {
- width: 'inherit',
- flex: '1 0 auto',
- height: '30px',
- margin: '8px',
- },
- }),
- ]),
-
- h('div', [
- h('span', {
- style: { fontWeight: 'bold', paddingRight: '10px'},
- }, 'Token Symbol'),
- ]),
-
- h('div', { style: {display: 'flex'} }, [
- h('input#token_symbol', {
- placeholder: `Like "ETH"`,
- value: symbol,
- style: {
- width: 'inherit',
- flex: '1 0 auto',
- height: '30px',
- margin: '8px',
- },
- onChange: (event) => {
- var element = event.target
- var symbol = element.value
- this.setState({ symbol })
- },
- }),
+AddTokenScreen.prototype.renderTokenList = function () {
+ const { searchQuery = '' } = this.state
+ const results = searchQuery
+ ? fuse.search(searchQuery) || []
+ : contractList
+
+ return Array(6).fill(undefined)
+ .map((_, i) => {
+ const { logo, symbol, name } = results[i] || {}
+ console.log({ i, logo, symbol, name })
+ return Boolean(logo || symbol || name) && (
+ h('div.add-token__token-wrapper', [
+ h('div.add-token__token-icon', {
+ style: {
+ backgroundImage: `url(images/contract/${logo})`,
+ },
+ }),
+ h('div.add-token__token-data', [
+ h('div.add-token__token-symbol', symbol),
+ h('div.add-token__token-name', name),
]),
+ ])
+ )
+ })
+}
- h('div', [
- h('span', {
- style: { fontWeight: 'bold', paddingRight: '10px'},
- }, 'Decimals of Precision'),
- ]),
+AddTokenScreen.prototype.render = function () {
+ const { isCollapsed } = this.state
- h('div', { style: {display: 'flex'} }, [
- h('input#token_decimals', {
- value: decimals,
- type: 'number',
- min: 0,
- max: 36,
- style: {
- width: 'inherit',
- flex: '1 0 auto',
- height: '30px',
- margin: '8px',
- },
- onChange: (event) => {
- var element = event.target
- var decimals = element.value.trim()
- this.setState({ decimals })
- },
+ return (
+ h('div.add-token', [
+ h('div.add-token__wrapper', [
+ h('div.add-token__title-container', [
+ h('div.add-token__title', 'Add Token'),
+ h('div.add-token__description', 'Keep track of the tokens you’ve bought with your MetaMask account. If you bought tokens using a different account, those tokens will not appear here.'),
+ h('div.add-token__description', 'Search for tokens or select from our list of popular tokens.'),
+ ]),
+ h('div.add-token__content-container', [
+ h('div.add-token__input-container', [
+ h('input.add-token__input', {
+ type: 'text',
+ placeholder: 'Search',
+ onChange: e => this.setState({ searchQuery: e.target.value }),
}),
]),
-
- h('button', {
- style: {
- alignSelf: 'center',
- },
- onClick: (event) => {
- const valid = this.validateInputs()
- if (!valid) return
-
- const { address, symbol, decimals } = this.state
- this.props.dispatch(actions.addToken(address.trim(), symbol.trim(), decimals))
- },
- }, 'Add'),
+ h(
+ 'div.add-token__token-icons-container',
+ this.renderTokenList(),
+ ),
+ ]),
+ h('div.add-token__footers', [
+ h('div.add-token__add-custom', {
+ onClick: () => this.setState({ isCollapsed: !isCollapsed }),
+ }, 'Add custom token'),
+ this.renderCustomForm(),
]),
]),
+ h('div.add-token__buttons', [
+ h('button.btn-secondary', 'Next'),
+ h('button.btn-tertiary', 'Cancel'),
+ ]),
])
)
}
+// AddTokenScreen.prototype.render = function () {
+// const state = this.state
+// const props = this.props
+// const { warning, symbol, decimals } = state
+
+// return (
+// h('.flex-column.flex-grow', [
+
+// // subtitle and nav
+// h('.section-title.flex-row.flex-center', [
+// h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', {
+// onClick: (event) => {
+// props.dispatch(actions.goHome())
+// },
+// }),
+// h('h2.page-subtitle', 'Add Token'),
+// ]),
+
+// h('.error', {
+// style: {
+// display: warning ? 'block' : 'none',
+// padding: '0 20px',
+// textAlign: 'center',
+// },
+// }, warning),
+
+// // conf view
+// h('.flex-column.flex-justify-center.flex-grow.select-none', [
+// h('.flex-space-around', {
+// style: {
+// padding: '20px',
+// },
+// }, [
+
+// h('div', [
+// h(Tooltip, {
+// position: 'top',
+// title: 'The contract of the actual token contract. Click for more info.',
+// }, [
+// h('a', {
+// style: { fontWeight: 'bold', paddingRight: '10px'},
+// href: 'https://consensyssupport.happyfox.com/staff/kb/article/24-what-is-a-token-contract-address',
+// target: '_blank',
+// }, [
+// h('span', 'Token Contract Address '),
+// h('i.fa.fa-question-circle'),
+// ]),
+// ]),
+// ]),
+
+// h('section.flex-row.flex-center', [
+// h('input#token-address', {
+// name: 'address',
+// placeholder: 'Token Contract Address',
+// onChange: this.tokenAddressDidChange.bind(this),
+// style: {
+// width: 'inherit',
+// flex: '1 0 auto',
+// height: '30px',
+// margin: '8px',
+// },
+// }),
+// ]),
+
+// h('div', [
+// h('span', {
+// style: { fontWeight: 'bold', paddingRight: '10px'},
+// }, 'Token Symbol'),
+// ]),
+
+// h('div', { style: {display: 'flex'} }, [
+// h('input#token_symbol', {
+// placeholder: `Like "ETH"`,
+// value: symbol,
+// style: {
+// width: 'inherit',
+// flex: '1 0 auto',
+// height: '30px',
+// margin: '8px',
+// },
+// onChange: (event) => {
+// var element = event.target
+// var symbol = element.value
+// this.setState({ symbol })
+// },
+// }),
+// ]),
+
+// h('div', [
+// h('span', {
+// style: { fontWeight: 'bold', paddingRight: '10px'},
+// }, 'Decimals of Precision'),
+// ]),
+
+// h('div', { style: {display: 'flex'} }, [
+// h('input#token_decimals', {
+// value: decimals,
+// type: 'number',
+// min: 0,
+// max: 36,
+// style: {
+// width: 'inherit',
+// flex: '1 0 auto',
+// height: '30px',
+// margin: '8px',
+// },
+// onChange: (event) => {
+// var element = event.target
+// var decimals = element.value.trim()
+// this.setState({ decimals })
+// },
+// }),
+// ]),
+
+// h('button', {
+// style: {
+// alignSelf: 'center',
+// },
+// onClick: (event) => {
+// const valid = this.validateInputs()
+// if (!valid) return
+
+// const { address, symbol, decimals } = this.state
+// this.props.dispatch(actions.addToken(address.trim(), symbol.trim(), decimals))
+// },
+// }, 'Add'),
+// ]),
+// ]),
+// ])
+// )
+// }
+
AddTokenScreen.prototype.componentWillMount = function () {
if (typeof global.ethereumProvider === 'undefined') return
diff --git a/ui/app/css/itcss/components/add-token.scss b/ui/app/css/itcss/components/add-token.scss
new file mode 100644
index 000000000..db1d0dc18
--- /dev/null
+++ b/ui/app/css/itcss/components/add-token.scss
@@ -0,0 +1,173 @@
+.add-token {
+ width: 498px;
+ display: flex;
+ flex-flow: column nowrap;
+ align-items: center;
+ position: relative;
+ top: -36px;
+ z-index: 12;
+ font-family: 'DIN Next Light';
+
+ @media screen and (max-width: $break-small) {
+ top: 0;
+ width: 100%;
+
+ &__wrapper {
+ box-shadow: none !important;
+ }
+
+ &__footers {
+ border-bottom: 1px solid $gallery;
+ }
+ }
+
+ &__wrapper {
+ background-color: $white;
+ box-shadow: 0 2px 4px 0 rgba($black, .08);
+ display: flex;
+ flex-flow: column nowrap;
+ align-items: center;
+ flex: 0 0 auto;
+ }
+
+ &__title-container {
+ display: flex;
+ flex-flow: column nowrap;
+ align-items: center;
+ padding: 30px 60px 12px;
+ border-bottom: 1px solid $gallery;
+ flex: 0 0 auto;
+ }
+
+ &__title {
+ color: $scorpion;
+ font-size: 20px;
+ line-height: 26px;
+ text-align: center;
+ font-weight: 600;
+ margin-bottom: 12px;
+ }
+
+ &__description {
+ text-align: center;
+ }
+
+ &__description + &__description {
+ margin-top: 24px;
+ }
+
+ &__content-container {
+ width: 100%;
+ border-bottom: 1px solid $gallery;
+ }
+
+ &__input-container {
+ padding: 11px 0;
+ width: 263px;
+ margin: 0 auto;
+ }
+
+ &__input {
+ width: 100%;
+ border: 2px solid $gallery;
+ border-radius: 4px;
+ padding: 5px 15px;
+ font-size: 14px;
+ line-height: 19px;
+
+ &::placeholder {
+ color: $silver;
+ }
+ }
+
+ &__footers {
+ width: 100%;
+ }
+
+ &__add-custom {
+ color: $scorpion;
+ font-size: 18px;
+ line-height: 24px;
+ text-align: center;
+ padding: 11px 0 19px;
+ font-weight: 600;
+ cursor: pointer;
+ }
+
+ &__add-custom-form {
+ display: flex;
+ flex-flow: column nowrap;
+ margin: 8px 0 51px;
+ }
+
+ &__add-custom-field {
+ width: 290px;
+ margin: 0 auto;
+ }
+
+ &__add-custom-label {
+ font-size: 16px;
+ line-height: 21px;
+ margin-bottom: 8px;
+ }
+
+ &__add-custom-input {
+ width: 100%;
+ border: 1px solid $silver;
+ padding: 5px 15px;
+ font-size: 14px;
+ line-height: 19px;
+
+ &::placeholder {
+ color: $silver;
+ }
+ }
+
+ &__add-custom-field + &__add-custom-field {
+ margin-top: 21px;
+ }
+
+ &__buttons {
+ display: flex;
+ flex-flow: column nowrap;
+ margin: 30px 0 51px;
+ flex: 0 0 auto;
+ }
+
+ &__token-icons-container {
+ display: flex;
+ flex-flow: row wrap;
+ }
+
+ &__token-wrapper {
+ display: flex;
+ flex-flow: row nowrap;
+ flex: 0 0 50%;
+ align-items: center;
+ padding: 24px 0 24px 24px;
+ }
+
+ &__token-name {
+ font-size: 14px;
+ line-height: 19px;
+ }
+
+ &__token-symbol {
+ font-size: 22px;
+ line-height: 29px;
+ font-weight: 600;
+ }
+
+ &__token-icon {
+ width: 60px;
+ height: 60px;
+ background-repeat: no-repeat;
+ background-size: contain;
+ background-position: center;
+ border-radius: 50%;
+ background-color: $white;
+ box-shadow: 0 2px 4px 0 rgba($black, .24);
+ margin-right: 12px;
+ flex: 0 0 auto;
+ }
+}
diff --git a/ui/app/css/itcss/components/index.scss b/ui/app/css/itcss/components/index.scss
index 63ac8bd47..9b3690099 100644
--- a/ui/app/css/itcss/components/index.scss
+++ b/ui/app/css/itcss/components/index.scss
@@ -27,3 +27,5 @@
@import './sections.scss';
@import './token-list.scss';
+
+@import './add-token.scss';
diff --git a/yarn.lock b/yarn.lock
index aed3a9da8..078ab75cf 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1950,6 +1950,12 @@ cli-width@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639"
+cli@0.4.3:
+ version "0.4.3"
+ resolved "https://registry.yarnpkg.com/cli/-/cli-0.4.3.tgz#e6819c8d5faa957f64f98f66a8506268c1d1f17d"
+ dependencies:
+ glob ">= 3.1.4"
+
client-sw-ready-event@^3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/client-sw-ready-event/-/client-sw-ready-event-3.3.0.tgz#988d1045562b0c228e33d9247a6dd3ed7b276fe3"
@@ -2063,7 +2069,7 @@ colors@1.0.3, colors@1.0.x:
version "1.0.3"
resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b"
-colors@^1.1.0, colors@^1.1.2:
+colors@>=0.6.x, colors@^1.1.0, colors@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63"
@@ -3370,7 +3376,7 @@ eth-block-tracker@^2.0.1, eth-block-tracker@^2.1.2:
pify "^2.3.0"
tape "^4.6.3"
-eth-contract-metadata@^1.1.4:
+eth-contract-metadata@^1.1.5:
version "1.1.5"
resolved "https://registry.yarnpkg.com/eth-contract-metadata/-/eth-contract-metadata-1.1.5.tgz#301f51b0460b8dd044997dc05870751fb7f4cfcb"
@@ -4211,6 +4217,20 @@ functional-red-black-tree@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
+fuse.js@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/fuse.js/-/fuse.js-3.1.0.tgz#9062146c471552189b0f678b4f5a155731ae3b3c"
+
+fuse@^0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/fuse/-/fuse-0.4.0.tgz#2c38eaf888abb0a9ba7960cfe3339d1f3f53f6e6"
+ dependencies:
+ colors ">=0.6.x"
+ jshint "0.9.x"
+ optimist ">=0.3.5"
+ uglify-js ">=2.2.x"
+ underscore ">=1.4.x"
+
gather-stream@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/gather-stream/-/gather-stream-1.0.0.tgz#b33994af457a8115700d410f317733cbe7a0904b"
@@ -4346,24 +4366,24 @@ glob@7.1.1:
once "^1.3.0"
path-is-absolute "^1.0.0"
-glob@^5.0.15, glob@^5.0.3, glob@~5.0.0:
- version "5.0.15"
- resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1"
+"glob@>= 3.1.4", glob@^7.0.0, glob@^7.0.3, glob@^7.0.4, glob@^7.0.5, glob@^7.0.6, glob@^7.1.0, glob@^7.1.1, glob@^7.1.2, glob@~7.1.1, glob@~7.1.2:
+ version "7.1.2"
+ resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
dependencies:
+ fs.realpath "^1.0.0"
inflight "^1.0.4"
inherits "2"
- minimatch "2 || 3"
+ minimatch "^3.0.4"
once "^1.3.0"
path-is-absolute "^1.0.0"
-glob@^7.0.0, glob@^7.0.3, glob@^7.0.4, glob@^7.0.5, glob@^7.0.6, glob@^7.1.0, glob@^7.1.1, glob@^7.1.2, glob@~7.1.1, glob@~7.1.2:
- version "7.1.2"
- resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
+glob@^5.0.15, glob@^5.0.3, glob@~5.0.0:
+ version "5.0.15"
+ resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1"
dependencies:
- fs.realpath "^1.0.0"
inflight "^1.0.4"
inherits "2"
- minimatch "^3.0.4"
+ minimatch "2 || 3"
once "^1.3.0"
path-is-absolute "^1.0.0"
@@ -5521,6 +5541,13 @@ jshint-stylish@~2.2.1:
string-length "^1.0.0"
text-table "^0.2.0"
+jshint@0.9.x:
+ version "0.9.1"
+ resolved "https://registry.yarnpkg.com/jshint/-/jshint-0.9.1.tgz#ff32ec7f09f84001f7498eeafd63c9e4fbb2dc0e"
+ dependencies:
+ cli "0.4.3"
+ minimatch "0.0.x"
+
jsmin@1.x:
version "1.0.1"
resolved "https://registry.yarnpkg.com/jsmin/-/jsmin-1.0.1.tgz#e7bd0dcd6496c3bf4863235bf461a3d98aa3b98c"
@@ -6236,6 +6263,10 @@ lru-cache@^4.0.1:
pseudomap "^1.0.2"
yallist "^2.1.2"
+lru-cache@~1.0.2:
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-1.0.6.tgz#aa50f97047422ac72543bda177a9c9d018d98452"
+
lru-queue@0.1:
version "0.1.0"
resolved "https://registry.yarnpkg.com/lru-queue/-/lru-queue-0.1.0.tgz#2738bd9f0d3cf4f84490c5736c48699ac632cda3"
@@ -6487,6 +6518,12 @@ minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a"
+minimatch@0.0.x:
+ version "0.0.5"
+ resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.0.5.tgz#96bb490bbd3ba6836bbfac111adf75301b1584de"
+ dependencies:
+ lru-cache "~1.0.2"
+
"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4, minimatch@~3.0.2:
version "3.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
@@ -7074,7 +7111,7 @@ opener@^1.3.0:
version "1.4.3"
resolved "https://registry.yarnpkg.com/opener/-/opener-1.4.3.tgz#5c6da2c5d7e5831e8ffa3964950f8d6674ac90b8"
-optimist@^0.6.1:
+optimist@>=0.3.5, optimist@^0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686"
dependencies:
@@ -9697,6 +9734,13 @@ uglify-js@1.x:
version "1.3.5"
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-1.3.5.tgz#4b5bfff9186effbaa888e4c9e94bd9fc4c94929d"
+uglify-js@>=2.2.x:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.1.1.tgz#e7144307281a1bc38a9a20715090b546c9f44791"
+ dependencies:
+ commander "~2.11.0"
+ source-map "~0.5.1"
+
uglify-js@^2.6, uglify-js@^2.8.27:
version "2.8.29"
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd"
@@ -9736,7 +9780,7 @@ unc-path-regex@^0.1.0:
version "0.1.2"
resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa"
-underscore@>=1.8.3, underscore@^1.6.0:
+underscore@>=1.4.x, underscore@>=1.8.3, underscore@^1.6.0:
version "1.8.3"
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.8.3.tgz#4f3fb53b106e6097fcf9cb4109f2a5e9bdfa5022"