Browse Source

Merge pull request #265 from meriadec/master

Update wallet-common & currencies. Simplify again InputCurrency.
master
Loëck Vézien 7 years ago
committed by GitHub
parent
commit
c0a3309d80
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 18
      .circleci/config.yml
  2. 4
      package.json
  3. 4
      src/actions/counterValues.js
  4. 1
      src/components/CounterValue/index.js
  5. 5
      src/components/RequestAmount/index.js
  6. 99
      src/components/base/InputCurrency/index.js
  7. 11
      src/components/base/InputCurrency/stories.js
  8. 84
      yarn.lock

18
.circleci/config.yml

@ -30,12 +30,12 @@ jobs:
- run: - run:
name: Test name: Test
command: yarn test command: yarn test
- run: # - run:
name: Build # name: Build
command: yarn dist:dir # command: yarn dist:dir
- run: # - run:
name: Generate build stats # name: Generate build stats
command: "du -h dist | sort -h > /tmp/build-stats.txt" # command: "du -h dist | sort -h > /tmp/build-stats.txt"
- store_artifacts: # - store_artifacts:
path: /tmp/build-stats.txt # path: /tmp/build-stats.txt
destination: build-stats.txt # destination: build-stats.txt

4
package.json

@ -44,12 +44,12 @@
"webpack-sources": "1.0.1" "webpack-sources": "1.0.1"
}, },
"dependencies": { "dependencies": {
"@ledgerhq/currencies": "^4.7.5", "@ledgerhq/currencies": "^4.10.1",
"@ledgerhq/hw-app-btc": "^4.7.3", "@ledgerhq/hw-app-btc": "^4.7.3",
"@ledgerhq/hw-app-eth": "^4.7.3", "@ledgerhq/hw-app-eth": "^4.7.3",
"@ledgerhq/hw-transport": "^4.7.3", "@ledgerhq/hw-transport": "^4.7.3",
"@ledgerhq/hw-transport-node-hid": "^4.7.6", "@ledgerhq/hw-transport-node-hid": "^4.7.6",
"@ledgerhq/wallet-common": "^0.10.1", "@ledgerhq/wallet-common": "^0.12.0",
"axios": "^0.18.0", "axios": "^0.18.0",
"bcryptjs": "^2.4.3", "bcryptjs": "^2.4.3",
"bitcoinjs-lib": "^3.3.2", "bitcoinjs-lib": "^3.3.2",

4
src/actions/counterValues.js

@ -1,7 +1,7 @@
// @flow // @flow
import { getFiatUnit } from '@ledgerhq/currencies' import { getFiatUnit } from '@ledgerhq/currencies'
import { fetchHistodayCounterValuesMultiple } from '@ledgerhq/wallet-common/lib/api/countervalue' import { fetchHistodayRates } from '@ledgerhq/wallet-common/lib/api/countervalue'
import type { Currency } from '@ledgerhq/currencies' import type { Currency } from '@ledgerhq/currencies'
import type { Dispatch } from 'redux' import type { Dispatch } from 'redux'
@ -32,6 +32,6 @@ export const fetchCounterValues: FetchCounterValues = (currencies: ?(Currency[])
const { counterValue } = settings const { counterValue } = settings
const fiatUnit = getFiatUnit(counterValue) const fiatUnit = getFiatUnit(counterValue)
const counterValues = await fetchHistodayCounterValuesMultiple(currencies, fiatUnit) const counterValues = await fetchHistodayRates(currencies, fiatUnit)
dispatch(updateCounterValues(counterValues)) dispatch(updateCounterValues(counterValues))
} }

1
src/components/CounterValue/index.js

@ -63,6 +63,7 @@ class CounterValue extends PureComponent<Props> {
function generateFakeCurrency(ticker) { function generateFakeCurrency(ticker) {
return { return {
ticker,
units: [ units: [
{ {
code: ticker, code: ticker,

5
src/components/RequestAmount/index.js

@ -6,7 +6,7 @@ import { translate } from 'react-i18next'
import styled from 'styled-components' import styled from 'styled-components'
import { connect } from 'react-redux' import { connect } from 'react-redux'
import type { Account, CalculateCounterValue } from '@ledgerhq/wallet-common/lib/types' import type { Account, CalculateCounterValue } from '@ledgerhq/wallet-common/lib/types'
import type { Unit } from '@ledgerhq/currencies' import type { FiatUnit } from '@ledgerhq/currencies'
import type { T } from 'types/common' import type { T } from 'types/common'
@ -59,7 +59,7 @@ type Props = {
// used to determine the right input unit // used to determine the right input unit
// retrieved via selector (take the chosen countervalue unit) // retrieved via selector (take the chosen countervalue unit)
rightUnit: Unit, rightUnit: FiatUnit,
// used to calculate the opposite field value (right & left) // used to calculate the opposite field value (right & left)
getCounterValue: CalculateCounterValue, getCounterValue: CalculateCounterValue,
@ -102,6 +102,7 @@ export class RequestAmount extends PureComponent<Props> {
value={right} value={right}
onChange={this.handleChangeAmount('right')} onChange={this.handleChangeAmount('right')}
renderRight={<InputRight>{rightUnit.code}</InputRight>} renderRight={<InputRight>{rightUnit.code}</InputRight>}
showAllDigits
/> />
</Box> </Box>
<Box grow justify="flex-end"> <Box grow justify="flex-end">

99
src/components/base/InputCurrency/index.js

@ -2,7 +2,7 @@
import React, { PureComponent } from 'react' import React, { PureComponent } from 'react'
import styled from 'styled-components' import styled from 'styled-components'
import { parseCurrencyUnit, formatCurrencyUnit } from '@ledgerhq/currencies' import { formatCurrencyUnit } from '@ledgerhq/currencies'
import noop from 'lodash/noop' import noop from 'lodash/noop'
import isNaN from 'lodash/isNaN' import isNaN from 'lodash/isNaN'
@ -17,24 +17,14 @@ function parseValue(value) {
return value.toString().replace(/,/g, '.') return value.toString().replace(/,/g, '.')
} }
function format(unit: Unit, value: number) { function format(unit: Unit, value: number, { isFocused, showAllDigits }) {
return formatCurrencyUnit(unit, value, { return formatCurrencyUnit(unit, value, {
useGrouping: !isFocused,
disableRounding: true, disableRounding: true,
showAllDigits: false, showAllDigits: !!showAllDigits && !isFocused,
}) })
} }
function unformat(unit, value) {
if (value === 0 || value === '') {
return '0'
}
let v = parseCurrencyUnit(unit, value.toString())
v /= 10 ** unit.magnitude
return v.toString()
}
const Currencies = styled(Box)` const Currencies = styled(Box)`
position: relative; position: relative;
top: -1px; top: -1px;
@ -54,11 +44,12 @@ type Props = {
unit: Unit, unit: Unit,
units: Array<Unit>, units: Array<Unit>,
value: number, value: number,
showAllDigits?: boolean,
} }
type State = { type State = {
unit: Unit, unit: Unit,
isFocus: boolean, isFocused: boolean,
displayValue: string, displayValue: string,
} }
@ -68,37 +59,52 @@ class InputCurrency extends PureComponent<Props, State> {
renderRight: null, renderRight: null,
units: [], units: [],
value: 0, value: 0,
showAllDigits: false,
} }
state = { state = {
isFocus: false, isFocused: false,
displayValue: '0', displayValue: '',
unit: this.props.unit, unit: this.props.unit,
} }
componentWillMount() { componentWillMount() {
const { value } = this.props this.syncInput({ isFocused: false })
const { unit } = this.state
const displayValue = format(unit, value)
this.setState({ displayValue })
} }
componentWillReceiveProps(nextProps: Props) { componentWillReceiveProps(nextProps: Props) {
const { value, showAllDigits } = this.props
const { unit } = this.state const { unit } = this.state
if (this.props.value !== nextProps.value) { const needsToBeReformatted =
const { isFocus } = this.state value !== nextProps.value || showAllDigits !== nextProps.showAllDigits
const displayValue = isFocus if (needsToBeReformatted) {
? (nextProps.value / 10 ** unit.magnitude).toString() const { isFocused } = this.state
: format(unit, nextProps.value) this.setState({
this.setState({ displayValue }) displayValue:
nextProps.value === 0
? ''
: format(unit, nextProps.value, {
isFocused,
showAllDigits: nextProps.showAllDigits,
}),
})
} }
} }
handleChange = (v: string) => { handleChange = (v: string) => {
// const { displayValue } = this.state
v = parseValue(v) v = parseValue(v)
if (v.startsWith('00')) { // allow to type directly `.` in input to have `0.`
if (v.startsWith('.')) {
v = `0${v}`
}
// forbid multiple 0 at start
if (v === '' || v.startsWith('00')) {
const { onChange } = this.props
const { unit } = this.state
onChange(0, unit)
this.setState({ displayValue: '' })
return return
} }
@ -108,23 +114,19 @@ class InputCurrency extends PureComponent<Props, State> {
} }
this.emitOnChange(v) this.emitOnChange(v)
this.setState({ displayValue: v || '0' }) this.setState({ displayValue: v || '' })
} }
handleBlur = () => { handleBlur = () => this.syncInput({ isFocused: false })
const { value } = this.props handleFocus = () => this.syncInput({ isFocused: true })
const { unit } = this.state
const v = format(unit, value)
this.setState({ isFocus: false, displayValue: v })
}
handleFocus = () => { syncInput = ({ isFocused }: { isFocused: boolean }) => {
const { value, showAllDigits } = this.props
const { unit } = this.state const { unit } = this.state
this.setState({
this.setState(prev => ({ isFocused,
isFocus: true, displayValue: value === 0 ? '' : format(unit, value, { isFocused, showAllDigits }),
displayValue: unformat(unit, prev.displayValue), })
}))
} }
emitOnChange = (v: string) => { emitOnChange = (v: string) => {
@ -138,7 +140,7 @@ class InputCurrency extends PureComponent<Props, State> {
} }
renderListUnits = () => { renderListUnits = () => {
const { units, value } = this.props const { units, value, showAllDigits } = this.props
const { unit } = this.state const { unit } = this.state
if (units.length <= 1) { if (units.length <= 1) {
@ -152,8 +154,10 @@ class InputCurrency extends PureComponent<Props, State> {
keyProp="code" keyProp="code"
flatLeft flatLeft
onChange={item => { onChange={item => {
this.setState({ unit: item, displayValue: format(item, value) }) this.setState({
// onChange(unformat(item, value), item) unit: item,
displayValue: format(item, value, { isFocused: false, showAllDigits }),
})
}} }}
items={units} items={units}
value={unit} value={unit}
@ -165,8 +169,8 @@ class InputCurrency extends PureComponent<Props, State> {
} }
render() { render() {
const { renderRight } = this.props const { renderRight, showAllDigits } = this.props
const { displayValue } = this.state const { displayValue, unit } = this.state
return ( return (
<Input <Input
@ -177,6 +181,7 @@ class InputCurrency extends PureComponent<Props, State> {
onFocus={this.handleFocus} onFocus={this.handleFocus}
onBlur={this.handleBlur} onBlur={this.handleBlur}
renderRight={renderRight || this.renderListUnits()} renderRight={renderRight || this.renderListUnits()}
placeholder={format(unit, 0, { isFocused: false, showAllDigits })}
/> />
) )
} }

11
src/components/base/InputCurrency/stories.js

@ -3,6 +3,7 @@
import React, { Component } from 'react' import React, { Component } from 'react'
import { storiesOf } from '@storybook/react' import { storiesOf } from '@storybook/react'
import { action } from '@storybook/addon-actions' import { action } from '@storybook/addon-actions'
import { boolean } from '@storybook/addon-knobs'
import { getCurrencyByCoinType } from '@ledgerhq/currencies' import { getCurrencyByCoinType } from '@ledgerhq/currencies'
@ -14,7 +15,7 @@ const { units } = getCurrencyByCoinType(1)
class Wrapper extends Component<any, any> { class Wrapper extends Component<any, any> {
state = { state = {
value: 1e8, value: 0,
unit: units[0], unit: units[0],
} }
@ -38,7 +39,13 @@ class Wrapper extends Component<any, any> {
stories.add('InputCurrency', () => ( stories.add('InputCurrency', () => (
<Wrapper <Wrapper
render={({ value, unit, onChange }) => ( render={({ value, unit, onChange }) => (
<InputCurrency value={value} unit={unit} units={units} onChange={onChange} /> <InputCurrency
value={value}
unit={unit}
units={units}
onChange={onChange}
showAllDigits={boolean('showAllDigits', false)}
/>
)} )}
/> />
)) ))

84
yarn.lock

@ -913,17 +913,9 @@
lodash "^4.2.0" lodash "^4.2.0"
to-fast-properties "^2.0.0" to-fast-properties "^2.0.0"
"@ledgerhq/currencies@^4.7.1": "@ledgerhq/currencies@^4.10.1":
version "4.7.3" version "4.10.1"
resolved "https://registry.yarnpkg.com/@ledgerhq/currencies/-/currencies-4.7.3.tgz#0e28c0f1c74cf00b990be6865fbec374f808b71f" resolved "https://registry.yarnpkg.com/@ledgerhq/currencies/-/currencies-4.10.1.tgz#462081005e3e37e0737bad9aba189eef1663e96a"
dependencies:
lodash "^4.17.5"
numeral "^2.0.6"
querystring "^0.2.0"
"@ledgerhq/currencies@^4.7.5":
version "4.7.5"
resolved "https://registry.yarnpkg.com/@ledgerhq/currencies/-/currencies-4.7.5.tgz#e852b58359254fbb2087de328df84343b586f4ab"
dependencies: dependencies:
lodash "^4.17.5" lodash "^4.17.5"
numeral "^2.0.6" numeral "^2.0.6"
@ -955,13 +947,13 @@
dependencies: dependencies:
events "^2.0.0" events "^2.0.0"
"@ledgerhq/wallet-common@^0.10.1": "@ledgerhq/wallet-common@^0.12.0":
version "0.10.1" version "0.12.0"
resolved "https://registry.yarnpkg.com/@ledgerhq/wallet-common/-/wallet-common-0.10.1.tgz#72e17329de02bebb5ed54bf797113266824e4af8" resolved "https://registry.yarnpkg.com/@ledgerhq/wallet-common/-/wallet-common-0.12.0.tgz#50ac697929062772182735e4013266c41a661fe2"
dependencies: dependencies:
"@ledgerhq/currencies" "^4.7.1" "@ledgerhq/currencies" "^4.10.1"
axios "^0.18.0" axios "^0.18.0"
babel-jest "^23.0.0-alpha.0" babel-jest "^22.4.3"
invariant "^2.2.2" invariant "^2.2.2"
lodash "^4.17.4" lodash "^4.17.4"
prando "^3.0.1" prando "^3.0.1"
@ -1927,13 +1919,6 @@ babel-jest@^22.4.3:
babel-plugin-istanbul "^4.1.5" babel-plugin-istanbul "^4.1.5"
babel-preset-jest "^22.4.3" babel-preset-jest "^22.4.3"
babel-jest@^23.0.0-alpha.0:
version "23.0.0-alpha.4"
resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-23.0.0-alpha.4.tgz#e3bb1e486f4178b381cc7b37e6cafb1af3a9d1bf"
dependencies:
babel-plugin-istanbul "^4.1.6"
babel-preset-jest "^23.0.0-alpha.4"
babel-loader@^7.1.4: babel-loader@^7.1.4:
version "7.1.4" version "7.1.4"
resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-7.1.4.tgz#e3463938bd4e6d55d1c174c5485d406a188ed015" resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-7.1.4.tgz#e3463938bd4e6d55d1c174c5485d406a188ed015"
@ -1976,23 +1961,10 @@ babel-plugin-istanbul@^4.1.5:
istanbul-lib-instrument "^1.7.5" istanbul-lib-instrument "^1.7.5"
test-exclude "^4.1.1" test-exclude "^4.1.1"
babel-plugin-istanbul@^4.1.6:
version "4.1.6"
resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.6.tgz#36c59b2192efce81c5b378321b74175add1c9a45"
dependencies:
babel-plugin-syntax-object-rest-spread "^6.13.0"
find-up "^2.1.0"
istanbul-lib-instrument "^1.10.1"
test-exclude "^4.2.1"
babel-plugin-jest-hoist@^22.4.3: babel-plugin-jest-hoist@^22.4.3:
version "22.4.3" version "22.4.3"
resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-22.4.3.tgz#7d8bcccadc2667f96a0dcc6afe1891875ee6c14a" resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-22.4.3.tgz#7d8bcccadc2667f96a0dcc6afe1891875ee6c14a"
babel-plugin-jest-hoist@^23.0.0-alpha.4:
version "23.0.0-alpha.4"
resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-23.0.0-alpha.4.tgz#3f32715d54640e37cc62a84a9d3d7eada6a067fc"
babel-plugin-macros@^2.2.0: babel-plugin-macros@^2.2.0:
version "2.2.0" version "2.2.0"
resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-2.2.0.tgz#31fc16748d6480697a517f692dc4421cb7bff0cc" resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-2.2.0.tgz#31fc16748d6480697a517f692dc4421cb7bff0cc"
@ -2584,13 +2556,6 @@ babel-preset-jest@^22.4.3:
babel-plugin-jest-hoist "^22.4.3" babel-plugin-jest-hoist "^22.4.3"
babel-plugin-syntax-object-rest-spread "^6.13.0" babel-plugin-syntax-object-rest-spread "^6.13.0"
babel-preset-jest@^23.0.0-alpha.4:
version "23.0.0-alpha.4"
resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-23.0.0-alpha.4.tgz#d3080507330e6d23c47dcc366d69f7a330174f70"
dependencies:
babel-plugin-jest-hoist "^23.0.0-alpha.4"
babel-plugin-syntax-object-rest-spread "^6.13.0"
babel-preset-minify@^0.3.0: babel-preset-minify@^0.3.0:
version "0.3.0" version "0.3.0"
resolved "https://registry.yarnpkg.com/babel-preset-minify/-/babel-preset-minify-0.3.0.tgz#7db64afa75f16f6e06c0aa5f25195f6f36784d77" resolved "https://registry.yarnpkg.com/babel-preset-minify/-/babel-preset-minify-0.3.0.tgz#7db64afa75f16f6e06c0aa5f25195f6f36784d77"
@ -4817,7 +4782,7 @@ electron-builder-lib@~20.6.2:
semver "^5.5.0" semver "^5.5.0"
temp-file "^3.1.1" temp-file "^3.1.1"
electron-builder@^20.0.4, electron-builder@^20.8.1: electron-builder@^20.8.1:
version "20.8.1" version "20.8.1"
resolved "https://registry.yarnpkg.com/electron-builder/-/electron-builder-20.8.1.tgz#3d19607a7f7d3ee7f3e110a6fc66c720ed1d2cc0" resolved "https://registry.yarnpkg.com/electron-builder/-/electron-builder-20.8.1.tgz#3d19607a7f7d3ee7f3e110a6fc66c720ed1d2cc0"
dependencies: dependencies:
@ -4997,7 +4962,7 @@ electron-webpack@^2.0.1:
webpack-merge "^4.1.2" webpack-merge "^4.1.2"
yargs "^11.1.0" yargs "^11.1.0"
electron@1.8.4, electron@^1.8.2: electron@1.8.4:
version "1.8.4" version "1.8.4"
resolved "https://registry.yarnpkg.com/electron/-/electron-1.8.4.tgz#cca8d0e6889f238f55b414ad224f03e03b226a38" resolved "https://registry.yarnpkg.com/electron/-/electron-1.8.4.tgz#cca8d0e6889f238f55b414ad224f03e03b226a38"
dependencies: dependencies:
@ -7287,28 +7252,12 @@ istanbul-lib-coverage@^1.1.1, istanbul-lib-coverage@^1.1.2:
version "1.1.2" version "1.1.2"
resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.2.tgz#4113c8ff6b7a40a1ef7350b01016331f63afde14" resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.2.tgz#4113c8ff6b7a40a1ef7350b01016331f63afde14"
istanbul-lib-coverage@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.0.tgz#f7d8f2e42b97e37fe796114cb0f9d68b5e3a4341"
istanbul-lib-hook@^1.1.0: istanbul-lib-hook@^1.1.0:
version "1.1.0" version "1.1.0"
resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.1.0.tgz#8538d970372cb3716d53e55523dd54b557a8d89b" resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.1.0.tgz#8538d970372cb3716d53e55523dd54b557a8d89b"
dependencies: dependencies:
append-transform "^0.4.0" append-transform "^0.4.0"
istanbul-lib-instrument@^1.10.1:
version "1.10.1"
resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.1.tgz#724b4b6caceba8692d3f1f9d0727e279c401af7b"
dependencies:
babel-generator "^6.18.0"
babel-template "^6.16.0"
babel-traverse "^6.18.0"
babel-types "^6.18.0"
babylon "^6.18.0"
istanbul-lib-coverage "^1.2.0"
semver "^5.3.0"
istanbul-lib-instrument@^1.7.5, istanbul-lib-instrument@^1.8.0, istanbul-lib-instrument@^1.9.2: istanbul-lib-instrument@^1.7.5, istanbul-lib-instrument@^1.8.0, istanbul-lib-instrument@^1.9.2:
version "1.9.2" version "1.9.2"
resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.9.2.tgz#84905bf47f7e0b401d6b840da7bad67086b4aab6" resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.9.2.tgz#84905bf47f7e0b401d6b840da7bad67086b4aab6"
@ -8028,9 +7977,6 @@ ledger-test-library@KhalilBellakrid/ledger-test-library-nodejs#7d37482:
dependencies: dependencies:
axios "^0.17.1" axios "^0.17.1"
bindings "^1.3.0" bindings "^1.3.0"
electron "^1.8.2"
electron-builder "^20.0.4"
electron-rebuild "^1.7.3"
nan "^2.6.2" nan "^2.6.2"
prebuild-install "^2.2.2" prebuild-install "^2.2.2"
@ -11931,16 +11877,6 @@ test-exclude@^4.1.1:
read-pkg-up "^1.0.1" read-pkg-up "^1.0.1"
require-main-filename "^1.0.1" require-main-filename "^1.0.1"
test-exclude@^4.2.1:
version "4.2.1"
resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.2.1.tgz#dfa222f03480bca69207ca728b37d74b45f724fa"
dependencies:
arrify "^1.0.1"
micromatch "^3.1.8"
object-assign "^4.1.0"
read-pkg-up "^1.0.1"
require-main-filename "^1.0.1"
text-table@0.2.0, text-table@^0.2.0, text-table@~0.2.0: text-table@0.2.0, text-table@^0.2.0, text-table@~0.2.0:
version "0.2.0" version "0.2.0"
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"

Loading…
Cancel
Save