Rework council display (#1976)

* Rework council layout

* Updates

* Bump API
This commit is contained in:
Jaco Greeff 2019-12-02 15:49:46 +01:00 committed by GitHub
parent 55bd0feb78
commit 43d6f3d969
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 230 additions and 208 deletions

View File

@ -10,10 +10,10 @@
"packages/*"
],
"resolutions": {
"@polkadot/api": "^0.98.0-beta.1",
"@polkadot/api-contract": "^0.98.0-beta.1",
"@polkadot/api": "^0.98.0-beta.2",
"@polkadot/api-contract": "^0.98.0-beta.2",
"@polkadot/keyring": "^1.7.1",
"@polkadot/types": "^0.98.0-beta.1",
"@polkadot/types": "^0.98.0-beta.2",
"@polkadot/util": "^1.7.1",
"@polkadot/util-crypto": "^1.7.1",
"babel-core": "^7.0.0-bridge.0",

View File

@ -11,7 +11,7 @@
"license": "Apache-2.0",
"dependencies": {
"@babel/runtime": "^7.7.4",
"@polkadot/api-contract": "^0.98.0-beta.1",
"@polkadot/api-contract": "^0.98.0-beta.2",
"@polkadot/react-components": "^0.38.0-beta.12"
}
}

View File

@ -3,39 +3,38 @@
// of the Apache-2.0 license. See the LICENSE file for details.
import { I18nProps } from '@polkadot/react-components/types';
import { AccountId } from '@polkadot/types/interfaces';
import { AccountId, Balance } from '@polkadot/types/interfaces';
import React from 'react';
import { AddressCard, Badge, Icon } from '@polkadot/react-components';
import { AddressSmall } from '@polkadot/react-components';
import { FormatBalance } from '@polkadot/react-query';
import translate from '../translate';
import Voters from './Voters';
interface Props extends I18nProps {
address: AccountId;
isRunnerUp?: boolean;
balance?: Balance;
voters?: AccountId[];
}
function Candidate ({ address, isRunnerUp, t, voters }: Props): React.ReactElement<Props> {
function Candidate ({ address, balance, t, voters }: Props): React.ReactElement<Props> {
return (
<AddressCard
defaultName={isRunnerUp ? t('runner up') : t('candidate')}
iconInfo={isRunnerUp && (
<Badge
hover={t('Runner up')}
info={<Icon name='chevron down' />}
isTooltip
type='runnerup'
/>
)}
value={address}
withIndexOrAddress
>
{voters && voters.length !== 0 && (
<Voters voters={voters} />
)}
</AddressCard>
<tr>
<td className='top'>
<AddressSmall value={address} />
</td>
<td className='top together right'>
{balance && balance.gtn(0) && (
<FormatBalance label={<label>{t('backing')}</label>} value={balance} />
)}
</td>
<td className='all'>
{voters && voters.length !== 0 && (
<Voters voters={voters} />
)}
</td>
</tr>
);
}

View File

@ -0,0 +1,63 @@
/* eslint-disable @typescript-eslint/camelcase */
// Copyright 2017-2019 @polkadot/app-democracy authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { AccountId } from '@polkadot/types/interfaces';
import { I18nProps } from '@polkadot/react-components/types';
import { ComponentProps } from './types';
import React from 'react';
import { Table } from '@polkadot/react-components';
import translate from '../translate';
import Candidate from './Candidate';
interface Props extends I18nProps, ComponentProps {
allVotes?: Record<string, AccountId[]>;
className?: string;
}
function Candidates ({ allVotes = {}, className, electionsInfo: { candidates, runnersUp }, t }: Props): React.ReactElement<Props> {
return (
<div className={className}>
<h1>{t('runners up')}</h1>
{runnersUp.length
? (
<Table>
<Table.Body>
{runnersUp.map(([accountId, balance]): React.ReactNode => (
<Candidate
address={accountId}
balance={balance}
key={accountId.toString()}
voters={allVotes[accountId.toString()]}
/>
))}
</Table.Body>
</Table>
)
: t('No runners up found')
}
<h1>{t('candidates')}</h1>
{candidates.length
? (
<Table>
<Table.Body>
{candidates.map((accountId): React.ReactNode => (
<Candidate
address={accountId}
key={accountId.toString()}
voters={allVotes[accountId.toString()]}
/>
))}
</Table.Body>
</Table>
)
: t('No candidates found')
}
</div>
);
}
export default translate(Candidates);

View File

@ -1,41 +0,0 @@
// Copyright 2017-2019 @polkadot/app-democracy authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { I18nProps } from '@polkadot/react-components/types';
import { AccountId } from '@polkadot/types/interfaces';
import React from 'react';
import { AddressCard, Badge, Icon } from '@polkadot/react-components';
import translate from '../translate';
import Voters from './Voters';
interface Props extends I18nProps {
address: AccountId;
voters?: AccountId[];
}
function Member ({ address, t, voters }: Props): React.ReactElement<Props> {
return (
<AddressCard
defaultName={t('council member')}
iconInfo={
<Badge
hover={t('Current member')}
info={<Icon name='check' />}
isTooltip
type='selected'
/>
}
value={address}
withIndexOrAddress
>
{voters && voters.length !== 0 && (
<Voters voters={voters} />
)}
</AddressCard>
);
}
export default translate(Member);

View File

@ -8,78 +8,38 @@ import { I18nProps } from '@polkadot/react-components/types';
import { ComponentProps } from './types';
import React from 'react';
import { withCalls } from '@polkadot/react-api';
import { Columar, Column } from '@polkadot/react-components';
import { Table } from '@polkadot/react-components';
import translate from '../translate';
import Candidate from './Candidate';
import Member from './Member';
interface Props extends I18nProps, ComponentProps {
allVotes?: Record<string, AccountId[]>;
className?: string;
}
function Members ({ allVotes = {}, electionsInfo: { candidates, members, runnersUp }, t }: Props): React.ReactElement<Props> {
function Members ({ allVotes = {}, className, electionsInfo: { members }, t }: Props): React.ReactElement<Props> {
return (
<Columar>
<Column
emptyText={t('No members found')}
headerText={t('members')}
>
{members.map(([accountId]): React.ReactNode => (
<Member
address={accountId}
key={accountId.toString()}
voters={allVotes[accountId.toString()]}
/>
))}
</Column>
<Column
emptyText={t('No candidates found')}
headerText={t('candidates')}
>
{(!!candidates.length || !!runnersUp.length) && (
<>
{runnersUp.map(([accountId]): React.ReactNode => (
<Candidate
address={accountId}
isRunnerUp
key={accountId.toString()}
voters={allVotes[accountId.toString()]}
/>
))}
{candidates.map((accountId): React.ReactNode => (
<Candidate
address={accountId}
key={accountId.toString()}
voters={allVotes[accountId.toString()]}
/>
))}
</>
)}
</Column>
</Columar>
<div className={className}>
{members.length
? (
<Table>
<Table.Body>
{members.map(([accountId, balance]): React.ReactNode => (
<Candidate
address={accountId}
balance={balance}
key={accountId.toString()}
voters={allVotes[accountId.toString()]}
/>
))}
</Table.Body>
</Table>
)
: t('No members found')
}
</div>
);
}
export default translate(
withCalls<Props>(
['query.electionsPhragmen.votesOf', {
propName: 'allVotes',
transform: ([voters, casted]: [AccountId[], AccountId[][]]): Record<string, AccountId[]> =>
voters.reduce((result: Record<string, AccountId[]>, voter, index): Record<string, AccountId[]> => {
casted[index].forEach((candidate): void => {
const address = candidate.toString();
if (!result[address]) {
result[address] = [];
}
result[address].push(voter);
});
return result;
}, {})
}]
)(Members)
);
export default translate(Members);

View File

@ -17,9 +17,9 @@ interface Props extends I18nProps, ComponentProps {
bestNumber?: BlockNumber;
}
function Summary ({ bestNumber, electionsInfo: { members, candidateCount, desiredSeats, runnersUp, termDuration, voteCount }, t }: Props): React.ReactElement<Props> {
function Summary ({ bestNumber, className, electionsInfo: { members, candidateCount, desiredSeats, runnersUp, termDuration, voteCount }, t }: Props): React.ReactElement<Props> {
return (
<SummaryBox>
<SummaryBox className={className}>
<section>
<CardSummary label={t('seats')}>
{formatNumber(members.length)}/{formatNumber(desiredSeats)}

View File

@ -56,8 +56,7 @@ const Candidates = styled.div`
border: 1px solid #eee;
border-radius: 0.25rem;
margin: 0.25rem;
padding-bottom: 0.25rem;
padding-right: 0.5rem;
padding: 0 0.5rem 0.25rem;
position: relative;
&::after {

View File

@ -3,21 +3,23 @@
// of the Apache-2.0 license. See the LICENSE file for details.
import { DerivedElectionsInfo } from '@polkadot/api-derive/types';
import { BlockNumber } from '@polkadot/types/interfaces';
import { ComponentProps } from './types';
import { AccountId, BlockNumber } from '@polkadot/types/interfaces';
import React from 'react';
import { withCalls, registry } from '@polkadot/react-api';
import { useLocation } from 'react-router-dom';
import { registry } from '@polkadot/react-api';
import { Button } from '@polkadot/react-components';
import { useApi, trackStream } from '@polkadot/react-hooks';
import { createType } from '@polkadot/types';
import Candidates from './Candidates';
import Members from './Members';
import SubmitCandidacy from './SubmitCandidacy';
import Summary from './Summary';
import Vote from './Vote';
interface Props extends ComponentProps {
bestNumber?: BlockNumber;
interface Props {
className?: string;
}
const NULL_INFO: DerivedElectionsInfo = {
@ -29,28 +31,54 @@ const NULL_INFO: DerivedElectionsInfo = {
termDuration: createType(registry, 'BlockNumber')
};
function Overview ({ bestNumber, electionsInfo = NULL_INFO }: Props): React.ReactElement<Props> {
export default function Overview ({ className }: Props): React.ReactElement<Props> {
const { api } = useApi();
const bestNumber = trackStream<BlockNumber>(api.derive.chain.bestNumber, []);
const _electionsInfo = trackStream<DerivedElectionsInfo>(api.derive.elections.info, []);
const allVotes = trackStream<Record<string, AccountId[]>>(api.query.electionsPhragmen.votesOf, [], {
transform: ([voters, casted]: [AccountId[], AccountId[][]]): Record<string, AccountId[]> =>
voters.reduce((result: Record<string, AccountId[]>, voter, index): Record<string, AccountId[]> => {
casted[index].forEach((candidate): void => {
const address = candidate.toString();
if (!result[address]) {
result[address] = [];
}
result[address].push(voter);
});
return result;
}, {})
});
const { pathname } = useLocation();
const electionsInfo = _electionsInfo || NULL_INFO;
return (
<>
<Summary
bestNumber={bestNumber}
<div className={className}>
{pathname === '/council' && (
<>
<Summary
bestNumber={bestNumber}
electionsInfo={electionsInfo}
/>
<Button.Group>
<SubmitCandidacy electionsInfo={electionsInfo} />
<Button.Or />
<Vote electionsInfo={electionsInfo} />
</Button.Group>
</>
)}
<Members
allVotes={allVotes}
className={pathname === '/council' ? '' : 'council--hidden'}
electionsInfo={electionsInfo}
/>
<Button.Group>
<SubmitCandidacy electionsInfo={electionsInfo} />
<Button.Or />
<Vote electionsInfo={electionsInfo} />
</Button.Group>
<Members electionsInfo={electionsInfo} />
</>
<Candidates
allVotes={allVotes}
className={pathname === '/council' ? 'council--hidden' : ''}
electionsInfo={electionsInfo}
/>
</div>
);
}
export default withCalls<Props>(
['derive.elections.info', {
propName: 'electionsInfo'
}],
['derive.chain.bestNumber', {
propName: 'bestNumber'
}]
)(Overview);

View File

@ -6,6 +6,8 @@ import { AppProps, BareProps, I18nProps } from '@polkadot/react-components/types
import React from 'react';
import { Route, Switch } from 'react-router';
import { useLocation } from 'react-router-dom';
import styled from 'styled-components';
import { Tabs } from '@polkadot/react-components';
import Overview from './Overview';
@ -14,9 +16,11 @@ import translate from './translate';
interface Props extends AppProps, BareProps, I18nProps {}
function App ({ basePath, t }: Props): React.ReactElement<Props> {
function App ({ basePath, className, t }: Props): React.ReactElement<Props> {
const { pathname } = useLocation();
return (
<main>
<main className={className}>
<header>
<Tabs
basePath={basePath}
@ -26,6 +30,10 @@ function App ({ basePath, t }: Props): React.ReactElement<Props> {
name: 'overview',
text: t('Council overview')
},
{
name: 'candidates',
text: t('Candidates')
},
{
name: 'motions',
text: t('Motions')
@ -35,10 +43,16 @@ function App ({ basePath, t }: Props): React.ReactElement<Props> {
</header>
<Switch>
<Route path={`${basePath}/motions`} component={Motions} />
<Route component={Overview} />
</Switch>
<Overview className={[basePath, `${basePath}/candidates`].includes(pathname) ? '' : 'council--hidden'} />
</main>
);
}
export default translate(App);
export default translate(
styled(App)`
.council--hidden {
display: none;
}
`
);

View File

@ -31,7 +31,7 @@
"homepage": "https://github.com/polkadot-js/ui/tree/master/packages/ui-reactive#readme",
"dependencies": {
"@babel/runtime": "^7.7.4",
"@polkadot/api": "^0.98.0-beta.1",
"@polkadot/api": "^0.98.0-beta.2",
"@polkadot/extension-dapp": "^0.14.0-beta.6",
"edgeware-node-types": "^1.0.10",
"rxjs-compat": "^6.5.3"

View File

@ -2029,35 +2029,35 @@
dependencies:
"@types/node" ">= 8"
"@polkadot/api-contract@^0.98.0-beta.1":
version "0.98.0-beta.1"
resolved "https://registry.yarnpkg.com/@polkadot/api-contract/-/api-contract-0.98.0-beta.1.tgz#dde866e8968566f4245db1f304e41aa7cacf0f07"
integrity sha512-y6VQF6jB/jYUVqspmlq28ALFVeyAU0Vr7MlsXAshGA5Ejx7XjSJYqEkl4ESeraIDYGrLxHBJZxz8828xb3w88Q==
"@polkadot/api-contract@^0.98.0-beta.2":
version "0.98.0-beta.2"
resolved "https://registry.yarnpkg.com/@polkadot/api-contract/-/api-contract-0.98.0-beta.2.tgz#8ad3cf5f3928840618a6b30198994417cb5d9f97"
integrity sha512-nfnDEt+SFxf0AkypLKXlaauInDZNmMrWGHQQMwyZB1VnekmTugw/Ftj7ptDoSsFqKu0XFIIswLgfeVFkyX9dxA==
dependencies:
"@babel/runtime" "^7.7.4"
"@polkadot/types" "^0.98.0-beta.1"
"@polkadot/types" "^0.98.0-beta.2"
"@polkadot/api-derive@^0.98.0-beta.1":
version "0.98.0-beta.1"
resolved "https://registry.yarnpkg.com/@polkadot/api-derive/-/api-derive-0.98.0-beta.1.tgz#2d8eaa185f6351b32f906d25fb49e81334311a41"
integrity sha512-MpcbN7oRJ8xmQ2mynAN62CrwXFDJQG9wLewA7SgUAgSMXM/D3g88iyxuIFV6N/lAZKFfVWqg86ALWep+DpJYJQ==
"@polkadot/api-derive@^0.98.0-beta.2":
version "0.98.0-beta.2"
resolved "https://registry.yarnpkg.com/@polkadot/api-derive/-/api-derive-0.98.0-beta.2.tgz#b42ce023391263c7f94476e5c37340f7579b7dd5"
integrity sha512-CxaCv1+CHrXOFKEM+X1ZBmLJH5Af/+g5IPTBCb9QFzWuGFkOy+4u4Zra9mkVvmr0/FGoE0Mmy6X4XMjTaHnHLA==
dependencies:
"@babel/runtime" "^7.7.4"
"@polkadot/api" "^0.98.0-beta.1"
"@polkadot/types" "^0.98.0-beta.1"
"@polkadot/api" "^0.98.0-beta.2"
"@polkadot/types" "^0.98.0-beta.2"
"@polkadot/api@^0.98.0-beta.1":
version "0.98.0-beta.1"
resolved "https://registry.yarnpkg.com/@polkadot/api/-/api-0.98.0-beta.1.tgz#ad1bf45c9db4a310326c21ecc6fe6b3a6286715a"
integrity sha512-4JIEIbtPnl38EXWOB+TjMnICMCvSMEbXZq4JbbLHl8FY0E0vOaeSWRrwuB4sz+Ho9oCt0usFtpomdowFHA6neQ==
"@polkadot/api@^0.98.0-beta.2":
version "0.98.0-beta.2"
resolved "https://registry.yarnpkg.com/@polkadot/api/-/api-0.98.0-beta.2.tgz#3b2cfe28ad700bba84cd2ae7a6d20946e1efcd29"
integrity sha512-gg0rF/NVNnHfFk+AcikjWrvS3s1RmM87RyQV/PsgSvPjciAg2kYhs41r6Tg/UMupgJ6EOGeYodBNuuQx7rWyxg==
dependencies:
"@babel/runtime" "^7.7.4"
"@polkadot/api-derive" "^0.98.0-beta.1"
"@polkadot/api-derive" "^0.98.0-beta.2"
"@polkadot/keyring" "^1.7.1"
"@polkadot/metadata" "^0.98.0-beta.1"
"@polkadot/rpc-core" "^0.98.0-beta.1"
"@polkadot/rpc-provider" "^0.98.0-beta.1"
"@polkadot/types" "^0.98.0-beta.1"
"@polkadot/metadata" "^0.98.0-beta.2"
"@polkadot/rpc-core" "^0.98.0-beta.2"
"@polkadot/rpc-provider" "^0.98.0-beta.2"
"@polkadot/types" "^0.98.0-beta.2"
"@polkadot/util-crypto" "^1.7.1"
"@polkadot/dev-react@^0.32.0-beta.15":
@ -2161,10 +2161,10 @@
dependencies:
"@babel/runtime" "^7.7.4"
"@polkadot/jsonrpc@^0.98.0-beta.1":
version "0.98.0-beta.1"
resolved "https://registry.yarnpkg.com/@polkadot/jsonrpc/-/jsonrpc-0.98.0-beta.1.tgz#8c0a09b94d9fa432e64ec08bc52ca5db9ba8fd4b"
integrity sha512-dhFECHZq0vE1orTxxQ0yfkj+9goH1bFzVSWoNIt6UW4JSaOsKhTmMX3zjGxOBkzl88dOgMzaqF9HE4Vp3Ghyiw==
"@polkadot/jsonrpc@^0.98.0-beta.2":
version "0.98.0-beta.2"
resolved "https://registry.yarnpkg.com/@polkadot/jsonrpc/-/jsonrpc-0.98.0-beta.2.tgz#6ede1e788bd56cee980c1db35f1af0b80853040b"
integrity sha512-kAqvjkcLWvZJ/lO3LbsYkOz+ItsIeWZhS3Hzd+dCSTdTcapOXpKTVWP7Miwk1lg+xtyYlHzaFWn8Jdi0m6jl1w==
dependencies:
"@babel/runtime" "^7.7.4"
@ -2177,13 +2177,13 @@
"@polkadot/util" "^1.7.1"
"@polkadot/util-crypto" "^1.7.1"
"@polkadot/metadata@^0.98.0-beta.1":
version "0.98.0-beta.1"
resolved "https://registry.yarnpkg.com/@polkadot/metadata/-/metadata-0.98.0-beta.1.tgz#3491cc376b0a466423315c4f18f1bc38853db0be"
integrity sha512-233F/gFt+kv1Fm43TvUHHVYk/WcknBBUmBSQ015rX/wyLtrxl0lCEUrPe5mGrTrhSxzhjDRLt2KPUAAA1RDVjg==
"@polkadot/metadata@^0.98.0-beta.2":
version "0.98.0-beta.2"
resolved "https://registry.yarnpkg.com/@polkadot/metadata/-/metadata-0.98.0-beta.2.tgz#2660d6d28371cd15cfd431d231b973a8922fdd46"
integrity sha512-uneR572tQb62OxoL1K2hQRDpjuasT52LRrRY8bBfkPC9O4gcMEslHUtUlEIHbqyAloYCAhoNpKAY5dxlFELjEQ==
dependencies:
"@babel/runtime" "^7.7.4"
"@polkadot/types" "^0.98.0-beta.1"
"@polkadot/types" "^0.98.0-beta.2"
"@polkadot/util" "^1.7.1"
"@polkadot/util-crypto" "^1.7.1"
@ -2212,25 +2212,25 @@
qrcode-generator "^1.4.4"
react-qr-reader "^2.2.1"
"@polkadot/rpc-core@^0.98.0-beta.1":
version "0.98.0-beta.1"
resolved "https://registry.yarnpkg.com/@polkadot/rpc-core/-/rpc-core-0.98.0-beta.1.tgz#211838c2566771556a368fba0a0aaa52f9efefa9"
integrity sha512-e0dtdg08Yl3uJ1G9QoWj4h5zyQ1v5CY4+SEWryk5WaXUGcUCaHWBI30pi/8vD6KZ8S2p51+MsZ1x5kOLlFskRg==
"@polkadot/rpc-core@^0.98.0-beta.2":
version "0.98.0-beta.2"
resolved "https://registry.yarnpkg.com/@polkadot/rpc-core/-/rpc-core-0.98.0-beta.2.tgz#8900d6f8120d286ebccf9e3d94e1ee3fb0106edd"
integrity sha512-zZcutXF2RGrnsbg3Eg68S4d0lYQYEYgqGnKp8pEhlPnnmRbniat9E9veYa2UIjh7XrJ4vHsy0zbkbQe2aduWAg==
dependencies:
"@babel/runtime" "^7.7.4"
"@polkadot/jsonrpc" "^0.98.0-beta.1"
"@polkadot/rpc-provider" "^0.98.0-beta.1"
"@polkadot/types" "^0.98.0-beta.1"
"@polkadot/jsonrpc" "^0.98.0-beta.2"
"@polkadot/rpc-provider" "^0.98.0-beta.2"
"@polkadot/types" "^0.98.0-beta.2"
"@polkadot/util" "^1.7.1"
rxjs "^6.5.3"
"@polkadot/rpc-provider@^0.98.0-beta.1":
version "0.98.0-beta.1"
resolved "https://registry.yarnpkg.com/@polkadot/rpc-provider/-/rpc-provider-0.98.0-beta.1.tgz#d3f45ddc5d98213cc2b7ba146ae693a23b758eb7"
integrity sha512-JtoqWDesXQQaIw8I0BNvo15/BR/yNOZLBaAxfMV+wgppaAlPBTjm/YmALsd36KG7a68XqaOV6cua4Gqc3d7QRw==
"@polkadot/rpc-provider@^0.98.0-beta.2":
version "0.98.0-beta.2"
resolved "https://registry.yarnpkg.com/@polkadot/rpc-provider/-/rpc-provider-0.98.0-beta.2.tgz#d5edd198cc60d2244df42e6adcf86a6fb37d6bd0"
integrity sha512-bUM+9Vez/dV9sL8PPOEddgmMs9XLVQTcSF8hoFDlT8Y3d4ARHGwQDhTTngZw1p9cNYMKVqi9f4AwPL4rGpUm3w==
dependencies:
"@babel/runtime" "^7.7.4"
"@polkadot/metadata" "^0.98.0-beta.1"
"@polkadot/metadata" "^0.98.0-beta.2"
"@polkadot/util" "^1.7.1"
"@polkadot/util-crypto" "^1.7.1"
eventemitter3 "^4.0.0"
@ -2244,10 +2244,10 @@
dependencies:
"@types/chrome" "^0.0.91"
"@polkadot/types@^0.98.0-beta.1":
version "0.98.0-beta.1"
resolved "https://registry.yarnpkg.com/@polkadot/types/-/types-0.98.0-beta.1.tgz#01f6e9f896a6e7224bc0f269df445ea561149de5"
integrity sha512-9vCaK/gdbfs1ABAaAhrcFDrTVhUXLqwdZ/JlJiPxiI7o1Ful+SYO4f0jOpsX8RMsbA6ErwmbFYdvW+bNvgmdCA==
"@polkadot/types@^0.98.0-beta.2":
version "0.98.0-beta.2"
resolved "https://registry.yarnpkg.com/@polkadot/types/-/types-0.98.0-beta.2.tgz#1fd5d987944c7ea7918b521c4d2bdea9c7eebf87"
integrity sha512-qHqT7vJcjTRZjkQhfIb+13oDNQRWB63MSPCvcy6VTdEvz233wSxsdFNCYVSo1hQfSBS4O2mtZghE7+MWjR7suw==
dependencies:
"@babel/runtime" "^7.7.4"
"@polkadot/util" "^1.7.1"