From 20a0283380e6c3dece4ee5c73b062a7c87fb7b28 Mon Sep 17 00:00:00 2001 From: Daniel Maricic Date: Tue, 31 Mar 2020 16:14:48 +0200 Subject: [PATCH] Add prettier and format the code (#242) * prettier * linter * add prettier, and format the code * make the travis pass Signed-off-by: Daniel Maricic * travis to make a build Signed-off-by: Daniel Maricic * tslint and prettier + travis Signed-off-by: Daniel Maricic * useless setting, we use spaces Signed-off-by: Daniel Maricic * backend tests added to the travis Signed-off-by: Daniel Maricic --- .travis.yml | 4 +- package.json | 2 + packages/frontend/.prettierrc | 4 + packages/frontend/package.json | 22 +- packages/frontend/src/AfgHandling.ts | 99 ++- packages/frontend/src/App.tsx | 73 +- packages/frontend/src/Connection.ts | 120 ++- packages/frontend/src/components/Ago.tsx | 24 +- .../frontend/src/components/AllChains.css | 14 +- .../frontend/src/components/AllChains.tsx | 26 +- .../frontend/src/components/Chain/Chain.css | 4 +- .../frontend/src/components/Chain/Chain.tsx | 66 +- .../frontend/src/components/Chain/Tab.css | 6 +- .../frontend/src/components/Chain/Tab.tsx | 2 +- packages/frontend/src/components/Chains.css | 17 +- packages/frontend/src/components/Chains.tsx | 36 +- .../src/components/Consensus/Consensus.css | 8 +- .../src/components/Consensus/Consensus.tsx | 312 +++++--- .../components/Consensus/ConsensusBlock.css | 9 +- .../components/Consensus/ConsensusBlock.tsx | 284 ++++--- .../src/components/Consensus/Jdenticon.tsx | 20 +- packages/frontend/src/components/Filter.css | 2 +- packages/frontend/src/components/Filter.tsx | 36 +- packages/frontend/src/components/Icon.css | 18 +- packages/frontend/src/components/Icon.tsx | 20 +- .../frontend/src/components/List/Column.tsx | 222 ++++-- .../src/components/List/HeaderCell.tsx | 28 +- .../frontend/src/components/List/List.tsx | 41 +- packages/frontend/src/components/List/Row.css | 15 +- packages/frontend/src/components/List/Row.tsx | 40 +- .../frontend/src/components/List/Truncate.tsx | 12 +- .../frontend/src/components/Map/Location.css | 9 +- .../frontend/src/components/Map/Location.tsx | 81 +- packages/frontend/src/components/Map/Map.tsx | 30 +- .../src/components/OfflineIndicator.css | 2 +- .../src/components/OfflineIndicator.tsx | 12 +- .../frontend/src/components/PolkadotIcon.tsx | 132 ++-- .../src/components/Settings/Setting.css | 6 +- .../src/components/Settings/Setting.tsx | 4 +- .../src/components/Settings/Settings.tsx | 23 +- .../frontend/src/components/Sparkline.tsx | 34 +- packages/frontend/src/components/Tile.css | 6 +- packages/frontend/src/components/Tile.tsx | 6 +- packages/frontend/src/components/Tooltip.css | 2 +- packages/frontend/src/components/Tooltip.tsx | 14 +- packages/frontend/src/icons/assets.d.ts | 2 +- packages/frontend/src/index.tsx | 5 +- packages/frontend/src/persist/Persistent.ts | 13 +- .../frontend/src/persist/PersistentSet.ts | 4 +- .../frontend/src/registerServiceWorker.ts | 2 +- packages/frontend/src/state.ts | 20 +- packages/frontend/src/utils.ts | 32 +- packages/frontend/tslint.json | 16 +- yarn.lock | 694 +++++++++++++++++- 54 files changed, 2043 insertions(+), 692 deletions(-) create mode 100644 packages/frontend/.prettierrc diff --git a/.travis.yml b/.travis.yml index bbef02b..7c9e79e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,10 +28,8 @@ before_script: - if [ $TRAVIS_RUST_VERSION = $CLIPPY_TOOLCHAIN ]; then rustup component add clippy-preview --toolchain=$CLIPPY_TOOLCHAIN; fi - curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh -s -- -f -script: ./test.sh - script: - yarn + - yarn check:all - yarn build:all - - yarn test - cd backend && cargo test diff --git a/package.json b/package.json index cdcd944..edef960 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,8 @@ "scripts": { "deploy": "scripts/deploy.sh", "build:all": "scripts/build-all.sh", + "check:frontend": "cd packages/frontend; yarn pretty:check", + "check:all": "yarn check:common && yarn check:frontend", "start:frontend": "scripts/start-frontend.sh", "build:frontend": "scripts/build-frontend.sh", "build:common": "tsc -p packages/common", diff --git a/packages/frontend/.prettierrc b/packages/frontend/.prettierrc new file mode 100644 index 0000000..650cb88 --- /dev/null +++ b/packages/frontend/.prettierrc @@ -0,0 +1,4 @@ +{ + "singleQuote": true, + "semi": true +} diff --git a/packages/frontend/package.json b/packages/frontend/package.json index d2ff07f..372791b 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -20,21 +20,27 @@ }, "dependencies": { "@fnando/sparkline": "maciejhirsz/sparkline", - "@types/react-measure": "^2.0.5", "@polkadot/util-crypto": "^1.6.1", + "@types/react-measure": "^2.0.5", + "blakejs": "^1.1.0", + "husky": "^4.2.3", + "lint-staged": "^10.1.0", "react": "16.4.0", "react-dom": "16.4.2", "react-measure": "^2.3.0", "react-scripts-ts": "2.17.0", "react-svg": "^4.1.1", "stable": "^0.1.8", - "blakejs": "^1.1.0" + "tslint": "^6.1.0" }, "scripts": { + "precommit": "lint-staged", "start": "react-scripts-ts start", "build": "react-scripts-ts build", "test": "echo 'FIXME: FE tests need updating'", - "eject": "react-scripts-ts eject" + "eject": "react-scripts-ts eject", + "pretty:check": "prettier --check src/**/*.{ts,tsx}", + "pretty:fix": "prettier --write src" }, "devDependencies": { "@types/jest": "^23.0.2", @@ -52,6 +58,14 @@ "mock-socket": "^8.0.2", "react-test-renderer": "^16.5.2", "ts-jest": "^23.10.2", + "tslint-config-prettier": "^1.18.0", + "prettier": "^2.0.2", + "tslint-plugin-prettier": "^2.3.0", "typescript": "^2.9.2" + }, + "lint-staged": { + "src/**/*.{ts,tsx,json,css}": [ + "pretty:fix" + ] } -} +} \ No newline at end of file diff --git a/packages/frontend/src/AfgHandling.ts b/packages/frontend/src/AfgHandling.ts index 635baef..0f1c162 100644 --- a/packages/frontend/src/AfgHandling.ts +++ b/packages/frontend/src/AfgHandling.ts @@ -8,19 +8,19 @@ export class AfgHandling { private updateState: UpdateBound; private getState: () => Readonly; - constructor( - updateState: UpdateBound, - getState: () => Readonly, - ) { + constructor(updateState: UpdateBound, getState: () => Readonly) { this.updateState = updateState; this.getState = getState; } public receivedAuthoritySet( authoritySetId: Types.AuthoritySetId, - authorities: Types.Authorities, + authorities: Types.Authorities ) { - if (this.getState().authoritySetId != null && authoritySetId !== this.getState().authoritySetId) { + if ( + this.getState().authoritySetId != null && + authoritySetId !== this.getState().authoritySetId + ) { // the visualization is restarted when we receive a new auhority set this.updateState({ authoritySetId, @@ -43,12 +43,12 @@ export class AfgHandling { public receivedFinalized( addr: Types.Address, finalizedNumber: Types.BlockNumber, - finalizedHash: Types.BlockHash, + finalizedHash: Types.BlockHash ) { const state = this.getState(); if (finalizedNumber < state.best - BLOCKS_LIMIT) { return; - }; + } const data = { Finalized: true, @@ -62,15 +62,26 @@ export class AfgHandling { Prevote: true, Precommit: true, } as Types.ConsensusDetail; - this.initialiseConsensusView(state.consensusInfo, finalizedNumber, addr, addr); + this.initialiseConsensusView( + state.consensusInfo, + finalizedNumber, + addr, + addr + ); - this.updateConsensusInfo(state.consensusInfo, finalizedNumber, addr, addr, data as Partial); + this.updateConsensusInfo( + state.consensusInfo, + finalizedNumber, + addr, + addr, + data as Partial + ); // Finalizing a block implicitly includes finalizing all // preceding blocks. This function marks the preceding // blocks as implicitly finalized on and stores a pointer // to the block which contains the explicit finalization. - const op = (i: Types.BlockNumber, index: number) : boolean => { + const op = (i: Types.BlockNumber, index: number): boolean => { const consensusDetail = state.consensusInfo[index][1][addr][addr]; if (consensusDetail.Finalized || consensusDetail.ImplicitFinalized) { return false; @@ -96,7 +107,7 @@ export class AfgHandling { this.backfill(state.consensusInfo, finalizedNumber, op, addr, addr); this.pruneBlocks(state.consensusInfo); - this.updateState({consensusInfo: state.consensusInfo}); + this.updateState({ consensusInfo: state.consensusInfo }); } public receivedPre( @@ -104,37 +115,48 @@ export class AfgHandling { height: Types.BlockNumber, hash: Types.BlockHash, voter: Types.Address, - what: string, + what: string ) { const state = this.getState(); if (height < state.best - BLOCKS_LIMIT) { return; - }; + } - const data = what === "prevote" ? { Prevote: true } : { Precommit: true }; + const data = what === 'prevote' ? { Prevote: true } : { Precommit: true }; this.initialiseConsensusView(state.consensusInfo, height, addr, voter); - this.updateConsensusInfo(state.consensusInfo, height, addr, voter, data as Partial); + this.updateConsensusInfo( + state.consensusInfo, + height, + addr, + voter, + data as Partial + ); // A Prevote or Precommit on a block implicitly includes // a vote on all preceding blocks. This function marks // the preceding blocks as implicitly voted on and stores // a pointer to the block which contains the explicit vote. - const op = (i: Types.BlockNumber, index: number) : boolean => { + const op = (i: Types.BlockNumber, index: number): boolean => { const consensusDetail = state.consensusInfo[index][1][addr][voter]; - if (what === "prevote" && (consensusDetail.Prevote || consensusDetail.ImplicitPrevote)) { + if ( + what === 'prevote' && + (consensusDetail.Prevote || consensusDetail.ImplicitPrevote) + ) { return false; } - if (what === "precommit" && (consensusDetail.Precommit || consensusDetail.ImplicitPrecommit) - - // because of extrapolation a prevote needs to be set as well. - // if it is not we continue backfilling (and set it during that process). - && (consensusDetail.Prevote || consensusDetail.ImplicitPrevote)) { + if ( + what === 'precommit' && + (consensusDetail.Precommit || consensusDetail.ImplicitPrecommit) && + // because of extrapolation a prevote needs to be set as well. + // if it is not we continue backfilling (and set it during that process). + (consensusDetail.Prevote || consensusDetail.ImplicitPrevote) + ) { return false; } - if (what === "prevote") { + if (what === 'prevote') { consensusInfo[index][1][addr][voter].ImplicitPrevote = true; - } else if (what === "precommit") { + } else if (what === 'precommit') { consensusInfo[index][1][addr][voter].ImplicitPrecommit = true; // Extrapolate. Precommit implies Prevote. @@ -147,7 +169,7 @@ export class AfgHandling { this.backfill(consensusInfo, height, op, addr, voter); this.pruneBlocks(consensusInfo); - this.updateState({consensusInfo}); + this.updateState({ consensusInfo }); } // Initializes the `ConsensusView` with empty objects. @@ -155,10 +177,9 @@ export class AfgHandling { consensusInfo: Types.ConsensusInfo, height: Types.BlockNumber, own: Types.Address, - other: Types.Address, + other: Types.Address ) { - const found = - consensusInfo.find(([blockNumber,]) => blockNumber === height); + const found = consensusInfo.find(([blockNumber]) => blockNumber === height); let consensusView; if (found) { @@ -170,7 +191,9 @@ export class AfgHandling { this.initialiseConsensusViewByRef(consensusView, own, other); const item: Types.ConsensusItem = [height, consensusView]; - const insertPos = consensusInfo.findIndex(([elHeight, elView]) => elHeight < height); + const insertPos = consensusInfo.findIndex( + ([elHeight, elView]) => elHeight < height + ); if (insertPos >= 0) { consensusInfo.splice(insertPos, 0, item); } else { @@ -183,7 +206,7 @@ export class AfgHandling { private initialiseConsensusViewByRef( consensusView: Types.ConsensusView, own: Types.Address, - other: Types.Address, + other: Types.Address ) { if (!consensusView[own]) { consensusView[own] = {} as Types.ConsensusState; @@ -204,7 +227,7 @@ export class AfgHandling { start: Types.BlockNumber, f: (i: Types.BlockNumber, index: number) => boolean, own: Types.Address, - other: Types.Address, + other: Types.Address ) { // if this is the first block then we don't fill latter blocks // if there is only one block, then it also doesn't make @@ -241,8 +264,9 @@ export class AfgHandling { const startBlockNumber = start as Types.BlockNumber; this.initialiseConsensusView(consensusInfo, startBlockNumber, own, other); - const index = - consensusInfo.findIndex(([blockNumber,]) => blockNumber === start); + const index = consensusInfo.findIndex( + ([blockNumber]) => blockNumber === start + ); const cont = f(start, index); if (!cont) { break; @@ -261,10 +285,11 @@ export class AfgHandling { height: Types.BlockNumber, addr: Types.Address, voter: Types.Address, - data: Partial, + data: Partial ) { - const found = - consensusInfo.findIndex(([blockNumber,]) => blockNumber === height); + const found = consensusInfo.findIndex( + ([blockNumber]) => blockNumber === height + ); if (found < 0) { return; } diff --git a/packages/frontend/src/App.tsx b/packages/frontend/src/App.tsx index b7dfcd2..a505355 100644 --- a/packages/frontend/src/App.tsx +++ b/packages/frontend/src/App.tsx @@ -52,8 +52,8 @@ export default class App extends React.Component<{}, State> { const selectedColumns = this.selectedColumns(settings); this.sortBy.set(null); - this.setState({ settings, selectedColumns, sortBy: null }) - }, + this.setState({ settings, selectedColumns, sortBy: null }); + } ); this.pins = new PersistentSet('pinned_names', (pins) => { @@ -105,7 +105,7 @@ export default class App extends React.Component<{}, State> { return this.state; }); - setInterval(() => this.chainsCache = [], 10000); // Wipe sorted chains cache every 10 seconds + setInterval(() => (this.chainsCache = []), 10000); // Wipe sorted chains cache every 10 seconds } public render() { @@ -123,15 +123,30 @@ export default class App extends React.Component<{}, State> { ); } - const overlay = tab === 'all-chains' - ? - : null; + const overlay = + tab === 'all-chains' ? ( + + ) : null; return (
- - + + {overlay}
); @@ -148,7 +163,8 @@ export default class App extends React.Component<{}, State> { } private onKeyPress = (event: KeyboardEvent) => { - if (event.keyCode !== 9) { // TAB KEY + if (event.keyCode !== 9) { + // TAB KEY return; } @@ -170,41 +186,42 @@ export default class App extends React.Component<{}, State> { this.connection.then((connection) => { connection.subscribe(chains[index]); - }) - } + }); + }; private onHashChange = (event: Event) => { const { tab = '' } = getHashData(); this.setState({ tab }); - } + }; private chains(): ChainData[] { if (this.chainsCache.length === this.state.chains.size) { return this.chainsCache; } - this.chainsCache = stable - .inplace( - Array.from(this.state.chains.values()), - (a, b) => { - if (a.label === PINNED_CHAIN) { - return -1; - } - - if (b.label === PINNED_CHAIN) { - return 1; - } - - return b.nodeCount - a.nodeCount; + this.chainsCache = stable.inplace( + Array.from(this.state.chains.values()), + (a, b) => { + if (a.label === PINNED_CHAIN) { + return -1; } - ); + + if (b.label === PINNED_CHAIN) { + return 1; + } + + return b.nodeCount - a.nodeCount; + } + ); return this.chainsCache; } private selectedColumns(settings: State.Settings): Column[] { - return Row.columns.filter(({ setting }) => setting == null || settings[setting]); + return Row.columns.filter( + ({ setting }) => setting == null || settings[setting] + ); } private getComparator(sortBy: Maybe): Compare { @@ -228,7 +245,7 @@ export default class App extends React.Component<{}, State> { } else { return Node.compare(a, b); } - } + }; } } diff --git a/packages/frontend/src/Connection.ts b/packages/frontend/src/Connection.ts index ff8e454..fd4124e 100644 --- a/packages/frontend/src/Connection.ts +++ b/packages/frontend/src/Connection.ts @@ -1,5 +1,19 @@ -import { VERSION, timestamp, FeedMessage, Types, Maybe, sleep } from '@dotstats/common'; -import { State, Update, Node, UpdateBound, ChainData, PINNED_CHAIN } from './state'; +import { + VERSION, + timestamp, + FeedMessage, + Types, + Maybe, + sleep, +} from '@dotstats/common'; +import { + State, + Update, + Node, + UpdateBound, + ChainData, + PINNED_CHAIN, +} from './state'; import { PersistentSet } from './persist'; import { getHashData, setHashData } from './utils'; import { AfgHandling } from './AfgHandling'; @@ -12,15 +26,19 @@ const TIMEOUT_BASE = (1000 * 5) as Types.Milliseconds; // 5 seconds const TIMEOUT_MAX = (1000 * 60 * 5) as Types.Milliseconds; // 5 minutes export class Connection { - public static async create(pins: PersistentSet, update: Update): Promise { + public static async create( + pins: PersistentSet, + update: Update + ): Promise { return new Connection(await Connection.socket(), update, pins); } private static readonly utf8decoder = new TextDecoder('utf-8'); - private static readonly address = window.location.protocol === 'https:' - ? `wss://${window.location.hostname}/feed/` - : `ws://127.0.0.1:8000/feed`; + private static readonly address = + window.location.protocol === 'https:' + ? `wss://${window.location.hostname}/feed/` + : `ws://127.0.0.1:8000/feed`; // private static readonly address = 'wss://telemetry.polkadot.io/feed/'; @@ -58,7 +76,7 @@ export class Connection { const socket = new WebSocket(Connection.address); - socket.binaryType = "arraybuffer"; + socket.binaryType = 'arraybuffer'; socket.addEventListener('open', onSuccess); socket.addEventListener('error', onFailure); socket.addEventListener('close', onFailure); @@ -75,7 +93,11 @@ export class Connection { private readonly update: Update; private readonly pins: PersistentSet; - constructor(socket: WebSocket, update: Update, pins: PersistentSet) { + constructor( + socket: WebSocket, + update: Update, + pins: PersistentSet + ) { this.socket = socket; this.update = update; this.pins = pins; @@ -97,7 +119,7 @@ export class Connection { public subscribeConsensus(chain: Types.ChainLabel) { if (this.state.authorities.length <= VIS_AUTHORITIES_LIMIT) { - setHashData({chain}); + setHashData({ chain }); this.resubscribeSendFinality = true; this.socket.send(`send-finality:${chain}`); } @@ -121,14 +143,17 @@ export class Connection { const { nodes, chains, sortBy, selectedColumns } = this.state; const ref = nodes.ref(); - const updateState: UpdateBound = (state) => { this.state = this.update(state); }; + const updateState: UpdateBound = (state) => { + this.state = this.update(state); + }; const getState = () => this.state; const afg = new AfgHandling(updateState, getState); let sortByColumn: Maybe = null; if (sortBy != null) { - sortByColumn = sortBy < 0 ? selectedColumns[~sortBy] : selectedColumns[sortBy]; + sortByColumn = + sortBy < 0 ? selectedColumns[~sortBy] : selectedColumns[sortBy]; } for (const message of messages) { @@ -166,9 +191,28 @@ export class Connection { } case Actions.AddedNode: { - const [id, nodeDetails, nodeStats, nodeIO, nodeHardware, blockDetails, location, connectedAt] = message.payload; + const [ + id, + nodeDetails, + nodeStats, + nodeIO, + nodeHardware, + blockDetails, + location, + connectedAt, + ] = message.payload; const pinned = this.pins.has(nodeDetails[0]); - const node = new Node(pinned, id, nodeDetails, nodeStats, nodeIO, nodeHardware, blockDetails, location, connectedAt); + const node = new Node( + pinned, + id, + nodeDetails, + nodeStats, + nodeIO, + nodeHardware, + blockDetails, + location, + connectedAt + ); nodes.add(node); @@ -194,7 +238,11 @@ export class Connection { case Actions.LocatedNode: { const [id, lat, lon, city] = message.payload; - nodes.mutAndMaybeSort(id, (node) => node.updateLocation([lat, lon, city]), sortByColumn === Column.LOCATION); + nodes.mutAndMaybeSort( + id, + (node) => node.updateLocation([lat, lon, city]), + sortByColumn === Column.LOCATION + ); break; } @@ -213,7 +261,8 @@ export class Connection { nodes.mutAndMaybeSort( id, (node) => node.updateFinalized(height, hash), - sortByColumn === Column.FINALIZED || sortByColumn === Column.FINALIZED_HASH, + sortByColumn === Column.FINALIZED || + sortByColumn === Column.FINALIZED_HASH ); break; @@ -225,7 +274,7 @@ export class Connection { nodes.mutAndMaybeSort( id, (node) => node.updateStats(nodeStats), - sortByColumn === Column.PEERS || sortByColumn === Column.TXS, + sortByColumn === Column.PEERS || sortByColumn === Column.TXS ); break; @@ -237,10 +286,10 @@ export class Connection { nodes.mutAndMaybeSort( id, (node) => node.updateHardware(nodeHardware), - sortByColumn === Column.CPU - || sortByColumn === Column.MEM - || sortByColumn === Column.UPLOAD - || sortByColumn === Column.DOWNLOAD, + sortByColumn === Column.CPU || + sortByColumn === Column.MEM || + sortByColumn === Column.UPLOAD || + sortByColumn === Column.DOWNLOAD ); break; @@ -252,10 +301,10 @@ export class Connection { nodes.mutAndMaybeSort( id, (node) => node.updateIO(nodeIO), - sortByColumn === Column.STATE_CACHE - || sortByColumn === Column.DB_CACHE - || sortByColumn === Column.DISK_READ - || sortByColumn === Column.DISK_WRITE, + sortByColumn === Column.STATE_CACHE || + sortByColumn === Column.DB_CACHE || + sortByColumn === Column.DISK_READ || + sortByColumn === Column.DISK_WRITE ); break; @@ -263,7 +312,7 @@ export class Connection { case Actions.TimeSync: { this.state = this.update({ - timeDiff: (timestamp() - message.payload) as Types.Milliseconds + timeDiff: (timestamp() - message.payload) as Types.Milliseconds, }); break; @@ -331,7 +380,7 @@ export class Connection { case Actions.AfgReceivedPrevote: { const [nodeAddress, blockNumber, blockHash, voter] = message.payload; const no = parseInt(String(blockNumber), 10) as Types.BlockNumber; - afg.receivedPre(nodeAddress, no, blockHash, voter, "prevote"); + afg.receivedPre(nodeAddress, no, blockHash, voter, 'prevote'); break; } @@ -339,7 +388,7 @@ export class Connection { case Actions.AfgReceivedPrecommit: { const [nodeAddress, blockNumber, blockHash, voter] = message.payload; const no = parseInt(String(blockNumber), 10) as Types.BlockNumber; - afg.receivedPre(nodeAddress, no, blockHash, voter, "precommit"); + afg.receivedPre(nodeAddress, no, blockHash, voter, 'precommit'); break; } @@ -362,7 +411,7 @@ export class Connection { } this.autoSubscribe(); - } + }; private bindSocket() { this.ping(); @@ -398,7 +447,7 @@ export class Connection { this.socket.send(`ping:${this.pingId}`); this.pingTimeout = setTimeout(this.ping, 30000); - } + }; private pong(id: number) { if (!this.pingSent) { @@ -430,12 +479,15 @@ export class Connection { } private handleFeedData = (event: MessageEvent) => { - const data = typeof event.data === 'string' - ? event.data as any as FeedMessage.Data - : Connection.utf8decoder.decode(event.data) as any as FeedMessage.Data; + const data = + typeof event.data === 'string' + ? ((event.data as any) as FeedMessage.Data) + : ((Connection.utf8decoder.decode( + event.data + ) as any) as FeedMessage.Data); this.handleMessages(FeedMessage.deserialize(data)); - } + }; private autoSubscribe() { const { subscribed, chains } = this.state; @@ -480,5 +532,5 @@ export class Connection { this.socket.close(); this.socket = await Connection.socket(); this.bindSocket(); - } + }; } diff --git a/packages/frontend/src/components/Ago.tsx b/packages/frontend/src/components/Ago.tsx index b9b4344..68ac94e 100644 --- a/packages/frontend/src/components/Ago.tsx +++ b/packages/frontend/src/components/Ago.tsx @@ -4,12 +4,12 @@ import { timestamp, Types } from '@dotstats/common'; export namespace Ago { export interface Props { - when: Types.Timestamp, - justTime?: boolean, + when: Types.Timestamp; + justTime?: boolean; } export interface State { - now: Types.Timestamp, + now: Types.Timestamp; } } @@ -29,7 +29,7 @@ tick(); export namespace Ago { export interface State { - now: Types.Timestamp + now: Types.Timestamp; } } @@ -42,16 +42,16 @@ export class Ago extends React.Component { super(props); this.state = { - now: (timestamp() - Ago.timeDiff) as Types.Timestamp + now: (timestamp() - Ago.timeDiff) as Types.Timestamp, }; } public componentWillMount() { tickers.set(this, (now) => { this.setState({ - now: (now - Ago.timeDiff) as Types.Timestamp + now: (now - Ago.timeDiff) as Types.Timestamp, }); - }) + }); } public componentWillUnmount() { @@ -72,17 +72,19 @@ export class Ago extends React.Component { } else if (ago < 60) { agoStr = `${ago | 0}s`; } else if (ago < 3600) { - agoStr = `${ ago / 60 | 0}m`; + agoStr = `${(ago / 60) | 0}m`; } else if (ago < 3600 * 24) { - agoStr = `${ ago / 3600 | 0}h`; + agoStr = `${(ago / 3600) | 0}h`; } else { - agoStr = `${ ago / (3600 * 24) | 0}d`; + agoStr = `${(ago / (3600 * 24)) | 0}d`; } if (this.props.justTime !== true) { agoStr += ' ago'; } - return {agoStr} + return ( + {agoStr} + ); } } diff --git a/packages/frontend/src/components/AllChains.css b/packages/frontend/src/components/AllChains.css index 176ed0d..6eab244 100644 --- a/packages/frontend/src/components/AllChains.css +++ b/packages/frontend/src/components/AllChains.css @@ -8,7 +8,7 @@ width: 25vw; min-width: 300px; background: #fff; - box-shadow: 0 2px 20px rgba(0,0,0,0.35); + box-shadow: 0 2px 20px rgba(0, 0, 0, 0.35); overflow-y: scroll; overflow-x: hide; } @@ -17,7 +17,7 @@ position: fixed; display: block; z-index: 19; - background: rgba(0,0,0,0.35); + background: rgba(0, 0, 0, 0.35); left: 0; right: 0; top: 0; @@ -26,10 +26,10 @@ .AllChains-chain { padding: 0 12px; - background: #B5AEAE; + background: #b5aeae; color: #444; display: block; - border-bottom: 1px solid rgba(255,255,255,0.5); + border-bottom: 1px solid rgba(255, 255, 255, 0.5); height: 40px; line-height: 40px; cursor: pointer; @@ -42,10 +42,10 @@ display: inline-block; padding: 0 0.5em 0.1em; border-radius: 1em; - background: #8C8787; + background: #8c8787; color: #fff; font-weight: normal; - text-shadow: rgba(0,0,0,0.5) 0 1px 0; + text-shadow: rgba(0, 0, 0, 0.5) 0 1px 0; font-size: 0.9em; line-height: 1.4em; margin: 0 -0.3em 0 0.3em; @@ -57,5 +57,5 @@ } .AllChains-chain-selected .AllChains-node-count { - background: #E6007A; + background: #e6007a; } diff --git a/packages/frontend/src/components/AllChains.tsx b/packages/frontend/src/components/AllChains.tsx index 6fb3e08..3b32743 100644 --- a/packages/frontend/src/components/AllChains.tsx +++ b/packages/frontend/src/components/AllChains.tsx @@ -7,9 +7,9 @@ import './AllChains.css'; export namespace AllChains { export interface Props { - chains: ChainData[], - subscribed: Maybe, - connection: Promise + chains: ChainData[]; + subscribed: Maybe; + connection: Promise; } } @@ -31,15 +31,23 @@ export class AllChains extends React.Component { private renderChain(chain: ChainData): React.ReactNode { const { label, nodeCount } = chain; - const className = label === this.props.subscribed - ? 'AllChains-chain AllChains-chain-selected' - : 'AllChains-chain'; + const className = + label === this.props.subscribed + ? 'AllChains-chain AllChains-chain-selected' + : 'AllChains-chain'; return ( - - {label} {nodeCount} + + {label}{' '} + + {nodeCount} + - ) + ); } private async subscribe(chain: Types.ChainLabel) { diff --git a/packages/frontend/src/components/Chain/Chain.css b/packages/frontend/src/components/Chain/Chain.css index a16d65f..fc2d243 100644 --- a/packages/frontend/src/components/Chain/Chain.css +++ b/packages/frontend/src/components/Chain/Chain.css @@ -28,7 +28,7 @@ width: 100%; min-width: 1350px; min-height: 100%; - background: #2C2B2B; + background: #2c2b2b; color: #fff; - box-shadow: rgba(0,0,0,0.5) 0 3px 30px; + box-shadow: rgba(0, 0, 0, 0.5) 0 3px 30px; } diff --git a/packages/frontend/src/components/Chain/Chain.tsx b/packages/frontend/src/components/Chain/Chain.tsx index 1d632f4..66e41f5 100644 --- a/packages/frontend/src/components/Chain/Chain.tsx +++ b/packages/frontend/src/components/Chain/Chain.tsx @@ -65,21 +65,57 @@ export class Chain extends React.Component { return (
- #{formatNumber(best)} - #{formatNumber(finalized)} - { blockAverage == null ? '-' : secondsWithPrecision(blockAverage / 1000) } - + + #{formatNumber(best)} + + + #{formatNumber(finalized)} + + + {blockAverage == null + ? '-' + : secondsWithPrecision(blockAverage / 1000)} + + + +
- - - - + + + +
-
- {this.renderContent()} -
+
{this.renderContent()}
); @@ -98,10 +134,10 @@ export class Chain extends React.Component { return ; } - return ( - display === 'list' - ? - : + return display === 'list' ? ( + + ) : ( + ); } diff --git a/packages/frontend/src/components/Chain/Tab.css b/packages/frontend/src/components/Chain/Tab.css index ea360fa..36c611e 100644 --- a/packages/frontend/src/components/Chain/Tab.css +++ b/packages/frontend/src/components/Chain/Tab.css @@ -1,4 +1,3 @@ - .Chain-Tab { display: inline-block; } @@ -18,7 +17,8 @@ background: #ccc; } -.Chain-Tab-on .Icon, .Chain-Tab-on:hover .Icon { - background: #E6007A; +.Chain-Tab-on .Icon, +.Chain-Tab-on:hover .Icon { + background: #e6007a; color: #fff; } diff --git a/packages/frontend/src/components/Chain/Tab.tsx b/packages/frontend/src/components/Chain/Tab.tsx index ce1e9db..814794e 100644 --- a/packages/frontend/src/components/Chain/Tab.tsx +++ b/packages/frontend/src/components/Chain/Tab.tsx @@ -33,5 +33,5 @@ export class Tab extends React.Component { const { tab, display, setDisplay } = this.props; setHashData({ tab }); setDisplay(display); - } + }; } diff --git a/packages/frontend/src/components/Chains.css b/packages/frontend/src/components/Chains.css index d6eced2..ee06e7d 100644 --- a/packages/frontend/src/components/Chains.css +++ b/packages/frontend/src/components/Chains.css @@ -1,5 +1,5 @@ .Chains { - background: #B5AEAE; + background: #b5aeae; color: #000; padding: 0 76px 0 16px; height: 40px; @@ -9,10 +9,10 @@ .Chains-chain { padding: 0 12px; - background: #B5AEAE; + background: #b5aeae; color: #444; display: inline-block; - border-right: 1px solid rgba(255,255,255,0.5); + border-right: 1px solid rgba(255, 255, 255, 0.5); height: 40px; line-height: 40px; cursor: pointer; @@ -22,7 +22,7 @@ } .Chains-chain:first-child { - border-left: 1px solid rgba(255,255,255,0.5); + border-left: 1px solid rgba(255, 255, 255, 0.5); } .Chains-all-chains { @@ -43,7 +43,8 @@ top: 6px; } -.Chains-all-chains .Icon, .Chains-fork-me .Icon { +.Chains-all-chains .Icon, +.Chains-fork-me .Icon { font-size: 28px; margin: 0; height: 28px; @@ -55,10 +56,10 @@ display: inline-block; padding: 0 0.5em 0.1em; border-radius: 1em; - background: #8C8787; + background: #8c8787; color: #fff; font-weight: normal; - text-shadow: rgba(0,0,0,0.5) 0 1px 0; + text-shadow: rgba(0, 0, 0, 0.5) 0 1px 0; font-size: 0.9em; line-height: 1.4em; margin: 0 -0.3em 0 0.3em; @@ -70,5 +71,5 @@ } .Chains-chain-selected .Chains-node-count { - background: #E6007A; + background: #e6007a; } diff --git a/packages/frontend/src/components/Chains.tsx b/packages/frontend/src/components/Chains.tsx index 2891d19..4dadc56 100644 --- a/packages/frontend/src/components/Chains.tsx +++ b/packages/frontend/src/components/Chains.tsx @@ -10,15 +10,17 @@ import './Chains.css'; export namespace Chains { export interface Props { - chains: ChainData[], - subscribed: Maybe, - connection: Promise + chains: ChainData[]; + subscribed: Maybe; + connection: Promise; } } export class Chains extends React.Component { public render() { - const allChainsHref = this.props.subscribed ? `#all-chains/${this.props.subscribed}` : `#all-chains`; + const allChainsHref = this.props.subscribed + ? `#all-chains/${this.props.subscribed}` + : `#all-chains`; const { chains } = this.props; return ( @@ -27,7 +29,11 @@ export class Chains extends React.Component { - + @@ -37,15 +43,23 @@ export class Chains extends React.Component { private renderChain(chain: ChainData): React.ReactNode { const { label, nodeCount } = chain; - const className = label === this.props.subscribed - ? 'Chains-chain Chains-chain-selected' - : 'Chains-chain'; + const className = + label === this.props.subscribed + ? 'Chains-chain Chains-chain-selected' + : 'Chains-chain'; return ( - - {label} {nodeCount} + + {label}{' '} + + {nodeCount} + - ) + ); } private async subscribe(chain: Types.ChainLabel) { diff --git a/packages/frontend/src/components/Consensus/Consensus.css b/packages/frontend/src/components/Consensus/Consensus.css index 6d256b1..60187cd 100644 --- a/packages/frontend/src/components/Consensus/Consensus.css +++ b/packages/frontend/src/components/Consensus/Consensus.css @@ -1,5 +1,5 @@ .Consensus .ConsensusList { - opacity: 0.0; /* the box should only show up once flexing has been applied */ + opacity: 0; /* the box should only show up once flexing has been applied */ } .Consensus .ConsensusList table { @@ -10,11 +10,11 @@ display: flex; align-items: stretch; flex-direction: row; - opacity: 1.0; + opacity: 1; } .Consensus .flexContainerLargeRow .firstInRow { - width: 100% + width: 100%; } .Consensus .flexContainerLargeRow .firstInRow .emptylegend, @@ -29,7 +29,7 @@ align-items: stretch; flex-direction: row; flex-wrap: wrap; - opacity: 1.0; + opacity: 1; } .Consensus .flexContainerSmallRow div { diff --git a/packages/frontend/src/components/Consensus/Consensus.tsx b/packages/frontend/src/components/Consensus/Consensus.tsx index 311258b..35dd8c8 100644 --- a/packages/frontend/src/components/Consensus/Consensus.tsx +++ b/packages/frontend/src/components/Consensus/Consensus.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { Types, Maybe } from '@dotstats/common'; import { Connection } from '../../Connection'; -import Measure, {BoundingRect, ContentRect} from 'react-measure'; +import Measure, { BoundingRect, ContentRect } from 'react-measure'; import { ConsensusBlock } from './'; import { State as AppState } from '../../state'; @@ -21,16 +21,16 @@ export namespace Consensus { export interface State { dimensions: BoundingRect; - largeBlockWithLegend: BoundingRect, - largeBlock: BoundingRect, - countBlocksInLargeRow: number, - largeRowsAddFlexClass: boolean, + largeBlockWithLegend: BoundingRect; + largeBlock: BoundingRect; + countBlocksInLargeRow: number; + largeRowsAddFlexClass: boolean; - smallBlock: BoundingRect, - smallBlocksRows: number, - countBlocksInSmallRow: number, - smallRowsAddFlexClass: boolean, - lastConsensusInfo: string, + smallBlock: BoundingRect; + smallBlocksRows: number; + countBlocksInSmallRow: number; + smallRowsAddFlexClass: boolean; + lastConsensusInfo: string; } } @@ -48,48 +48,59 @@ export class Consensus extends React.Component { smallBlocksRows: 1, countBlocksInSmallRow: 1, smallRowsAddFlexClass: false, - lastConsensusInfo: "", + lastConsensusInfo: '', }; - public shouldComponentUpdate(nextProps: Consensus.Props, nextState: Consensus.State): boolean { - if (this.props.appState.authorities.length === 0 && nextProps.appState.authorities.length === 0) { + public shouldComponentUpdate( + nextProps: Consensus.Props, + nextState: Consensus.State + ): boolean { + if ( + this.props.appState.authorities.length === 0 && + nextProps.appState.authorities.length === 0 + ) { return false; } this.calculateBoxCount(false); // size detected, but flex class has not yet been added - const largeBlocksSizeDetected = this.largeBlocksSizeDetected(nextState) === true && + const largeBlocksSizeDetected = + this.largeBlocksSizeDetected(nextState) === true && this.state.largeRowsAddFlexClass === false; if (largeBlocksSizeDetected) { return true; } - const smallBlocksSizeDetected = this.smallBlocksSizeDetected(nextState) === true && + const smallBlocksSizeDetected = + this.smallBlocksSizeDetected(nextState) === true && this.state.smallRowsAddFlexClass === false; if (smallBlocksSizeDetected) { return true; } - const windowSizeChanged = JSON.stringify(this.state.dimensions) !== + const windowSizeChanged = + JSON.stringify(this.state.dimensions) !== JSON.stringify(nextState.dimensions); if (windowSizeChanged) { return true; } - const newConsensusInfoAvailable = this.state.lastConsensusInfo !== + const newConsensusInfoAvailable = + this.state.lastConsensusInfo !== JSON.stringify(nextProps.appState.consensusInfo); if (newConsensusInfoAvailable) { return true; } - const authoritySetIdDidChange = this.props.appState.authoritySetId !== - nextProps.appState.authoritySetId; + const authoritySetIdDidChange = + this.props.appState.authoritySetId !== nextProps.appState.authoritySetId; if (authoritySetIdDidChange) { return true; } - const authoritiesDidChange = JSON.stringify(this.props.appState.authorities) !== + const authoritiesDidChange = + JSON.stringify(this.props.appState.authorities) !== JSON.stringify(nextProps.appState.authorities); if (authoritiesDidChange) { return true; @@ -123,70 +134,107 @@ export class Consensus extends React.Component { // if there is more than one block then the size of the first block (with legend) // will be different from the succeeding blocks (without legend) - return state.largeBlockWithLegend.width > -1 && state.largeBlockWithLegend.height > -1 && - state.largeBlock.width > -1 && state.largeBlock.height > -1; + return ( + state.largeBlockWithLegend.width > -1 && + state.largeBlockWithLegend.height > -1 && + state.largeBlock.width > -1 && + state.largeBlock.height > -1 + ); } public smallBlocksSizeDetected(state: Consensus.State): boolean { - return state.smallBlock.width > -1 && state.largeBlockWithLegend.height > -1; + return ( + state.smallBlock.width > -1 && state.largeBlockWithLegend.height > -1 + ); } public calculateBoxCount(wasResized: boolean) { // if the css class for flexing has already been added we don't calculate // any box measurements then, because the box sizes would be skewed then. - if ((wasResized || this.state.largeRowsAddFlexClass === false) && this.largeBlocksSizeDetected(this.state)) { + if ( + (wasResized || this.state.largeRowsAddFlexClass === false) && + this.largeBlocksSizeDetected(this.state) + ) { // we need to add +2 because of the last block which doesn't contain a border. - let countBlocks = (this.state.dimensions.width - this.state.largeBlockWithLegend.width + 2) / + let countBlocks = + (this.state.dimensions.width - + this.state.largeBlockWithLegend.width + + 2) / (this.state.largeBlock.width + 2); // +1 because the firstRect was subtracted above and needs to be counted back in. // default count is 2 because we need two blocks to measure properly (one with legend // and one without. these measures are necessary to calculate the number of blocks // which fit. - countBlocks = Math.floor(countBlocks + 1) < 1 ? 2 : Math.floor(countBlocks + 1); + countBlocks = + Math.floor(countBlocks + 1) < 1 ? 2 : Math.floor(countBlocks + 1); - this.setState({largeRowsAddFlexClass: true, countBlocksInLargeRow: countBlocks }); + this.setState({ + largeRowsAddFlexClass: true, + countBlocksInLargeRow: countBlocks, + }); } - if ((wasResized || this.state.smallRowsAddFlexClass === false) && this.smallBlocksSizeDetected(this.state)) { + if ( + (wasResized || this.state.smallRowsAddFlexClass === false) && + this.smallBlocksSizeDetected(this.state) + ) { const howManyRows = 2; - const heightLeft = this.state.dimensions.height - (this.state.largeBlock.height * howManyRows); + const heightLeft = + this.state.dimensions.height - + this.state.largeBlock.height * howManyRows; let smallBlocksRows = heightLeft / this.state.smallBlock.height; smallBlocksRows = smallBlocksRows < 1 ? 1 : Math.floor(smallBlocksRows); - let countBlocksInSmallRow = this.state.dimensions.width / this.state.smallBlock.width; - countBlocksInSmallRow = countBlocksInSmallRow < 1 ? 1 : Math.floor(countBlocksInSmallRow); + let countBlocksInSmallRow = + this.state.dimensions.width / this.state.smallBlock.width; + countBlocksInSmallRow = + countBlocksInSmallRow < 1 ? 1 : Math.floor(countBlocksInSmallRow); - this.setState({ smallRowsAddFlexClass: true, countBlocksInSmallRow, smallBlocksRows }); + this.setState({ + smallRowsAddFlexClass: true, + countBlocksInSmallRow, + smallBlocksRows, + }); } } public render() { - this.state.lastConsensusInfo = JSON.stringify(this.props.appState.consensusInfo); + this.state.lastConsensusInfo = JSON.stringify( + this.props.appState.consensusInfo + ); const lastBlocks = this.props.appState.consensusInfo; if (this.props.appState.authorities.length > VIS_AUTHORITIES_LIMIT) { - return
-
-

- Too many authorities.

-

- Won't display for more than {VIS_AUTHORITIES_LIMIT} authorities - to protect your browser. -

-
; -
; + return ( +
+
+

Too many authorities.

+

+ Won't display for more than {VIS_AUTHORITIES_LIMIT} authorities to + protect your browser. +

+
+ ; +
+ ); } - if (this.props.appState.displayConsensusLoadingScreen && lastBlocks.length < 2) { - return
-
- {lastBlocks.length === 0 ? "No " : "Not yet enough "} - GRANDPA data received by the authorities… -
; -
; + if ( + this.props.appState.displayConsensusLoadingScreen && + lastBlocks.length < 2 + ) { + return ( +
+
+ {lastBlocks.length === 0 ? 'No ' : 'Not yet enough '} + GRANDPA data received by the authorities… +
+ ; +
+ ); } let from = 0; @@ -198,26 +246,29 @@ export class Consensus extends React.Component { const secondLargeRow = this.getLargeRow(lastBlocks.slice(from, to), 1); from = to; - to = to + (this.state.smallBlocksRows * this.state.countBlocksInSmallRow); + to = to + this.state.smallBlocksRows * this.state.countBlocksInSmallRow; const smallRow = this.getSmallRow(lastBlocks.slice(from, to)); - const get = (measureRef: Maybe<(ref: Element | null) => void>) => + const get = (measureRef: Maybe<(ref: Element | null) => void>) => (
{firstLargeRow} {secondLargeRow} {smallRow} -
; + + ); - if (!(this.state.smallRowsAddFlexClass && this.state.largeRowsAddFlexClass)) { + if ( + !(this.state.smallRowsAddFlexClass && this.state.largeRowsAddFlexClass) + ) { return ( - {({measureRef}) => get(measureRef)} + {({ measureRef }) => get(measureRef)} ); } else { - return (get(null)); + return get(null); } } @@ -232,91 +283,132 @@ export class Consensus extends React.Component { return []; } - return this.props.appState.authorities.map(address => { - const node2 = this.props.appState.nodes.sorted().filter(node => node.validator === address)[0]; + return this.props.appState.authorities.map((address) => { + const node2 = this.props.appState.nodes + .sorted() + .filter((node) => node.validator === address)[0]; if (!node2) { - return {Address: address, NodeId: null, Name: null} as Types.Authority; + return { + Address: address, + NodeId: null, + Name: null, + } as Types.Authority; } - return {Address: address, NodeId: node2.id, Name: node2.name} as Types.Authority; + return { + Address: address, + NodeId: node2.id, + Name: node2.name, + } as Types.Authority; }); } private getLargeRow(blocks: Types.ConsensusInfo, id: number) { - const largeBlockSizeChanged = (isFirstBlock: boolean, rect: BoundingRect) => { + const largeBlockSizeChanged = ( + isFirstBlock: boolean, + rect: BoundingRect + ) => { if (this.largeBlocksSizeDetected(this.state)) { return; } if (isFirstBlock) { - this.setState({largeBlockWithLegend: {width: rect.width, height: rect.height} }); + this.setState({ + largeBlockWithLegend: { width: rect.width, height: rect.height }, + }); } else { - this.setState({largeBlock: {width: rect.width, height: rect.height} }); + this.setState({ + largeBlock: { width: rect.width, height: rect.height }, + }); } }; - const stretchLastRowMajor = blocks.length < this.state.countBlocksInLargeRow ? - 'noStretchOnLastRow' : ''; - const flexClass = this.state.largeRowsAddFlexClass ? 'flexContainerLargeRow' : ''; + const stretchLastRowMajor = + blocks.length < this.state.countBlocksInLargeRow + ? 'noStretchOnLastRow' + : ''; + const flexClass = this.state.largeRowsAddFlexClass + ? 'flexContainerLargeRow' + : ''; - return
+ key={`consensusList_${id}`} + > {blocks.map((item, i) => { - const [height, consensusView] = item; - return ; + const [height, consensusView] = item; + return ( + + ); })} -
; + + ); } private getSmallRow(blocks: Types.ConsensusInfo) { - const smallBlockSizeChanged = (isFirstBlock: boolean, rect: BoundingRect) => { + const smallBlockSizeChanged = ( + isFirstBlock: boolean, + rect: BoundingRect + ) => { if (this.smallBlocksSizeDetected(this.state)) { return; } - const dimensionsChanged = this.state.smallBlock.height !== rect.height && + const dimensionsChanged = + this.state.smallBlock.height !== rect.height && this.state.smallBlock.width !== rect.width; if (dimensionsChanged) { - this.setState({ smallBlock: {width: rect.width, height: rect.height} }); + this.setState({ + smallBlock: { width: rect.width, height: rect.height }, + }); } }; const stretchLastRow = - blocks.length < this.state.countBlocksInSmallRow * this.state.smallBlocksRows ? - 'noStretchOnLastRow' : ''; - const classes = `ConsensusList SmallRow ${this.state.smallRowsAddFlexClass ? 'flexContainerSmallRow' : ''} ${stretchLastRow}`; + blocks.length < + this.state.countBlocksInSmallRow * this.state.smallBlocksRows + ? 'noStretchOnLastRow' + : ''; + const classes = `ConsensusList SmallRow ${ + this.state.smallRowsAddFlexClass ? 'flexContainerSmallRow' : '' + } ${stretchLastRow}`; - return
- {blocks.map((item, i) => { - const [height, consensusView] = item; - let lastInRow = (i+1) % this.state.countBlocksInSmallRow === 0 ? true : false; - if (lastInRow && i === 0) { - // should not be marked as last one in row if it's the very first in row - lastInRow = false; - } + return ( +
+ {blocks.map((item, i) => { + const [height, consensusView] = item; + let lastInRow = + (i + 1) % this.state.countBlocksInSmallRow === 0 ? true : false; + if (lastInRow && i === 0) { + // should not be marked as last one in row if it's the very first in row + lastInRow = false; + } - return ; - }) - } -
; + return ( + + ); + })} +
+ ); } private async subscribeConsensus(chain: Types.ChainLabel) { diff --git a/packages/frontend/src/components/Consensus/ConsensusBlock.css b/packages/frontend/src/components/Consensus/ConsensusBlock.css index b5cccf0..6b608b4 100644 --- a/packages/frontend/src/components/Consensus/ConsensusBlock.css +++ b/packages/frontend/src/components/Consensus/ConsensusBlock.css @@ -21,7 +21,8 @@ border-bottom: 1px dashed #999; } -.Consensus .finalizedInfo, .legend { +.Consensus .finalizedInfo, +.legend { border-bottom: 1px dotted #555555; } @@ -89,7 +90,7 @@ } .Consensus .explicit { - fill: #E70E81; + fill: #e70e81; } .Consensus .nodeName { @@ -134,7 +135,8 @@ cursor: pointer; } -.Consensus .Row th, .Consensus .Row td { +.Consensus .Row th, +.Consensus .Row td { text-align: left; padding: 2px; } @@ -199,4 +201,3 @@ .Consensus .even { background-color: #333; } - diff --git a/packages/frontend/src/components/Consensus/ConsensusBlock.tsx b/packages/frontend/src/components/Consensus/ConsensusBlock.tsx index 1945503..5e021da 100644 --- a/packages/frontend/src/components/Consensus/ConsensusBlock.tsx +++ b/packages/frontend/src/components/Consensus/ConsensusBlock.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; -import Measure, {BoundingRect, ContentRect} from 'react-measure'; +import Measure, { BoundingRect, ContentRect } from 'react-measure'; import { Types, Maybe } from '@dotstats/common'; import { Icon, Tooltip, PolkadotIcon } from '../'; @@ -28,15 +28,19 @@ export namespace ConsensusBlock { export class ConsensusBlock extends React.Component { public state = { - lastConsensusView: "", + lastConsensusView: '', }; public shouldComponentUpdate(nextProps: ConsensusBlock.Props): boolean { - if (this.props.authorities.length === 0 && nextProps.authorities.length === 0) { + if ( + this.props.authorities.length === 0 && + nextProps.authorities.length === 0 + ) { return false; } - const positionInfoChanged = this.props.firstInRow !== nextProps.firstInRow || + const positionInfoChanged = + this.props.firstInRow !== nextProps.firstInRow || this.props.lastInRow !== nextProps.lastInRow; if (positionInfoChanged) { return true; @@ -53,75 +57,104 @@ export class ConsensusBlock extends React.Component { public render() { this.state.lastConsensusView = JSON.stringify(this.props.consensusView); - const finalizedByWhom = this.props.authorities.filter(authority => this.isFinalized(authority)); + const finalizedByWhom = this.props.authorities.filter((authority) => + this.isFinalized(authority) + ); const ratio = finalizedByWhom.length + '/' + this.props.authorities.length; let titleFinal = {ratio}; - const majorityFinalized = finalizedByWhom.length / this.props.authorities.length >= 2/3; + const majorityFinalized = + finalizedByWhom.length / this.props.authorities.length >= 2 / 3; if (majorityFinalized && !this.props.compact) { titleFinal = FINAL; } else if (majorityFinalized && this.props.compact) { const hash = this.getFinalizedHash(finalizedByWhom[0]); - titleFinal = + titleFinal = ( + + ); } const handleOnResize = (contentRect: ContentRect) => { - this.props.changeBlocks(this.props.firstInRow, contentRect.bounds as BoundingRect); + this.props.changeBlocks( + this.props.firstInRow, + contentRect.bounds as BoundingRect + ); }; const get = (measureRef: Maybe<(ref: Element | null) => void>) => { - return
- - - - {this.props.firstInRow && !this.props.compact ? - : null} - - - {this.props.authorities.map(authority => - )} - - - - {this.props.authorities.map((authority, row) => - this.renderMatriceRow(authority, this.props.authorities, row))} - -
  - - {this.displayBlockNumber()} - - - {titleFinal} - - {this.getAuthorityContent(authority)} -
-
+ return ( +
+ + + + {this.props.firstInRow && !this.props.compact ? ( + + ) : null} + + + {this.props.authorities.map((authority) => ( + + ))} + + + + {this.props.authorities.map((authority, row) => + this.renderMatriceRow(authority, this.props.authorities, row) + )} + +
+   + + + {this.displayBlockNumber()} + + + {titleFinal} + + {this.getAuthorityContent(authority)} +
+
+ ); }; if (this.props.measure) { return ( - {({measureRef}) => ( - get(measureRef) - )} - + + {({ measureRef }) => get(measureRef)} + ); } else { - return (get(null)); + return get(null); } } private displayBlockNumber(): string { const blockNumber = String(this.props.height); - return blockNumber.length > 2 ? - '…' + blockNumber.substr(blockNumber.length - 2, blockNumber.length) : blockNumber; + return blockNumber.length > 2 + ? '…' + blockNumber.substr(blockNumber.length - 2, blockNumber.length) + : blockNumber; } private isFinalized(authority: Types.Authority): boolean { @@ -132,8 +165,12 @@ export class ConsensusBlock extends React.Component { const { Address: addr } = authority; const consensus = this.props.consensusView; - return consensus != null && addr in consensus && addr in consensus[addr] - && consensus[addr][addr].Finalized === true; + return ( + consensus != null && + addr in consensus && + addr in consensus[addr] && + consensus[addr][addr].Finalized === true + ); } private getFinalizedHash(authority: Types.Authority): Maybe { @@ -144,55 +181,114 @@ export class ConsensusBlock extends React.Component { return null; } - private renderMatriceRow(authority: Types.Authority, authorities: Types.Authority[], row: number): JSX.Element { + private renderMatriceRow( + authority: Types.Authority, + authorities: Types.Authority[], + row: number + ): JSX.Element { let finalizedInfo =  ; let finalizedHash; if (authority.NodeId != null && this.isFinalized(authority)) { - const matrice = this.props.consensusView[authority.Address][authority.Address]; + const matrice = this.props.consensusView[authority.Address][ + authority.Address + ]; - finalizedInfo = matrice.ImplicitFinalized ? - : - ; + finalizedInfo = matrice.ImplicitFinalized ? ( + + ) : ( + + ); - finalizedHash = matrice.FinalizedHash ? - : -
 
; + finalizedHash = matrice.FinalizedHash ? ( + + ) : ( +
 
+ ); } - const name = authority.Name ? - {authority.Name} : no data received from node; - const firstName = this.props.firstInRow ? - {name} : ''; + const name = authority.Name ? ( + {authority.Name} + ) : ( + no data received from node + ); + const firstName = this.props.firstInRow ? ( + + {name} + + ) : ( + '' + ); - return - {firstName} - {this.getAuthorityContent(authority)} - {finalizedInfo}{finalizedHash} - { - authorities.map((columnNode, column) => { + return ( + + {firstName} + + {this.getAuthorityContent(authority)} + + + {finalizedInfo} + {finalizedHash} + + {authorities.map((columnNode, column) => { const evenOdd = ((row % 2) + column) % 2 === 0 ? 'even' : 'odd'; - return {this.getCellContent(authority, columnNode)} - }) - } - ; + return ( + + {this.getCellContent(authority, columnNode)} + + ); + })} + + ); } private getAuthorityContent(authority: Types.Authority): JSX.Element { - return
-
- + return ( +
+
+ +
-
; + ); } - private getCellContent(rowAuthority: Types.Authority, columnAuthority: Types.Authority) { - const consensusInfo = this.props.consensusView && + private getCellContent( + rowAuthority: Types.Authority, + columnAuthority: Types.Authority + ) { + const consensusInfo = + this.props.consensusView && rowAuthority.Address && rowAuthority.Address in this.props.consensusView && - columnAuthority.Address in this.props.consensusView[rowAuthority.Address] ? - this.props.consensusView[rowAuthority.Address][columnAuthority.Address] : null; + columnAuthority.Address in this.props.consensusView[rowAuthority.Address] + ? this.props.consensusView[rowAuthority.Address][ + columnAuthority.Address + ] + : null; const prevote = consensusInfo && consensusInfo.Prevote; const implicitPrevote = consensusInfo && consensusInfo.ImplicitPrevote; @@ -205,23 +301,35 @@ export class ConsensusBlock extends React.Component { let statPrecommit; if (implicitPrevote) { - statPrevote = ; + statPrevote = ( + + ); } if (implicitPrecommit) { - statPrecommit = ; + statPrecommit = ( + + ); } if (prevote) { - statPrevote = ; + statPrevote = ( + + ); } if (precommit) { - statPrecommit = ; + statPrecommit = ( + + ); } - return {statPrevote}{statPrecommit}; + return ( + + {statPrevote} + {statPrecommit} + + ); } else { - return ; + return ; } } - } diff --git a/packages/frontend/src/components/Consensus/Jdenticon.tsx b/packages/frontend/src/components/Consensus/Jdenticon.tsx index f7f30cc..08b8653 100644 --- a/packages/frontend/src/components/Consensus/Jdenticon.tsx +++ b/packages/frontend/src/components/Consensus/Jdenticon.tsx @@ -3,8 +3,8 @@ import * as React from 'react'; import './Jdenticon.css'; export interface Props { - hash: string, - size: string + hash: string; + size: string; } class Jdenticon extends React.Component { @@ -26,13 +26,15 @@ class Jdenticon extends React.Component { public render() { const { hash, size } = this.props; - return this.handleRef(element)} - width={size} - height={size} - data-jdenticon-value={hash} - />; + return ( + this.handleRef(element)} + width={size} + height={size} + data-jdenticon-value={hash} + /> + ); } private handleRef(element: any) { diff --git a/packages/frontend/src/components/Filter.css b/packages/frontend/src/components/Filter.css index ebe23d5..9623ef5 100644 --- a/packages/frontend/src/components/Filter.css +++ b/packages/frontend/src/components/Filter.css @@ -10,7 +10,7 @@ border-radius: 4px; background: #111; color: #fff; - box-shadow: 0 2px 10px rgba(0,0,0,0.5); + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.5); } .Filter-hidden { diff --git a/packages/frontend/src/components/Filter.tsx b/packages/frontend/src/components/Filter.tsx index 748fbe4..2ca466a 100644 --- a/packages/frontend/src/components/Filter.tsx +++ b/packages/frontend/src/components/Filter.tsx @@ -21,7 +21,7 @@ const ESCAPE_KEY = 27; export class Filter extends React.Component { public state = { - value: '' + value: '', }; private filterInput: HTMLInputElement; @@ -34,23 +34,34 @@ export class Filter extends React.Component { window.removeEventListener('keyup', this.onWindowKeyUp); } - public shouldComponentUpdate(nextProps: Filter.Props, nextState: Filter.State): boolean { - return this.props.onChange !== nextProps.onChange || this.state.value !== nextState.value; + public shouldComponentUpdate( + nextProps: Filter.Props, + nextState: Filter.State + ): boolean { + return ( + this.props.onChange !== nextProps.onChange || + this.state.value !== nextState.value + ); } public render() { const { value } = this.state; - let className = "Filter"; + let className = 'Filter'; if (value === '') { - className += " Filter-hidden"; + className += ' Filter-hidden'; } return (
- +
); } @@ -63,11 +74,11 @@ export class Filter extends React.Component { private onRef = (el: HTMLInputElement) => { this.filterInput = el; - } + }; private onChange = () => { this.setValue(this.filterInput.value); - } + }; private onKeyUp = (event: React.KeyboardEvent) => { event.stopPropagation(); @@ -75,7 +86,7 @@ export class Filter extends React.Component { if (event.keyCode === ESCAPE_KEY) { this.setValue(''); } - } + }; private onWindowKeyUp = (event: KeyboardEvent) => { if (event.ctrlKey) { @@ -94,7 +105,7 @@ export class Filter extends React.Component { this.setValue(key); this.filterInput.focus(); } - } + }; private getNodeFilter(value: string): Maybe<(node: Node) => boolean> { if (value === '') { @@ -105,9 +116,10 @@ export class Filter extends React.Component { return ({ name, city }) => { const matchesName = name.toLowerCase().indexOf(filter) !== -1; - const matchesCity = city != null && city.toLowerCase().indexOf(filter) !== -1; + const matchesCity = + city != null && city.toLowerCase().indexOf(filter) !== -1; return matchesName || matchesCity; - } + }; } } diff --git a/packages/frontend/src/components/Icon.css b/packages/frontend/src/components/Icon.css index 135b9e7..768269c 100644 --- a/packages/frontend/src/components/Icon.css +++ b/packages/frontend/src/components/Icon.css @@ -1,14 +1,14 @@ .Icon { - fill: currentColor; - height: 1em; - width: 1em; - text-align: center; - line-height: 1em; - vertical-align: middle; - display: inline-block; + fill: currentColor; + height: 1em; + width: 1em; + text-align: center; + line-height: 1em; + vertical-align: middle; + display: inline-block; } .Icon svg { - width: auto; - height: 1em; + width: auto; + height: 1em; } diff --git a/packages/frontend/src/components/Icon.tsx b/packages/frontend/src/components/Icon.tsx index fdde9a2..cde4054 100644 --- a/packages/frontend/src/components/Icon.tsx +++ b/packages/frontend/src/components/Icon.tsx @@ -7,20 +7,30 @@ export interface Props { alt?: string; className?: string; onClick?: () => void; -}; +} export class Icon extends React.Component<{}, Props> { public props: Props; public shouldComponentUpdate(nextProps: Props) { - return this.props.src !== nextProps.src - || this.props.alt !== nextProps.alt - || this.props.className !== nextProps.className; + return ( + this.props.src !== nextProps.src || + this.props.alt !== nextProps.alt || + this.props.className !== nextProps.className + ); } public render() { const { alt, className, onClick, src } = this.props; - return ; + return ( + + ); } } diff --git a/packages/frontend/src/components/List/Column.tsx b/packages/frontend/src/components/List/Column.tsx index bae7a0b..cfa6058 100644 --- a/packages/frontend/src/components/List/Column.tsx +++ b/packages/frontend/src/components/List/Column.tsx @@ -3,7 +3,12 @@ import { Types, Maybe, timestamp } from '@dotstats/common'; import { State, Node } from '../../state'; import { Truncate } from './'; import { Ago, Icon, Tooltip, Sparkline, PolkadotIcon } from '../'; -import { formatNumber, getHashData, milliOrSecond, secondsWithPrecision } from '../../utils'; +import { + formatNumber, + getHashData, + milliOrSecond, + secondsWithPrecision, +} from '../../utils'; export interface Column { label: string; @@ -64,17 +69,17 @@ const ICONS = { 'edgeware-node': edgewareIcon, 'Edgeware Node': edgewareIcon, 'joystream-node': joystreamIcon, - 'ChainX': chainXIcon, + ChainX: chainXIcon, 'ladder-node': ladderIcon, 'cennznet-node': cennznetIcon, - 'Darwinia': darwiniaIcon, + Darwinia: darwiniaIcon, 'Darwinia Testnet': darwiniaIcon, 'turing-node': turingIcon, - 'dothereum': dothereumIcon, - 'katalchain': katalchainIcon, + dothereum: dothereumIcon, + katalchain: katalchainIcon, 'bifrost-node': bifrostIcon, 'totem-meccano-node': totemIcon, - 'Totem': totemIcon, + Totem: totemIcon, }; export namespace Column { @@ -82,7 +87,7 @@ export namespace Column { label: 'Node', icon: nodeIcon, sortBy: ({ sortableName }) => sortableName, - render: ({ name }) => + render: ({ name }) => , }; export const VALIDATOR: Column = { @@ -92,8 +97,16 @@ export namespace Column { setting: 'validator', sortBy: ({ validator }) => validator || '', render: ({ validator }) => { - return validator ? : '-'; - } + return validator ? ( + + + + + + ) : ( + '-' + ); + }, }; export const LOCATION: Column = { @@ -102,7 +115,8 @@ export namespace Column { width: 140, setting: 'location', sortBy: ({ city }) => city || '', - render: ({ city }) => city ? : '-' + render: ({ city }) => + city ? : '-', }; export const IMPLEMENTATION: Column = { @@ -120,7 +134,7 @@ export namespace Column { {semver} ); - } + }, }; export const NETWORK_ID: Column = { @@ -129,7 +143,8 @@ export namespace Column { width: 90, setting: 'networkId', sortBy: ({ networkId }) => networkId || '', - render: ({ networkId }) => networkId ? : '-' + render: ({ networkId }) => + networkId ? : '-', }; export const PEERS: Column = { @@ -138,7 +153,7 @@ export namespace Column { width: 26, setting: 'peers', sortBy: ({ peers }) => peers, - render: ({ peers }) => `${peers}` + render: ({ peers }) => `${peers}`, }; export const TXS: Column = { @@ -147,7 +162,7 @@ export namespace Column { width: 26, setting: 'txs', sortBy: ({ txs }) => txs, - render: ({ txs }) => `${txs}` + render: ({ txs }) => `${txs}`, }; export const CPU: Column = { @@ -155,16 +170,24 @@ export namespace Column { icon: cpuIcon, width: 40, setting: 'cpu', - sortBy: ({ cpu }) => cpu.length < 3 ? 0 : cpu[cpu.length - 1], + sortBy: ({ cpu }) => (cpu.length < 3 ? 0 : cpu[cpu.length - 1]), render: ({ cpu, chartstamps }) => { if (cpu.length < 3) { return '-'; } return ( - + ); - } + }, }; export const MEM: Column = { @@ -172,16 +195,24 @@ export namespace Column { icon: memoryIcon, width: 40, setting: 'mem', - sortBy: ({ mem }) => mem.length < 3 ? 0 : mem[mem.length - 1], + sortBy: ({ mem }) => (mem.length < 3 ? 0 : mem[mem.length - 1]), render: ({ mem, chartstamps }) => { if (mem.length < 3) { return '-'; } return ( - + ); - } + }, }; export const UPLOAD: Column = { @@ -189,16 +220,24 @@ export namespace Column { icon: uploadIcon, width: 40, setting: 'upload', - sortBy: ({ upload }) => upload.length < 3 ? 0 : upload[upload.length - 1], + sortBy: ({ upload }) => (upload.length < 3 ? 0 : upload[upload.length - 1]), render: ({ upload, chartstamps }) => { if (upload.length < 3) { return '-'; } return ( - + ); - } + }, }; export const DOWNLOAD: Column = { @@ -206,16 +245,25 @@ export namespace Column { icon: downloadIcon, width: 40, setting: 'download', - sortBy: ({ download }) => download.length < 3 ? 0 : download[download.length - 1], + sortBy: ({ download }) => + download.length < 3 ? 0 : download[download.length - 1], render: ({ download, chartstamps }) => { if (download.length < 3) { return '-'; } return ( - + ); - } + }, }; export const STATE_CACHE: Column = { @@ -223,16 +271,25 @@ export namespace Column { icon: stateIcon, width: 40, setting: 'stateCacheSize', - sortBy: ({ stateCacheSize }) => stateCacheSize.length < 3 ? 0 : stateCacheSize[stateCacheSize.length - 1], + sortBy: ({ stateCacheSize }) => + stateCacheSize.length < 3 ? 0 : stateCacheSize[stateCacheSize.length - 1], render: ({ stateCacheSize, chartstamps }) => { if (stateCacheSize.length < 3) { return '-'; } return ( - + ); - } + }, }; export const DB_CACHE: Column = { @@ -240,16 +297,25 @@ export namespace Column { icon: databaseIcon, width: 40, setting: 'dbCacheSize', - sortBy: ({ dbCacheSize }) => dbCacheSize.length < 3 ? 0 : dbCacheSize[dbCacheSize.length - 1], + sortBy: ({ dbCacheSize }) => + dbCacheSize.length < 3 ? 0 : dbCacheSize[dbCacheSize.length - 1], render: ({ dbCacheSize, chartstamps }) => { if (dbCacheSize.length < 3) { return '-'; } return ( - + ); - } + }, }; export const DISK_READ: Column = { @@ -257,16 +323,25 @@ export namespace Column { icon: readIcon, width: 40, setting: 'diskRead', - sortBy: ({ diskRead }) => diskRead.length < 3 ? 0 : diskRead[diskRead.length - 1], + sortBy: ({ diskRead }) => + diskRead.length < 3 ? 0 : diskRead[diskRead.length - 1], render: ({ diskRead, chartstamps }) => { if (diskRead.length < 3) { return '-'; } return ( - + ); - } + }, }; export const DISK_WRITE: Column = { @@ -274,16 +349,25 @@ export namespace Column { icon: writeIcon, width: 40, setting: 'diskWrite', - sortBy: ({ diskWrite }) => diskWrite.length < 3 ? 0 : diskWrite[diskWrite.length - 1], + sortBy: ({ diskWrite }) => + diskWrite.length < 3 ? 0 : diskWrite[diskWrite.length - 1], render: ({ diskWrite, chartstamps }) => { if (diskWrite.length < 3) { return '-'; } return ( - + ); - } + }, }; export const BLOCK_NUMBER: Column = { @@ -292,7 +376,7 @@ export namespace Column { width: 88, setting: 'blocknumber', sortBy: ({ height }) => height || 0, - render: ({ height }) => `#${formatNumber(height)}` + render: ({ height }) => `#${formatNumber(height)}`, }; export const BLOCK_HASH: Column = { @@ -301,7 +385,7 @@ export namespace Column { width: 154, setting: 'blockhash', sortBy: ({ hash }) => hash || '', - render: ({ hash }) => + render: ({ hash }) => , }; export const FINALIZED: Column = { @@ -310,7 +394,7 @@ export namespace Column { width: 88, setting: 'finalized', sortBy: ({ finalized }) => finalized || 0, - render: ({ finalized }) => `#${formatNumber(finalized)}` + render: ({ finalized }) => `#${formatNumber(finalized)}`, }; export const FINALIZED_HASH: Column = { @@ -319,7 +403,9 @@ export namespace Column { width: 154, setting: 'finalizedhash', sortBy: ({ finalizedHash }) => finalizedHash || '', - render: ({ finalizedHash }) => + render: ({ finalizedHash }) => ( + + ), }; export const BLOCK_TIME: Column = { @@ -327,8 +413,8 @@ export namespace Column { icon: blockTimeIcon, width: 80, setting: 'blocktime', - sortBy: ({ blockTime }) => blockTime == null ? Infinity : blockTime, - render: ({ blockTime }) => `${secondsWithPrecision(blockTime/1000)}` + sortBy: ({ blockTime }) => (blockTime == null ? Infinity : blockTime), + render: ({ blockTime }) => `${secondsWithPrecision(blockTime / 1000)}`, }; export const BLOCK_PROPAGATION: Column = { @@ -336,8 +422,10 @@ export namespace Column { icon: propagationTimeIcon, width: 58, setting: 'blockpropagation', - sortBy: ({ propagationTime }) => propagationTime == null ? Infinity : propagationTime, - render: ({ propagationTime }) => propagationTime == null ? '∞' : milliOrSecond(propagationTime) + sortBy: ({ propagationTime }) => + propagationTime == null ? Infinity : propagationTime, + render: ({ propagationTime }) => + propagationTime == null ? '∞' : milliOrSecond(propagationTime), }; export const BLOCK_LAST_TIME: Column = { @@ -346,7 +434,7 @@ export namespace Column { width: 100, setting: 'blocklasttime', sortBy: ({ blockTimestamp }) => blockTimestamp || 0, - render: ({ blockTimestamp }) => + render: ({ blockTimestamp }) => , }; export const UPTIME: Column = { @@ -355,7 +443,7 @@ export namespace Column { width: 58, setting: 'uptime', sortBy: ({ connectedAt }) => connectedAt || 0, - render: ({ connectedAt }) => + render: ({ connectedAt }) => , }; export const NETWORK_STATE: Column = { @@ -371,33 +459,40 @@ export namespace Column { } const uri = `${URI_BASE}${encodeURIComponent(chainLabel)}/${id}/`; - return ; + return ( + + + + ); }, }; -}; +} const SEMVER_PATTERN = /^\d+\.\d+\.\d+/; const BANDWIDTH_SCALE = 1024 * 1024; const MEMORY_SCALE = 2 * 1024 * 1024; -const URI_BASE = window.location.protocol === 'https:' - ? `/network_state/` - : `http://${window.location.hostname}:8000/network_state/`; +const URI_BASE = + window.location.protocol === 'https:' + ? `/network_state/` + : `http://${window.location.hostname}:8000/network_state/`; function formatStamp(stamp: Types.Timestamp): string { - const passed = (timestamp() - stamp) / 1000 | 0; + const passed = ((timestamp() - stamp) / 1000) | 0; - const hours = passed / 3600 | 0; - const minutes = (passed % 3600) / 60 | 0; - const seconds = (passed % 60) | 0; + const hours = (passed / 3600) | 0; + const minutes = ((passed % 3600) / 60) | 0; + const seconds = passed % 60 | 0; - return hours ? `${hours}h ago` - : minutes ? `${minutes}m ago` - : `${seconds}s ago`; + return hours + ? `${hours}h ago` + : minutes + ? `${minutes}m ago` + : `${seconds}s ago`; } function formatMemory(kbs: number, stamp: Maybe): string { const ago = stamp ? ` (${formatStamp(stamp)})` : ''; - const mbs = kbs / 1024 | 0; + const mbs = (kbs / 1024) | 0; if (mbs >= 1000) { return `${(mbs / 1024).toFixed(1)} GB${ago}`; @@ -434,10 +529,7 @@ function formatBandwidth(bps: number, stamp: Maybe): string { function formatCPU(cpu: number, stamp: Maybe): string { const ago = stamp ? ` (${formatStamp(stamp)})` : ''; - const fractionDigits = cpu > 100 ? 0 - : cpu > 10 ? 1 - : cpu > 1 ? 2 - : 3; + const fractionDigits = cpu > 100 ? 0 : cpu > 10 ? 1 : cpu > 1 ? 2 : 3; return `${cpu.toFixed(fractionDigits)}%${ago}`; } diff --git a/packages/frontend/src/components/List/HeaderCell.tsx b/packages/frontend/src/components/List/HeaderCell.tsx index d9218f6..86822fc 100644 --- a/packages/frontend/src/components/List/HeaderCell.tsx +++ b/packages/frontend/src/components/List/HeaderCell.tsx @@ -20,19 +20,29 @@ export class HeaderCell extends React.Component { public render() { const { column, index, last } = this.props; const { icon, width, label } = column; - const position = index === 0 ? 'left' - : index === last ? 'right' - : 'center'; + const position = index === 0 ? 'left' : index === last ? 'right' : 'center'; const sortBy = this.props.sortBy.get(); - const className = column.sortBy == null ? '' : sortBy === index || sortBy === ~index ? 'HeaderCell-sorted' : 'HeaderCell-sortable'; - const i = sortBy === index ? sortAscIcon : sortBy === ~index ? sortDescIcon : icon; + const className = + column.sortBy == null + ? '' + : sortBy === index || sortBy === ~index + ? 'HeaderCell-sorted' + : 'HeaderCell-sortable'; + const i = + sortBy === index ? sortAscIcon : sortBy === ~index ? sortDescIcon : icon; return ( - - + + + + - ) + ); } private toggleSort = () => { @@ -50,5 +60,5 @@ export class HeaderCell extends React.Component { } else { sortBy.set(index); } - } + }; } diff --git a/packages/frontend/src/components/List/List.tsx b/packages/frontend/src/components/List/List.tsx index b45b97e..e0470f5 100644 --- a/packages/frontend/src/components/List/List.tsx +++ b/packages/frontend/src/components/List/List.tsx @@ -4,7 +4,7 @@ import { Filter } from '../'; import { State as AppState, Node } from '../../state'; import { Row } from './'; import { Persistent, PersistentSet } from '../../persist'; -import { viewport } from '../../utils' +import { viewport } from '../../utils'; const HEADER = 148; const TH_HEIGHT = 35; @@ -64,7 +64,11 @@ export class List extends React.Component { if (nodes.length === 0) { return ( -
¯\_(ツ)_/¯
Nothing matches
+
+ ¯\_(ツ)_/¯ +
+ Nothing matches +
); @@ -73,7 +77,7 @@ export class List extends React.Component { const { listStart, listEnd } = this.state; - const height = (TH_HEIGHT + nodes.length * TR_HEIGHT); + const height = TH_HEIGHT + nodes.length * TR_HEIGHT; const transform = `translateY(${listStart * TR_HEIGHT}px)`; nodes = nodes.slice(listStart, listEnd); @@ -84,9 +88,14 @@ export class List extends React.Component { - { - nodes.map((node) => ) - } + {nodes.map((node) => ( + + ))}
@@ -100,7 +109,10 @@ export class List extends React.Component { return; } - const relativeTop = divisibleBy(window.scrollY - (HEADER + TR_HEIGHT), TR_HEIGHT * ROW_MARGIN); + const relativeTop = divisibleBy( + window.scrollY - (HEADER + TR_HEIGHT), + TR_HEIGHT * ROW_MARGIN + ); if (this.relativeTop === relativeTop) { return; @@ -110,14 +122,15 @@ export class List extends React.Component { this.scrolling = true; window.requestAnimationFrame(this.onScrollRAF); - } + }; private onScrollRAF = () => { const { relativeTop } = this; const { viewportHeight } = this.state; const top = Math.max(relativeTop, 0); - const height = relativeTop < 0 ? viewportHeight + relativeTop : viewportHeight; - const listStart = Math.max((top / TR_HEIGHT | 0) - ROW_MARGIN, 0); + const height = + relativeTop < 0 ? viewportHeight + relativeTop : viewportHeight; + const listStart = Math.max(((top / TR_HEIGHT) | 0) - ROW_MARGIN, 0); const listEnd = listStart + ROW_MARGIN * 2 + Math.ceil(height / TR_HEIGHT); if (listStart !== this.state.listStart || listEnd !== this.state.listEnd) { @@ -125,19 +138,19 @@ export class List extends React.Component { } this.scrolling = false; - } + }; private onResize = () => { const viewportHeight = viewport().height; this.setState({ viewportHeight }); - } + }; private onFilterChange = (filter: Maybe<(node: Node) => boolean>) => { this.setState({ filter }); - } + }; } function divisibleBy(n: number, dividor: number): number { - return n - n % dividor; + return n - (n % dividor); } diff --git a/packages/frontend/src/components/List/Row.css b/packages/frontend/src/components/List/Row.css index ca7d78e..8995eb6 100644 --- a/packages/frontend/src/components/List/Row.css +++ b/packages/frontend/src/components/List/Row.css @@ -1,5 +1,5 @@ .Row { - color: #B5AEAE; + color: #b5aeae; cursor: pointer; } @@ -12,7 +12,8 @@ text-decoration: underline; } -.Row-Header th, .Row td { +.Row-Header th, +.Row td { text-align: left; padding: 6px 13px; height: 19px; @@ -32,7 +33,7 @@ .Row-Header th.HeaderCell-sorted { cursor: pointer; - background: #E6007A; + background: #e6007a; color: #fff; } @@ -57,17 +58,17 @@ } .Row-pinned td:first-child { - border-left: 3px solid #E6007A; + border-left: 3px solid #e6007a; padding-left: 10px; } .Row-pinned td:last-child { - border-right: 3px solid #E6007A; + border-right: 3px solid #e6007a; padding-right: 10px; } .Row-pinned.Row-synced { - color: #E6007A; + color: #e6007a; } .Row-stale { @@ -75,7 +76,7 @@ } .Row:hover { - background-color: #1E1E1E; + background-color: #1e1e1e; } .Row-validator { diff --git a/packages/frontend/src/components/List/Row.tsx b/packages/frontend/src/components/List/Row.tsx index caf9e3a..b94a969 100644 --- a/packages/frontend/src/components/List/Row.tsx +++ b/packages/frontend/src/components/List/Row.tsx @@ -58,15 +58,19 @@ export class Row extends React.Component { return ( - { - columns.map((col, index) => ( - - )) - } + {columns.map((col, index) => ( + + ))} - ) - } + ); + }; public state = { update: 0 }; @@ -82,8 +86,14 @@ export class Row extends React.Component { node.unsubscribe(this.onUpdate); } - public shouldComponentUpdate(nextProps: Row.Props, nextState: Row.State): boolean { - return this.props.node.id !== nextProps.node.id || this.state.update !== nextState.update; + public shouldComponentUpdate( + nextProps: Row.Props, + nextState: Row.State + ): boolean { + return ( + this.props.node.id !== nextProps.node.id || + this.state.update !== nextState.update + ); } public render() { @@ -105,9 +115,9 @@ export class Row extends React.Component { return ( - { - columns.map(({ render }, index) => {render(node)}) - } + {columns.map(({ render }, index) => ( + {render(node)} + ))} ); } @@ -116,13 +126,13 @@ export class Row extends React.Component { const { pins, node } = this.props; if (node.pinned) { - pins.delete(node.name) + pins.delete(node.name); } else { pins.add(node.name); } - } + }; private onUpdate = () => { this.setState({ update: this.state.update + 1 }); - } + }; } diff --git a/packages/frontend/src/components/List/Truncate.tsx b/packages/frontend/src/components/List/Truncate.tsx index 908ce17..daa9f2d 100644 --- a/packages/frontend/src/components/List/Truncate.tsx +++ b/packages/frontend/src/components/List/Truncate.tsx @@ -18,13 +18,21 @@ export class Truncate extends React.Component { } return ( - +
{text}
); } public shouldComponentUpdate(nextProps: Truncate.Props): boolean { - return this.props.text !== nextProps.text || this.props.position !== nextProps.position; + return ( + this.props.text !== nextProps.text || + this.props.position !== nextProps.position + ); } } diff --git a/packages/frontend/src/components/Map/Location.css b/packages/frontend/src/components/Map/Location.css index d331695..76eb70d 100644 --- a/packages/frontend/src/components/Map/Location.css +++ b/packages/frontend/src/components/Map/Location.css @@ -1,4 +1,3 @@ - .Location { width: 6px; height: 6px; @@ -37,7 +36,7 @@ .Location-synced { z-index: 3; - border-color: #E6007A; + border-color: #e6007a; } .Location-synced .Location-ping { @@ -58,7 +57,7 @@ font-family: monospace, sans-serif; background: #222; color: #fff; - box-shadow: 0 3px 20px rgba(0,0,0,0.5); + box-shadow: 0 3px 20px rgba(0, 0, 0, 0.5); border-collapse: collapse; } @@ -104,7 +103,7 @@ width: 6px; height: 6px; border-width: 1px; - border-color: rgba(255,255,255,1); + border-color: rgba(255, 255, 255, 1); } to { @@ -113,7 +112,7 @@ width: 40px; height: 40px; border-width: 1px; - border-color: rgba(255,255,255,0); + border-color: rgba(255, 255, 255, 0); } } diff --git a/packages/frontend/src/components/Map/Location.tsx b/packages/frontend/src/components/Map/Location.tsx index 0ec829a..7362a76 100644 --- a/packages/frontend/src/components/Map/Location.tsx +++ b/packages/frontend/src/components/Map/Location.tsx @@ -1,5 +1,10 @@ import * as React from 'react'; -import { formatNumber, trimHash, milliOrSecond, secondsWithPrecision } from '../../utils'; +import { + formatNumber, + trimHash, + milliOrSecond, + secondsWithPrecision, +} from '../../utils'; import { Ago, Icon, PolkadotIcon } from '../'; import { Node } from '../../state'; @@ -60,10 +65,13 @@ export class Location extends React.Component { } return ( -
- { - this.state.hover ? this.renderDetails() : null - } +
+ {this.state.hover ? this.renderDetails() : null}
); @@ -88,10 +96,14 @@ export class Location extends React.Component { if (validator) { validatorRow = ( - + + + {trimHash(validator, 30)} - + + + ); @@ -101,28 +113,57 @@ export class Location extends React.Component { - + + {validatorRow} - + + - + + - + + - + + - - - - - - + + + + + +
{name} + + {name}
{implementation} v{version} + + + {implementation} v{version} +
{city} + + {city}
#{formatNumber(height)} + + #{formatNumber(height)}
{trimHash(hash, 20)} + + {trimHash(hash, 20)}
{secondsWithPrecision(blockTime/1000)}{propagationTime == null ? '∞' : milliOrSecond(propagationTime)} + + + {secondsWithPrecision(blockTime / 1000)} + + + + {propagationTime == null ? '∞' : milliOrSecond(propagationTime)} + + + + +
@@ -131,9 +172,9 @@ export class Location extends React.Component { private onMouseOver = () => { this.setState({ hover: true }); - } + }; private onMouseOut = () => { this.setState({ hover: false }); - } + }; } diff --git a/packages/frontend/src/components/Map/Map.tsx b/packages/frontend/src/components/Map/Map.tsx index 93df01e..b850eaf 100644 --- a/packages/frontend/src/components/Map/Map.tsx +++ b/packages/frontend/src/components/Map/Map.tsx @@ -31,8 +31,8 @@ export class Map extends React.Component { width: 0, height: 0, top: 0, - left: 0 - } + left: 0, + }; public componentWillMount() { this.onResize(); @@ -52,8 +52,7 @@ export class Map extends React.Component { return (
- { - nodes.map((node) => { + {nodes.map((node) => { const { lat, lon } = node; const focused = filter == null || filter(node); @@ -66,23 +65,32 @@ export class Map extends React.Component { const position = this.pixelPosition(lat, lon); return ( - + ); - }) - } + })}
); } - private pixelPosition(lat: Types.Latitude, lon: Types.Longitude): Location.Position { + private pixelPosition( + lat: Types.Latitude, + lon: Types.Longitude + ): Location.Position { const { state } = this; // Longitude ranges -180 (west) to +180 (east) // Latitude ranges +90 (north) to -90 (south) const left = Math.round(((180 + lon) / 360) * state.width + state.left); - const top = Math.round(((90 - lat) / 180) * state.height * MAP_HEIGHT_ADJUST + state.top); + const top = Math.round( + ((90 - lat) / 180) * state.height * MAP_HEIGHT_ADJUST + state.top + ); let quarter: Location.Quarter = 0; @@ -121,9 +129,9 @@ export class Map extends React.Component { } this.setState({ top, left, width, height }); - } + }; private onFilterChange = (filter: Maybe<(node: Node) => boolean>) => { this.setState({ filter }); - } + }; } diff --git a/packages/frontend/src/components/OfflineIndicator.css b/packages/frontend/src/components/OfflineIndicator.css index f1daf4c..ae5ef5d 100644 --- a/packages/frontend/src/components/OfflineIndicator.css +++ b/packages/frontend/src/components/OfflineIndicator.css @@ -9,7 +9,7 @@ font-size: 30px; padding: 16px; border-radius: 50px; - box-shadow: rgba(0,0,0,0.5) 0 3px 20px; + box-shadow: rgba(0, 0, 0, 0.5) 0 3px 20px; } .OfflineIndicator-upgrade { diff --git a/packages/frontend/src/components/OfflineIndicator.tsx b/packages/frontend/src/components/OfflineIndicator.tsx index ed0dda5..802230d 100644 --- a/packages/frontend/src/components/OfflineIndicator.tsx +++ b/packages/frontend/src/components/OfflineIndicator.tsx @@ -7,16 +7,22 @@ import upgradeIcon from '../icons/flame.svg'; export namespace OfflineIndicator { export interface Props { - status: State["status"]; + status: State['status']; } } -export function OfflineIndicator(props: OfflineIndicator.Props): React.ReactElement | null { +export function OfflineIndicator( + props: OfflineIndicator.Props +): React.ReactElement | null { switch (props.status) { case 'online': return null; case 'offline': - return
; + return ( +
+ +
+ ); case 'upgrade-requested': return (
diff --git a/packages/frontend/src/components/PolkadotIcon.tsx b/packages/frontend/src/components/PolkadotIcon.tsx index e2ca643..5513cc5 100644 --- a/packages/frontend/src/components/PolkadotIcon.tsx +++ b/packages/frontend/src/components/PolkadotIcon.tsx @@ -21,52 +21,79 @@ interface Scheme { colors: number[]; } -const blake2 = (value: Uint8Array): Uint8Array => - blake2AsU8a(value, 512); +const blake2 = (value: Uint8Array): Uint8Array => blake2AsU8a(value, 512); const S = 64; const C = S / 2; -const Z = S / 64 * 5; +const Z = (S / 64) * 5; const ZERO = blake2(new Uint8Array(32)); const SCHEMA: Scheme[] = [ // target - { freq: 1, colors: [0, 28, 0, 0, 28, 0, 0, 28, 0, 0, 28, 0, 0, 28, 0, 0, 28, 0, 1] }, + { + freq: 1, + colors: [0, 28, 0, 0, 28, 0, 0, 28, 0, 0, 28, 0, 0, 28, 0, 0, 28, 0, 1], + }, // cube - { freq: 20, colors: [0, 1, 3, 2, 4, 3, 0, 1, 3, 2, 4, 3, 0, 1, 3, 2, 4, 3, 5] }, + { + freq: 20, + colors: [0, 1, 3, 2, 4, 3, 0, 1, 3, 2, 4, 3, 0, 1, 3, 2, 4, 3, 5], + }, // quazar - { freq: 16, colors: [1, 2, 3, 1, 2, 4, 5, 5, 4, 1, 2, 3, 1, 2, 4, 5, 5, 4, 0] }, + { + freq: 16, + colors: [1, 2, 3, 1, 2, 4, 5, 5, 4, 1, 2, 3, 1, 2, 4, 5, 5, 4, 0], + }, // flower - { freq: 32, colors: [0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 3] }, + { + freq: 32, + colors: [0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 3], + }, // cyclic - { freq: 32, colors: [0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6] }, + { + freq: 32, + colors: [0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6], + }, // vmirror - { freq: 128, colors: [0, 1, 2, 3, 4, 5, 3, 4, 2, 0, 1, 6, 7, 8, 9, 7, 8, 6, 10] }, + { + freq: 128, + colors: [0, 1, 2, 3, 4, 5, 3, 4, 2, 0, 1, 6, 7, 8, 9, 7, 8, 6, 10], + }, // hmirror - { freq: 128, colors: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 8, 6, 7, 5, 3, 4, 2, 11] }, + { + freq: 128, + colors: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 8, 6, 7, 5, 3, 4, 2, 11], + }, ]; const OUTER_CIRCLE: Circle = { cx: C, cy: C, r: C, - fill: '#eee' + fill: '#eee', }; -function getRotation (isSixPoint: boolean): { r: number; ro2: number; r3o4: number; ro4: number; rroot3o2: number; rroot3o4: number } { - const r = isSixPoint - ? (C / 8 * 5) - : (C / 4 * 3); - const rroot3o2 = r * Math.sqrt(3) / 2; +function getRotation( + isSixPoint: boolean +): { + r: number; + ro2: number; + r3o4: number; + ro4: number; + rroot3o2: number; + rroot3o4: number; +} { + const r = isSixPoint ? (C / 8) * 5 : (C / 4) * 3; + const rroot3o2 = (r * Math.sqrt(3)) / 2; const ro2 = r / 2; - const rroot3o4 = r * Math.sqrt(3) / 4; + const rroot3o4 = (r * Math.sqrt(3)) / 4; const ro4 = r / 4; - const r3o4 = r * 3 / 4; + const r3o4 = (r * 3) / 4; return { r, ro2, r3o4, ro4, rroot3o2, rroot3o4 }; } -function getCircleXY (isSixPoint: boolean): Array<[number, number]> { +function getCircleXY(isSixPoint: boolean): Array<[number, number]> { const { r, ro2, r3o4, ro4, rroot3o2, rroot3o4 } = getRotation(isSixPoint); return [ @@ -88,11 +115,11 @@ function getCircleXY (isSixPoint: boolean): Array<[number, number]> { [C + rroot3o2, C - ro2], [C + rroot3o4, C - ro4], [C + rroot3o4, C - r3o4], - [C, C] + [C, C], ]; } -function findScheme (d: number): Scheme { +function findScheme(d: number): Scheme { let sum = 0; const schema = SCHEMA.find((s): boolean => { sum += s.freq; @@ -107,19 +134,23 @@ function findScheme (d: number): Scheme { return schema; } -function addressToId (address: string): Uint8Array { - return blake2(decodeAddress(address)).map((x, i): number => (x + 256 - ZERO[i]) % 256); +function addressToId(address: string): Uint8Array { + return blake2(decodeAddress(address)).map( + (x, i): number => (x + 256 - ZERO[i]) % 256 + ); } -function getColors (address: string): string[] { - const total = SCHEMA.map((s): number => s.freq).reduce((a, b): number => a + b); +function getColors(address: string): string[] { + const total = SCHEMA.map((s): number => s.freq).reduce( + (a, b): number => a + b + ); const id = addressToId(address); const d = Math.floor((id[30] + id[31] * 256) % total); const rot = (id[28] % 6) * 3; - const sat = (Math.floor(id[29] * 70 / 256 + 26) % 80) + 30; + const sat = (Math.floor((id[29] * 70) / 256 + 26) % 80) + 30; const scheme = findScheme(d); const palette = Array.from(id).map((x, i): string => { - const b = (x + i % 28 * 58) % 256; + const b = (x + (i % 28) * 58) % 256; if (b === 0) { return '#444'; @@ -127,27 +158,35 @@ function getColors (address: string): string[] { return 'transparent'; } - const h = Math.floor(b % 64 * 360 / 64); + const h = Math.floor(((b % 64) * 360) / 64); const l = [53, 15, 35, 75][Math.floor(b / 64)]; return `hsl(${h}, ${sat}%, ${l}%)`; }); - return scheme.colors.map((_, i): string => - palette[scheme.colors[i < 18 ? (i + rot) % 18 : 18]] + return scheme.colors.map( + (_, i): string => palette[scheme.colors[i < 18 ? (i + rot) % 18 : 18]] ); } /** * @description Generate a array of the circles that make up an indenticon */ -export default function generate (address: string, isSixPoint = false): Circle[] { +export default function generate( + address: string, + isSixPoint = false +): Circle[] { const colors = getColors(address); return [OUTER_CIRCLE].concat( - getCircleXY(isSixPoint).map(([cx, cy], index): Circle => ({ - cx, cy, r: Z, fill: colors[index] - })) + getCircleXY(isSixPoint).map( + ([cx, cy], index): Circle => ({ + cx, + cy, + r: Z, + fill: colors[index], + }) + ) ); } @@ -159,29 +198,20 @@ export namespace PolkadotIcon { } export class PolkadotIcon extends React.Component { - public render (): React.ReactNode { + public render(): React.ReactNode { const { account, size } = this.props; return ( - + {generate(account, false).map(this.renderCircle)} ); } - private renderCircle = ({ cx, cy, r, fill }: Circle, key: number): React.ReactNode => { - return ( - - ); - } + private renderCircle = ( + { cx, cy, r, fill }: Circle, + key: number + ): React.ReactNode => { + return ; + }; } diff --git a/packages/frontend/src/components/Settings/Setting.css b/packages/frontend/src/components/Settings/Setting.css index 88d2d93..8f87c81 100644 --- a/packages/frontend/src/components/Settings/Setting.css +++ b/packages/frontend/src/components/Settings/Setting.css @@ -1,5 +1,5 @@ .Setting { - color: #635F5F; + color: #635f5f; padding: 0; margin: 0 0 8px 0; cursor: pointer; @@ -25,8 +25,8 @@ } .Setting-on .Setting-switch { - background: #E6007A; - border-color: #E6007A; + background: #e6007a; + border-color: #e6007a; } .Setting-knob { diff --git a/packages/frontend/src/components/Settings/Setting.tsx b/packages/frontend/src/components/Settings/Setting.tsx index 81d3fd1..013ce74 100644 --- a/packages/frontend/src/components/Settings/Setting.tsx +++ b/packages/frontend/src/components/Settings/Setting.tsx @@ -19,7 +19,7 @@ export class Setting extends React.Component { const { icon, label, setting, settings } = this.props; const checked = settings.get(setting); - const className = checked ? "Setting Setting-on" : "Setting"; + const className = checked ? 'Setting Setting-on' : 'Setting'; return (
@@ -36,5 +36,5 @@ export class Setting extends React.Component { const { setting, settings } = this.props; settings.set(setting, !settings.get(setting)); - } + }; } diff --git a/packages/frontend/src/components/Settings/Settings.tsx b/packages/frontend/src/components/Settings/Settings.tsx index 44720e9..4fdd3a0 100644 --- a/packages/frontend/src/components/Settings/Settings.tsx +++ b/packages/frontend/src/components/Settings/Settings.tsx @@ -29,16 +29,21 @@ export class Settings extends React.Component {

List View

Visible Columns

- { - Row.columns - .map(({ label, icon, setting }, index) => { - if (!setting) { - return null; - } + {Row.columns.map(({ label, icon, setting }, index) => { + if (!setting) { + return null; + } - return ; - }) - } + return ( + + ); + })}
); diff --git a/packages/frontend/src/components/Sparkline.tsx b/packages/frontend/src/components/Sparkline.tsx index af36c48..a4ad368 100644 --- a/packages/frontend/src/components/Sparkline.tsx +++ b/packages/frontend/src/components/Sparkline.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; -import { Types, Maybe } from "@dotstats/common"; -import sparkline from "@fnando/sparkline"; +import { Types, Maybe } from '@dotstats/common'; +import sparkline from '@fnando/sparkline'; import { Tooltip } from './'; import './Sparkline.css'; @@ -33,7 +33,12 @@ export class Sparkline extends React.Component { public shouldComponentUpdate(nextProps: Sparkline.Props): boolean { const { stroke, width, height, minScale, format } = this.props; - if (stroke !== nextProps.stroke || width !== nextProps.width || height !== nextProps.height || format !== nextProps.format) { + if ( + stroke !== nextProps.stroke || + width !== nextProps.width || + height !== nextProps.height || + format !== nextProps.format + ) { return true; } @@ -54,22 +59,33 @@ export class Sparkline extends React.Component { return ( - + ); } private onRef = (el: SVGSVGElement) => { this.el = el; - } + }; private onTooltipInit = (update: Tooltip.UpdateCallback) => { this.update = update; - } + }; - private onMouseMove = (event: MouseEvent, data: { value: number, index: number }) => { + private onMouseMove = ( + event: MouseEvent, + data: { value: number; index: number } + ) => { const { format, stamps } = this.props; - const str = format ? format(data.value, stamps ? stamps[data.index] : null) : `${data.value}`; + const str = format + ? format(data.value, stamps ? stamps[data.index] : null) + : `${data.value}`; this.update(str); - } + }; } diff --git a/packages/frontend/src/components/Tile.css b/packages/frontend/src/components/Tile.css index c87db0a..6c5967d 100644 --- a/packages/frontend/src/components/Tile.css +++ b/packages/frontend/src/components/Tile.css @@ -29,9 +29,9 @@ position: absolute; left: 20px; top: 20px; - font-size: .8em; + font-size: 0.8em; padding: 0.5em; border-radius: 1.25em; - border: 2px solid #E6007A; - color: #E6007A; + border: 2px solid #e6007a; + color: #e6007a; } diff --git a/packages/frontend/src/components/Tile.tsx b/packages/frontend/src/components/Tile.tsx index 4a2e91a..5f35994 100644 --- a/packages/frontend/src/components/Tile.tsx +++ b/packages/frontend/src/components/Tile.tsx @@ -4,9 +4,9 @@ import { Icon } from './Icon'; export namespace Tile { export interface Props { - title: string, - icon: string, - children?: React.ReactNode, + title: string; + icon: string; + children?: React.ReactNode; } } diff --git a/packages/frontend/src/components/Tooltip.css b/packages/frontend/src/components/Tooltip.css index 10b0b62..8a0a354 100644 --- a/packages/frontend/src/components/Tooltip.css +++ b/packages/frontend/src/components/Tooltip.css @@ -12,7 +12,7 @@ left: 50%; transform: translateX(-50%); display: none; - box-shadow: 0 2px 10px rgba(0,0,0,0.5); + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.5); pointer-events: none; transition: color 0.15s ease-in-out; } diff --git a/packages/frontend/src/components/Tooltip.tsx b/packages/frontend/src/components/Tooltip.tsx index 9208260..2da1612 100644 --- a/packages/frontend/src/components/Tooltip.tsx +++ b/packages/frontend/src/components/Tooltip.tsx @@ -26,7 +26,7 @@ function copyToClipboard(text: string) { el.select(); document.execCommand('copy'); document.body.removeChild(el); -}; +} export class Tooltip extends React.Component { public state = { copied: false }; @@ -69,7 +69,9 @@ export class Tooltip extends React.Component { return (
-
{copied ? 'Copied to clipboard!' : text}
+
+ {copied ? 'Copied to clipboard!' : text} +
{this.props.children}
); @@ -77,11 +79,11 @@ export class Tooltip extends React.Component { private onRef = (el: HTMLDivElement) => { this.el = el; - } + }; private update = (text: string) => { this.el.textContent = text; - } + }; private onClick = (event: React.MouseEvent) => { if (this.props.copy !== true) { @@ -96,9 +98,9 @@ export class Tooltip extends React.Component { this.setState({ copied: true }); this.timer = setTimeout(this.restore, 2000); - } + }; private restore = () => { this.setState({ copied: false }); - } + }; } diff --git a/packages/frontend/src/icons/assets.d.ts b/packages/frontend/src/icons/assets.d.ts index dd4ab7e..bff9471 100644 --- a/packages/frontend/src/icons/assets.d.ts +++ b/packages/frontend/src/icons/assets.d.ts @@ -1 +1 @@ -declare module "*.svg"; +declare module '*.svg'; diff --git a/packages/frontend/src/index.tsx b/packages/frontend/src/index.tsx index a7563e0..04e438a 100644 --- a/packages/frontend/src/index.tsx +++ b/packages/frontend/src/index.tsx @@ -4,9 +4,6 @@ import App from './App'; import './index.css'; import { unregister } from './registerServiceWorker'; -ReactDOM.render( - , - document.getElementById('root') as HTMLElement -); +ReactDOM.render(, document.getElementById('root') as HTMLElement); unregister(); diff --git a/packages/frontend/src/persist/Persistent.ts b/packages/frontend/src/persist/Persistent.ts index 6c02897..00c1a0c 100644 --- a/packages/frontend/src/persist/Persistent.ts +++ b/packages/frontend/src/persist/Persistent.ts @@ -5,7 +5,11 @@ export class Persistent { private readonly key: string; private value: Data; - constructor(key: string, initial: Data, onChange: (value: Readonly) => void) { + constructor( + key: string, + initial: Data, + onChange: (value: Readonly) => void + ) { this.key = key; this.onChange = onChange; @@ -23,7 +27,7 @@ export class Persistent { window.addEventListener('storage', (event) => { if (event.key === this.key) { - this.value = parse(event.newValue as any as Stringified); + this.value = parse((event.newValue as any) as Stringified); this.onChange(this.value); } @@ -36,7 +40,10 @@ export class Persistent { public set(value: Data) { this.value = value; - window.localStorage.setItem(this.key, stringify(this.value) as any as string); + window.localStorage.setItem( + this.key, + (stringify(this.value) as any) as string + ); this.onChange(this.value); } } diff --git a/packages/frontend/src/persist/PersistentSet.ts b/packages/frontend/src/persist/PersistentSet.ts index bd22f8a..a89a6cc 100644 --- a/packages/frontend/src/persist/PersistentSet.ts +++ b/packages/frontend/src/persist/PersistentSet.ts @@ -5,7 +5,9 @@ export class PersistentSet { private value: Set; constructor(key: string, onChange: (value: Set) => void) { - this.inner = new Persistent(key, [], (raw: Readonly) => onChange(this.value = new Set(raw as Item[]))); + this.inner = new Persistent(key, [], (raw: Readonly) => + onChange((this.value = new Set(raw as Item[]))) + ); this.value = new Set(this.inner.get() as Item[]); } diff --git a/packages/frontend/src/registerServiceWorker.ts b/packages/frontend/src/registerServiceWorker.ts index 0b85282..6855fe1 100644 --- a/packages/frontend/src/registerServiceWorker.ts +++ b/packages/frontend/src/registerServiceWorker.ts @@ -11,7 +11,7 @@ export function unregister() { if ('serviceWorker' in navigator) { - navigator.serviceWorker.ready.then(registration => { + navigator.serviceWorker.ready.then((registration) => { registration.unregister(); }); } diff --git a/packages/frontend/src/state.ts b/packages/frontend/src/state.ts index 78b8020..cc20ab5 100644 --- a/packages/frontend/src/state.ts +++ b/packages/frontend/src/state.ts @@ -7,8 +7,10 @@ export class Node { public static compare(a: Node, b: Node): number { if (a.pinned === b.pinned && a.stale === b.stale) { if (a.height === b.height) { - const aPropagation = a.propagationTime == null ? Infinity : a.propagationTime as number; - const bPropagation = b.propagationTime == null ? Infinity : b.propagationTime as number; + const aPropagation = + a.propagationTime == null ? Infinity : (a.propagationTime as number); + const bPropagation = + b.propagationTime == null ? Infinity : (b.propagationTime as number); // Ascending sort by propagation time return aPropagation - bPropagation; @@ -74,7 +76,7 @@ export class Node { nodeHardware: Types.NodeHardware, blockDetails: Types.BlockDetails, location: Maybe, - connectedAt: Types.Timestamp, + connectedAt: Types.Timestamp ) { const [name, implementation, version, validator, networkId] = nodeDetails; @@ -88,7 +90,9 @@ export class Node { this.networkId = networkId; this.connectedAt = connectedAt; - const [major = 0, minor = 0, patch = 0] = (version || '0.0.0').split('.').map((n) => parseInt(n, 10) | 0); + const [major = 0, minor = 0, patch = 0] = (version || '0.0.0') + .split('.') + .map((n) => parseInt(n, 10) | 0); this.sortableName = name.toLocaleLowerCase(); this.sortableVersion = (major * 1000 + minor * 100 + patch) | 0; @@ -262,8 +266,12 @@ export interface State { selectedColumns: Column[]; } -export type Update = (changes: Pick | null) => Readonly; -export type UpdateBound = (changes: Pick | null) => void; +export type Update = ( + changes: Pick | null +) => Readonly; +export type UpdateBound = ( + changes: Pick | null +) => void; export interface ChainData { label: Types.ChainLabel; diff --git a/packages/frontend/src/utils.ts b/packages/frontend/src/utils.ts index af28f79..9585ef8 100644 --- a/packages/frontend/src/utils.ts +++ b/packages/frontend/src/utils.ts @@ -6,14 +6,20 @@ export interface Viewport { } export function viewport(): Viewport { - const width = Math.max(document.documentElement.clientWidth, window.innerWidth || 0); - const height = Math.max(document.documentElement.clientHeight, window.innerHeight || 0); + const width = Math.max( + document.documentElement.clientWidth, + window.innerWidth || 0 + ); + const height = Math.max( + document.documentElement.clientHeight, + window.innerHeight || 0 + ); return { width, height }; } export function formatNumber(num: number): string { - const input = num.toString(); + const input = num.toString(); let output = ''; let length = input.length; @@ -38,7 +44,9 @@ export function trimHash(hash: string, length: number): string { return hash.substr(0, side) + '..' + hash.substr(-side, side); } -export function milliOrSecond(num: Types.Milliseconds | Types.PropagationTime): string { +export function milliOrSecond( + num: Types.Milliseconds | Types.PropagationTime +): string { if (num < 10000) { return `${num}ms`; } @@ -47,21 +55,25 @@ export function milliOrSecond(num: Types.Milliseconds | Types.PropagationTime): } export function secondsWithPrecision(num: number): string { - const intString = (num | 0).toString() + const intString = (num | 0).toString(); const intDigits = intString.length; switch (intDigits) { - case 1: return num.toFixed(3) + 's'; - case 2: return num.toFixed(2) + 's'; - case 3: return num.toFixed(1) + 's'; - default: return intString + 's'; + case 1: + return num.toFixed(3) + 's'; + case 2: + return num.toFixed(2) + 's'; + case 3: + return num.toFixed(1) + 's'; + default: + return intString + 's'; } } export interface HashData { tab?: string; chain?: Types.ChainLabel; -}; +} export function getHashData(): HashData { const { hash } = window.location; diff --git a/packages/frontend/tslint.json b/packages/frontend/tslint.json index e73d4bb..7ae3abf 100644 --- a/packages/frontend/tslint.json +++ b/packages/frontend/tslint.json @@ -1,19 +1,23 @@ { - "extends": ["tslint:recommended", "tslint-react", "tslint-config-prettier"], + "extends": [ + "tslint:recommended", + "tslint-react", + "tslint-plugin-prettier", + "tslint-config-prettier" + ], "linterOptions": { - "exclude": [ - "config/**/*.js", - "node_modules/**/*.ts" - ] + "exclude": ["config/**/*.js", "node_modules/**/*.ts"] }, "rules": { + "prettier": true, "ordered-imports": false, "object-literal-sort-keys": false, "no-console": false, - "no-unused-variable": [true, {"ignore-pattern": "^_"}], "no-empty": false, "no-namespace": false, "no-bitwise": false, + "quotemark": [true, "single", "jsx-double"], + "semicolon": [true, "always", "ignore-bound-class-methods"], "interface-name": false } } diff --git a/yarn.lock b/yarn.lock index 085efea..29782fa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,13 @@ # yarn lockfile v1 +"@babel/code-frame@^7.0.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.8.3.tgz#33e25903d7481181534e12ec0a25f16b6fcf419e" + integrity sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g== + dependencies: + "@babel/highlight" "^7.8.3" + "@babel/code-frame@^7.0.0-beta.35": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8" @@ -9,6 +16,11 @@ dependencies: "@babel/highlight" "^7.0.0" +"@babel/helper-validator-identifier@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.0.tgz#ad53562a7fc29b3b9a91bbf7d10397fd146346ed" + integrity sha512-6G8bQKjOh+of4PV/ThDm/rRqlU7+IGoJuofpagU5GlEl29Vv0RGqqt86ZGRV8ZuSOY3o+8yXl5y782SMcG7SHw== + "@babel/highlight@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0.tgz#f710c38c8d458e6dd9a201afb637fcb781ce99e4" @@ -18,6 +30,15 @@ esutils "^2.0.2" js-tokens "^4.0.0" +"@babel/highlight@^7.8.3": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.9.0.tgz#4e9b45ccb82b79607271b2979ad82c7b68163079" + integrity sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ== + dependencies: + "@babel/helper-validator-identifier" "^7.9.0" + chalk "^2.0.0" + js-tokens "^4.0.0" + "@babel/runtime@^7.2.0": version "7.4.3" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.4.3.tgz#79888e452034223ad9609187a0ad1fe0d2ad4bdc" @@ -32,6 +53,13 @@ dependencies: regenerator-runtime "^0.13.2" +"@babel/runtime@^7.8.7": + version "7.9.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.9.2.tgz#d90df0583a3a252f09aaa619665367bae518db06" + integrity sha512-NE2DtOdufG7R5vnfQUTehdTfNycfUANEtCa9PssN9O/xmTzP4E08UI797ixaei6hBEVL9BI/PsdJS5x7mWoB9Q== + dependencies: + regenerator-runtime "^0.13.4" + "@fnando/sparkline@maciejhirsz/sparkline": version "0.3.10" resolved "https://codeload.github.com/maciejhirsz/sparkline/tar.gz/2bdb002b171436be078a84f1e4e617a44ef1fb42" @@ -76,6 +104,13 @@ resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto/-/wasm-crypto-0.14.1.tgz#f4923bba22d7c68a4be3575ba27790947b212633" integrity sha512-Xng7L2Z8TNZa/5g6pot4O06Jf0ohQRZdvfl8eQL+E/L2mcqJYC1IjkMxJBSBuQEV7hisWzh9mHOy5WCcgPk29Q== +"@samverschueren/stream-to-observable@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz#ecdf48d532c58ea477acfcab80348424f8d0662f" + integrity sha512-MI4Xx6LHs4Webyvi6EbspgyAb4D2Q2VtnCQ1blOJcoLS6mVa8lNN2rkIy1CVxfTUpoyIbCTkXES1rLXztFD1lg== + dependencies: + any-observable "^0.3.0" + "@tanem/svg-injector@^1.2.1": version "1.2.1" resolved "https://registry.yarnpkg.com/@tanem/svg-injector/-/svg-injector-1.2.1.tgz#3120e90246d0eb3c4fc6c61586a6f028a3c658ae" @@ -109,6 +144,11 @@ dependencies: "@types/base-x" "*" +"@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" + integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== + "@types/jest@^23.0.2": version "23.3.12" resolved "https://registry.yarnpkg.com/@types/jest/-/jest-23.3.12.tgz#7e0ced251fa94c3bc2d1023d4b84b2992fa06376" @@ -124,6 +164,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.18.tgz#1d3ca764718915584fcd9f6344621b7672665c67" integrity sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ== +"@types/parse-json@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" + integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== + "@types/pbkdf2@^3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@types/pbkdf2/-/pbkdf2-3.0.0.tgz#5d9ca5f12a78a08cc89ad72883ad4a30af359229" @@ -320,6 +365,19 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1: dependencies: color-convert "^1.9.0" +ansi-styles@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359" + integrity sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA== + dependencies: + "@types/color-name" "^1.1.1" + color-convert "^2.0.1" + +any-observable@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/any-observable/-/any-observable-0.3.0.tgz#af933475e5806a67d0d7df090dd5e8bef65d119b" + integrity sha512-/FQM1EDkTsf63Ub2C6O7GuYFDsSXUwsaZDurV0np41ocwq0jthUAYCmhBX9f+KwlaCgIuWyr/4WlUQUBfKfZog== + anymatch@^1.3.0: version "1.3.2" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a" @@ -1515,6 +1573,13 @@ braces@^2.3.0, braces@^2.3.1: split-string "^3.0.2" to-regex "^3.0.1" +braces@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + brorand@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" @@ -1719,6 +1784,11 @@ callsites@^2.0.0: resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + camel-case@3.0.x: version "3.0.0" resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73" @@ -1830,6 +1900,14 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" +chalk@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" + integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + chardet@^0.4.0: version "0.4.2" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" @@ -1893,6 +1971,11 @@ ci-info@^1.5.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" integrity sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A== +ci-info@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" + integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== + cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" @@ -1930,13 +2013,21 @@ cli-boxes@^1.0.0: resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" integrity sha1-T6kXw+WclKAEzWH47lCdplFocUM= -cli-cursor@^2.1.0: +cli-cursor@^2.0.0, cli-cursor@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= dependencies: restore-cursor "^2.0.0" +cli-truncate@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-0.2.1.tgz#9f15cfbb0705005369216c626ac7d05ab90dd574" + integrity sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ= + dependencies: + slice-ansi "0.0.4" + string-width "^1.0.1" + cli-width@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" @@ -2006,12 +2097,19 @@ color-convert@^1.3.0, color-convert@^1.9.0: dependencies: color-name "1.1.3" +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + color-name@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= -color-name@^1.0.0: +color-name@^1.0.0, color-name@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== @@ -2063,6 +2161,11 @@ commander@^2.12.1, commander@^2.19.0: resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== +commander@^4.0.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" + integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== + commander@~2.13.0: version "2.13.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c" @@ -2078,6 +2181,11 @@ commondir@^1.0.1: resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= +compare-versions@^3.5.1: + version "3.6.0" + resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.6.0.tgz#1a5689913685e5a87637b8d3ffca75514ec41d62" + integrity sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA== + component-emitter@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" @@ -2224,6 +2332,17 @@ cosmiconfig@^2.1.0, cosmiconfig@^2.1.1: parse-json "^2.2.0" require-from-string "^1.1.0" +cosmiconfig@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982" + integrity sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg== + dependencies: + "@types/parse-json" "^4.0.0" + import-fresh "^3.1.0" + parse-json "^5.0.0" + path-type "^4.0.0" + yaml "^1.7.2" + cpx@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/cpx/-/cpx-1.5.0.tgz#185be018511d87270dedccc293171e37655ab88f" @@ -2288,6 +2407,15 @@ cross-spawn@5.1.0, cross-spawn@^5.0.1: shebang-command "^1.2.0" which "^1.2.9" +cross-spawn@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.1.tgz#0ab56286e0f7c24e153d04cc2aa027e43a9a5d14" + integrity sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + crypto-browserify@^3.11.0: version "3.12.0" resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" @@ -2467,6 +2595,11 @@ data-urls@^1.0.0: whatwg-mimetype "^2.2.0" whatwg-url "^7.0.0" +date-fns@^1.27.2: + version "1.30.1" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.30.1.tgz#2e71bf0b119153dbb4cc4e88d9ea5acfb50dc05c" + integrity sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw== + date-now@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" @@ -2493,6 +2626,13 @@ debug@^3.1.0: dependencies: ms "^2.1.1" +debug@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" + integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== + dependencies: + ms "^2.1.1" + 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" @@ -2503,6 +2643,11 @@ decode-uri-component@^0.2.0: resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= +dedent@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" + integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= + deep-equal@^1.0.1, deep-equal@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" @@ -2652,6 +2797,11 @@ diff@^3.2.0: resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + diffie-hellman@^5.0.0: version "5.0.3" resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" @@ -2831,6 +2981,11 @@ electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.30, electron-to-chromium@ resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.103.tgz#a695777efdbc419cad6cbb0e58458251302cd52f" integrity sha512-tObPqGmY9X8MUM8i3MEimYmbnLLf05/QV5gPlkR8MQ3Uj8G8B2govE1U4cQcBYtv3ymck9Y8cIOu4waoiykMZQ== +elegant-spinner@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e" + integrity sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4= + elliptic@^6.0.0: version "6.4.1" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.1.tgz#c2d0b7776911b86722c632c3c06c60f2f819939a" @@ -2951,7 +3106,7 @@ errno@^0.1.3, errno@~0.1.7: dependencies: prr "~1.0.1" -error-ex@^1.2.0: +error-ex@^1.2.0, error-ex@^1.3.1: version "1.3.2" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== @@ -3075,6 +3230,14 @@ escope@^3.6.0: esrecurse "^4.1.0" estraverse "^4.1.1" +eslint-plugin-prettier@^2.2.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-2.7.0.tgz#b4312dcf2c1d965379d7f9d5b5f8aaadc6a45904" + integrity sha512-CStQYJgALoQBw3FsBzH0VOVDRnJ/ZimUlpLm226U8qgqYJfPOY/CPK6wyRInMxh73HSKg5wyRwdS4BVYYHwokA== + dependencies: + fast-diff "^1.1.1" + jest-docblock "^21.0.0" + esprima@^2.6.0: version "2.7.3" resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" @@ -3165,6 +3328,22 @@ execa@^0.7.0: signal-exit "^3.0.0" strip-eof "^1.0.0" +execa@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-3.4.0.tgz#c08ed4550ef65d858fac269ffc8572446f37eb89" + integrity sha512-r9vdGQk4bmCuK1yKQu1KTwcT2zwfWdbdaXfCtAh+5nU/4fSX+JAb7vZGvI5naJrQlvONrEB20jeruESI69530g== + dependencies: + cross-spawn "^7.0.0" + get-stream "^5.0.0" + human-signals "^1.1.1" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.0" + onetime "^5.1.0" + p-finally "^2.0.0" + signal-exit "^3.0.2" + strip-final-newline "^2.0.0" + exit@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" @@ -3344,6 +3523,11 @@ fast-deep-equal@^2.0.1: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= +fast-diff@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" + integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== + fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" @@ -3393,7 +3577,7 @@ fbjs@^0.8.16: setimmediate "^1.0.5" ua-parser-js "^0.7.18" -figures@^1.4.0: +figures@^1.4.0, figures@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" integrity sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4= @@ -3459,6 +3643,13 @@ fill-range@^4.0.0: repeat-string "^1.6.1" to-regex-range "^2.1.0" +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + finalhandler@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.1.tgz#eebf4ed840079c83f4249038c9d703008301b105" @@ -3501,6 +3692,21 @@ find-up@^2.0.0, find-up@^2.1.0: dependencies: locate-path "^2.0.0" +find-up@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +find-versions@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/find-versions/-/find-versions-3.2.0.tgz#10297f98030a786829681690545ef659ed1d254e" + integrity sha512-P8WRou2S+oe222TOCHitLy8zj+SIsVJh52VP4lvXkaFVnOFFdoWv1H1Jjvel1aI6NCFOAaeAVm8qrI0odiLcww== + dependencies: + semver-regex "^2.0.0" + flatten@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782" @@ -3690,6 +3896,11 @@ get-node-dimensions@^1.2.1: resolved "https://registry.yarnpkg.com/get-node-dimensions/-/get-node-dimensions-1.2.1.tgz#fb7b4bb57060fb4247dd51c9d690dfbec56b0823" integrity sha512-2MSPMu7S1iOTL+BOa6K1S62hB2zUAYNF/lV0gSVlOaacd087lc6nR1H1r0e3B1CerTo+RceOmi1iJW+vp21xcQ== +get-own-enumerable-property-symbols@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" + integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g== + get-stdin@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" @@ -3700,6 +3911,13 @@ get-stream@^3.0.0: resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= +get-stream@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.1.0.tgz#01203cdc92597f9b909067c3e656cc1f4d3c4dc9" + integrity sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw== + dependencies: + pump "^3.0.0" + get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" @@ -3894,6 +4112,11 @@ has-flag@^3.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + has-symbols@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" @@ -4119,6 +4342,27 @@ https-browserify@^1.0.0: resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= +human-signals@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" + integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== + +husky@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/husky/-/husky-4.2.3.tgz#3b18d2ee5febe99e27f2983500202daffbc3151e" + integrity sha512-VxTsSTRwYveKXN4SaH1/FefRJYCtx+wx04sSVcOpD7N2zjoHxa+cEJ07Qg5NmV3HAK+IRKOyNVpi2YBIVccIfQ== + dependencies: + chalk "^3.0.0" + ci-info "^2.0.0" + compare-versions "^3.5.1" + cosmiconfig "^6.0.0" + find-versions "^3.2.0" + opencollective-postinstall "^2.0.2" + pkg-dir "^4.2.0" + please-upgrade-node "^3.2.0" + slash "^3.0.0" + which-pm-runs "^1.0.0" + iconv-lite@0.4.23: version "0.4.23" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" @@ -4162,6 +4406,14 @@ ignore-walk@^3.0.1: dependencies: minimatch "^3.0.4" +import-fresh@^3.1.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66" + integrity sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + import-lazy@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" @@ -4195,6 +4447,11 @@ indent-string@^2.1.0: dependencies: repeating "^2.0.0" +indent-string@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" + integrity sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok= + indexes-of@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" @@ -4505,11 +4762,23 @@ is-number@^4.0.0: resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ== -is-obj@^1.0.0: +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-obj@^1.0.0, is-obj@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= +is-observable@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-observable/-/is-observable-1.1.0.tgz#b3e986c8f44de950867cab5403f5a3465005975e" + integrity sha512-NqCa4Sa2d+u7BWc6CukaObG3Fh+CU9bvixbpcXYhy2VvYS7vVGIdAgnIS5Ks3A/cqk4rebLJ9s8zBstT2aKnIA== + dependencies: + symbol-observable "^1.1.0" + is-path-cwd@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" @@ -4568,6 +4837,11 @@ is-regex@^1.0.4: dependencies: has "^1.0.1" +is-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" + integrity sha1-/S2INUXEa6xaYz57mgnof6LLUGk= + is-retry-allowed@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" @@ -4583,6 +4857,11 @@ is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0: resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= +is-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" + integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== + is-string@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.4.tgz#cc3a9b69857d621e963725a24caeec873b826e64" @@ -4890,6 +5169,11 @@ jest-diff@^23.6.0: jest-get-type "^22.1.0" pretty-format "^23.6.0" +jest-docblock@^21.0.0: + version "21.2.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-21.2.0.tgz#51529c3b30d5fd159da60c27ceedc195faf8d414" + integrity sha512-5IZ7sY9dBAYSV+YjQ0Ovb540Ku7AO9Z5o2Cg789xj167iQuZ2cG+z0f3Uct6WeYLbU6aQiM2pCs7sZ+4dotydw== + jest-docblock@^22.4.0, jest-docblock@^22.4.3: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-22.4.3.tgz#50886f132b42b280c903c592373bb6e93bb68b19" @@ -5358,6 +5642,14 @@ js-tokens@^3.0.2: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= +js-yaml@^3.13.1: + version "3.13.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" + integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + js-yaml@^3.4.3, js-yaml@^3.7.0: version "3.12.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.1.tgz#295c8632a18a23e054cf5c9d3cecafe678167600" @@ -5426,6 +5718,11 @@ json-loader@^0.5.4: resolved "https://registry.yarnpkg.com/json-loader/-/json-loader-0.5.7.tgz#dca14a70235ff82f0ac9a3abeb60d337a365185d" integrity sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w== +json-parse-better-errors@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== + json-schema-traverse@^0.3.0: version "0.3.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" @@ -5572,6 +5869,74 @@ levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" +lines-and-columns@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" + integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= + +lint-staged@^10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-10.1.0.tgz#18785bb005d5ed404f1c1db6563e082f7a7baac2" + integrity sha512-WzZ/T+O/aEaaT679sMgI4JqK5mnG69V5KQSouzVsShzZ8wGWte39HT3z61LsxjVNeCf8m/ChhvWJa2wTiQLy5A== + dependencies: + chalk "^3.0.0" + commander "^4.0.1" + cosmiconfig "^6.0.0" + debug "^4.1.1" + dedent "^0.7.0" + execa "^3.4.0" + listr "^0.14.3" + log-symbols "^3.0.0" + micromatch "^4.0.2" + normalize-path "^3.0.0" + please-upgrade-node "^3.2.0" + string-argv "0.3.1" + stringify-object "^3.3.0" + +listr-silent-renderer@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz#924b5a3757153770bf1a8e3fbf74b8bbf3f9242e" + integrity sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4= + +listr-update-renderer@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/listr-update-renderer/-/listr-update-renderer-0.5.0.tgz#4ea8368548a7b8aecb7e06d8c95cb45ae2ede6a2" + integrity sha512-tKRsZpKz8GSGqoI/+caPmfrypiaq+OQCbd+CovEC24uk1h952lVj5sC7SqyFUm+OaJ5HN/a1YLt5cit2FMNsFA== + dependencies: + chalk "^1.1.3" + cli-truncate "^0.2.1" + elegant-spinner "^1.0.1" + figures "^1.7.0" + indent-string "^3.0.0" + log-symbols "^1.0.2" + log-update "^2.3.0" + strip-ansi "^3.0.1" + +listr-verbose-renderer@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/listr-verbose-renderer/-/listr-verbose-renderer-0.5.0.tgz#f1132167535ea4c1261102b9f28dac7cba1e03db" + integrity sha512-04PDPqSlsqIOaaaGZ+41vq5FejI9auqTInicFRndCBgE3bXG8D6W1I+mWhk+1nqbHmyhla/6BUrd5OSiHwKRXw== + dependencies: + chalk "^2.4.1" + cli-cursor "^2.1.0" + date-fns "^1.27.2" + figures "^2.0.0" + +listr@^0.14.3: + version "0.14.3" + resolved "https://registry.yarnpkg.com/listr/-/listr-0.14.3.tgz#2fea909604e434be464c50bddba0d496928fa586" + integrity sha512-RmAl7su35BFd/xoMamRjpIE4j3v+L28o8CT5YhAXQJm1fD+1l9ngXY8JAQRJ+tFK2i5njvi0iRUKV09vPwA0iA== + dependencies: + "@samverschueren/stream-to-observable" "^0.3.0" + is-observable "^1.1.0" + is-promise "^2.1.0" + is-stream "^1.1.0" + listr-silent-renderer "^1.1.1" + listr-update-renderer "^0.5.0" + listr-verbose-renderer "^0.5.0" + p-map "^2.0.0" + rxjs "^6.3.3" + load-json-file@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" @@ -5625,6 +5990,13 @@ locate-path@^2.0.0: p-locate "^2.0.0" path-exists "^3.0.0" +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + lodash._reinterpolate@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" @@ -5715,6 +6087,29 @@ lodash.uniq@^4.5.0: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== +log-symbols@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18" + integrity sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg= + dependencies: + chalk "^1.0.0" + +log-symbols@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-3.0.0.tgz#f3a08516a5dea893336a7dee14d18a1cfdab77c4" + integrity sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ== + dependencies: + chalk "^2.4.2" + +log-update@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/log-update/-/log-update-2.3.0.tgz#88328fd7d1ce7938b29283746f0b1bc126b24708" + integrity sha1-iDKP19HOeTiykoN0bwsbwSayRwg= + dependencies: + ansi-escapes "^3.0.0" + cli-cursor "^2.0.0" + wrap-ansi "^3.0.1" + loglevel@^1.4.1: version "1.6.1" resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.1.tgz#e0fc95133b6ef276cdc8887cdaf24aa6f156f8fa" @@ -5861,6 +6256,11 @@ merge-stream@^1.0.1: dependencies: readable-stream "^2.0.1" +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + merge@^1.2.0: version "1.2.1" resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.1.tgz#38bebf80c3220a8a487b6fcfb3941bb11720c145" @@ -5909,6 +6309,14 @@ micromatch@^3.1.10, micromatch@^3.1.4: snapdragon "^0.8.1" to-regex "^3.0.2" +micromatch@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" + integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q== + dependencies: + braces "^3.0.1" + picomatch "^2.0.5" + miller-rabin@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" @@ -5944,6 +6352,11 @@ mimic-fn@^1.0.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" @@ -6258,6 +6671,11 @@ normalize-path@^2.0.0, normalize-path@^2.0.1, normalize-path@^2.1.1: dependencies: remove-trailing-separator "^1.0.1" +normalize-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + normalize-range@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" @@ -6293,6 +6711,13 @@ npm-run-path@^2.0.0: dependencies: path-key "^2.0.0" +npm-run-path@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + npmlog@^4.0.2: version "4.1.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" @@ -6450,6 +6875,18 @@ onetime@^2.0.0: dependencies: mimic-fn "^1.0.0" +onetime@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.0.tgz#fff0f3c91617fe62bb50189636e99ac8a6df7be5" + integrity sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q== + dependencies: + mimic-fn "^2.1.0" + +opencollective-postinstall@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz#5657f1bede69b6e33a45939b061eb53d3c6c3a89" + integrity sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw== + opn@5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/opn/-/opn-5.2.0.tgz#71fdf934d6827d676cecbea1531f95d354641225" @@ -6535,6 +6972,11 @@ p-finally@^1.0.0: resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= +p-finally@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-2.0.1.tgz#bd6fcaa9c559a096b680806f4d657b3f0f240561" + integrity sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw== + p-limit@^1.1.0: version "1.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" @@ -6542,6 +6984,13 @@ p-limit@^1.1.0: dependencies: p-try "^1.0.0" +p-limit@^2.2.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.2.tgz#61279b67721f5287aa1c13a9a7fbbc48c9291b1e" + integrity sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ== + dependencies: + p-try "^2.0.0" + p-locate@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" @@ -6549,16 +6998,33 @@ p-locate@^2.0.0: dependencies: p-limit "^1.1.0" +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + p-map@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b" integrity sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA== +p-map@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" + integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw== + p-try@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + package-json@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" @@ -6590,6 +7056,13 @@ param-case@2.1.x: dependencies: no-case "^2.2.0" +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + parse-asn1@^5.0.0: version "5.1.3" resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.3.tgz#1600c6cc0727365d68b97f3aa78939e735a75204" @@ -6619,6 +7092,16 @@ parse-json@^2.2.0: dependencies: error-ex "^1.2.0" +parse-json@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.0.0.tgz#73e5114c986d143efa3712d4ea24db9a4266f60f" + integrity sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + lines-and-columns "^1.1.6" + parse-ms@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/parse-ms/-/parse-ms-1.0.1.tgz#56346d4749d78f23430ca0c713850aef91aa361d" @@ -6673,6 +7156,11 @@ path-exists@^3.0.0: resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" @@ -6688,6 +7176,11 @@ path-key@^2.0.0: resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + path-parse@^1.0.5, path-parse@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" @@ -6721,6 +7214,11 @@ path-type@^2.0.0: dependencies: pify "^2.0.0" +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + pbkdf2@^3.0.3, pbkdf2@^3.0.9: version "3.0.17" resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" @@ -6737,6 +7235,11 @@ performance-now@^2.1.0: resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= +picomatch@^2.0.5: + version "2.2.2" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" + integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== + pify@^2.0.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" @@ -6766,6 +7269,20 @@ pkg-dir@^2.0.0: dependencies: find-up "^2.1.0" +pkg-dir@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +please-upgrade-node@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz#aeddd3f994c933e4ad98b99d9a556efa0e2fe942" + integrity sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg== + dependencies: + semver-compare "^1.0.0" + plur@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/plur/-/plur-1.0.0.tgz#db85c6814f5e5e5a3b49efc28d604fec62975156" @@ -7127,6 +7644,11 @@ preserve@^0.2.0: resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks= +prettier@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.0.2.tgz#1ba8f3eb92231e769b7fcd7cb73ae1b6b74ade08" + integrity sha512-5xJQIPT8BraI7ZnaDwSbu5zLrB6vvi8hVV58yHQ+QK64qrY40dULy0HSRlQ2/2IdzeBpjhDkqdcFBnFeDEMVdg== + pretty-bytes@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-4.0.2.tgz#b2bf82e7350d65c6c33aa95aaa5a4f6327f61cd9" @@ -7263,6 +7785,14 @@ pump@^2.0.0, pump@^2.0.1: end-of-stream "^1.1.0" once "^1.3.1" +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + pumpify@^1.3.3: version "1.5.1" resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" @@ -7668,6 +8198,11 @@ regenerator-runtime@^0.13.2: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz#32e59c9a6fb9b1a4aff09b4930ca2d4477343447" integrity sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA== +regenerator-runtime@^0.13.4: + version "0.13.5" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz#d878a1d094b4306d10b9096484b33ebd55e26697" + integrity sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA== + regenerator-transform@^0.10.0: version "0.10.1" resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" @@ -7862,6 +8397,11 @@ resolve-from@^3.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" integrity sha1-six699nWiBvItuZTM17rywoYh0g= +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + resolve-url@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" @@ -7974,6 +8514,13 @@ rx-lite@*, rx-lite@^4.0.8: resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444" integrity sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ= +rxjs@^6.3.3: + version "6.5.4" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.4.tgz#e0777fe0d184cec7872df147f303572d414e211c" + integrity sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q== + dependencies: + tslib "^1.9.0" + safe-buffer@5.1.2, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" @@ -8061,6 +8608,11 @@ selfsigned@^1.9.1: dependencies: node-forge "0.7.5" +semver-compare@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" + integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= + semver-diff@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" @@ -8068,6 +8620,11 @@ semver-diff@^2.0.0: dependencies: semver "^5.0.3" +semver-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-2.0.0.tgz#a93c2c5844539a770233379107b38c7b4ac9d338" + integrity sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw== + "semver@2 || 3 || 4 || 5", semver@^5.0.1, semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5, semver@^5.5.0, semver@^5.6.0: version "5.6.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" @@ -8175,11 +8732,23 @@ shebang-command@^1.2.0: dependencies: shebang-regex "^1.0.0" +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + shebang-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + shell-quote@1.6.1, shell-quote@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.6.1.tgz#f4781949cce402697127430ea3b3c5476f481767" @@ -8210,6 +8779,16 @@ slash@^1.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +slice-ansi@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" + integrity sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU= + snapdragon-node@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" @@ -8495,6 +9074,11 @@ strict-uri-encode@^1.0.0: resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= +string-argv@0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da" + integrity sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg== + string-length@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/string-length/-/string-length-2.0.0.tgz#d40dbb686a3ace960c1cffca562bf2c45f8363ed" @@ -8555,6 +9139,15 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" +stringify-object@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629" + integrity sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw== + dependencies: + get-own-enumerable-property-symbols "^3.0.0" + is-obj "^1.0.1" + is-regexp "^1.0.0" + strip-ansi@3.0.1, strip-ansi@^3.0.0, strip-ansi@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" @@ -8586,6 +9179,11 @@ strip-eof@^1.0.0: resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + strip-indent@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" @@ -8639,6 +9237,13 @@ supports-color@^5.3.0, supports-color@^5.4.0: dependencies: has-flag "^3.0.0" +supports-color@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1" + integrity sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g== + dependencies: + has-flag "^4.0.0" + svgo@^0.7.0: version "0.7.2" resolved "https://registry.yarnpkg.com/svgo/-/svgo-0.7.2.tgz#9f5772413952135c6fefbf40afe6a4faa88b4bb5" @@ -8685,6 +9290,11 @@ sw-toolbox@^3.4.0: path-to-regexp "^1.0.1" serviceworker-cache-polyfill "^4.0.0" +symbol-observable@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" + integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== + symbol-tree@^3.2.2: version "3.2.2" resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6" @@ -8851,6 +9461,13 @@ to-regex-range@^2.1.0: is-number "^3.0.0" repeat-string "^1.6.1" +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + to-regex@^3.0.1, to-regex@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" @@ -8973,6 +9590,11 @@ tsconfig-paths@^3.1.1: minimist "^1.2.0" strip-bom "^3.0.0" +tslib@^1.10.0, tslib@^1.7.1, tslib@^1.9.0: + version "1.11.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35" + integrity sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA== + tslib@^1.8.0, tslib@^1.8.1: version "1.9.3" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" @@ -8983,6 +9605,20 @@ tslint-config-prettier@^1.10.0: resolved "https://registry.yarnpkg.com/tslint-config-prettier/-/tslint-config-prettier-1.17.0.tgz#946ed6117f98f3659a65848279156d87628c33dc" integrity sha512-NKWNkThwqE4Snn4Cm6SZB7lV5RMDDFsBwz6fWUkTxOKGjMx8ycOHnjIbhn7dZd5XmssW3CwqUjlANR6EhP9YQw== +tslint-config-prettier@^1.18.0: + version "1.18.0" + resolved "https://registry.yarnpkg.com/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz#75f140bde947d35d8f0d238e0ebf809d64592c37" + integrity sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg== + +tslint-plugin-prettier@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/tslint-plugin-prettier/-/tslint-plugin-prettier-2.3.0.tgz#73fe71bf9f03842ac48c104122ca9b1de012ecf4" + integrity sha512-F9e4K03yc9xuvv+A0v1EmjcnDwpz8SpCD8HzqSDe0eyg34cBinwn9JjmnnRrNAs4HdleRQj7qijp+P/JTxt4vA== + dependencies: + eslint-plugin-prettier "^2.2.0" + lines-and-columns "^1.1.6" + tslib "^1.7.1" + tslint-react@^3.2.0: version "3.6.0" resolved "https://registry.yarnpkg.com/tslint-react/-/tslint-react-3.6.0.tgz#7f462c95c4a0afaae82507f06517ff02942196a1" @@ -9008,7 +9644,26 @@ tslint@^5.7.0: tslib "^1.8.0" tsutils "^2.27.2" -tsutils@^2.13.1, tsutils@^2.27.2: +tslint@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/tslint/-/tslint-6.1.0.tgz#c6c611b8ba0eed1549bf5a59ba05a7732133d851" + integrity sha512-fXjYd/61vU6da04E505OZQGb2VCN2Mq3doeWcOIryuG+eqdmFUXTYVwdhnbEu2k46LNLgUYt9bI5icQze/j0bQ== + dependencies: + "@babel/code-frame" "^7.0.0" + builtin-modules "^1.1.1" + chalk "^2.3.0" + commander "^2.12.1" + diff "^4.0.1" + glob "^7.1.1" + js-yaml "^3.13.1" + minimatch "^3.0.4" + mkdirp "^0.5.1" + resolve "^1.3.2" + semver "^5.3.0" + tslib "^1.10.0" + tsutils "^2.29.0" + +tsutils@^2.13.1, tsutils@^2.27.2, tsutils@^2.29.0: version "2.29.0" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.29.0.tgz#32b488501467acbedd4b85498673a0812aca0b99" integrity sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA== @@ -9558,6 +10213,11 @@ which-module@^2.0.0: resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= +which-pm-runs@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/which-pm-runs/-/which-pm-runs-1.0.0.tgz#670b3afbc552e0b55df6b7780ca74615f23ad1cb" + integrity sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs= + which@^1.2.12, which@^1.2.14, which@^1.2.9, which@^1.3.0: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" @@ -9565,6 +10225,13 @@ which@^1.2.12, which@^1.2.14, which@^1.2.9, which@^1.3.0: dependencies: isexe "^2.0.0" +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + wide-align@^1.1.0: version "1.1.3" resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" @@ -9614,6 +10281,14 @@ wrap-ansi@^2.0.0: string-width "^1.0.1" strip-ansi "^3.0.1" +wrap-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-3.0.1.tgz#288a04d87eda5c286e060dfe8f135ce8d007f8ba" + integrity sha1-KIoE2H7aXChuBg3+jxNc6NAH+Lo= + dependencies: + string-width "^2.1.1" + strip-ansi "^4.0.0" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" @@ -9677,6 +10352,13 @@ yallist@^3.0.0, yallist@^3.0.2: resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9" integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A== +yaml@^1.7.2: + version "1.8.3" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.8.3.tgz#2f420fca58b68ce3a332d0ca64be1d191dd3f87a" + integrity sha512-X/v7VDnK+sxbQ2Imq4Jt2PRUsRsP7UcpSl3Llg6+NRRqWLIvxkMFYtH1FmvwNGYRKKPa+EPA4qDBlI9WVG1UKw== + dependencies: + "@babel/runtime" "^7.8.7" + yargs-parser@10.x: version "10.1.0" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8"