diff --git a/CHANGELOG.md b/CHANGELOG.md index 9de0e171f..ac595bc6e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,12 +8,14 @@ Web UI version numbers should always match the corresponding version of LBRY App ## [Unreleased] ### Added - * ShapeShift integration + * * ### Changed * The credit balance displayed in the main app navigation displays two decimal places instead of one. * Moved all redux code into /redux folder + * Channel names in pages are highlighted to indicate them being clickable(#814) + * ### Fixed * Long channel names causing inconsistent thumbnail sizes (#721) diff --git a/src/renderer/.flowconfig b/src/renderer/.flowconfig index 21d1a300a..18e154135 100644 --- a/src/renderer/.flowconfig +++ b/src/renderer/.flowconfig @@ -12,9 +12,6 @@ flow-typed suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe suppress_comment=\\(.\\|\n\\)*\\$FlowIssue module.name_mapper='^constants\(.*\)$' -> '/js/constants\1' -module.name_mapper='^util\(.*\)$' -> '/js/util\1' module.name_mapper='^redux\(.*\)$' -> '/js/redux\1' -module.name_mapper='^types\(.*\)$' -> '/js/types\1' -module.name_mapper='^component\(.*\)$' -> '/js/component\1' [strict] diff --git a/src/renderer/flow-typed/bluebird.js b/src/renderer/flow-typed/bluebird.js deleted file mode 100644 index b6ea52b19..000000000 --- a/src/renderer/flow-typed/bluebird.js +++ /dev/null @@ -1,3 +0,0 @@ -declare module 'bluebird' { - declare module.exports: any; -} diff --git a/src/renderer/flow-typed/classnames.js b/src/renderer/flow-typed/classnames.js deleted file mode 100644 index 8ed60a607..000000000 --- a/src/renderer/flow-typed/classnames.js +++ /dev/null @@ -1,3 +0,0 @@ -declare module 'classnames' { - declare module.exports: any; -} diff --git a/src/renderer/flow-typed/formik.js b/src/renderer/flow-typed/formik.js deleted file mode 100644 index 020efafd4..000000000 --- a/src/renderer/flow-typed/formik.js +++ /dev/null @@ -1,3 +0,0 @@ -declare module 'formik' { - declare module.exports: any; -} diff --git a/src/renderer/flow-typed/i18n.js b/src/renderer/flow-typed/i18n.js deleted file mode 100644 index cbceb4b59..000000000 --- a/src/renderer/flow-typed/i18n.js +++ /dev/null @@ -1 +0,0 @@ -declare function __(a: string): string; diff --git a/src/renderer/flow-typed/qrcode.react.js b/src/renderer/flow-typed/qrcode.react.js deleted file mode 100644 index 43a589258..000000000 --- a/src/renderer/flow-typed/qrcode.react.js +++ /dev/null @@ -1,3 +0,0 @@ -declare module 'qrcode.react' { - declare module.exports: any; -} diff --git a/src/renderer/flow-typed/shapeshift.io.js b/src/renderer/flow-typed/shapeshift.io.js deleted file mode 100644 index 2d32593ee..000000000 --- a/src/renderer/flow-typed/shapeshift.io.js +++ /dev/null @@ -1,3 +0,0 @@ -declare module 'shapeshift.io' { - declare module.exports: any; -} diff --git a/src/renderer/js/component/address/index.js b/src/renderer/js/component/address/index.js deleted file mode 100644 index 00bec962e..000000000 --- a/src/renderer/js/component/address/index.js +++ /dev/null @@ -1,7 +0,0 @@ -import { connect } from "react-redux"; -import { doShowSnackBar } from "redux/actions/app"; -import Address from "./view"; - -export default connect(null, { - doShowSnackBar, -})(Address); diff --git a/src/renderer/js/component/address/view.jsx b/src/renderer/js/component/address/view.jsx deleted file mode 100644 index 96049eb35..000000000 --- a/src/renderer/js/component/address/view.jsx +++ /dev/null @@ -1,52 +0,0 @@ -import React from "react"; -import PropTypes from "prop-types"; -import { clipboard } from "electron"; -import Link from "component/link"; -import classnames from "classnames"; - -export default class Address extends React.PureComponent { - static propTypes = { - address: PropTypes.string, - }; - - constructor(props) { - super(props); - - this._inputElem = null; - } - - render() { - const { address, showCopyButton, doShowSnackBar } = this.props; - - return ( -
- { - this._inputElem = input; - }} - onFocus={() => { - this._inputElem.select(); - }} - readOnly="readonly" - value={address || ""} - /> - {showCopyButton && ( - - { - clipboard.writeText(address); - doShowSnackBar({ message: __("Address copied") }); - }} - /> - - )} -
- ); - } -} diff --git a/src/renderer/js/component/common.js b/src/renderer/js/component/common.js index 2f8ae5489..c5352637b 100644 --- a/src/renderer/js/component/common.js +++ b/src/renderer/js/component/common.js @@ -137,6 +137,42 @@ export class CreditAmount extends React.PureComponent { } } +let addressStyle = { + fontFamily: + '"Consolas", "Lucida Console", "Adobe Source Code Pro", monospace', +}; +export class Address extends React.PureComponent { + static propTypes = { + address: PropTypes.string, + }; + + constructor(props) { + super(props); + + this._inputElem = null; + } + + render() { + return ( +
+ { + this._inputElem = input; + }} + onFocus={() => { + this._inputElem.select(); + }} + style={addressStyle} + readOnly="readonly" + value={this.props.address || ""} + /> +
+ ); + } +} + export class Thumbnail extends React.PureComponent { static propTypes = { src: PropTypes.string, diff --git a/src/renderer/js/component/common/spinner.jsx b/src/renderer/js/component/common/spinner.jsx deleted file mode 100644 index 8863459c8..000000000 --- a/src/renderer/js/component/common/spinner.jsx +++ /dev/null @@ -1,16 +0,0 @@ -import React from "react"; -import classnames from "classnames"; - -export default ({ dark, className }) => { - return ( -
- ); -}; diff --git a/src/renderer/js/component/link/view.jsx b/src/renderer/js/component/link/view.jsx index c9355f84d..9b949bf75 100644 --- a/src/renderer/js/component/link/view.jsx +++ b/src/renderer/js/component/link/view.jsx @@ -14,12 +14,11 @@ const Link = props => { navigate, navigateParams, doNavigate, - className, } = props; - const combinedClassName = - (className || "") + - (!className && !button ? "button-text" : "") + // Non-button links get the same look as text buttons + const className = + (props.className || "") + + (!props.className && !button ? "button-text" : "") + // Non-button links get the same look as text buttons (button ? " button-block button-" + button + " button-set-item" : "") + (disabled ? " disabled" : ""); @@ -44,7 +43,7 @@ const Link = props => { return ( ({ - receiveAddress: selectReceiveAddress(state), - shapeShift: selectShapeShift(state), -}); - -export default connect(select, { - shapeShiftInit, - getCoinStats, - createShapeShift, - clearShapeShift, - getActiveShift, - doShowSnackBar, -})(ShapeShift); diff --git a/src/renderer/js/component/shapeShift/internal/active-shift.jsx b/src/renderer/js/component/shapeShift/internal/active-shift.jsx deleted file mode 100644 index 40e5cad40..000000000 --- a/src/renderer/js/component/shapeShift/internal/active-shift.jsx +++ /dev/null @@ -1,161 +0,0 @@ -// @flow -import * as React from "react"; -import QRCode from "qrcode.react"; -import * as statuses from "constants/shape_shift"; -import Address from "component/address"; -import Link from "component/link"; -import type { Dispatch } from "redux/actions/shape_shift"; -import ShiftMarketInfo from "./market_info"; - -type Props = { - shiftState: ?string, - shiftCoinType: ?string, - shiftDepositAddress: ?string, - shiftReturnAddress: ?string, - shiftOrderId: ?string, - originCoinDepositMax: ?number, - clearShapeShift: Dispatch, - doShowSnackBar: Dispatch, - getActiveShift: Dispatch, - shapeShiftRate: ?number, - originCoinDepositMax: ?number, - originCoinDepositFee: ?number, - originCoinDepositMin: ?string, -}; - -class ActiveShapeShift extends React.PureComponent { - continousFetch: ?number; - - constructor() { - super(); - this.continousFetch = undefined; - } - - componentDidMount() { - const { getActiveShift, shiftDepositAddress } = this.props; - - getActiveShift(shiftDepositAddress); - this.continousFetch = setInterval(() => { - getActiveShift(shiftDepositAddress); - }, 10000); - } - - componentWillUpdate(nextProps: Props) { - const { shiftState } = nextProps; - if (shiftState === statuses.COMPLETE) { - this.clearContinuousFetch(); - } - } - - componentWillUnmount() { - this.clearContinuousFetch(); - } - - clearContinuousFetch() { - if (this.continousFetch) { - clearInterval(this.continousFetch); - this.continousFetch = null; - } - } - - render() { - const { - shiftCoinType, - shiftDepositAddress, - shiftReturnAddress, - shiftOrderId, - shiftState, - originCoinDepositMax, - clearShapeShift, - doShowSnackBar, - shapeShiftRate, - originCoinDepositFee, - originCoinDepositMin, - } = this.props; - - return ( -
- {shiftState === statuses.NO_DEPOSITS && ( -
-

- Send up to{" "} - - {originCoinDepositMax} {shiftCoinType} - {" "} - to the address below. -

- - -
-
-
- -
-
-
- )} - - {shiftState === statuses.RECEIVED && ( -
-

- {__( - "ShapeShift has received your payment! Sending the funds to your LBRY wallet." - )} -

- - {__("This can take a while, especially with BTC.")} - -
- )} - - {shiftState === statuses.COMPLETE && ( -
-

- {__( - "Transaction complete! You should see the new LBC in your wallet." - )} -

-
- )} -
- - {shiftOrderId && ( - - - - )} - {shiftState === statuses.NO_DEPOSITS && - shiftReturnAddress && ( -
- - If the transaction doesn't go through, ShapeShift will return - your {shiftCoinType} back to {shiftReturnAddress} - -
- )} -
-
- ); - } -} - -export default ActiveShapeShift; diff --git a/src/renderer/js/component/shapeShift/internal/form.jsx b/src/renderer/js/component/shapeShift/internal/form.jsx deleted file mode 100644 index 8a59c3a4c..000000000 --- a/src/renderer/js/component/shapeShift/internal/form.jsx +++ /dev/null @@ -1,109 +0,0 @@ -import React from "react"; -import Link from "component/link"; -import { getExampleAddress } from "util/shape_shift"; -import { Submit, FormRow } from "component/form"; -import type { ShapeShiftFormValues, Dispatch } from "redux/actions/shape_shift"; -import ShiftMarketInfo from "./market_info"; - -type ShapeShiftFormErrors = { - returnAddress?: string, -}; - -type Props = { - values: ShapeShiftFormValues, - errors: ShapeShiftFormErrors, - touched: boolean, - handleChange: Event => any, - handleBlur: Event => any, - handleSubmit: Event => any, - isSubmitting: boolean, - shiftSupportedCoins: Array, - originCoin: string, - updating: boolean, - getCoinStats: Dispatch, - receiveAddress: string, - originCoinDepositFee: number, - originCoinDepositMin: string, - originCoinDepositMax: number, - shapeShiftRate: number, -}; - -export default (props: Props) => { - const { - values, - errors, - touched, - handleChange, - handleBlur, - handleSubmit, - isSubmitting, - shiftSupportedCoins, - originCoin, - updating, - getCoinStats, - receiveAddress, - originCoinDepositMax, - originCoinDepositMin, - originCoinDepositFee, - shapeShiftRate, - } = props; - return ( -
-
- {__("Exchange")} - - {__("for LBC")} -
- {!updating && - originCoinDepositMax && ( - - )} -
-
- - - - - ({__("optional but recommended")}) {__("We will return your")}{" "} - {originCoin}{" "} - {__("to this address if the transaction doesn't go through.")} - - -
- -
- - ); -}; diff --git a/src/renderer/js/component/shapeShift/internal/market_info.jsx b/src/renderer/js/component/shapeShift/internal/market_info.jsx deleted file mode 100644 index 2d7395b81..000000000 --- a/src/renderer/js/component/shapeShift/internal/market_info.jsx +++ /dev/null @@ -1,34 +0,0 @@ -// @flow -import React from "react"; - -type Props = { - shapeShiftRate: ?number, - originCoin: ?string, - originCoinDepositFee: ?number, - originCoinDepositMax: ?number, - originCoinDepositMin: ?string, -}; - -export default (props: Props) => { - const { - shapeShiftRate, - originCoin, - originCoinDepositFee, - originCoinDepositMax, - originCoinDepositMin, - } = props; - - return ( -
- - {__("Receive")} {shapeShiftRate} LBC - {" / "} - {"1"} {originCoin} {__("less")} {originCoinDepositFee} LBC {__("fee")}. -
- {__("Exchange max")}: {originCoinDepositMax} {originCoin} -
- {__("Exchange min")}: {originCoinDepositMin} {originCoin} -
-
- ); -}; diff --git a/src/renderer/js/component/shapeShift/view.jsx b/src/renderer/js/component/shapeShift/view.jsx deleted file mode 100644 index a90a203cb..000000000 --- a/src/renderer/js/component/shapeShift/view.jsx +++ /dev/null @@ -1,150 +0,0 @@ -// @flow -import * as React from "react"; -import { shell } from "electron"; -import { Formik } from "formik"; -import classnames from "classnames"; -import * as statuses from "constants/shape_shift"; -import { validateShapeShiftForm } from "util/shape_shift"; -import Link from "component/link"; -import Spinner from "component/common/spinner"; -import { BusyMessage } from "component/common"; -import ShapeShiftForm from "./internal/form"; -import ActiveShapeShift from "./internal/active-shift"; - -import type { ShapeShiftState } from "redux/reducers/shape_shift"; -import type { Dispatch, ShapeShiftFormValues } from "redux/actions/shape_shift"; - -type Props = { - shapeShift: ShapeShiftState, - getCoinStats: Dispatch, - createShapeShift: Dispatch, - clearShapeShift: Dispatch, - getActiveShift: Dispatch, - doShowSnackBar: Dispatch, - shapeShiftInit: Dispatch, - receiveAddress: string, -}; - -class ShapeShift extends React.PureComponent { - componentDidMount() { - const { - shapeShiftInit, - shapeShift: { hasActiveShift, shiftSupportedCoins }, - } = this.props; - - if (!hasActiveShift && !shiftSupportedCoins.length) { - // calls shapeshift to see list of supported coins for shifting - shapeShiftInit(); - } - } - - render() { - const { - getCoinStats, - receiveAddress, - createShapeShift, - shapeShift, - clearShapeShift, - getActiveShift, - doShowSnackBar, - } = this.props; - - const { - loading, - updating, - error, - shiftSupportedCoins, - hasActiveShift, - originCoin, - // ShapeShift response values - originCoinDepositMax, - originCoinDepositMin, - originCoinDepositFee, - shiftDepositAddress, - shiftReturnAddress, - shiftCoinType, - shiftOrderId, - shiftState, - shapeShiftRate, - } = shapeShift; - - const initialFormValues: ShapeShiftFormValues = { - receiveAddress, - originCoin: "BTC", - returnAddress: "", - }; - - return ( - // add the "shapeshift__intital-wrapper class so we can avoid content jumping once everything loads" - // it just gives the section a min-height equal to the height of the content when the form is rendered - // if the markup below changes for the initial render (form.jsx) there will be content jumping - // the styling in shapeshift.scss will need to be updated to the correct min-height -
-
-

