add base layout/ui styles

This commit is contained in:
Andrea Franz 2020-05-18 11:21:57 +02:00
parent a89b4d76e6
commit e9e1af076b
No known key found for this signature in database
GPG Key ID: 4F0D2F2D9DE7F29D
10 changed files with 555 additions and 43 deletions

View File

@ -12,16 +12,23 @@
"author": "",
"license": "MIT",
"dependencies": {
"@fortawesome/fontawesome-free": "^5.13.0",
"@fortawesome/fontawesome-svg-core": "^1.2.28",
"@fortawesome/free-solid-svg-icons": "^5.13.0",
"@fortawesome/react-fontawesome": "^0.1.9",
"@types/history": "^4.7.5",
"@types/react": "^16.9.0",
"@types/react-dom": "^16.9.0",
"@types/react-fontawesome": "^1.6.4",
"@types/react-redux": "^7.1.7",
"@types/react-router-dom": "^5.1.5",
"bn.js": "^5.1.1",
"classnames": "^2.2.6",
"connected-react-router": "^6.7.0",
"eth-sig-util": "^2.5.3",
"history": "^4.10.1",
"minimist": "^1.2.3",
"node-sass": "^4.14.1",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-redux": "^7.2.0",
@ -30,6 +37,7 @@
"react-scripts": "3.4.1",
"redux": "^4.0.5",
"redux-thunk": "^2.3.0",
"typeface-roboto": "^0.0.75",
"typescript": "^3.8.3",
"web3": "1.2.7",
"web3-eth": "1.2.7"
@ -38,6 +46,7 @@
"extends": "react-app"
},
"devDependencies": {
"@types/classnames": "^2.2.10",
"embark": "^5.3.0-nightly.7",
"embark-geth": "^5.3.0-nightly.7",
"embark-graph": "^5.3.0-nightly.7",

25
src/actions/layout.ts Normal file
View File

@ -0,0 +1,25 @@
export const LAYOUT_TOGGLE_SIDEBAR = "LAYOUT_TOGGLE_SIDEBAR";
export interface LayoutToggleSidebarAction {
type: typeof LAYOUT_TOGGLE_SIDEBAR
open: boolean
}
export const LAYOUT_FLIP_CARD = "LAYOUT_FLIP_CARD";
export interface LayoutFlipCardAction {
type: typeof LAYOUT_FLIP_CARD
flipped: boolean
}
export type LayoutActions =
LayoutToggleSidebarAction |
LayoutFlipCardAction;
export const toggleSidebar = (open: boolean): LayoutToggleSidebarAction => ({
type: LAYOUT_TOGGLE_SIDEBAR,
open,
});
export const flipCard = (flipped: boolean): LayoutFlipCardAction => ({
type: LAYOUT_FLIP_CARD,
flipped,
});

View File

@ -1,4 +1,5 @@
import React from 'react';
import classNames from 'classnames';
import ERC20BucketFactory from '../embarkArtifacts/contracts/ERC20BucketFactory';
import { RootState } from '../reducers';
import {
@ -6,6 +7,7 @@ import {
useSelector,
} from 'react-redux';
import { Web3Type } from "../actions/web3";
import "../styles/Layout.scss";
const web3Type = (t: Web3Type) => {
switch (t) {
@ -28,6 +30,7 @@ export default function(ownProps: any) {
error: state.web3.error,
account: state.web3.account,
type: state.web3.type,
sidebarOpen: state.layout.sidebarOpen,
}
}, shallowEqual);
@ -39,14 +42,22 @@ export default function(ownProps: any) {
return <>initializing...</>;
}
return <>
Network ID: {props.networkID} <br />
Factory: {ERC20BucketFactory.address} <br />
Account: {props.account} <br />
Web3 Type: {web3Type(props.type)} <br />
<hr />
<div>
const sidebarClass = classNames({
sidebar: true,
open: props.sidebarOpen,
});
return <div className="main">
<div className={sidebarClass}>
<div className="inner">
Network ID: {props.networkID} <br />
Factory: {ERC20BucketFactory.address} <br />
Account: {props.account} <br />
Web3 Type: {web3Type(props.type)} <br />
</div>
</div>
<div className="content">
{ownProps.children}
</div>
</>;
</div>;
}

View File

@ -1,4 +1,5 @@
import React, { useEffect } from 'react';
import classNames from 'classnames';
import { RootState } from '../reducers';
import { useRouteMatch } from 'react-router-dom';
import {
@ -26,6 +27,14 @@ import {
ERROR_REDEEMING,
ERROR_WRONG_SIGNER,
} from '../actions/redeem';
import { flipCard } from "../actions/layout";
import "../styles/Redeemable.scss";
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import {
faUndo as flipIcon,
faUndo as unflipIcon,
} from '@fortawesome/free-solid-svg-icons'
const buckerErrorMessage = (error: RedeemableErrors): string => {
switch (error.type) {
@ -89,6 +98,7 @@ export default function(ownProps: any) {
redeeming: state.redeem.loading,
redeemError: state.redeem.error,
redeemTxHash: state.redeem.txHash,
cardFlipped: state.layout.cardFlipped,
}
}, shallowEqual);
@ -110,53 +120,120 @@ export default function(ownProps: any) {
return <>loading token info...</>;
}
const erc20Info = (token: TokenERC20) => {
const erc20Header = (token: TokenERC20) => {
const [displayAmount, roundedDisplayAmount] = toBaseUnit(props.amount!, token.decimals, 2);
return <>
Token Symbol: {token.symbol}<br />
Token Decimals: {token.decimals}<br />
Display Amount: {displayAmount} <br />
Rounded Display Amount: {roundedDisplayAmount} <br />
<span className="amount">{roundedDisplayAmount}</span>
<span className="erc20-symbol">{token.symbol}</span>
</>
}
const nftInfo = (token: TokenNFT) => {
const nftHeader = (token: TokenNFT) => {
return <>
<span className="nft-symbol">{token.symbol}</span>
{token.metadata !== undefined && <span className="name">
{token.metadata.name}
</span>}
</>
}
const erc20Content = (token: TokenERC20) => {
return <>
</>
}
const nftContent = (token: TokenNFT) => {
return <>
Token Symbol: {token.symbol}<br />
Token Metadata URI: {token.tokenURI}<br />
{props.loadingTokenMetadata ? "loading metadata..." : <>
{token.metadata !== undefined && <>
Name: {token.metadata.name}<br />
Description: {token.metadata.description}<br />
<img src={token.metadata.image} alt={token.metadata.name} />
<span className="nft-description">
{token.metadata.description}
</span>
<img className="nft-image" src={token.metadata.image} alt={token.metadata.name} />
</>}
</>}<br />
</>}
</>
}
const isERC20 = isTokenERC20(props.token);
const tokenInfo = isERC20 ? erc20Info(props.token as TokenERC20) : nftInfo(props.token as TokenNFT);
const tokenHeader = isERC20 ? erc20Header(props.token as TokenERC20) : nftHeader(props.token as TokenNFT);
const tokenContent = isERC20 ? erc20Content(props.token as TokenERC20) : nftContent(props.token as TokenNFT);
return <>
Bucket Address: {props.bucketAddress}<br />
Recipient: {props.recipient}<br />
Amount: {props.amount}<br />
Expiration Time: {new Date(props.expirationTime! * 1000).toLocaleDateString("default", {hour: "numeric", minute: "numeric"})}<br />
Code Hash: {props.codeHash} {emptyCode ? "(empty string)" : ""}<br />
Token Address: {props.tokenAddress}<br />
Token Type: {isERC20 ? "ERC20" : "NFT"}<br />
{tokenInfo}
Receiver: {props.receiver} <br />
const cardClass = classNames({
card: true,
flipped: props.cardFlipped,
});
<br /><br /><br />
<button
disabled={props.redeeming}
onClick={() => dispatch(redeem(bucketAddress, recipientAddress, "", isERC20))}>
{props.redeeming ? "Redeeming..." : "Redeem"}
</button>
<br />
{props.redeemError && `Error: ${redeemErrorMessage(props.redeemError)}`}
const frontClass = classNames({
side: true,
front: true,
erc20: isERC20,
nft: !isERC20,
});
{props.redeemTxHash && `Done! Tx Hash: ${props.redeemTxHash}`}
</>;
const backClass = classNames({ side: true, back: true });
return <div className={cardClass}>
<div className={frontClass}>
<div className="header">
<button className="flip" onClick={ () => { dispatch(flipCard(true)) } }>
<FontAwesomeIcon icon={flipIcon} />
</button>
<div className="info">
{tokenHeader}
</div>
</div>
<div className="content">
<div className="info">
{tokenContent}
</div>
{props.redeemError && <div className="error">
Error: {redeemErrorMessage(props.redeemError)}
</div>}
{props.redeemTxHash && <div className="success">
Done! Tx Hash: {props.redeemTxHash}
</div>}
</div>
<div className="footer">
<button
className="btn-redeem"
disabled={props.redeeming}
onClick={() => dispatch(redeem(bucketAddress, recipientAddress, "", isERC20))}>
{props.redeeming ? "Redeeming..." : "Redeem"}
</button>
</div>
</div>
<div className={backClass}>
<div className="header">
<button className="flip" onClick={ () => { dispatch(flipCard(false)) } }>
<FontAwesomeIcon icon={flipIcon} />
</button>
</div>
<div className="content">
<dl>
<dt>Bucket Address</dt>
<dd>{props.bucketAddress}</dd>
<dt>Bucket Address</dt>
<dd>{props.bucketAddress}</dd>
<dt>Recipient</dt>
<dd>{props.recipient}</dd>
<dt>Amount</dt>
<dd>{props.amount}</dd>
<dt>Expiration Time</dt>
<dd>{new Date(props.expirationTime! * 1000).toLocaleDateString("default", {hour: "numeric", minute: "numeric"})}</dd>
<dt>Code Hash</dt>
<dd>{props.codeHash} {emptyCode ? "(empty string)" : ""}</dd>
<dt>Token Address</dt>
<dd>{props.tokenAddress}</dd>
<dt>Token Type: {isERC20 ? "ERC20" : "NFT"}</dt>
<dt>Receiver</dt>
<dd>{props.receiver} </dd>
</dl>
</div>
<div className="footer">
</div>
</div>
</div>;
}

View File

@ -15,9 +15,9 @@ import Redeemable from './components/Redeemable';
import { redeemablePath } from './config';
const logger: Middleware = ({ getState }: MiddlewareAPI) => (next: Dispatch) => action => {
console.log('will dispatch', action);
console.log('dispatch', action);
const returnValue = next(action);
console.log('state after dispatch', getState());
console.log('state', getState());
return returnValue;
}

View File

@ -13,11 +13,16 @@ import {
RedeemState,
redeemReducer,
} from './redeem';
import {
LayoutState,
layoutReducer,
} from './layout';
export interface RootState {
web3: Web3State,
redeemable: RedeemableState,
redeem: RedeemState,
layout: LayoutState,
}
export default function(history: History) {
@ -26,5 +31,6 @@ export default function(history: History) {
router: connectRouter(history),
redeemable: redeemableReducer,
redeem: redeemReducer,
layout: layoutReducer,
});
}

34
src/reducers/layout.ts Normal file
View File

@ -0,0 +1,34 @@
import {
LayoutActions,
LAYOUT_TOGGLE_SIDEBAR,
LAYOUT_FLIP_CARD,
} from "../actions/layout";
export interface LayoutState {
sidebarOpen: boolean,
cardFlipped: boolean,
}
const initialState: LayoutState = {
sidebarOpen: false,
cardFlipped: false,
}
export const layoutReducer = (state: LayoutState = initialState, action: LayoutActions): LayoutState => {
switch(action.type) {
case LAYOUT_TOGGLE_SIDEBAR:
return {
...state,
sidebarOpen: action.open,
};
case LAYOUT_FLIP_CARD:
return {
...state,
cardFlipped: action.flipped,
};
default:
return state;
}
}

68
src/styles/Layout.scss Normal file
View File

@ -0,0 +1,68 @@
:link,:visited { text-decoration:none }
ul,ol { list-style:none }
h1,h2,h3,h4,h5,h6,pre,code { font-size:1em; }
ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,body,html,p,blockquote,fieldset,input
{ margin:0; padding:0 }
a img,:link img,:visited img { border:none }
address { font-style:normal }
body {
background-image: linear-gradient(90deg, #fa709a 0%, #fee140 100%);
color: rgba(0, 0, 0, 0.87);
font-size: 0.875rem;
font-weight: 400;
line-height: 1.43;
letter-spacing: 0.01071em;
font-family: "Roboto", "Helvetica", "Arial", sans-serif;
}
.sidebar {
z-index: 9999;
background: #fff;
position: absolute;
top: 0;
left: -100vw;
min-height: 100vh;
width: 100vw;
&.open {
animation-duration: 0.2s;
animation-name: slidein;
left: 0;
}
&.closed {
animation-duration: 0.2s;
animation-name: slideout;
left: -100vw;
}
.inner {
padding: 24px;
word-break: break-all;
}
}
@keyframes slidein {
from {
left: -100vw;
}
to {
left: 0;
}
}
@keyframes slideout {
from {
left: 0;
}
to {
left: -100vw;
}
}
.main {
margin-top: 50px;
}

172
src/styles/Redeemable.scss Normal file
View File

@ -0,0 +1,172 @@
.btn-redeem {
border: none;
outline: none;
cursor: pointer;
padding: 10px;
color: #fff;
box-shadow: 0 0 20px #eee;
border-radius: 10px;
width: 100%;
background-size: 200% auto;
text-align: center;
text-transform: uppercase;
font-weight: bold;
font-size: 0.8rem;
letter-spacing: 0.05rem;
transition: 0.5s;
// background-image: linear-gradient(to right, #84fab0 0%, #8fd3f4 51%, #84fab0 100%);
background-image: linear-gradient(to right, #fa709a 0%, #fee140 100%, #fbc2eb 100%);
&:hover {
background-position: right center;
}
}
.card {
color: #222;
width: 300px;
max-width: 100vw;
word-break: break-all;
margin: 0 auto;
perspective:1000px;
position: relative;
background: #fff;
box-shadow: 0px 2px 1px -1px rgba(0,0,0,0.2), 0px 1px 1px 0px rgba(0,0,0,0.14), 0px 1px 3px 0px rgba(0,0,0,0.12);
border-radius: 8px;
transform-style: preserve-3d;
transition: transform 1.0s;
height: 500px;
&.flipped {
transform: perspective(1000px) rotateY(180deg);
}
.side {
position: absolute;
width: 100%;
height: 100%;
-webkit-backface-visibility: hidden; /* Safari */
backface-visibility: hidden;
}
.back {
background: #fff;
transform: rotateY(180deg);
}
.front {
&.erc20, &.nft {
.header {
.info {
background-image: linear-gradient(to right, #fa709a 0%, #fee140 50%, #fbc2eb 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
.amount, .erc20-symbol, .nft-symbol, .name {
display: block;
text-align: center;
line-height: 3rem;
}
.amount {
font-size: 4rem;
}
.erc20-symbol {
font-size: 2rem;
}
.nft-symbol {
font-size: 2.5rem;
}
.name {
font-size: 1.5rem;
line-height: 1.5rem;
}
}
}
.content {
text-align: center;
.nft-description {
display: block;
text-align: center;
color: #565656;
text-shadow: 1px 1px #eee;
margin-bottom: 8px;
}
.nft-image {
margin: 0 auto;
max-width: 200px;
max-height: 200px;
border-radius: 8px;
box-shadow: 0 0 20px #eee;
}
}
}
}
.side {
will-change: initial;
display: flex;
flex-direction: column;
.header, .content, .footer {
padding: 12px;
position: relative;
}
.header {
// background: green;
.flip {
background: #fff;
position: absolute;
top: 12px;
right: 8px;
color: #d8d8d8;
border: none;
outline: none;
cursor: pointer;
}
}
.content {
// background: pink;
flex-grow: 1;
overflow-y: auto;
.error {
background: red;
padding: 8px;
font-weight: 500;
border-radius: 4px;
color: #fff;
}
}
.footer {
// background: yellow;
}
}
.side.front {
.header {
padding-top: 48px;
}
}
.side.back {
.content {
dl {
dt {
font-weight: bold;
}
dd {
margin: 0;
}
}
}
}
}

110
yarn.lock
View File

@ -1457,6 +1457,37 @@
utf8 "^3.0.0"
uuid "^3.3.2"
"@fortawesome/fontawesome-common-types@^0.2.28":
version "0.2.28"
resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.28.tgz#1091bdfe63b3f139441e9cba27aa022bff97d8b2"
integrity sha512-gtis2/5yLdfI6n0ia0jH7NJs5i/Z/8M/ZbQL6jXQhCthEOe5Cr5NcQPhgTvFxNOtURE03/ZqUcEskdn2M+QaBg==
"@fortawesome/fontawesome-free@^5.13.0":
version "5.13.0"
resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-5.13.0.tgz#fcb113d1aca4b471b709e8c9c168674fbd6e06d9"
integrity sha512-xKOeQEl5O47GPZYIMToj6uuA2syyFlq9EMSl2ui0uytjY9xbe8XS0pexNWmxrdcCyNGyDmLyYw5FtKsalBUeOg==
"@fortawesome/fontawesome-svg-core@^1.2.28":
version "1.2.28"
resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.28.tgz#e5b8c8814ef375f01f5d7c132d3c3a2f83a3abf9"
integrity sha512-4LeaNHWvrneoU0i8b5RTOJHKx7E+y7jYejplR7uSVB34+mp3Veg7cbKk7NBCLiI4TyoWS1wh9ZdoyLJR8wSAdg==
dependencies:
"@fortawesome/fontawesome-common-types" "^0.2.28"
"@fortawesome/free-solid-svg-icons@^5.13.0":
version "5.13.0"
resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.13.0.tgz#44d9118668ad96b4fd5c9434a43efc5903525739"
integrity sha512-IHUgDJdomv6YtG4p3zl1B5wWf9ffinHIvebqQOmV3U+3SLw4fC+LUCCgwfETkbTtjy5/Qws2VoVf6z/ETQpFpg==
dependencies:
"@fortawesome/fontawesome-common-types" "^0.2.28"
"@fortawesome/react-fontawesome@^0.1.9":
version "0.1.9"
resolved "https://registry.yarnpkg.com/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.9.tgz#c865b9286c707407effcec99958043711367cd02"
integrity sha512-49V3WNysLZU5fZ3sqSuys4nGRytsrxJktbv3vuaXkEoxv22C6T7TEG0TW6+nqVjMnkfCQd5xOnmJoZHMF78tOw==
dependencies:
prop-types "^15.7.2"
"@hapi/address@2.x.x":
version "2.1.4"
resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5"
@ -1863,6 +1894,11 @@
"@types/connect" "*"
"@types/node" "*"
"@types/classnames@^2.2.10":
version "2.2.10"
resolved "https://registry.yarnpkg.com/@types/classnames/-/classnames-2.2.10.tgz#cc658ca319b6355399efc1f5b9e818f1a24bf999"
integrity sha512-1UzDldn9GfYYEsWWnn/P4wkTlkZDH7lDb0wBMGbtIQc9zXEQq7FlKBdZUn6OBqD8sKZZ2RQO2mAjGpXiDGoRmQ==
"@types/color-name@^1.1.1":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0"
@ -2097,6 +2133,13 @@
dependencies:
"@types/react" "*"
"@types/react-fontawesome@^1.6.4":
version "1.6.4"
resolved "https://registry.yarnpkg.com/@types/react-fontawesome/-/react-fontawesome-1.6.4.tgz#95884bd8df906b423a254e00d5050f7fe75b3e76"
integrity sha512-/fHr+BoUX+3MYpCkb8a+Bpt+Je2/0FgFi1XSaHH0ga1hqMy5PS7Ny/XV0Qh5cJHeKvkONbKWPSwgPlqK7UtdqA==
dependencies:
"@types/react" "*"
"@types/react-redux@^7.1.7":
version "7.1.7"
resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.7.tgz#12a0c529aba660696947384a059c5c6e08185c7a"
@ -4033,6 +4076,11 @@ class-utils@^0.3.5:
isobject "^3.0.0"
static-extend "^0.1.1"
classnames@^2.2.6:
version "2.2.6"
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce"
integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==
clean-css@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.3.tgz#507b5de7d97b48ee53d84adb0160ff6216380f78"
@ -12236,6 +12284,29 @@ node-sass@4.13.0:
stdout-stream "^1.4.0"
"true-case-path" "^1.0.2"
node-sass@^4.14.1:
version "4.14.1"
resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.14.1.tgz#99c87ec2efb7047ed638fb4c9db7f3a42e2217b5"
integrity sha512-sjCuOlvGyCJS40R8BscF5vhVlQjNN069NtQ1gSxyK1u9iqvn6tf7O1R4GNowVZfiZUCRt5MmMs1xd+4V/7Yr0g==
dependencies:
async-foreach "^0.1.3"
chalk "^1.1.1"
cross-spawn "^3.0.0"
gaze "^1.0.0"
get-stdin "^4.0.1"
glob "^7.0.3"
in-publish "^2.0.0"
lodash "^4.17.15"
meow "^3.7.0"
mkdirp "^0.5.1"
nan "^2.13.2"
node-gyp "^3.8.0"
npmlog "^4.0.0"
request "^2.88.0"
sass-graph "2.2.5"
stdout-stream "^1.4.0"
"true-case-path" "^1.0.2"
nodeify@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/nodeify/-/nodeify-1.0.1.tgz#64ab69a7bdbaf03ce107b4f0335c87c0b9e91b1d"
@ -15237,6 +15308,16 @@ sanitize.css@^10.0.0:
resolved "https://registry.yarnpkg.com/sanitize.css/-/sanitize.css-10.0.0.tgz#b5cb2547e96d8629a60947544665243b1dc3657a"
integrity sha512-vTxrZz4dX5W86M6oVWVdOVe72ZiPs41Oi7Z6Km4W5Turyz28mrXSJhhEBZoRtzJWIv3833WKVwLSDWWkEfupMg==
sass-graph@2.2.5:
version "2.2.5"
resolved "https://registry.yarnpkg.com/sass-graph/-/sass-graph-2.2.5.tgz#a981c87446b8319d96dce0671e487879bd24c2e8"
integrity sha512-VFWDAHOe6mRuT4mZRd4eKE+d8Uedrk6Xnh7Sh9b4NGufQLQjOrvf/MQoOdx+0s92L89FeyUUNfU597j/3uNpag==
dependencies:
glob "^7.0.0"
lodash "^4.0.0"
scss-tokenizer "^0.2.3"
yargs "^13.3.2"
sass-graph@^2.2.4:
version "2.2.4"
resolved "https://registry.yarnpkg.com/sass-graph/-/sass-graph-2.2.4.tgz#13fbd63cd1caf0908b9fd93476ad43a51d1e0b49"
@ -16928,6 +17009,11 @@ typedarray@^0.0.6:
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
typeface-roboto@^0.0.75:
version "0.0.75"
resolved "https://registry.yarnpkg.com/typeface-roboto/-/typeface-roboto-0.0.75.tgz#98d5ba35ec234bbc7172374c8297277099cc712b"
integrity sha512-VrR/IiH00Z1tFP4vDGfwZ1esNqTiDMchBEXYY9kilT6wRGgFoCAlgkEUMHb1E3mB0FsfZhv756IF0+R+SFPfdg==
typescript@^3.8.3:
version "3.8.3"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.8.3.tgz#409eb8544ea0335711205869ec458ab109ee1061"
@ -18467,6 +18553,14 @@ yargs-parser@^11.1.1:
camelcase "^5.0.0"
decamelize "^1.2.0"
yargs-parser@^13.1.2:
version "13.1.2"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38"
integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==
dependencies:
camelcase "^5.0.0"
decamelize "^1.2.0"
yargs-parser@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.0.tgz#275ecf0d7ffe05c77e64e7c86e4cd94bf0e1228a"
@ -18534,6 +18628,22 @@ yargs@13.3.0, yargs@^13.3.0:
y18n "^4.0.0"
yargs-parser "^13.1.1"
yargs@^13.3.2:
version "13.3.2"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd"
integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==
dependencies:
cliui "^5.0.0"
find-up "^3.0.0"
get-caller-file "^2.0.1"
require-directory "^2.1.1"
require-main-filename "^2.0.0"
set-blocking "^2.0.0"
string-width "^3.0.0"
which-module "^2.0.0"
y18n "^4.0.0"
yargs-parser "^13.1.2"
yargs@^7.0.0:
version "7.1.0"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.0.tgz#6ba318eb16961727f5d284f8ea003e8d6154d0c8"