diff --git a/package.json b/package.json index 008e32b..7d706fb 100644 --- a/package.json +++ b/package.json @@ -29,8 +29,8 @@ "@conet.project/seguro-worker-lib": "0.13.8", "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", - "@mui/icons-material": "^5.14.12", - "@mui/material": "^5.14.12", + "@mui/icons-material": "^5.14.13", + "@mui/material": "^5.14.13", "@react-icons/all-files": "^4.1.0", "@tippyjs/react": "^4.2.6", "buffer": "^6.0.3", @@ -43,7 +43,10 @@ "react-lottie-player": "^1.5.5", "react-router-dom": "^6.16.0", "uuid": "^9.0.1", - "web-vitals": "^3.5.0" + "web-vitals": "^3.5.0", + "country-flag-icons": "^1.5.7", + "react-terminal-ui": "^1.0.5" + }, "devDependencies": { "@reduxjs/toolkit": "^1.9.7", diff --git a/src/assets/logo/CoNET_logo_white.svg b/src/assets/logo/CoNET_logo_white.svg new file mode 100644 index 0000000..67acf50 --- /dev/null +++ b/src/assets/logo/CoNET_logo_white.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/src/components/App/App.tsx b/src/components/App/App.tsx index 7cf4342..4925f5c 100644 --- a/src/components/App/App.tsx +++ b/src/components/App/App.tsx @@ -8,7 +8,6 @@ import {OnboardingPageProvider} from '../Providers/OnboardingPageProvider' import OnboardingScreen from "./OnboardingScreen/OnboardingScreen" import UnlockScreen from "./UnlockScreen/UnlockScreen" import LaunchScreen from "./LaunchScreen/LaunchScreen" -import {Overlay, OverlayWithLoaderText} from '../UI/Common/Overlay/Overlay' const StyledContainer = styled.div` height: 100vh; @@ -19,7 +18,6 @@ const StyledContainer = styled.div` color: black; ` - const App = () => { const { dAPPInitialize, @@ -114,38 +112,9 @@ const App = () => { ) } - // let content = - // // launch screen - // if (appState.isInitializing) { - // content = ( - // - // ) - // } else if (appState.isInitialized && appState.noContainer) { - // content = ( - // - // - // - // ) - // } else if (appState.isInitialized && appState.hasContainer && appState.isLocked) { - // content = ( - // - // ) - // } + } - // // unlock screen - // else if (appState.isInitialized && appState.isLocked) { - // content = ( - // - // ) - // } - // // main screen - // else if (appState.isInitialized && appState.isUnlocked) { - // content = ( - // - // ) - // } return ( <> @@ -165,4 +134,4 @@ const App = () => { ) } -export default App +export default App \ No newline at end of file diff --git a/src/components/App/Apps/API/index.ts b/src/components/App/Apps/API/index.ts new file mode 100644 index 0000000..249cba6 --- /dev/null +++ b/src/components/App/Apps/API/index.ts @@ -0,0 +1,187 @@ + +import {v4} from 'uuid' +import {logger} from '../../../../components/App/logger' + +type WorkerCommandErrorType = 'NOT_READY'|'INVALID_DATA'| +'NO_UUID'|'INVALID_COMMAND'|'OPENPGP_RUNNING_ERROR'| +'PouchDB_ERROR'|'GENERATE_PASSCODE_ERROR'|'FAILURE'|'COUNTDOWN' + +type WorkerCommandType = 'READY'|'encrypt_TestPasscode'|'getCONETBalance'|'getRegiestNodes'| +'encrypt_createPasscode'|'encrypt_lock'|'encrypt_deletePasscode'|'storePreferences'| +'newProfile'|'storeProfile'|'invitation'|'WORKER_MESSAGE'| +'isAddress'|'getFaucet'|'syncAsset'|'sendAsset'|'getUSDCPrice'| +'buyUSDC'|'mintCoNETCash'|'getSINodes'|'getRecipientCoNETCashAddress'| +'getUserProfile'|'sendMessage'|'setRegion' + +export type WorkerCallStatus = 'SUCCESS' | 'NOT_READY' | 'UNKNOWN_COMMAND' | +'TIME_OUT' | 'SYSTEM_ERROR' +export type PasscodeStatus = 'LOCKED' | 'UNLOCKED' | 'NOT_SET' +export type ColorTheme = 'LIGHT' | 'DARK' +export type Language = 'en-CA' | 'fr-CA' | 'ja-JP' | 'zh-CN' | 'zh-TW' +export type secondVerificationValume = '1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9' +export type SeguroNetworkStatus = WorkerCallStatus | +'TIMEOUT_EMAIL_SERVER' | 'TIMEOUT_SEGURO_NETWORK' | +'NO_INTERNET' | 'CONNECTING_ACCESS_POINT' | +'CONNECTING_SEGURO_NETWORK'|'INIT'|'NOT_STRIPE'| +'LOCAL_SERVER_ERROR'|'INVITATION_CODE_ERROR'| +'SEGURO_ERROR'|'UNKNOW_ERROR'|'SEGURO_DATA_FORMAT_ERROR' + +/*eslint-disable */ +export interface profile { + bio: string + nickname: string + keyID?: string + tags: string[] + alias: string + isPrimary: boolean + profileImg: string +} + +export type passcodeUnlockStatus = + [status: 'FAILURE' | 'COUNTDOWN' | WorkerCallStatus, payload?: ContainerData] + +export type SINodesSortby = 'CUSTOMER_REVIEW'|'TOTAL_ONLINE_TIME'| + 'STORAGE_PRICE_LOW'|'STORAGE_PRICE_HIGH'|'OUTBOUND_PRICE_HIGH'|'OUTBOUND_PRICE_LOW' + +export type SINodesRegion = 'USA'|'UK'|'ES'|'DE' + +export interface ContainerData { + method: { + testPasscode?: ( + passcode: string, + progressCallback: ( progressInteger: string, progressFractional: string ) => void + ) => Promise + createPasscode?: ( + passcode: string, + progressCallback: ( progressInteger: string, progressFractional: string ) => void + ) => Promise <[WorkerCallStatus, ContainerData?]> + deletePasscode?: () => Promise <[WorkerCallStatus, ContainerData?]> + lock?: () => Promise <[WorkerCallStatus, ContainerData?]> + storePreferences?: () => Promise <[WorkerCallStatus, ContainerData?]> + newProfile?: (profile: profile) => Promise + storeProfile?: () => Promise + isAddress?: (address: string) => Promise + getFaucet?: (address: string) => Promise + syncAsset?: () => Promise + sendAsset?: (sendAddr: string, total: number, toAddr: string, asset: string ) => Promise + getUSDCPrice?: () => Promise + buyUSDC?: (conetVal: number, keyID: string) => Promise + mintCoNETCash?: (usdcVal: number, keyID: string ) => Promise + getSINodes?: (sortby: SINodesSortby, region: SINodesRegion) => Promise < StartWorkerResolve > + getRecipientCoNETCashAddress?: (amount: number, callback: any) => Promise + getUserProfile?: (keyID: string) => Promise + sendMessage?: (keyAddress: string, message: string ) => Promise + listening?: (data: any) => void + } + status: PasscodeStatus + data: any + preferences: any +} + +export interface WorkerCommand { + cmd: WorkerCommandType + data?: any + uuid: string + err?: WorkerCommandErrorType +} + +export type regionType = { + us: boolean, + uk: boolean, + ge: boolean, + sp: boolean, + fr: boolean +} + +export type CreatePasscodeResolve = + [status: WorkerCallStatus, updateProgress?: ( percentage: number ) => void ] + +export type StartWorkerResolve = [WorkerCallStatus, ContainerData?] +type StartWorkerResolveForAPI = [WorkerCallStatus, any []] + +const channelWrokerListenName = 'toMainWroker' + + + +export class CONET_Platfrom_API { + + private postMessage = (cmd: WorkerCommand, resolve: (value: StartWorkerResolveForAPI | PromiseLike) => void) => { + + const channel = new BroadcastChannel(channelWrokerListenName) + const listenChannel = new BroadcastChannel(cmd.uuid) + + const kk = (e: any) => { + listeningChannel(e.data, cmd.uuid, resolve) + } + + const listeningChannel = (data: any, uuid: string, resolve: (value: StartWorkerResolveForAPI | PromiseLike) => void) => { + let cmd: WorkerCommand + + try{ + cmd = JSON.parse(data) + } catch (ex) { + // 'searchPage.tsx', 'checkLinkedUrl ifram is NULL' + return logger ('class CONET_Platfrom_API', `listeningChannel JSON.parse(data) Error`) + } + + listenChannel.close() + + if (cmd.err) { + return resolve(['SYSTEM_ERROR', cmd.data]) + } + + return resolve(['SUCCESS', cmd.data]) + } + + listenChannel.addEventListener('message', kk) + channel.postMessage(JSON.stringify(cmd)) + channel.close() + } + + constructor () { + } + + public faucet (): Promise < StartWorkerResolveForAPI > { + return new Promise( resolve => { + const cmd: WorkerCommand = { + cmd: 'getFaucet', + data: [], + uuid: v4() + } + return this.postMessage (cmd, resolve) + }) + } + + public getCONETBalance (): Promise < StartWorkerResolveForAPI > { + return new Promise( resolve => { + const cmd: WorkerCommand = { + cmd: 'getCONETBalance', + uuid: v4() + } + return this.postMessage (cmd, resolve) + }) + } + + public setRegion(region: regionType): Promise < StartWorkerResolveForAPI > { + return new Promise( resolve => { + const cmd: WorkerCommand = { + cmd: 'setRegion', + uuid: v4(), + data: [region] + } + return this.postMessage (cmd, resolve) + }) + } + + public getRegiestNodes () : Promise < StartWorkerResolveForAPI >{ + return new Promise( resolve => { + const cmd: WorkerCommand = { + cmd: 'getRegiestNodes', + uuid: v4(), + data: [] + } + return this.postMessage (cmd, resolve) + }) + } + +} \ No newline at end of file diff --git a/src/components/App/Apps/Browser/TodoContext.tsx b/src/components/App/Apps/Browser/TodoContext.tsx index fe8f52e..35ed12b 100644 --- a/src/components/App/Apps/Browser/TodoContext.tsx +++ b/src/components/App/Apps/Browser/TodoContext.tsx @@ -23,5 +23,4 @@ const TodoContext = createContext ({ }) -export default TodoContext - +export default TodoContext \ No newline at end of file diff --git a/src/components/App/Apps/CONET-Proxy/SaasNodes.tsx b/src/components/App/Apps/CONET-Proxy/SaasNodes.tsx new file mode 100644 index 0000000..1c729cd --- /dev/null +++ b/src/components/App/Apps/CONET-Proxy/SaasNodes.tsx @@ -0,0 +1,324 @@ +import React, {HTMLAttributes, useState, useEffect} from 'react' +import { styled } from '@mui/material/styles' +import ArrowForwardIosSharpIcon from '@mui/icons-material/ArrowForwardIosSharp' +import MuiAccordion, { AccordionProps } from '@mui/material/Accordion' +import MuiAccordionSummary, { + AccordionSummaryProps, +} from '@mui/material/AccordionSummary' +import MuiAccordionDetails from '@mui/material/AccordionDetails' +import Typography from '@mui/material/Typography' +import {CONET_Platfrom_API} from '../API/index' +import {logger} from '../../logger' +import Chip from '@mui/material/Chip' +import { US } from 'country-flag-icons/react/3x2' +import SvgIcon from '@mui/material/SvgIcon' +import {ReactComponent as CONETIcon} from '../../../../assets/logo/CoNET_logo.svg' +import ConetIcon from '../../../../assets/logo/CoNET_logo.svg' +import Paper from '@mui/material/Paper' +import Box from '@mui/material/Box' +import Grid from '@mui/material/Grid' +import Rating from '@mui/material/Rating' +import BarChartIcon from '@mui/icons-material/BarChart' +import { grey, green, indigo } from '@mui/material/colors' +import Avatar from '@mui/material/Avatar' +import List from '@mui/material/List' +import ListItem from '@mui/material/ListItem' +import ListItemText from '@mui/material/ListItemText' +import Divider from '@mui/material/Divider' +import Link from '@mui/material/Link' +import styledCom from "styled-components" +import useAppState from "../../../../store/appState/useAppState" +import {BlockScanBody} from '../blockscan/index' +import ExpandMoreIcon from '@mui/icons-material/ExpandMore' +import ProxyLogs from './proxyLogs' + +export type CryptoAssetHistory = { + status: string + Nonce?: string + to?: string + transactionFee?: string + gasLimit?: string + gasUsed: string + baseFee?: string + priorityFee?: string + totalGasFee?: string + maxFeePerGas?: string + transactionHash?: string + time: string + blockHash?: string + blockNumber: string + contractAddress?: string + effectiveGasPrice: string + cumulativeGasUsed: string + from: string + logs?: any[] + logsBloom?: string + transactionIndex?: string + type?: string + value: number + isSend: boolean + +} + +export type nodes_info = { + country: string + customs_review_total: number + ip_addr: string + last_online: string + lat: number + lon: number + nft_tokenid: string + outbound_fee: number + outbound_total: number + pgp_publickey_id: string + region: string + registration_date: string + storage_fee: number + storage_total: number + total_online: number + wallet_addr: string + entryChecked?: boolean + recipientChecked?: boolean + disable?: boolean + armoredPublicKey?: string + CoNETCashWalletAddress: string + receipt: CryptoAssetHistory[] + balance: string +} + +const ItemTopArea2 = styled(Paper)(({ theme }) => ({ + padding: '2rem', + borderRadius: '5px', + textAlign: 'center', + +})) + +const Accordion = styled((props: AccordionProps) => ( + +))(({ theme }) => ({ + border: `1px solid ${theme.palette.divider}`, + '&:not(:last-child)': { + borderBottom: 0, + }, + '&:before': { + display: 'none', + }, +})) + + +const AccordionSummary = styled((props: AccordionSummaryProps) => ( + } + {...props} + /> +))(({ theme }) => ({ + backgroundColor: + theme.palette.mode === 'dark' + ? 'rgba(255, 255, 255, .05)' + : 'rgba(0, 0, 0, .03)', + flexDirection: 'row-reverse', + '& .MuiAccordionSummary-expandIconWrapper.Mui-expanded': { + transform: 'rotate(90deg)', + }, + '& .MuiAccordionSummary-content': { + marginLeft: theme.spacing(1), + }, +})) + +const AccordionDetails = styled(MuiAccordionDetails)(({ theme }) => ({ + padding: theme.spacing(2), + borderTop: '1px solid rgba(0, 0, 0, .125)', +})) + +const styleList = { + width: '100%', + bgcolor: 'background.paper', +} + +const TextLine1 = styledCom.span` + +` +const TextLineIcon = styledCom.span` + top: 0.2rem; + position: relative; + padding-left: 0.5rem; +` +const receiptDetail = (receipt: CryptoAssetHistory,openBlockScan: (data: CryptoAssetHistory)=> void) => { + return ( + + + + Address: + + + + {receipt.to} + + + + + Value: + + + + {receipt.value} + + + + + + + + + Transaction Hash: + + openBlockScan(receipt)}> + + {receipt.transactionHash} + + + + + }/> + + + ) +} + +const paymentDetail = (node: nodes_info, openBlockScan: (data: CryptoAssetHistory)=> void) => { + return ( + + + + Transaction Receipt Event Logs + + + + + + { + node.receipt.map( n => receiptDetail(n, openBlockScan)) + } + + + + + + ) +} + + + +const nodeItem = (expanded: string|false, handleChange: (panel: string) => (event: React.SyntheticEvent, newExpanded: boolean) => void, nodes: nodes_info[], proxyLogs: any[]) => { + const [primary, setprimary] = React.useState(1) + const [blockScanData, setBlockScanData] = React.useState() + + const openBlockScan = (data: CryptoAssetHistory) => { + setBlockScanData (data) + setprimary(5) + } + return ( +
+ { + nodes.map((node, index) => { + return ( + + + + {`Node 0x${node.wallet_addr.substring(2,4)}...${node.wallet_addr.substring(node.wallet_addr.length-4)} `} + + } sx={{ backgroundColor: 'none', border: 'none', padding: '0 0 0 1rem'}}/> + + {node.ip_addr} + + + + } sx={{ backgroundColor: 'none', borderRadius: '5px'}}/> + + } sx={{ backgroundColor: 'none', borderRadius: '5px', borderColor: green[300], margin: '0 0 0 0.5rem'}}/> + + + + + + { + setprimary(1) + }} + /> + { + + setprimary(2) + + }} + /> + { + setprimary(3) + }} + /> + { + setprimary(4) + + }} + /> + + + + + { + primary === 2 && + paymentDetail (node, openBlockScan) + } + { + primary === 5 && + BlockScanBody(blockScanData) + } + { + primary === 3 && + ProxyLogs(node, proxyLogs[index]) + } + + + + + + ) + }) + } +
+ ) +} + +const SaasNodes = (regiestNodes: nodes_info[], proxyLogs: any[]) => { + + const [expanded, setExpanded] = React.useState('panel1') + const [expandedMain, setExpandedMain] = React.useState(regiestNodes.length > 0 ? true: false) + + const handleChange = + (panel: string) => (event: React.SyntheticEvent, newExpanded: boolean) => { + setExpanded(newExpanded ? panel : false) + } + + return ( + + setExpandedMain(expandedMain ? false: true)}> + + Usage + + + + {nodeItem(expanded, handleChange, regiestNodes, proxyLogs)} + + + ) +} + +export default SaasNodes \ No newline at end of file diff --git a/src/components/App/Apps/CONET-Proxy/TippyDropdown.tsx b/src/components/App/Apps/CONET-Proxy/TippyDropdown.tsx new file mode 100644 index 0000000..5b49f4c --- /dev/null +++ b/src/components/App/Apps/CONET-Proxy/TippyDropdown.tsx @@ -0,0 +1,88 @@ +import {TippyDropdown} from '../../../UI/Tippy/Tippy'//"../../../../Tippy/Tippy" +import ProfileDropdown from '../../../UI/Dropdowns/ProfileDropdown/ProfileDropdown' //"../../Dropdowns/ProfileDropdown/ProfileDropdown" +import { useState} from "react" +import useAppState from "../../../../store/appState/useAppState" +import styled from 'styled-components' +import SvgIcon from '@mui/material/SvgIcon' +import IconButton from '@mui/material/IconButton' +import {ReactComponent as StarIcon} from '../../../../assets/logo/CoNET_logo_white.svg' + +type Dropdowns = 'applications' | 'profiles' | 'notifications' | 'network' | null + +const StyledGlobalButton = styled.div` + position: absolute; + right:1.3rem; + zIndex:9999; + top:1.3rem; +` + +const StyledGlobalItem = styled(StyledGlobalButton)` +` +const TippyDropdownTab = () => { + const [currentDropdown, setCurrentDropdown] = useState(null) + const { + hasUpdateAvailable, + networkStrength, + setIsDrawerOpen, + isDrawerOpen, + setIsShowOverlay, + windowInnerSize: {width}, + activeProfile, + setIsModalOpen, + hasNotification, + setShowGuide, + setShowAppStore + } = useAppState() + + + const closeDropdown = (app: string ) => { + setCurrentDropdown(null) + + if (app) { + if (app === 'showGuide') { + setShowAppStore (false) + return setShowGuide(true) + } + if (app == 'showAppStore') { + setShowGuide(false) + + return setShowAppStore (true) + } + setShowAppStore (false) + setShowGuide(false) + } + } + const setDropdownToggle = (dropdown: Dropdowns) => { + if (currentDropdown === dropdown) { + return setCurrentDropdown(null) + } + return setCurrentDropdown(dropdown) + } + + return ( + } + visible={currentDropdown === 'profiles'} + verticalOffset={2} + onClickOutside={()=>{ + closeDropdown('') + }} + > + { + setDropdownToggle('profiles') + }}> + + + + + + + + ) +} + +export default TippyDropdownTab + diff --git a/src/components/App/Apps/CONET-Proxy/assets/images/CoNET_logoV41500.png b/src/components/App/Apps/CONET-Proxy/assets/images/CoNET_logoV41500.png new file mode 100644 index 0000000..41cfb14 Binary files /dev/null and b/src/components/App/Apps/CONET-Proxy/assets/images/CoNET_logoV41500.png differ diff --git a/src/components/App/Apps/CONET-Proxy/assets/images/faucet.png b/src/components/App/Apps/CONET-Proxy/assets/images/faucet.png deleted file mode 100644 index 74d0a00..0000000 Binary files a/src/components/App/Apps/CONET-Proxy/assets/images/faucet.png and /dev/null differ diff --git a/src/components/App/Apps/CONET-Proxy/assets/images/screen1.png b/src/components/App/Apps/CONET-Proxy/assets/images/screen1.png index 7d12381..779bce0 100644 Binary files a/src/components/App/Apps/CONET-Proxy/assets/images/screen1.png and b/src/components/App/Apps/CONET-Proxy/assets/images/screen1.png differ diff --git a/src/components/App/Apps/CONET-Proxy/index.tsx b/src/components/App/Apps/CONET-Proxy/index.tsx index 3dbaf31..d9ffb6f 100644 --- a/src/components/App/Apps/CONET-Proxy/index.tsx +++ b/src/components/App/Apps/CONET-Proxy/index.tsx @@ -21,7 +21,17 @@ import Button from '@mui/material/Button' import FormGroup from '@mui/material/FormGroup' import FormControlLabel from '@mui/material/FormControlLabel' import Checkbox from '@mui/material/Checkbox' - +import TippyDropdownTab from './TippyDropdown' +import {CONET_Platfrom_API, regionType} from '../API/index' +import {logger} from '../../logger' +import CircularProgress from '@mui/material/CircularProgress' +import Accordion from '@mui/material/Accordion' +import AccordionSummary from '@mui/material/AccordionSummary' +import ExpandMoreIcon from '@mui/icons-material/ExpandMore' +import AccordionDetails from '@mui/material/AccordionDetails' +import SaaSNodes from './SaasNodes' +import type {nodes_info} from './SaasNodes' +import { ColorMode, TerminalOutput } from 'react-terminal-ui' const themeTopArea1 = createTheme ({ typography: { @@ -52,7 +62,6 @@ const ItemTopArea1 = styled(Paper)(({ theme }) => ({ const ItemTopArea2 = styled(Paper)(({ theme }) => ({ padding: 0, - borderRadius: 0, textAlign: 'center', @@ -161,8 +170,8 @@ const FeatureArea7Item = () => { const FeatureArea5 = () => { return ( - - + + @@ -185,7 +194,8 @@ const FeatureArea5 = () => { ) } -const featureArea8Item = (conetBalance: string, loading: boolean, faucet: () => void) => { + +const featureArea8Item = (conetBalance: string, loading: boolean, faucet: () => void, wallet: string, regionProgress: boolean) => { return ( @@ -194,18 +204,30 @@ const featureArea8Item = (conetBalance: string, loading: boolean, faucet: () => Step 1 Wallet recharge - + + Wallet {wallet.substring(0,6)+'...'+ wallet.substring(wallet.length - 4)} + CONET balance - + {conetBalance} - - - Billed by traffic, each 1GB will cost 1 CONET + { + loading && + + + + } + { + !loading && + + } + + + Billed by traffic, each 1MB will cost 1 CONET @@ -213,7 +235,7 @@ const featureArea8Item = (conetBalance: string, loading: boolean, faucet: () => ) } -const FeatureArea9Item = () => { +const featureArea9Item = (onchange: ((event: React.SyntheticEvent, checked: boolean, region: string) => void), regionConfirm: () => void, regionProgress: boolean, loading: boolean, showConfirm: boolean) => { return ( @@ -221,15 +243,39 @@ const FeatureArea9Item = () => { Step 2 proxy server localtion - - } label="United States" /> - } label="United Kingdom" /> - } label="Germany" /> - } label="Spain" /> - } label="France" /> - - - Multiple selections will adapt accordingly + + + + + } label="United States" onChange={(e, checked) => onchange(e, checked, 'us')}/> + } label="United Kingdom" onChange={(e, checked) => onchange(e, checked, 'uk')}/> + } label="Germany" onChange={(e, checked) => onchange(e, checked, 'ge')}/> + } label="Spain" onChange={(e, checked) => onchange(e, checked, 'sp')}/> + {/* } label="France" onChange={(e, checked) => onchange(e, checked, 'fr')}/> */} + + + + + + { + showConfirm && !regionProgress && + } + + { + regionProgress && + + + + } + + + + + + + Multiple selections will random select @@ -240,29 +286,38 @@ const FeatureArea9Item = () => { const FeatureArea10Item = () => { return ( - - - - Setp 3 Setup Your Browser - - - - - - - - - - - + + } + aria-controls="panel1a-content" + id="panel1a-header" + sx={{backgroundColor: 'rgb(240,240,240)'}} + > + Setp 3 Setup Your FireFox + + + + + + + ) } -const featureArea6 = (conetBalance: string, loading: boolean, faucet: ()=> void) => { +const featureArea6 = (conetBalance: string, loading: boolean, + faucet: ()=> void, + onChange: (event: React.SyntheticEvent, + checked: boolean, region: string) => void, + regionConfirm: () => void, + regionProgress: boolean, wallet: string, + nodes: nodes_info[], + showConfirm: boolean, + proxyLogs: any[] + ) => { return ( - + @@ -272,8 +327,11 @@ const featureArea6 = (conetBalance: string, loading: boolean, faucet: ()=> void) - { featureArea8Item(conetBalance, loading, faucet)} - + + {SaaSNodes(nodes, proxyLogs)} + + {featureArea8Item(conetBalance, loading, faucet, wallet, regionProgress)} + {featureArea9Item(onChange, regionConfirm, regionProgress, loading, showConfirm)} @@ -281,40 +339,131 @@ const featureArea6 = (conetBalance: string, loading: boolean, faucet: ()=> void) ) } +const regions: regionType = { + us: true, + uk: false, + ge: false, + sp: false, + fr: false +} + +const getBalance = (conetTokens: number) => { + if (conetTokens < 1) { + return conetTokens * 1000 + ' KBeys' + } + return conetTokens + ' MBeys' +} + +const fetchProxyData = async (node: nodes_info, setProxyNodeLog: React.Dispatch>) => { + const url = `http://localhost:3001/getProxyusage` + + const xhttp = new XMLHttpRequest() + let last_response_len = 0 + + xhttp.onprogress = () => { + const responseText = xhttp.response.substr(last_response_len) + last_response_len = xhttp.response.length + responseText.split('\r\n\r\n') + .filter((n: string) => n.length) + .forEach((n: any, index: number) => { + let obj + try { + obj = JSON.parse(n) + } catch(ex) { + return logger(`fetchProxyData responseText JSON parse Error typeof [${typeof n}]`, n) + } + logger (`fetchProxyData Got Stream data typeof data[${typeof obj}][${obj.data[0].data}]`, n) + + //setProxyNodeLog(proxyLogo) + }) + + } + + xhttp.open('POST', url, true) + xhttp.setRequestHeader('Content-Type', 'application/json;charset=UTF-8') + xhttp.setRequestHeader('Accept', 'text/event-stream') + xhttp.send(JSON.stringify({data: node.ip_addr})) + + // const connect = await fetch (url, { + // method: "POST", + // headers: { + // Accept: "text/event-stream", + // "Content-Type": 'application/json;charset=UTF-8' + // }, + // body: JSON.stringify({data: node.ip_addr}), + // cache: 'no-store', + // referrerPolicy: 'no-referrer' + // }) + // .then (value => value.json()) + // .then(data=> { + // logger(`fetchData =========>`) + // logger (data) + // }) + // logger (`fetchProxyData [${url}]`) +} + + + const LaunchPage = () => { - let workerService: any - let assetList:any + const { setShowGuide, setShowAppStore } = useAppState() - const [showAssetBalance_balance, setshowAssetBalance_balanc] = useState('0') + const [showAssetBalance_balance, setshowAssetBalance_balance] = useState('0') + const [walletAddress, setWalletAddress] = useState('') const [loading, setLoading] = useState(false) - const [resultSuccess, setResultSuccess ] = useState(false) + const [resultSuccess, setResultSuccess ] = useState(false) const [sendStep, setSendStep] = useState(0) const [resultError, setResultError] = useState(false) - + const [region, setRegion] = useState(regions) + const [regionProgress,setRegionProgress] = useState(false) + const [nodes, setNodes] = useState([]) + const [showConfirm, setShowConfirm] = useState(true) + const [showProxyNodeLogs, setProxyNodeLog] = useState([]) + const [terminalLineData, setTerminalLineData] = useState([ + Welcome to the React Terminal UI Demo! + ]) useEffect(() => { const fetchData = async () => { - workerService = getWorkerService() - assetList = reflashAssetList() + + const workChannel = new CONET_Platfrom_API() + const [status, data] = await workChannel.getCONETBalance() + if (status !== 'SUCCESS' || !data) { + return logger('LaunchPage Error', 'useEffect fetchData getCONETBalance had no SUCCESS') + } + + logger (`getCONETBalance SUCCESS`, data) + setWalletAddress(data[0]) + setshowAssetBalance_balance(data[1]) + const _nodes: nodes_info[] = data[2] + if (_nodes.length > 0) { + + setNodes(_nodes) + setShowConfirm(false) + + } + + + } // call the function fetchData() // make sure to catch any error .catch(console.error) - }, []) + }, []) const HeaderArea = () => { - return ( + + @@ -331,16 +480,15 @@ const LaunchPage = () => { - + CoNET Proxy - + THE FAST & PRIVACY PROXY - @@ -352,70 +500,44 @@ const LaunchPage = () => { ) } - const [currectAsset, setcurrectAsset] = useState(0) - const currentProfile = () => { - if (workerService.data.passcode.status === 'LOCKED') { - return null - } - const index = workerService.data.profiles.findIndex((n:any) => { - return n.isPrimary - }) - setcurrectAsset(index) - return workerService.data.profiles[index] - } - - const reflashAssetList = () => { - - const ret = [ - { - primary: 'CoNET', - balance: currentProfile().tokens.conet.balance}, - // { - // primary: 'CoNETCash', - // balance: workerService.data?.CoNETCash ? workerService.data.CoNETCash.Total : 0, - // icon: , - // }, - // { - // primary: 'USDC', - // balance: currentProfile().tokens.usdc.balance, - // icon: , - // } - ] - return ret - } + const faucet = async () => { + const workChannel = new CONET_Platfrom_API() + setLoading(true) + const [status, data] = await workChannel.faucet() + setLoading(false) + if (status !== 'SUCCESS' || !data) { + return logger('LaunchPage Error', 'useEffect fetchData getCONETBalance had no SUCCESS') + } + setWalletAddress(data[0]) + setshowAssetBalance_balance(data[1]) + } - - const syncAsset = () => { - - return new Promise ( async (resolve)=> { - if ( !workerService.method?.syncAsset) { - return resolve (null) - } - const [ status, data ] = await workerService.method?.syncAsset () - assetList = reflashAssetList() - setshowAssetBalance_balanc(assetList[currectAsset].balance) - return resolve (null) - }) - } - - const getFaucet = () => { - if ( !workerService.method?.getFaucet) { - return - } - setLoading (true) - return workerService.method.getFaucet (currentProfile().keyID) - .then (async (n: any) => { - const [status, check] = n - setLoading(false) - - if (status === 'SUCCESS') { - await syncAsset () - setResultSuccess (true) - return setSendStep (1) - } - return setResultError(true) - }) - } + const selectOnChange = (event: React.SyntheticEvent, checked: boolean, _area: string) => { + + const obj = region + //@ts-ignore + obj[_area] = checked + setRegion(obj) + } + + const regionConfirm = async () => { + const workChannel = new CONET_Platfrom_API() + setRegionProgress(true) + const [status, data] = await workChannel.setRegion(region) + setRegionProgress(false) + if (status === 'SUCCESS') { + const [status1, data1] = await workChannel.getRegiestNodes() + if (status1 !== 'SUCCESS' || !data) { + return logger('LaunchPage Error', 'useEffect fetchData getCONETBalance had no SUCCESS') + } + const _nodes: nodes_info[] = data1[0] + _nodes.forEach( n => { + n.balance = getBalance(n.receipt[0].value) + }) + setNodes(_nodes) + setShowConfirm(false) + } + } // // const conetToken = currentProfile().tokens.conet @@ -424,8 +546,9 @@ const LaunchPage = () => { + { - featureArea6(showAssetBalance_balance, loading, getFaucet) + featureArea6(showAssetBalance_balance, loading, faucet, selectOnChange, regionConfirm, regionProgress, walletAddress, nodes, showConfirm, showProxyNodeLogs) } diff --git a/src/components/App/Apps/CONET-Proxy/proxyLogs.tsx b/src/components/App/Apps/CONET-Proxy/proxyLogs.tsx new file mode 100644 index 0000000..861d957 --- /dev/null +++ b/src/components/App/Apps/CONET-Proxy/proxyLogs.tsx @@ -0,0 +1,18 @@ + +import type {nodes_info} from './SaasNodes' +import React, {HTMLAttributes, useState, useEffect} from 'react' +import {logger} from '../../logger' +import Terminal, { ColorMode, TerminalOutput } from 'react-terminal-ui' + +const ProxyLogs = (node: nodes_info, logs: any[]) => { + return ( + + + ) +} + + +11 +export default ProxyLogs \ No newline at end of file diff --git a/src/components/App/Apps/blockscan/asset/images/conetscan-log.svg b/src/components/App/Apps/blockscan/asset/images/conetscan-log.svg new file mode 100644 index 0000000..32f2f4c --- /dev/null +++ b/src/components/App/Apps/blockscan/asset/images/conetscan-log.svg @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/components/App/Apps/blockscan/index.tsx b/src/components/App/Apps/blockscan/index.tsx new file mode 100644 index 0000000..1c925bf --- /dev/null +++ b/src/components/App/Apps/blockscan/index.tsx @@ -0,0 +1,283 @@ +import { createTheme, ThemeProvider, makeStyles, rgbToHex } from '@mui/material/styles'; +import Box from '@mui/material/Box' +import { styled } from '@mui/material/styles' +import Grid from '@mui/material/Grid' +import Paper from '@mui/material/Paper' +import styledCom from "styled-components" +import Breadcrumbs from '@mui/material/Breadcrumbs' +import Link from '@mui/material/Link' +import React, {HTMLAttributes, useState, useEffect} from "react" +import HomeIcon from '@mui/icons-material/Home' +import useAppState from "../../../../store/appState/useAppState" +import SearchInput from '../../../UI/Inputs/searchInput/SearchInput' +import ConetScanIcon from './asset/images/conetscan-log.svg' +import SvgIcon from '@mui/material/SvgIcon' +import Slide from '@mui/material/Slide' +import Typography, {TypographyProps} from '@mui/material/Typography' +import { grey, green } from '@mui/material/colors' +import Chip from '@mui/material/Chip' +import CheckCircleIcon from '@mui/icons-material/CheckCircle' +import Divider from '@mui/material/Divider' +import {ReactComponent as StarIcon} from '../../../../assets/logo/CoNET_logo.svg' +import type {CryptoAssetHistory} from '../CONET-Proxy/SaasNodes' +const themeTopArea1 = createTheme ({ + typography: { + h3: { + 'fontWeight': '600' + }, + h4: { + 'fontWeight': '600' + }, + h6: { + color: 'rgba(0,0,0,0.6)' + }, + fontFamily: [ + 'Inter', + '"Inter Placeholder"', + 'sans-serif', + ].join(','), + }, +}) + +const ItemContainer = styled(Box)(({ theme }) => ({ + paddingBottom: '10rem', + overflow: "auto", + maxHeight: '100%' + +})) + +const ItemTopArea1 = styled(Paper)(({ theme }) => ({ + padding: 0, + borderRadius: 0, + textAlign: 'center' +})) + +const BreadcrumbsArea = styledCom.div` + padding: 2rem 2rem 0 2rem; + +` + +const ItemTopArea2 = styled(Paper)(({ theme }) => ({ + padding: '2rem', + textAlign: 'center' +})) + +const headerArea = (setShowBlockScan: (showBlockScan: boolean) => void, setShowGuide: (showguide: boolean) => void) => { + + return ( + + + + + + + + + + + { + setShowBlockScan (false) + setShowGuide (true) + }} + > + + CONET Home + + + + + + + + + + + + + + + + + + ) +} + + +const ooo = { + blockHash: "0xb570cdc8549c176bdc41a87499ac7dc02ef5536051b42ec007b08179b33f8153", + blockNumber: "58", + cumulativeGasUsed: "21000", + effectiveGasPrice: "25000000000", + from: "0x0a775e944074547b72ac79b7677d2b58fec387e1", + gasUsed: "21000", + isSend: true, + logs: [], + logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + status: '0', + time: "2023-10-15T12:50:07.670Z", + to: "0xa642cfa2ad4790c5a753868480243d720ac472d0", + transactionHash: "0xbf32ba33e774a9ed9582b639ce829ed59b90096664120b21f135ae9892f45c97", + transactionIndex: "0", + type: "Confirmed", + value: 0.499475 +} + +export const BlockScanBody = (receipt: CryptoAssetHistory|undefined) => { + if (receipt === undefined) { + return ( +
+ ) + } + return ( + + + + + + + + + + + + + Transaction Hash: + + + + + {receipt.transactionHash} + + + + + Status: + + + + } sx={{ backgroundColor: green[50], borderRadius: '5px'}}/> + + + + Block: + + + + + + + {receipt.blockNumber} + + + + + + Block Hash: + + + + + {receipt.blockHash} + + + + + + Timestamp: + + + + + {receipt.time} + + + + + + + + Method: + + + + + + + + From: + + + + + {receipt.from} + + + + + To: + + + + + { receipt.to} + + + + + + + + Value: + + + + } sx={{ backgroundColor: 'white', border: 'none'}}/> + + + + + Transaction Fee: + + + + + {parseFloat(receipt.gasUsed) * parseFloat(receipt.effectiveGasPrice)/10**18} CONET + + + + + Gas Price: + + + + + {parseFloat(receipt.effectiveGasPrice)/10**9} Gwei CONET + + + + + + ) +} + + +const BlockScan = () => { + const { + setShowGuide, + setShowBlockScan + } = useAppState() + const [receipt, setrRceipt] = useState() + return ( + + + {headerArea(setShowBlockScan, setShowGuide)} + {BlockScanBody(ooo)} + + + ) +} + + + +export default BlockScan \ No newline at end of file diff --git a/src/components/App/Apps/launchPage/index.tsx b/src/components/App/Apps/launchPage/index.tsx index d8d8ee6..cdbc057 100644 --- a/src/components/App/Apps/launchPage/index.tsx +++ b/src/components/App/Apps/launchPage/index.tsx @@ -388,8 +388,8 @@ const FeatureArea6 = () => { const LaunchPage = () => { const { setShowGuide, - setShowAppStore - + setShowAppStore, + setShowBlockScan } = useAppState() const HeaderArea = () => { diff --git a/src/components/App/MainScreen/MainScreen.tsx b/src/components/App/MainScreen/MainScreen.tsx index 5fae791..eaa838e 100644 --- a/src/components/App/MainScreen/MainScreen.tsx +++ b/src/components/App/MainScreen/MainScreen.tsx @@ -13,6 +13,7 @@ import CONETProxy from '../Apps/CONET-Proxy/index' import {getWorkerService} from '../../../services/workerService/workerService' import {ClientProfiles} from '../../../store/appState/appStateReducer' import React,{useEffect} from 'react' +import BlockScan from '../Apps/blockscan' import Box from '@mui/material/Box' @@ -42,6 +43,7 @@ const MainScreen = () => { showGuide, setClientProfiles, showAppStore, + showBlockScan, setIsModalOpen } = useAppState() @@ -111,9 +113,10 @@ const MainScreen = () => { { showGuide && } { showAppStore && } - + { showBlockScan && } + {/* {!showGuide && !showAppStore && } - + */} diff --git a/src/components/UI/Inputs/searchInput/SearchInput.tsx b/src/components/UI/Inputs/searchInput/SearchInput.tsx new file mode 100644 index 0000000..376608a --- /dev/null +++ b/src/components/UI/Inputs/searchInput/SearchInput.tsx @@ -0,0 +1,52 @@ +import React, { FunctionComponent, useState } from "react" +import Paper from "@mui/material/Paper" +import InputAdornment from '@mui/material/InputAdornment' +import TextField from '@mui/material/TextField' + +import SearchIcon from '@mui/icons-material/Search' +import IconButton from '@mui/material/IconButton' +import MenuIcon from '@mui/icons-material/Menu' +import InputBase from '@mui/material/InputBase' +import Divider from '@mui/material/Divider' + +import DirectionsIcon from '@mui/icons-material/Directions' + +const TypeSearch: FunctionComponent = () => { + + + const [showClearIcon, setShowClearIcon] = useState("none") + + const handleChange = (event: React.ChangeEvent): void => { + setShowClearIcon(event.target.value === "" ? "none" : "flex"); + } + + const handleClick = (): void => { + // TODO: Clear the search input + console.log("clicked the clear icon...") + } + + return ( + + {/* + + */} + + + + + {/* + + + */} + + ) +} + +export default TypeSearch diff --git a/src/index.tsx b/src/index.tsx index d2e8f68..8847c27 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -22,7 +22,7 @@ if (rootElement && 'serviceWorker' in navigator) { ) - navigator.serviceWorker.register("/sw.js") + // navigator.serviceWorker.register("/sw.js") } else { console.log (`CoNET Platform Loader Error: can't find rootElement`) diff --git a/src/store/appState/appStateActions.ts b/src/store/appState/appStateActions.ts index bf4546e..4ab3bb4 100644 --- a/src/store/appState/appStateActions.ts +++ b/src/store/appState/appStateActions.ts @@ -2,6 +2,7 @@ import {createAction} from '@reduxjs/toolkit' import {Theme} from '../../theme/types' import {Locale} from '../../localization/types' import {WindowInnerSize} from './useAppState' + import { ClientProfiles, DeviceData, @@ -67,6 +68,16 @@ export const setShowAppStore= createAction( } ) +export const setShowBlockScan= createAction( + 'appState/showBlockScan', + (showBlockScan: boolean) => { + return { + payload: { + showBlockScan + } + } + } +) export const setHasContainer = createAction( diff --git a/src/store/appState/appStateReducer.ts b/src/store/appState/appStateReducer.ts index eed92e6..d197165 100644 --- a/src/store/appState/appStateReducer.ts +++ b/src/store/appState/appStateReducer.ts @@ -24,7 +24,8 @@ import { updateClientDevice, updateClientProfile, setShowGuide, - setShowAppStore + setShowAppStore, + setShowBlockScan } from './appStateActions' import {Theme} from '../../theme/types' import {Locale} from '../../localization/types' @@ -150,6 +151,7 @@ type AppStateReducerState = { networkState: NetworkStates showGuide: boolean showAppStore: boolean + showBlockScan: boolean } const initialState: AppStateReducerState = { @@ -159,6 +161,7 @@ const initialState: AppStateReducerState = { isModalOpen: null, showGuide: true, showAppStore: false, + showBlockScan: false, isPlatformLoading: null, hasContainer: false, networkStrength: 3, @@ -234,7 +237,11 @@ const appStateReducer = createReducer(initialState, builder => { state.showGuide = action.payload.showGuide }) - .addCase(setShowAppStore, (state, action) => { + .addCase(setShowBlockScan, (state, action) => { + state.showBlockScan = action.payload.showBlockScan + }) + + .addCase(setShowAppStore, (state, action) => { state.showAppStore = action.payload.showAppStore }) diff --git a/src/store/appState/useAppState.ts b/src/store/appState/useAppState.ts index 1d9ca98..f71c2ca 100644 --- a/src/store/appState/useAppState.ts +++ b/src/store/appState/useAppState.ts @@ -24,7 +24,8 @@ import { updateClientDevice as updateClientDeviceActionCreator, updateClientProfile as updateClientProfileActionCreator, setShowGuide as _setShowGuide, - setShowAppStore as _setShowAppStore + setShowAppStore as _setShowAppStore, + setShowBlockScan as _setShowBlockScan } from './appStateActions' @@ -67,6 +68,12 @@ const useAppState = () => { dispatch (_setShowGuide(showguide)) } + const showBlockScan = useTypedSelector(state => state.appState.showBlockScan) + + const setShowBlockScan = (showBlockScan: boolean ) => { + dispatch (_setShowBlockScan(showBlockScan)) + } + const showAppStore = useTypedSelector(state => state.appState.showAppStore) const setShowAppStore = (showAppStore: boolean ) => { @@ -319,6 +326,7 @@ const useAppState = () => { return { showGuide, showAppStore, + showBlockScan, dAPPInitialize, isInitialized, isInitializing, @@ -365,7 +373,8 @@ const useAppState = () => { updateClientDevice, deleteClientDevice, setShowGuide, - setShowAppStore + setShowAppStore, + setShowBlockScan } } diff --git a/yarn.lock b/yarn.lock index 2c41623..b3a888e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2929,91 +2929,91 @@ "@types/mdx" "^2.0.0" "@types/react" ">=16" -"@mui/base@5.0.0-beta.18": - version "5.0.0-beta.18" - resolved "https://registry.yarnpkg.com/@mui/base/-/base-5.0.0-beta.18.tgz#f95d393cf80974e77c0823170cc15c854d5af84b" - integrity sha512-e9ZCy/ndhyt5MTshAS3qAUy/40UiO0jX+kAo6a+XirrPJE+rrQW+mKPSI0uyp+5z4Vh+z0pvNoJ2S2gSrNz3BQ== +"@mui/base@5.0.0-beta.19": + version "5.0.0-beta.19" + resolved "https://registry.yarnpkg.com/@mui/base/-/base-5.0.0-beta.19.tgz#c1776e91b6a377c1a6a0079b5d6fec6e07a3bf9c" + integrity sha512-maNBgAscddyPNzFZQUJDF/puxM27Li+NqSBsr/lAP8TLns2VvWS2SoL3OKFOIoRnAMKGY/Ic6Aot6gCYeQnssA== dependencies: "@babel/runtime" "^7.23.1" "@floating-ui/react-dom" "^2.0.2" - "@mui/types" "^7.2.5" - "@mui/utils" "^5.14.12" + "@mui/types" "^7.2.6" + "@mui/utils" "^5.14.13" "@popperjs/core" "^2.11.8" clsx "^2.0.0" prop-types "^15.8.1" -"@mui/core-downloads-tracker@^5.14.12": - version "5.14.12" - resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-5.14.12.tgz#7be13094ef0c2fc7c3854da2b90a7eae456ebefd" - integrity sha512-WZhCkKqhrXaSVBzoC6LNcVkIawS000OOt7gmnp4g9HhyvN0PSclRXc/JrkC7EwfzUAZJh+hiK2LaVsbtOpNuOg== +"@mui/core-downloads-tracker@^5.14.13": + version "5.14.13" + resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-5.14.13.tgz#4b87e28aec6e568613683517ce4b7a7f75fa681a" + integrity sha512-3ZUbzcH4yloLKlV6Y+S0Edn2wef9t+EGHSfEkwVCn8E0ULdshifEFgfEroKRegQifDIwcKS/ofccxuZ8njTAYg== -"@mui/icons-material@^5.14.12": - version "5.14.12" - resolved "https://registry.yarnpkg.com/@mui/icons-material/-/icons-material-5.14.12.tgz#6634cdc3198bc438e8d38ce591c96d63d5df99a0" - integrity sha512-aFm6g/AIB3RQN9h/4MKoBoBybLZXeR3aDHWNx6KzemEpIlElUxv5uXRX5Qk1VC6v/YPkhbaPsiLLjsRSTiZF3w== +"@mui/icons-material@^5.14.13": + version "5.14.13" + resolved "https://registry.yarnpkg.com/@mui/icons-material/-/icons-material-5.14.13.tgz#d5169f804cc97c86282e85b5b7fdb523fb04689d" + integrity sha512-fxKE1UrjI4xVxHe9IAGuVQZrc18dSBJg0P+Sqi2SZmcDUCShmgRq6Jq7l7GduvuMIkOSqAJdNgLtXmtmZkjtLg== dependencies: "@babel/runtime" "^7.23.1" -"@mui/material@^5.14.12": - version "5.14.12" - resolved "https://registry.yarnpkg.com/@mui/material/-/material-5.14.12.tgz#8fa5bebd1a096796a288b548f1ba867e068601c8" - integrity sha512-EelF2L46VcVqhg3KjzIGBBpOtcBgRh0MMy9Efuk6Do81QdcZsFC9RebCVAflo5jIdbHiBmxBs5/l5Q9NjONozg== +"@mui/material@^5.14.13": + version "5.14.13" + resolved "https://registry.yarnpkg.com/@mui/material/-/material-5.14.13.tgz#d2df8270cafaa0cae595e843a01e8a9047a05e8e" + integrity sha512-iPEFwhoVG789UVsXX4gqd1eJUlcLW1oceqwJYQN8Z4MpcAKfL9Lv3fda65AwG7pQ5lf+d7IbHzm4m48SWZxI2g== dependencies: "@babel/runtime" "^7.23.1" - "@mui/base" "5.0.0-beta.18" - "@mui/core-downloads-tracker" "^5.14.12" - "@mui/system" "^5.14.12" - "@mui/types" "^7.2.5" - "@mui/utils" "^5.14.12" - "@types/react-transition-group" "^4.4.6" + "@mui/base" "5.0.0-beta.19" + "@mui/core-downloads-tracker" "^5.14.13" + "@mui/system" "^5.14.13" + "@mui/types" "^7.2.6" + "@mui/utils" "^5.14.13" + "@types/react-transition-group" "^4.4.7" clsx "^2.0.0" csstype "^3.1.2" prop-types "^15.8.1" react-is "^18.2.0" react-transition-group "^4.4.5" -"@mui/private-theming@^5.14.12": - version "5.14.12" - resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-5.14.12.tgz#b07f710b9794c928052ee4c91bf67fc3e0a442ea" - integrity sha512-TWwm+9+BgHFpoR3w04FG+IqID4ALa74A27RuKq2CEaWgxliBZB24EVeI6djfjFt5t4FYmIb8BMw2ZJEir7YjLQ== +"@mui/private-theming@^5.14.13": + version "5.14.13" + resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-5.14.13.tgz#10cb55a6e2caaf568dfaae894969a933c037da80" + integrity sha512-5EFqk4tqiSwPguj4NW/6bUf4u1qoUWXy9lrKfNh9H6oAohM+Ijv/7qSxFjnxPGBctj469/Sc5aKAR35ILBKZLQ== dependencies: "@babel/runtime" "^7.23.1" - "@mui/utils" "^5.14.12" + "@mui/utils" "^5.14.13" prop-types "^15.8.1" -"@mui/styled-engine@^5.14.12": - version "5.14.12" - resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-5.14.12.tgz#bfacc045f14f8f8bef735c76ecfd90bc99427c43" - integrity sha512-bocxt1nDmXfB3gpLfCCmFCyJ7sVmscFs+PuheO210QagZwHVp47UIRT1AiswLDYSQo1ZqmVGn7KLEJEYK0d4Xw== +"@mui/styled-engine@^5.14.13": + version "5.14.13" + resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-5.14.13.tgz#4ab4ef7d86ffe8709bdce4b8b2e3dba9090da199" + integrity sha512-1ff/egFQl26hiwcUtCMKAkp4Sgqpm3qIewmXq+GN27fb44lDIACquehMFBuadOjceOFmbIXbayzbA46ZyqFYzA== dependencies: "@babel/runtime" "^7.23.1" "@emotion/cache" "^11.11.0" csstype "^3.1.2" prop-types "^15.8.1" -"@mui/system@^5.14.12": - version "5.14.12" - resolved "https://registry.yarnpkg.com/@mui/system/-/system-5.14.12.tgz#da5b32c2a10bbe58f8b4839c5d5de449dc35e425" - integrity sha512-6DXfjjLhW0/ia5qU3Crke7j+MnfDbMBOHlLIrqbrEqNs0AuSBv8pXniEGb+kqO0H804NJreRTEJRjCngwOX5CA== +"@mui/system@^5.14.13": + version "5.14.13" + resolved "https://registry.yarnpkg.com/@mui/system/-/system-5.14.13.tgz#6c7a3cb28e45e3b66eb162ee5b292a6cf80efb8e" + integrity sha512-+5+Dx50lG4csbx2sGjrKLozXQJeCpJ4dIBZolyFLkZ+XphD1keQWouLUvJkPQ3MSglLLKuD37pp52YjMncZMEQ== dependencies: "@babel/runtime" "^7.23.1" - "@mui/private-theming" "^5.14.12" - "@mui/styled-engine" "^5.14.12" - "@mui/types" "^7.2.5" - "@mui/utils" "^5.14.12" + "@mui/private-theming" "^5.14.13" + "@mui/styled-engine" "^5.14.13" + "@mui/types" "^7.2.6" + "@mui/utils" "^5.14.13" clsx "^2.0.0" csstype "^3.1.2" prop-types "^15.8.1" -"@mui/types@^7.2.5": - version "7.2.5" - resolved "https://registry.yarnpkg.com/@mui/types/-/types-7.2.5.tgz#cd62a1fc5eb1044137ccab2053b431dd7cfc3cb8" - integrity sha512-S2BwfNczr7VwS6ki8GoAXJyARoeSJDLuxOEPs3vEMyTALlf9PrdHv+sluX7kk3iKrCg/ML2mIWwapZvWbkMCQA== +"@mui/types@^7.2.6": + version "7.2.6" + resolved "https://registry.yarnpkg.com/@mui/types/-/types-7.2.6.tgz#d72b9e9eb0032e107e76033932d65c3f731d2608" + integrity sha512-7sjLQrUmBwufm/M7jw/quNiPK/oor2+pGUQP2CULRcFCArYTq78oJ3D5esTaL0UMkXKJvDqXn6Ike69yAOBQng== -"@mui/utils@^5.14.12": - version "5.14.12" - resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.14.12.tgz#58b570839e22e0fba71e17d37d9c083fe233704d" - integrity sha512-RFNXnhKQlzIkIUig6mmv0r5VbtjPdWoaBPYicq25LETdZux59HAqoRdWw15T7lp3c7gXOoE8y67+hTB8C64m2g== +"@mui/utils@^5.14.13": + version "5.14.13" + resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.14.13.tgz#42c352b342da90b44a29a83d3dbda6ee1e56a0f8" + integrity sha512-2AFpyXWw7uDCIqRu7eU2i/EplZtks5LAMzQvIhC79sPV9IhOZU2qwOWVnPtdctRXiQJOAaXulg+A37pfhEueQw== dependencies: "@babel/runtime" "^7.23.1" "@types/prop-types" "^15.7.7" @@ -4478,7 +4478,7 @@ "@types/history" "^4.7.11" "@types/react" "*" -"@types/react-transition-group@^4.4.6": +"@types/react-transition-group@^4.4.7": version "4.4.7" resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.7.tgz#bf69f269d74aa78b99097673ca6dd6824a68ef1c" integrity sha512-ICCyBl5mvyqYp8Qeq9B5G/fyBSRC0zx3XM3sCC6KkcMsNeAHqXBKkmat4GqdJET5jtYUpZXrxI5flve5qhi2Eg== @@ -4590,7 +4590,7 @@ "@types/ws@^8.5.1": version "8.5.3" - resolved "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.3.tgz#7d25a1ffbecd3c4f2d35068d0b283c037003274d" integrity sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w== dependencies: "@types/node" "*" @@ -6022,6 +6022,11 @@ cosmiconfig@^7.0.0: path-type "^4.0.0" yaml "^1.10.0" +country-flag-icons@^1.5.7: + version "1.5.7" + resolved "https://registry.yarnpkg.com/country-flag-icons/-/country-flag-icons-1.5.7.tgz#f1f2ddf14f3cbf01cba6746374aeba94db35d4b4" + integrity sha512-AdvXhMcmSp7nBSkpGfW4qR/luAdRUutJqya9PuwRbsBzuoknThfultbv7Ib6fWsHXC43Es/4QJ8gzQQdBNm75A== + cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" @@ -9521,7 +9526,7 @@ mini-css-extract-plugin@^2.4.5: minimalistic-assert@^1.0.0: version "1.0.1" - resolved "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== minimatch@3.0.4: @@ -11134,6 +11139,11 @@ react-style-singleton@^2.2.1: invariant "^2.2.4" tslib "^2.0.0" +react-terminal-ui@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/react-terminal-ui/-/react-terminal-ui-1.0.5.tgz#8ead28bd0ea0143db4c44a166b9e8fb0c0627c64" + integrity sha512-yR19ej58dwU3koLiTR0m0nLbqJZoOyeThGWg1B3VrwUs+PLraqjP2C4AkRgiGNUwWMn4u6T0djY5DZXq0Zlvjg== + react-transition-group@^4.4.5: version "4.4.5" resolved "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz" @@ -12715,7 +12725,7 @@ util.promisify@~1.0.0: util@^0.12.0: version "0.12.5" - resolved "https://registry.npmjs.org/util/-/util-0.12.5.tgz" + resolved "https://registry.yarnpkg.com/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc" integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA== dependencies: inherits "^2.0.3"