{__("Convert Crypto to LBC")}

-

- {__("Powered by ShapeShift. Read our FAQ")}{" "} - {__("here")}. - {hasActiveShift && - shiftState !== "complete" && ( - {__("This will update automatically.")} - )} -

-
- -
- {error &&
{error}
} - {loading && } - {!loading && - !hasActiveShift && - !!shiftSupportedCoins.length && ( - ( - - )} - /> - )} - {hasActiveShift && ( - - )} -
-
- ); - } -} - -export default ShapeShift; diff --git a/src/renderer/js/component/uriIndicator/view.jsx b/src/renderer/js/component/uriIndicator/view.jsx index cff4bd073..3bf850d11 100644 --- a/src/renderer/js/component/uriIndicator/view.jsx +++ b/src/renderer/js/component/uriIndicator/view.jsx @@ -1,7 +1,8 @@ import React from "react"; import { Icon } from "component/common"; import Link from "component/link"; -import lbryuri from "lbryuri.js"; +import lbryuri from "lbryuri"; +import classnames from "classnames"; class UriIndicator extends React.PureComponent { componentWillMount() { @@ -60,7 +61,12 @@ class UriIndicator extends React.PureComponent { const inner = ( - + {channelName} {" "} {!signatureIsValid ? ( diff --git a/src/renderer/js/component/video/internal/loading-screen.jsx b/src/renderer/js/component/video/internal/loading-screen.jsx index 94cc7ce4d..bc388833c 100644 --- a/src/renderer/js/component/video/internal/loading-screen.jsx +++ b/src/renderer/js/component/video/internal/loading-screen.jsx @@ -1,10 +1,9 @@ import React from "react"; -import Spinner from "component/common/spinner"; const LoadingScreen = ({ status, spinner = true }) => (
- {spinner && } + {spinner &&
}
{status}
diff --git a/src/renderer/js/component/walletAddress/view.jsx b/src/renderer/js/component/walletAddress/view.jsx index 63afa2b31..bdf6f81fe 100644 --- a/src/renderer/js/component/walletAddress/view.jsx +++ b/src/renderer/js/component/walletAddress/view.jsx @@ -1,6 +1,6 @@ import React from "react"; import Link from "component/link"; -import Address from "component/address"; +import { Address } from "component/common"; class WalletAddress extends React.PureComponent { componentWillMount() { diff --git a/src/renderer/js/constants/action_types.js b/src/renderer/js/constants/action_types.js index 3670912fd..b2f88f31f 100644 --- a/src/renderer/js/constants/action_types.js +++ b/src/renderer/js/constants/action_types.js @@ -144,18 +144,3 @@ export const FETCH_REWARD_CONTENT_COMPLETED = "FETCH_REWARD_CONTENT_COMPLETED"; //Language export const DOWNLOAD_LANGUAGE_SUCCEEDED = "DOWNLOAD_LANGUAGE_SUCCEEDED"; export const DOWNLOAD_LANGUAGE_FAILED = "DOWNLOAD_LANGUAGE_FAILED"; - -// ShapeShift -export const GET_SUPPORTED_COINS_START = "GET_SUPPORTED_COINS_START"; -export const GET_SUPPORTED_COINS_SUCCESS = "GET_SUPPORTED_COINS_SUCCESS"; -export const GET_SUPPORTED_COINS_FAIL = "GET_SUPPORTED_COINS_FAIL"; -export const GET_COIN_STATS_START = "GET_COIN_STATS_START"; -export const GET_COIN_STATS_SUCCESS = "GET_COIN_STATS_SUCCESS"; -export const GET_COIN_STATS_FAIL = "GET_COIN_STATS_FAIL"; -export const PREPARE_SHAPE_SHIFT_START = "PREPARE_SHAPE_SHIFT_START"; -export const PREPARE_SHAPE_SHIFT_SUCCESS = "PREPARE_SHAPE_SHIFT_SUCCESS"; -export const PREPARE_SHAPE_SHIFT_FAIL = "PREPARE_SHAPE_SHIFT_FAIL"; -export const GET_ACTIVE_SHIFT_START = "GET_ACTIVE_SHIFT_START"; -export const GET_ACTIVE_SHIFT_SUCCESS = "GET_ACTIVE_SHIFT_SUCCESS"; -export const GET_ACTIVE_SHIFT_FAIL = "GET_ACTIVE_SHIFT_FAIL"; -export const CLEAR_SHAPE_SHIFT = "CLEAR_SHAPE_SHIFT"; diff --git a/src/renderer/js/constants/shape_shift.js b/src/renderer/js/constants/shape_shift.js deleted file mode 100644 index d898f2fc2..000000000 --- a/src/renderer/js/constants/shape_shift.js +++ /dev/null @@ -1,3 +0,0 @@ -export const NO_DEPOSITS = "no_deposits"; -export const RECEIVED = "received"; -export const COMPLETE = "complete"; diff --git a/src/renderer/js/main.js b/src/renderer/js/main.js index 9c63a17f0..759b2a179 100644 --- a/src/renderer/js/main.js +++ b/src/renderer/js/main.js @@ -9,8 +9,6 @@ import { doDaemonReady } from "redux/actions/app"; import { doNavigate } from "redux/actions/navigation"; import { doDownloadLanguages } from "redux/actions/settings"; import * as types from "constants/action_types"; -import amplitude from "amplitude-js"; -import lbry from "lbry"; const env = ENV; const { remote, ipcRenderer, shell } = require("electron"); @@ -50,23 +48,6 @@ ipcRenderer.on("window-is-focused", (event, data) => { document.addEventListener("click", event => { var target = event.target; while (target && target !== document) { - if (target.matches("a") || target.matches("button")) { - // TODO: Look into using accessiblity labels (this would also make the app more accessible) - let hrefParts = window.location.href.split("#"); - let element = target.title || target.text.trim(); - if (element) { - amplitude.getInstance().logEvent("CLICK", { - target: element, - location: - hrefParts.length > 1 ? hrefParts[hrefParts.length - 1] : "/", - }); - } else { - amplitude.getInstance().logEvent("UNMARKED_CLICK", { - location: - hrefParts.length > 1 ? hrefParts[hrefParts.length - 1] : "/", - }); - } - } if ( target.matches('a[href^="http"]') || target.matches('a[href^="mailto"]') @@ -85,28 +66,18 @@ var init = function() { app.store.dispatch(doDownloadLanguages()); function onDaemonReady() { - lbry.status().then(info => { - amplitude.getInstance().init( - // Amplitude API Key - "0b130efdcbdbf86ec2f7f9eff354033e", - info.lbry_id, - null, - function() { - window.sessionStorage.setItem("loaded", "y"); //once we've made it here once per session, we don't need to show splash again - app.store.dispatch(doDaemonReady()); + window.sessionStorage.setItem("loaded", "y"); //once we've made it here once per session, we don't need to show splash again + app.store.dispatch(doDaemonReady()); - ReactDOM.render( - -
- - -
-
, - canvas - ); - } - ); - }); + ReactDOM.render( + +
+ + +
+
, + canvas + ); } if (window.sessionStorage.getItem("loaded") == "y") { diff --git a/src/renderer/js/page/receiveCredits/view.jsx b/src/renderer/js/page/receiveCredits/view.jsx index 5052b868e..120071748 100644 --- a/src/renderer/js/page/receiveCredits/view.jsx +++ b/src/renderer/js/page/receiveCredits/view.jsx @@ -2,17 +2,15 @@ import React from "react"; import SubHeader from "component/subHeader"; import Link from "component/link"; import WalletAddress from "component/walletAddress"; -import ShapeShift from "component/shapeShift"; const ReceiveCreditsPage = props => { return (
-
-

{__("More ways to get LBRY Credits")}

+

{__("Where To Find Credits")}

diff --git a/src/renderer/js/redux/actions/shape_shift.js b/src/renderer/js/redux/actions/shape_shift.js deleted file mode 100644 index 8f3e683f6..000000000 --- a/src/renderer/js/redux/actions/shape_shift.js +++ /dev/null @@ -1,137 +0,0 @@ -// @flow -import Promise from "bluebird"; -import * as types from "constants/action_types"; -import { coinRegexPatterns } from "util/shape_shift"; -import type { - GetSupportedCoinsSuccess, - GetCoinStatsStart, - GetCoinStatsSuccess, - GetCoinStatsFail, - PrepareShapeShiftSuccess, - PrepareShapeShiftFail, - GetActiveShiftSuccess, - GetActiveShiftFail, -} from "redux/reducers/shape_shift"; -import type { FormikActions } from "types/common"; - -// use promise chains instead of callbacks for shapeshift api -const shapeShift = Promise.promisifyAll(require("shapeshift.io")); - -// All ShapeShift actions -// Action types defined in the reducer will contain some payload -export type Action = - | { type: types.GET_SUPPORTED_COINS_START } - | { type: types.GET_SUPPORTED_COINS_FAIL } - | GetSupportedCoinsSuccess - | GetCoinStatsStart - | { type: types.GET_COIN_STATS_START } - | GetCoinStatsFail - | GetCoinStatsSuccess - | { type: types.PREPARE_SHAPE_SHIFT_START } - | PrepareShapeShiftFail - | PrepareShapeShiftSuccess - | { type: types.GET_ACTIVE_SHIFT_START } - | GetActiveShiftFail - | GetActiveShiftSuccess; - -// Basic thunk types -// It would be nice to import these from types/common -// Not sure how that would work since they rely on the Action type -type PromiseAction = Promise; -type ThunkAction = (dispatch: Dispatch) => any; -export type Dispatch = ( - action: Action | ThunkAction | PromiseAction | Array -) => any; - -// ShapeShift form values -export type ShapeShiftFormValues = { - originCoin: string, - returnAddress: ?string, - receiveAddress: string, -}; - -export const shapeShiftInit = () => (dispatch: Dispatch): ThunkAction => { - dispatch({ type: types.GET_SUPPORTED_COINS_START }); - - return shapeShift - .coinsAsync() - .then(coinData => { - let supportedCoins = []; - Object.keys(coinData).forEach(symbol => { - if (coinData[symbol].status === "available") { - supportedCoins.push(coinData[symbol]); - } - }); - - // only use larger coins with client side validation - supportedCoins = supportedCoins - .filter(coin => coinRegexPatterns[coin.symbol]) - .map(coin => coin.symbol); - - dispatch({ - type: types.GET_SUPPORTED_COINS_SUCCESS, - data: supportedCoins, - }); - dispatch(getCoinStats(supportedCoins[0])); - }) - .catch(err => - dispatch({ type: types.GET_SUPPORTED_COINS_FAIL, data: err }) - ); -}; - -export const getCoinStats = (coin: string) => ( - dispatch: Dispatch -): ThunkAction => { - const pair = `${coin.toLowerCase()}_lbc`; - - dispatch({ type: types.GET_COIN_STATS_START, data: coin }); - - return shapeShift - .marketInfoAsync(pair) - .then(marketInfo => - dispatch({ type: types.GET_COIN_STATS_SUCCESS, data: marketInfo }) - ) - .catch(err => dispatch({ type: types.GET_COIN_STATS_FAIL, data: err })); -}; - -export const createShapeShift = ( - values: ShapeShiftFormValues, - actions: FormikActions -) => (dispatch: Dispatch): ThunkAction => { - const { - originCoin, - returnAddress, - receiveAddress: withdrawalAddress, - } = values; - - const pair = `${originCoin.toLowerCase()}_lbc`; - const options = { - returnAddress: returnAddress, - }; - - dispatch({ type: types.PREPARE_SHAPE_SHIFT_START }); - return shapeShift - .shiftAsync(withdrawalAddress, pair, options) - .then(res => - dispatch({ type: types.PREPARE_SHAPE_SHIFT_SUCCESS, data: res }) - ) - .catch(err => { - dispatch({ type: types.PREPARE_SHAPE_SHIFT_FAIL, data: err }); - // for formik to stop the submit - actions.setSubmitting(false); - }); -}; - -export const getActiveShift = (depositAddress: string) => ( - dispatch: Dispatch -): ThunkAction => { - dispatch({ type: types.GET_ACTIVE_SHIFT_START }); - - return shapeShift - .statusAsync(depositAddress) - .then(res => dispatch({ type: types.GET_ACTIVE_SHIFT_SUCCESS, data: res })) - .catch(err => dispatch({ type: types.GET_ACTIVE_SHIFT_FAIL, data: err })); -}; - -export const clearShapeShift = () => (dispatch: Dispatch): Action => - dispatch({ type: types.CLEAR_SHAPE_SHIFT }); diff --git a/src/renderer/js/redux/reducers/navigation.js b/src/renderer/js/redux/reducers/navigation.js index e32658b76..00453f9de 100644 --- a/src/renderer/js/redux/reducers/navigation.js +++ b/src/renderer/js/redux/reducers/navigation.js @@ -1,6 +1,5 @@ import * as types from "constants/action_types"; import { parseQueryParams } from "util/query_params"; -import amplitude from "amplitude-js"; const currentPath = () => { const hash = document.location.hash; @@ -70,14 +69,6 @@ reducers[types.WINDOW_SCROLLED] = (state, action) => { export default function reducer(state = defaultState, action) { const handler = reducers[action.type]; - if (handler) { - let nextState = handler(state, action); - if (nextState.currentPath !== state.currentPath) { - amplitude - .getInstance() - .logEvent("NAVIGATION", { destination: nextState.currentPath }); - } - return nextState; - } + if (handler) return handler(state, action); return state; } diff --git a/src/renderer/js/redux/reducers/shape_shift.js b/src/renderer/js/redux/reducers/shape_shift.js deleted file mode 100644 index 71b59addd..000000000 --- a/src/renderer/js/redux/reducers/shape_shift.js +++ /dev/null @@ -1,245 +0,0 @@ -// @flow -import { handleActions } from "util/redux-utils"; -import * as actions from "constants/action_types"; -import * as statuses from "constants/shape_shift"; - -export type ShapeShiftState = { - loading: boolean, - updating: boolean, - shiftSupportedCoins: Array, - hasActiveShift: boolean, - originCoin: ?string, - error: ?string, - shiftDepositAddress: ?string, - shiftReturnAddress: ?string, - shiftCoinType: ?string, - shiftOrderId: ?string, - shiftState: ?string, - originCoinDepositMax: ?number, - // originCoinDepositMin is a string because we need to convert it from scientifc notation - // it will usually be something like 0.00000001 coins - // using Number(x) or parseInt(x) will either change it back to scientific notation or round to zero - originCoinDepositMin: ?string, - originCoinDepositFee: ?number, - shapeShiftRate: ?number, -}; - -// All ShapeShift actions that will have some payload -export type GetSupportedCoinsSuccess = { - type: actions.GET_SUPPORTED_COINS_SUCCESS, - data: Array, -}; -export type GetCoinStatsStart = { - type: actions.GET_SUPPORTED_COINS_SUCCESS, - data: string, -}; -export type GetCoinStatsSuccess = { - type: actions.GET_COIN_STATS_SUCCESS, - data: ShapeShiftMarketInfo, -}; -export type GetCoinStatsFail = { - type: actions.GET_COIN_STATS_FAIL, - data: string, -}; -export type PrepareShapeShiftSuccess = { - type: actions.PREPARE_SHAPE_SHIFT_SUCCESS, - data: ActiveShiftInfo, -}; -export type PrepareShapeShiftFail = { - type: actions.PREPARE_SHAPE_SHIFT_FAIL, - data: ShapeShiftErrorResponse, -}; -export type GetActiveShiftSuccess = { - type: actions.GET_ACTIVE_SHIFT_SUCCESS, - data: string, -}; -export type GetActiveShiftFail = { - type: actions.GET_ACTIVE_SHIFT_FAIL, - data: ShapeShiftErrorResponse, -}; - -// ShapeShift sub-types -// Defined for actions that contain an object in the payload -type ShapeShiftMarketInfo = { - limit: number, - minimum: number, - minerFee: number, - rate: number, -}; - -type ActiveShiftInfo = { - deposit: string, - depositType: string, - returnAddress: string, - orderId: string, -}; - -type ShapeShiftErrorResponse = { - message: string, -}; - -const defaultState: ShapeShiftState = { - loading: true, - updating: false, - shiftSupportedCoins: [], - hasActiveShift: false, - originCoin: undefined, - error: undefined, - shiftDepositAddress: undefined, // shapeshift address to send your coins to - shiftReturnAddress: undefined, - shiftCoinType: undefined, - shiftOrderId: undefined, - shiftState: undefined, - originCoinDepositMax: undefined, - originCoinDepositMin: undefined, - originCoinDepositFee: undefined, - shapeShiftRate: undefined, -}; - -export default handleActions( - { - [actions.GET_SUPPORTED_COINS_START]: ( - state: ShapeShiftState - ): ShapeShiftState => ({ - ...state, - loading: true, - error: undefined, - }), - [actions.GET_SUPPORTED_COINS_SUCCESS]: ( - state: ShapeShiftState, - action: GetSupportedCoinsSuccess - ): ShapeShiftState => { - const shiftSupportedCoins = action.data; - return { - ...state, - error: undefined, - shiftSupportedCoins, - }; - }, - [actions.GET_SUPPORTED_COINS_FAIL]: ( - state: ShapeShiftState - ): ShapeShiftState => ({ - ...state, - loading: false, - error: "Error getting available coins", - }), - - [actions.GET_COIN_STATS_START]: ( - state: ShapeShiftState, - action: GetCoinStatsStart - ): ShapeShiftState => { - const coin = action.data; - return { - ...state, - updating: true, - originCoin: coin, - }; - }, - [actions.GET_COIN_STATS_SUCCESS]: ( - state: ShapeShiftState, - action: GetCoinStatsSuccess - ): ShapeShiftState => { - const marketInfo: ShapeShiftMarketInfo = action.data; - - return { - ...state, - loading: false, - updating: false, - originCoinDepositMax: marketInfo.limit, - // this will come in scientific notation - // toFixed shows the real number, then regex to remove trailing zeros - originCoinDepositMin: marketInfo.minimum - .toFixed(10) - .replace(/\.?0+$/, ""), - originCoinDepositFee: marketInfo.minerFee, - shapeShiftRate: marketInfo.rate, - }; - }, - [actions.GET_COIN_STATS_FAIL]: ( - state: ShapeShiftState, - action: GetCoinStatsFail - ): ShapeShiftState => { - const error = action.data; - return { - ...state, - loading: false, - error, - }; - }, - - [actions.PREPARE_SHAPE_SHIFT_START]: ( - state: ShapeShiftState - ): ShapeShiftState => ({ - ...state, - error: undefined, - }), - [actions.PREPARE_SHAPE_SHIFT_SUCCESS]: ( - state: ShapeShiftState, - action: PrepareShapeShiftSuccess - ) => { - const activeShiftInfo: ActiveShiftInfo = action.data; - return { - ...state, - hasActiveShift: true, - shiftDepositAddress: activeShiftInfo.deposit, - shiftCoinType: activeShiftInfo.depositType, - shiftReturnAddress: activeShiftInfo.returnAddress, - shiftOrderId: activeShiftInfo.orderId, - shiftState: statuses.NO_DEPOSITS, - }; - }, - [actions.PREPARE_SHAPE_SHIFT_FAIL]: ( - state: ShapeShiftState, - action: PrepareShapeShiftFail - ) => { - const error: ShapeShiftErrorResponse = action.data; - return { - ...state, - error: error.message, - }; - }, - - [actions.CLEAR_SHAPE_SHIFT]: (state: ShapeShiftState): ShapeShiftState => ({ - ...state, - loading: false, - updating: false, - hasActiveShift: false, - shiftDepositAddress: undefined, - shiftReturnAddress: undefined, - shiftCoinType: undefined, - shiftOrderId: undefined, - originCoin: state.shiftSupportedCoins[0], - }), - - [actions.GET_ACTIVE_SHIFT_START]: ( - state: ShapeShiftState - ): ShapeShiftState => ({ - ...state, - error: undefined, - updating: true, - }), - [actions.GET_ACTIVE_SHIFT_SUCCESS]: ( - state: ShapeShiftState, - action: GetActiveShiftSuccess - ): ShapeShiftState => { - const status = action.data; - return { - ...state, - updating: false, - shiftState: status, - }; - }, - [actions.GET_ACTIVE_SHIFT_FAIL]: ( - state: ShapeShiftState, - action: GetActiveShiftFail - ): ShapeShiftState => { - const error: ShapeShiftErrorResponse = action.data; - return { - ...state, - updating: false, - error: error.message, - }; - }, - }, - defaultState -); diff --git a/src/renderer/js/redux/selectors/navigation.js b/src/renderer/js/redux/selectors/navigation.js index 7633e81c2..4f91467eb 100644 --- a/src/renderer/js/redux/selectors/navigation.js +++ b/src/renderer/js/redux/selectors/navigation.js @@ -44,8 +44,8 @@ export const selectHeaderLinks = createSelector(selectCurrentPage, page => { return { wallet: __("Overview"), history: __("History"), - send: __("Send Credits"), - receive: __("Get Credits"), + send: __("Send"), + receive: __("Receive"), rewards: __("Rewards"), invite: __("Invites"), }; @@ -78,9 +78,9 @@ export const selectPageTitle = createSelector( case "wallet": return __("Wallet"); case "send": - return __("Send LBRY Credits"); + return __("Send Credits"); case "receive": - return __("Get LBRY Credits"); + return __("Wallet Address"); case "backup": return __("Backup Your Wallet"); case "rewards": diff --git a/src/renderer/js/redux/selectors/search.js b/src/renderer/js/redux/selectors/search.js index fc78e50f4..d64289d78 100644 --- a/src/renderer/js/redux/selectors/search.js +++ b/src/renderer/js/redux/selectors/search.js @@ -65,7 +65,7 @@ export const selectWunderBarIcon = createSelector( return "icon-envelope-open"; case "address": case "receive": - return "icon-credit-card"; + return "icon-address-book"; case "wallet": case "backup": return "icon-bank"; diff --git a/src/renderer/js/redux/selectors/shape_shift.js b/src/renderer/js/redux/selectors/shape_shift.js deleted file mode 100644 index e60af9fb4..000000000 --- a/src/renderer/js/redux/selectors/shape_shift.js +++ /dev/null @@ -1,7 +0,0 @@ -import { createSelector } from "reselect"; - -const _selectState = state => state.shapeShift; - -export const selectShapeShift = createSelector(_selectState, state => ({ - ...state, -})); diff --git a/src/renderer/js/store.js b/src/renderer/js/store.js index 36ea0c6a4..8d1b70363 100644 --- a/src/renderer/js/store.js +++ b/src/renderer/js/store.js @@ -11,7 +11,6 @@ import searchReducer from "redux/reducers/search"; import settingsReducer from "redux/reducers/settings"; import userReducer from "redux/reducers/user"; import walletReducer from "redux/reducers/wallet"; -import shapeShiftReducer from "redux/reducers/shape_shift"; import { persistStore, autoRehydrate } from "redux-persist"; import createCompressor from "redux-persist-transform-compress"; import createFilter from "redux-persist-transform-filter"; @@ -68,7 +67,6 @@ const reducers = redux.combineReducers({ settings: settingsReducer, wallet: walletReducer, user: userReducer, - shapeShift: shapeShiftReducer, }); const bulkThunk = createBulkThunkMiddleware(); diff --git a/src/renderer/js/types/common.js b/src/renderer/js/types/common.js deleted file mode 100644 index ea8c0d815..000000000 --- a/src/renderer/js/types/common.js +++ /dev/null @@ -1,3 +0,0 @@ -export type FormikActions = { - setSubmitting: boolean => mixed, -}; diff --git a/src/renderer/js/util/redux-utils.js b/src/renderer/js/util/redux-utils.js index 17aa4fdaf..6875ec550 100644 --- a/src/renderer/js/util/redux-utils.js +++ b/src/renderer/js/util/redux-utils.js @@ -1,7 +1,6 @@ // util for creating reducers // based off of redux-actions // https://redux-actions.js.org/docs/api/handleAction.html#handleactions - export const handleActions = (actionMap, defaultState) => { return (state = defaultState, action) => { const handler = actionMap[action.type]; diff --git a/src/renderer/js/util/shape_shift.js b/src/renderer/js/util/shape_shift.js deleted file mode 100644 index 7adfc1abc..000000000 --- a/src/renderer/js/util/shape_shift.js +++ /dev/null @@ -1,50 +0,0 @@ -// these don't need to be exact -// shapeshift does a more thourough check on validity -// just general matches to prevent unneccesary api calls -export const coinRegexPatterns = { - BTC: /^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$/, - BCH: /^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$/, - ETH: /^(0x)?[0-9a-fA-F]{40}$/, - DASH: /^X([0-9a-zA-Z]){33}/, - LTC: /^L[a-zA-Z0-9]{26,33}$/, - XMR: /^4[0-9ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{94}$/, -}; - -const validateAddress = (coinType, address) => { - if (!coinType || !address) return false; - - const coinRegex = coinRegexPatterns[coinType.toUpperCase()]; - if (!coinRegex) return false; - - return coinRegex.test(address); -}; - -export const validateShapeShiftForm = (vals, props) => { - let errors = {}; - - if (!vals.returnAddress) { - return errors; - } - - const isValidAddress = validateAddress(vals.originCoin, vals.returnAddress); - - if (!isValidAddress) { - errors.returnAddress = `Enter a valid ${vals.originCoin} address`; - } - - return errors; -}; - -const exampleCoinAddresses = { - BTC: "1745oPaHeW7Fmpb1fUKTtasYfxr4zu9bwq", - BCH: "1745oPaHeW7Fmpb1fUKTtasYfxr4zu9bwq", - ETH: "0x8507cA6a274123fC8f80d929AF9D83602bC4e8cC", - DASH: "XedBP7vLPFXbS3URjrH2Z57Fg9SWftBmQ6", - LTC: "LgZivMvFMTDoqcA5weCQ2QrmRp7pa56bBk", - XMR: - "466XMeJEcowYGx7RzUJj3VDWBZgRWErVQQX6tHYbsacS5QF6v3tidE6LZZnTJgzeEh6bKEEJ6GC9jHirrUKvJwVKVj9e7jm", -}; - -export const getExampleAddress = coin => { - return exampleCoinAddresses[coin]; -}; diff --git a/src/renderer/package.json b/src/renderer/package.json index 9e1c39247..4a6e9f03e 100644 --- a/src/renderer/package.json +++ b/src/renderer/package.json @@ -22,15 +22,10 @@ }, "homepage": "https://github.com/lbryio/lbry-app", "dependencies": { - "amplitude-js": "^4.0.0", - "bluebird": "^3.5.1", - "classnames": "^2.2.5", - "formik": "^0.10.4", "from2": "^2.3.0", "jshashes": "^1.0.7", "localforage": "^1.5.0", "node-sass": "^4.5.3", - "qrcode.react": "^0.7.2", "rc-progress": "^2.0.6", "react": "^16.2.0", "react-dom": "^16.2.0", @@ -48,7 +43,6 @@ "redux-thunk": "^2.2.0", "render-media": "^2.10.0", "reselect": "^3.0.0", - "shapeshift.io": "^1.3.1", "y18n": "^3.2.1" }, "devDependencies": { diff --git a/src/renderer/scss/_gui.scss b/src/renderer/scss/_gui.scss index 4cdd66370..580862b54 100644 --- a/src/renderer/scss/_gui.scss +++ b/src/renderer/scss/_gui.scss @@ -34,11 +34,6 @@ body color: var(--color-meta-light); } -.credit-amount--bold -{ - font-weight: 700; -} - #main-content { margin: auto; diff --git a/src/renderer/scss/all.scss b/src/renderer/scss/all.scss index 40c63b1f4..dc4be7179 100644 --- a/src/renderer/scss/all.scss +++ b/src/renderer/scss/all.scss @@ -26,6 +26,4 @@ @import "component/_divider.scss"; @import "component/_checkbox.scss"; @import "component/_radio.scss"; -@import "component/_shapeshift.scss"; -@import "component/_spinner.scss"; @import "page/_show.scss"; diff --git a/src/renderer/scss/component/_button.scss b/src/renderer/scss/component/_button.scss index e3dad6330..642e3de92 100644 --- a/src/renderer/scss/component/_button.scss +++ b/src/renderer/scss/component/_button.scss @@ -98,4 +98,4 @@ $button-focus-shift: 12%; .button--submit { font-family: inherit; line-height: 0; -} \ No newline at end of file +} diff --git a/src/renderer/scss/component/_card.scss b/src/renderer/scss/component/_card.scss index 53d8c6d1e..a630d5558 100644 --- a/src/renderer/scss/component/_card.scss +++ b/src/renderer/scss/component/_card.scss @@ -26,7 +26,6 @@ .card__actions { padding: 0 var(--card-padding); } - .card--small { .card__title-primary, .card__title-identity, @@ -51,7 +50,7 @@ .card__actions { margin-top: var(--card-margin); margin-bottom: var(--card-margin); - user-select: none; + user-select: none; } .card__actions--bottom { @@ -73,18 +72,6 @@ margin-bottom: var(--card-margin); } } - -.card__actions--only-vertical { - margin-left: 0; - margin-right: 0; - padding-left: 0; - padding-right: 0; -} - -.card__content--extra-vertical-space { - margin: $spacing-vertical 0; -} - $font-size-subtext-multiple: 0.82; .card__subtext { color: var(--color-meta-light); diff --git a/src/renderer/scss/component/_channel-indicator.scss b/src/renderer/scss/component/_channel-indicator.scss index 6c63a4235..50b7648d0 100644 --- a/src/renderer/scss/component/_channel-indicator.scss +++ b/src/renderer/scss/component/_channel-indicator.scss @@ -1,9 +1,9 @@ .channel-name { - display: inline-block; + display: inline-flex; overflow: hidden; white-space: nowrap; - text-overflow: ellipsis + text-overflow: ellipsis; } // this shouldn't know about the card width diff --git a/src/renderer/scss/component/_form-field.scss b/src/renderer/scss/component/_form-field.scss index 1d7398d7a..c7aedf480 100644 --- a/src/renderer/scss/component/_form-field.scss +++ b/src/renderer/scss/component/_form-field.scss @@ -56,11 +56,6 @@ padding-left: 5px; padding-right: 5px; width: 100%; - font-family: "Consolas", "Lucida Console", "Adobe Source Code Pro", monospace; - - &.input-copyable--with-copy-btn { - width: 85%; - } } input[readonly] { diff --git a/src/renderer/scss/component/_header.scss b/src/renderer/scss/component/_header.scss index bdc72dcbd..769622fd8 100644 --- a/src/renderer/scss/component/_header.scss +++ b/src/renderer/scss/component/_header.scss @@ -43,8 +43,6 @@ .wunderbar--active .icon-search { color: var(--color-primary); } -// below styles should be inside the common input styling -// will come back to this with the redesign - sean .wunderbar__input { background: var(--search-bg); width: 100%; diff --git a/src/renderer/scss/component/_shapeshift.scss b/src/renderer/scss/component/_shapeshift.scss deleted file mode 100644 index cb69676a7..000000000 --- a/src/renderer/scss/component/_shapeshift.scss +++ /dev/null @@ -1,40 +0,0 @@ -// Can't think of a better way to do this -// The initial shapeshift form is 311px tall -// the .shapeshift__initial-wrapper class is only added when the form is being loaded -// Once the form is rendered, there is a very smooth transition because the height doesn't change -.shapeshift__wrapper.shapeshift__initial-wrapper { - min-height: 346px; -} - -.shapeshift__content { - .spinner { - margin-top: $spacing-vertical * 3; - } -} - -.shapeshift__tx-info { - min-height: 55px; -} - -.shapeshift__deposit-address-wrapper { - display: flex; - flex-direction: row; - - * { - align-self: center; - } -} - -// this should be pulled out into it's own styling when we add more qr codes -.shapeshift__qrcode { - // don't use a variable here. adds a white border for easier reading in dark mode - // needs to stay the same no matter what theme is present - background-color: #fff; - padding: 2px; - margin-left: 40px; -} - - -.shapeshift__link { - padding-left: 10px; -} diff --git a/src/renderer/scss/component/_spinner.scss b/src/renderer/scss/component/_spinner.scss deleted file mode 100644 index ec339e5a1..000000000 --- a/src/renderer/scss/component/_spinner.scss +++ /dev/null @@ -1,58 +0,0 @@ -.spinner { - position: relative; - width: 11em; - height: 11em; - margin: 20px auto; - font-size: 3px; - border-radius: 50%; - - background: linear-gradient(to right, #fff 10%, rgba(255, 255, 255, 0) 50%); - animation: spin 1.4s infinite linear; - transform: translateZ(0); - - @keyframes spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } - } - - &:before, - &:after { - content: ''; - position: absolute; - top: 0; - left: 0; - } - - &:before { - width: 50%; - height: 50%; - background: #fff; - border-radius: 100% 0 0 0; - } - - &:after { - height: 75%; - width: 75%; - margin: auto; - bottom: 0; - right: 0; - background: #000; - border-radius: 50%; - } -} - -.spinner.spinner--dark { - background: linear-gradient(to right, var(--button-primary-bg) 10%, var(--color-bg) 50%); - - &:before { - background: var(--button-primary-bg); - } - - &:after { - background: var(--color-bg); - } -} \ No newline at end of file diff --git a/src/renderer/scss/component/_video.scss b/src/renderer/scss/component/_video.scss index d6021849e..3f3204308 100644 --- a/src/renderer/scss/component/_video.scss +++ b/src/renderer/scss/component/_video.scss @@ -46,6 +46,53 @@ video { align-items: center; } +.video__loading-spinner { + position: relative; + width: 11em; + height: 11em; + margin: 20px auto; + font-size: 3px; + border-radius: 50%; + + background: linear-gradient(to right, #ffffff 10%, rgba(255, 255, 255, 0) 50%); + animation: spin 1.4s infinite linear; + transform: translateZ(0); + + @keyframes spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } + } + + &:before, + &:after { + content: ''; + position: absolute; + top: 0; + left: 0; + } + + &:before { + width: 50%; + height: 50%; + background: #ffffff; + border-radius: 100% 0 0 0; + } + + &:after { + height: 75%; + width: 75%; + margin: auto; + bottom: 0; + right: 0; + background: black; + border-radius: 50%; + } +} + .video__loading-status { padding-top: 20px; color: white; diff --git a/src/renderer/webpack.common.js b/src/renderer/webpack.common.js index db0f69d2c..3e843a89e 100644 --- a/src/renderer/webpack.common.js +++ b/src/renderer/webpack.common.js @@ -18,7 +18,7 @@ module.exports = { }, resolve: { modules: [appPath, "node_modules"], - extensions: [".js", ".jsx", ".css", ".json"] + extensions: [".js", ".jsx", ".css"] }, module: { rules: [ diff --git a/src/renderer/yarn.lock b/src/renderer/yarn.lock index 4aca36930..d7049810b 100644 --- a/src/renderer/yarn.lock +++ b/src/renderer/yarn.lock @@ -2,13 +2,6 @@ # yarn lockfile v1 -"@segment/top-domain@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@segment/top-domain/-/top-domain-3.0.0.tgz#02e5a5a4fd42a9f6cf886b05e82f104012a3c3a7" - dependencies: - component-cookie "^1.1.2" - component-url "^0.2.1" - abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" @@ -63,9 +56,9 @@ ajv@^4.7.0, ajv@^4.9.1: co "^4.6.0" json-stable-stringify "^1.0.1" -ajv@^5.0.0, ajv@^5.1.0, ajv@^5.1.5, ajv@^5.2.3: - version "5.5.1" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.1.tgz#b38bb8876d9e86bee994956a04e721e88b248eb2" +ajv@^5.0.0, ajv@^5.1.5, ajv@^5.2.3: + version "5.4.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.4.0.tgz#32d1cf08dbc80c432f426f12e10b2511f6b46474" dependencies: co "^4.6.0" fast-deep-equal "^1.0.0" @@ -88,16 +81,6 @@ amdefine@>=0.0.4: version "1.0.1" resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" -amplitude-js@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/amplitude-js/-/amplitude-js-4.0.0.tgz#70bbc0ec893b01d00453d3765f78bc0f32a395cc" - dependencies: - "@segment/top-domain" "^3.0.0" - blueimp-md5 "^2.10.0" - json3 "^3.3.2" - lodash "^4.17.4" - ua-parser-js "github:amplitude/ua-parser-js#ed538f1" - ansi-escapes@^1.0.0, ansi-escapes@^1.1.0: version "1.4.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" @@ -293,11 +276,7 @@ aws-sign2@~0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - -aws4@^1.2.1, aws4@^1.6.0: +aws4@^1.2.1: version "1.6.0" resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" @@ -1018,14 +997,6 @@ block-stream@*: dependencies: inherits "~2.0.0" -bluebird@^3.5.1: - version "3.5.1" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" - -blueimp-md5@^2.10.0: - version "2.10.0" - resolved "https://registry.yarnpkg.com/blueimp-md5/-/blueimp-md5-2.10.0.tgz#02f0843921f90dca14f5b8920a38593201d6964d" - bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: version "4.11.8" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" @@ -1062,18 +1033,6 @@ boom@2.x.x: dependencies: hoek "2.x.x" -boom@4.x.x: - version "4.3.1" - resolved "https://registry.yarnpkg.com/boom/-/boom-4.3.1.tgz#4f8a3005cb4a7e3889f749030fd25b96e01d2e31" - dependencies: - hoek "4.x.x" - -boom@5.x.x: - version "5.2.0" - resolved "https://registry.yarnpkg.com/boom/-/boom-5.2.0.tgz#5dd9da6ee3a5f302077436290cb717d3f4a54e02" - dependencies: - hoek "4.x.x" - brace-expansion@^1.1.7: version "1.1.8" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" @@ -1239,8 +1198,8 @@ caniuse-api@^1.5.2: lodash.uniq "^4.5.0" caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639: - version "1.0.30000778" - resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000778.tgz#167c60e9542a2aa60537c446fb3881d853a3072a" + version "1.0.30000769" + resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000769.tgz#c230b9c1b9e8db3e1c0d858c96e685741b96cc10" cardinal@^1.0.0: version "1.0.0" @@ -1417,8 +1376,8 @@ codemirror-spell-checker@*: typo-js "*" codemirror@*: - version "5.32.0" - resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.32.0.tgz#cb6ff5d8ef36d0b10f031130e2d9ebeee92c902e" + version "5.31.0" + resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.31.0.tgz#ecf3d057eb74174147066bfc7c5f37b4c4e07df2" color-convert@^1.3.0, color-convert@^1.9.0: version "1.9.1" @@ -1467,8 +1426,8 @@ combined-stream@^1.0.5, combined-stream@~1.0.5: delayed-stream "~1.0.0" commander@^2.11.0, commander@^2.5.0, commander@^2.9.0: - version "2.12.2" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.12.2.tgz#0f5946c427ed9ec0d91a46bb9def53e54650e555" + version "2.11.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563" commondir@^1.0.1: version "1.0.1" @@ -1505,16 +1464,6 @@ commonmark@^0.24.0: mdurl "~ 1.0.1" string.prototype.repeat "^0.2.0" -component-cookie@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/component-cookie/-/component-cookie-1.1.3.tgz#053e14a3bd7748154f55724fd39a60c01994ebed" - dependencies: - debug "*" - -component-url@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/component-url/-/component-url-0.2.1.tgz#4e4f4799c43ead9fd3ce91b5a305d220208fee47" - compressible@~2.0.11: version "2.0.12" resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.12.tgz#c59a5c99db76767e9876500e271ef63b3493bd66" @@ -1576,8 +1525,8 @@ content-type@~1.0.4: resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" convert-source-map@^1.5.0: - version "1.5.1" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5" + version "1.5.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.0.tgz#9acd70851c6d5dfdd93d9282e5edf94a03ff46b5" cookie-signature@1.0.6: version "1.0.6" @@ -1664,12 +1613,6 @@ cryptiles@2.x.x: dependencies: boom "2.x.x" -cryptiles@3.x.x: - version "3.1.2" - resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-3.1.2.tgz#a89fbb220f5ce25ec56e8c4aa8a4fd7b5b0d29fe" - dependencies: - boom "5.x.x" - crypto-browserify@3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.3.0.tgz#b9fc75bb4a0ed61dcf1cd5dae96eb30c9c3e506c" @@ -1804,18 +1747,18 @@ date-now@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" -debug@*, debug@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" - dependencies: - ms "2.0.0" - debug@2.6.9, debug@^2.1.1, debug@^2.2.0, debug@^2.5.1, debug@^2.6.3, debug@^2.6.6, debug@^2.6.8: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" dependencies: ms "2.0.0" +debug@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + dependencies: + ms "2.0.0" + decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" @@ -1906,18 +1849,18 @@ detect-indent@^4.0.0: repeating "^2.0.0" detect-libc@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + version "1.0.2" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.2.tgz#71ad5d204bf17a6a6ca8f450c61454066ef461e1" detect-node@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.3.tgz#a2033c09cc8e158d37748fbde7507832bd6ce127" detective@^4.3.1: - version "4.7.0" - resolved "https://registry.yarnpkg.com/detective/-/detective-4.7.0.tgz#6276e150f9e50829ad1f90ace4d9a2304188afcf" + version "4.5.0" + resolved "https://registry.yarnpkg.com/detective/-/detective-4.5.0.tgz#6e5a8c6b26e6c7a254b1c6b6d7490d98ec91edd1" dependencies: - acorn "^5.2.1" + acorn "^4.0.3" defined "^1.0.0" diffie-hellman@^5.0.0: @@ -1953,14 +1896,11 @@ doctrine@1.5.0, doctrine@^1.2.2: isarray "^1.0.0" doctrine@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.2.tgz#68f96ce8efc56cc42651f1faadb4f175273b0075" + version "2.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.0.tgz#c73d8d2909d22291e1a007a395804da8b665fe63" dependencies: esutils "^2.0.2" - -dom-walk@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018" + isarray "^1.0.0" domain-browser@^1.1.1: version "1.1.7" @@ -1995,8 +1935,8 @@ electron-rebuild@^1.5.11: yargs "^7.0.2" electron-to-chromium@^1.2.7: - version "1.3.28" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.28.tgz#8dd4e6458086644e9f9f0a1cf32e2a1f9dffd9ee" + version "1.3.27" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.27.tgz#78ecb8a399066187bb374eede35d9c70565a803d" elegant-spinner@^1.0.1: version "1.0.1" @@ -2075,8 +2015,8 @@ error-ex@^1.2.0: is-arrayish "^0.2.1" es-abstract@^1.7.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.10.0.tgz#1ecb36c197842a00d8ee4c2dfd8646bb97d60864" + version "1.9.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.9.0.tgz#690829a07cae36b222e7fd9b75c0d0573eb25227" dependencies: es-to-primitive "^1.1.1" function-bind "^1.1.1" @@ -2101,8 +2041,8 @@ es3ify@^0.1.3: through "~2.3.4" es5-ext@^0.10.14, es5-ext@^0.10.35, es5-ext@^0.10.9, es5-ext@~0.10.14: - version "0.10.37" - resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.37.tgz#0ee741d148b80069ba27d020393756af257defc3" + version "0.10.35" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.35.tgz#18ee858ce6a3c45c7d79e91c15fcca9ec568494f" dependencies: es6-iterator "~2.0.1" es6-symbol "~3.1.1" @@ -2400,7 +2340,7 @@ expand-range@^1.8.1: dependencies: fill-range "^2.1.0" -express@^4.16.2: +express@^4.13.3: version "4.16.2" resolved "https://registry.yarnpkg.com/express/-/express-4.16.2.tgz#e35c6dfe2d64b7dca0a5cd4f21781be3299e076c" dependencies: @@ -2435,7 +2375,7 @@ express@^4.16.2: utils-merge "1.0.1" vary "~1.1.2" -extend@~3.0.0, extend@~3.0.1: +extend@~3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" @@ -2627,12 +2567,6 @@ flow-typed@^2.2.3: which "^1.2.14" yargs "^4.2.0" -for-each@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.2.tgz#2c40450b9348e97f281322593ba96704b9abd4d4" - dependencies: - is-function "~1.0.0" - for-in@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" @@ -2659,22 +2593,6 @@ form-data@~2.1.1: combined-stream "^1.0.5" mime-types "^2.1.12" -form-data@~2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.1.tgz#6fb94fbd71885306d73d15cc497fe4cc4ecd44bf" - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.5" - mime-types "^2.1.12" - -formik@^0.10.4: - version "0.10.5" - resolved "https://registry.yarnpkg.com/formik/-/formik-0.10.5.tgz#6984d2f22e918c6d2264a3cb86b8582f7277faca" - dependencies: - lodash.isequal "4.5.0" - prop-types "^15.5.10" - warning "^3.0.0" - forwarded@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" @@ -2699,8 +2617,8 @@ fs-extra@^3.0.1: universalify "^0.1.0" fs-extra@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" + version "4.0.2" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.2.tgz#f91704c53d1b461f893452b0c307d9997647ab6b" dependencies: graceful-fs "^4.1.2" jsonfile "^4.0.0" @@ -2855,13 +2773,6 @@ glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@~7.1.1: 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" - dependencies: - min-document "^2.19.0" - process "~0.5.1" - globals@^9.14.0, globals@^9.18.0: version "9.18.0" resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" @@ -2936,10 +2847,6 @@ har-schema@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e" -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - har-validator@~2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-2.0.6.tgz#cdcbc08188265ad119b6a5a7c8ab70eecfb5d27d" @@ -2956,13 +2863,6 @@ har-validator@~4.2.1: ajv "^4.9.1" har-schema "^1.0.5" -har-validator@~5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd" - dependencies: - ajv "^5.1.0" - har-schema "^2.0.0" - has-ansi@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" @@ -3026,15 +2926,6 @@ hawk@3.1.3, hawk@~3.1.3: hoek "2.x.x" sntp "1.x.x" -hawk@~6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/hawk/-/hawk-6.0.2.tgz#af4d914eb065f9b5ce4d9d11c1cb2126eecc3038" - dependencies: - boom "4.x.x" - cryptiles "3.x.x" - hoek "4.x.x" - sntp "2.x.x" - hmac-drbg@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" @@ -3047,10 +2938,6 @@ hoek@2.x.x: version "2.16.3" resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" -hoek@4.x.x: - version "4.2.0" - resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d" - hoist-non-react-statics@^2.2.1: version "2.3.1" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.3.1.tgz#343db84c6018c650778898240135a1420ee22ce0" @@ -3124,14 +3011,6 @@ http-signature@~1.1.0: jsprim "^1.2.2" sshpk "^1.7.0" -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - https-browserify@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-0.0.1.tgz#3f91365cabe60b77ed0ebba24b454e3e09d95a82" @@ -3272,8 +3151,8 @@ interpret@^0.6.4: resolved "https://registry.yarnpkg.com/interpret/-/interpret-0.6.6.tgz#fecd7a18e7ce5ca6abfb953e1f86213a49f1625b" interpret@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614" + version "1.0.4" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.4.tgz#820cdd588b868ffb191a809506d6c9c8f212b1b0" invariant@^2.0.0, invariant@^2.2.2: version "2.2.2" @@ -3373,10 +3252,6 @@ is-fullwidth-code-point@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" -is-function@^1.0.1, is-function@~1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.1.tgz#12cfb98b65b57dd3d193a3121f5f6e2f437602b5" - is-glob@^2.0.0, is-glob@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" @@ -3425,8 +3300,8 @@ is-path-in-cwd@^1.0.0: is-path-inside "^1.0.0" is-path-inside@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.0.tgz#fc06e5a1683fbda13de667aff717bbc10a48f37f" dependencies: path-is-inside "^1.0.1" @@ -3529,8 +3404,8 @@ isurl@^1.0.0-alpha5: is-object "^1.0.1" js-base64@^2.1.8, js-base64@^2.1.9: - version "2.4.0" - resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.4.0.tgz#9e566fee624751a1d720c966cd6226d29d4025aa" + version "2.3.2" + resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.3.2.tgz#a79a923666372b580f8e27f51845c6f7e8fbfbaf" js-tokens@^3.0.0, js-tokens@^3.0.2: version "3.0.2" @@ -3798,8 +3673,8 @@ loader-utils@^1.0.2, loader-utils@^1.1.0: json5 "^0.5.0" localforage@^1.5.0: - version "1.5.5" - resolved "https://registry.yarnpkg.com/localforage/-/localforage-1.5.5.tgz#55fc1c3a88a47f67f5fac6f1231b25ff13556423" + version "1.5.3" + resolved "https://registry.yarnpkg.com/localforage/-/localforage-1.5.3.tgz#698aa16af1022340b240be9d93192e8af022ff16" dependencies: lie "3.0.2" @@ -3903,10 +3778,6 @@ lodash.isempty@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.isempty/-/lodash.isempty-4.4.0.tgz#6f86cbedd8be4ec987be9aaf33c9684db1b31e7e" -lodash.isequal@4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" - lodash.isplainobject@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" @@ -4029,8 +3900,8 @@ marked-terminal@^1.6.2: node-emoji "^1.4.1" marked@*, marked@^0.3.6: - version "0.3.7" - resolved "https://registry.yarnpkg.com/marked/-/marked-0.3.7.tgz#80ef3bbf1bd00d1c9cfebe42ba1b8c85da258d0d" + version "0.3.6" + resolved "https://registry.yarnpkg.com/marked/-/marked-0.3.6.tgz#b2c6c618fccece4ef86c4fc6cb8a7cbf5aeda8d7" "match-stream@>= 0.0.2 < 1": version "0.0.2" @@ -4156,14 +4027,10 @@ mime-types@^2.1.12, mime-types@~2.1.15, mime-types@~2.1.16, mime-types@~2.1.17, dependencies: mime-db "~1.30.0" -mime@1.4.1: +mime@1.4.1, mime@^1.2.11, mime@^1.3.4: version "1.4.1" resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" -mime@^1.2.11, mime@^1.5.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" - mimic-fn@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18" @@ -4172,12 +4039,6 @@ mimic-response@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.0.tgz#df3d3652a73fded6b9b0b24146e6fd052353458e" -min-document@^2.19.0: - version "2.19.0" - resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" - dependencies: - dom-walk "^0.1.0" - minimalistic-assert@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz#702be2dda6b37f4836bcb3f5db56641b64a1d3d3" @@ -4230,8 +4091,8 @@ multicast-dns-service-types@^1.1.0: resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901" multicast-dns@^6.0.1: - version "6.2.1" - resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-6.2.1.tgz#c5035defa9219d30640558a49298067352098060" + version "6.2.0" + resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-6.2.0.tgz#13f22d0c32dc5ee82a32878e3c380d875b3eab22" dependencies: dns-packet "^1.0.1" thunky "^0.1.0" @@ -4252,8 +4113,8 @@ nan@^2.3.0, nan@^2.3.2: resolved "https://registry.yarnpkg.com/nan/-/nan-2.8.0.tgz#ed715f3fe9de02b57a5e6252d90a96675e1f085a" natives@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/natives/-/natives-1.1.1.tgz#011acce1f7cbd87f7ba6b3093d6cd9392be1c574" + version "1.1.0" + resolved "https://registry.yarnpkg.com/natives/-/natives-1.1.0.tgz#e9ff841418a6b2ec7a495e939984f78f163e6e31" natural-compare@^1.4.0: version "1.4.0" @@ -4502,7 +4363,7 @@ number-is-nan@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" -oauth-sign@~0.8.1, oauth-sign@~0.8.2: +oauth-sign@~0.8.1: version "0.8.2" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" @@ -4719,13 +4580,6 @@ parse-glob@^3.0.4: is-extglob "^1.0.0" is-glob "^2.0.0" -parse-headers@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.1.tgz#6ae83a7aa25a9d9b700acc28698cd1f1ed7e9536" - dependencies: - for-each "^0.3.2" - trim "0.0.1" - parse-json@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" @@ -4806,10 +4660,6 @@ performance-now@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - pify@^2.0.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" @@ -4975,8 +4825,8 @@ postcss-minify-selectors@^2.0.4: postcss-selector-parser "^2.0.0" postcss-modules-extract-imports@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.2.0.tgz#66140ecece38ef06bf0d3e355d69bf59d141ea85" + version "1.1.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.1.0.tgz#b614c9720be6816eaee35fb3a5faa1dba6a05ddb" dependencies: postcss "^6.0.1" @@ -5111,8 +4961,8 @@ preserve@^0.2.0: resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" prettier@^1.4.2: - version "1.9.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.9.1.tgz#41638a0d47c1efbd1b7d5a742aaa5548eab86d70" + version "1.8.2" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.8.2.tgz#bff83e7fd573933c607875e5ba3abbdffb96aeb8" private@^0.1.6, private@^0.1.7, private@~0.1.5: version "0.1.8" @@ -5126,10 +4976,6 @@ process@^0.11.0, process@^0.11.10: version "0.11.10" resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" -process@~0.5.1: - version "0.5.2" - resolved "https://registry.yarnpkg.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf" - progress@^1.1.8: version "1.1.8" resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be" @@ -5201,18 +5047,7 @@ q@^1.1.2: version "1.5.1" resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" -qr.js@0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/qr.js/-/qr.js-0.0.0.tgz#cace86386f59a0db8050fa90d9b6b0e88a1e364f" - -qrcode.react@^0.7.2: - version "0.7.2" - resolved "https://registry.yarnpkg.com/qrcode.react/-/qrcode.react-0.7.2.tgz#72a5718fd56baafe15c2c153fe436628d83aa286" - dependencies: - prop-types "^15.5.8" - qr.js "0.0.0" - -qs@6.5.1, qs@~6.5.1: +qs@6.5.1: version "6.5.1" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" @@ -5288,8 +5123,8 @@ raw-body@2.3.2: unpipe "1.0.0" rc-progress@^2.0.6: - version "2.2.5" - resolved "https://registry.yarnpkg.com/rc-progress/-/rc-progress-2.2.5.tgz#e61d0544bf9d4208e5ba32fc50962159e7f952a3" + version "2.2.4" + resolved "https://registry.yarnpkg.com/rc-progress/-/rc-progress-2.2.4.tgz#45dbdb91cdd71cb5ce22e61313a351ceb5b1488a" dependencies: babel-runtime "6.x" prop-types "^15.5.8" @@ -5329,12 +5164,11 @@ react-markdown@^2.5.0: prop-types "^15.5.1" react-modal@^3.1.5: - version "3.1.7" - resolved "https://registry.yarnpkg.com/react-modal/-/react-modal-3.1.7.tgz#21feb937c95cd722bf2d375cada751fdc8189c0e" + version "3.1.5" + resolved "https://registry.yarnpkg.com/react-modal/-/react-modal-3.1.5.tgz#9cfdb7634b5003148ffb7c8ead13a36f671d744e" dependencies: exenv "^1.2.0" prop-types "^15.5.10" - warning "^3.0.0" react-paginate@^5.0.0: version "5.0.0" @@ -5626,34 +5460,32 @@ repeating@^2.0.0: dependencies: is-finite "^1.0.0" -request@2, request@^2.55.0, request@^2.81.0: - version "2.83.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356" +request@2, request@~2.79.0: + version "2.79.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de" dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.6.0" - caseless "~0.12.0" + aws-sign2 "~0.6.0" + aws4 "^1.2.1" + caseless "~0.11.0" combined-stream "~1.0.5" - extend "~3.0.1" + extend "~3.0.0" forever-agent "~0.6.1" - form-data "~2.3.1" - har-validator "~5.0.3" - hawk "~6.0.2" - http-signature "~1.2.0" + form-data "~2.1.1" + har-validator "~2.0.6" + hawk "~3.1.3" + http-signature "~1.1.0" is-typedarray "~1.0.0" isstream "~0.1.2" json-stringify-safe "~5.0.1" - mime-types "~2.1.17" - oauth-sign "~0.8.2" - performance-now "^2.1.0" - qs "~6.5.1" - safe-buffer "^5.1.1" - stringstream "~0.0.5" - tough-cookie "~2.3.3" - tunnel-agent "^0.6.0" - uuid "^3.1.0" + mime-types "~2.1.7" + oauth-sign "~0.8.1" + qs "~6.3.0" + stringstream "~0.0.4" + tough-cookie "~2.3.0" + tunnel-agent "~0.4.1" + uuid "^3.0.0" -request@2.81.0: +request@2.81.0, request@^2.81.0: version "2.81.0" resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" dependencies: @@ -5680,31 +5512,6 @@ request@2.81.0: tunnel-agent "^0.6.0" uuid "^3.0.0" -request@~2.79.0: - version "2.79.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de" - dependencies: - aws-sign2 "~0.6.0" - aws4 "^1.2.1" - caseless "~0.11.0" - combined-stream "~1.0.5" - extend "~3.0.0" - forever-agent "~0.6.1" - form-data "~2.1.1" - har-validator "~2.0.6" - hawk "~3.1.3" - http-signature "~1.1.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.7" - oauth-sign "~0.8.1" - qs "~6.3.0" - stringstream "~0.0.4" - tough-cookie "~2.3.0" - tunnel-agent "~0.4.1" - uuid "^3.0.0" - require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" @@ -5800,10 +5607,10 @@ rx-lite@^3.1.2: resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102" rxjs@^5.0.0-beta.11, rxjs@^5.1.1: - version "5.5.4" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.4.tgz#66a466acb21270b5f441645a1141f95fcae10ee6" + version "5.5.2" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.2.tgz#28d403f0071121967f18ad665563255d54236ac3" dependencies: - symbol-observable "1.0.1" + symbol-observable "^1.0.1" safe-buffer@5.1.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.1" @@ -5923,13 +5730,6 @@ sha.js@^2.4.0, sha.js@^2.4.8: inherits "^2.0.1" safe-buffer "^5.0.1" -shapeshift.io@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/shapeshift.io/-/shapeshift.io-1.3.1.tgz#939f7d89e6a93fad4b556567d3fcdab45d5cc021" - dependencies: - request "^2.55.0" - xhr "^2.0.1" - shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" @@ -5990,12 +5790,6 @@ sntp@1.x.x: dependencies: hoek "2.x.x" -sntp@2.x.x: - version "2.1.0" - resolved "https://registry.yarnpkg.com/sntp/-/sntp-2.1.0.tgz#2c6cec14fedc2222739caf9b5c3d85d1cc5a2cc8" - dependencies: - hoek "4.x.x" - sockjs-client@1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.1.4.tgz#5babe386b775e4cf14e7520911452654016c8b12" @@ -6197,7 +5991,7 @@ string_decoder@^1.0.0, string_decoder@~1.0.3: dependencies: safe-buffer "~5.1.0" -stringstream@~0.0.4, stringstream@~0.0.5: +stringstream@~0.0.4: version "0.0.5" resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" @@ -6272,13 +6066,9 @@ svgo@^0.7.0: sax "~1.2.1" whet.extend "~0.9.9" -symbol-observable@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.1.tgz#8340fc4702c3122df5d22288f88283f513d3fdd4" - -symbol-observable@^1.0.3: - version "1.1.0" - resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.1.0.tgz#5c68fd8d54115d9dfb72a84720549222e8db9b32" +symbol-observable@^1.0.1, symbol-observable@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.4.tgz#29bf615d4aa7121bdd898b22d4b3f9bc4e2aa03d" table@^3.7.8: version "3.8.3" @@ -6372,7 +6162,7 @@ to-fast-properties@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" -tough-cookie@~2.3.0, tough-cookie@~2.3.3: +tough-cookie@~2.3.0: version "2.3.3" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561" dependencies: @@ -6390,10 +6180,6 @@ trim-right@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" -trim@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/trim/-/trim-0.0.1.tgz#5858547f6b290757ee95cccc666fb50084c460dd" - "true-case-path@^1.0.2": version "1.0.2" resolved "https://registry.yarnpkg.com/true-case-path/-/true-case-path-1.0.2.tgz#7ec91130924766c7f573be3020c34f8fdfd00d62" @@ -6447,10 +6233,6 @@ ua-parser-js@^0.7.9: version "0.7.17" resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.17.tgz#e9ec5f9498b9ec910e7ae3ac626a805c4d09ecac" -"ua-parser-js@github:amplitude/ua-parser-js#ed538f1": - version "0.7.10" - resolved "https://codeload.github.com/amplitude/ua-parser-js/tar.gz/ed538f1" - uglify-js@^2.8.29: version "2.8.29" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" @@ -6589,7 +6371,7 @@ 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.1.0: +uuid@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" @@ -6641,12 +6423,6 @@ vm-browserify@0.0.4: dependencies: indexof "0.0.1" -warning@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/warning/-/warning-3.0.0.tgz#32e5377cb572de4ab04753bdf8821c01ed605b7c" - dependencies: - loose-envify "^1.0.0" - watchpack@^0.2.1: version "0.2.9" resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-0.2.9.tgz#62eaa4ab5e5ba35fdfc018275626e3c0f5e3fb0b" @@ -6677,18 +6453,18 @@ webpack-core@~0.6.9: source-map "~0.4.1" webpack-dev-middleware@^1.11.0: - version "1.12.2" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-1.12.2.tgz#f8fc1120ce3b4fc5680ceecb43d777966b21105e" + version "1.12.0" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-1.12.0.tgz#d34efefb2edda7e1d3b5dbe07289513219651709" dependencies: memory-fs "~0.4.1" - mime "^1.5.0" + mime "^1.3.4" path-is-absolute "^1.0.0" range-parser "^1.0.3" time-stamp "^2.0.0" webpack-dev-server@^2.4.4: - version "2.9.5" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-2.9.5.tgz#79336fba0087a66ae491f4869f6545775b18daa8" + version "2.9.4" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-2.9.4.tgz#7883e61759c6a4b33e9b19ec4037bd4ab61428d1" dependencies: ansi-html "0.0.7" array-includes "^3.0.3" @@ -6698,7 +6474,7 @@ webpack-dev-server@^2.4.4: connect-history-api-fallback "^1.3.0" debug "^3.1.0" del "^3.0.0" - express "^4.16.2" + express "^4.13.3" html-entities "^1.2.0" http-proxy-middleware "~0.17.4" import-local "^0.1.1" @@ -6733,8 +6509,8 @@ webpack-notifier@^1.5.0: strip-ansi "^3.0.1" webpack-sources@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.1.0.tgz#a101ebae59d6507354d71d8013950a3a8b7a5a54" + version "1.0.2" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.0.2.tgz#d0148ec083b3b5ccef1035a6b3ec16442983b27a" dependencies: source-list-map "^2.0.0" source-map "~0.6.1" @@ -6766,8 +6542,8 @@ webpack@^1.12.0: webpack-core "~0.6.9" webpack@^3.0.0: - version "3.10.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-3.10.0.tgz#5291b875078cf2abf42bdd23afe3f8f96c17d725" + version "3.8.1" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-3.8.1.tgz#b16968a81100abe61608b0153c9159ef8bb2bd83" dependencies: acorn "^5.0.0" acorn-dynamic-import "^2.0.0" @@ -6872,15 +6648,6 @@ write@^0.2.1: dependencies: mkdirp "^0.5.1" -xhr@^2.0.1: - version "2.4.0" - resolved "https://registry.yarnpkg.com/xhr/-/xhr-2.4.0.tgz#e16e66a45f869861eeefab416d5eff722dc40993" - dependencies: - global "~4.3.0" - is-function "^1.0.1" - parse-headers "^2.0.0" - xtend "^4.0.0" - xss-filters@^1.2.6: version "1.2.7" resolved "https://registry.yarnpkg.com/xss-filters/-/xss-filters-1.2.7.tgz#59fa1de201f36f2f3470dcac5f58ccc2830b0a9a"