Merge branch 'master' of https://github.com/ethereum/remix-project into movemonaco

pull/3492/head^2
filip mertens 2 years ago
commit 7dc44f224f
  1. 6
      .circleci/config.yml
  2. 3
      apps/remix-ide-e2e/src/tests/solidityImport.test.ts
  3. 49
      apps/remix-ide-e2e/src/tests/transactionExecution.test.ts
  4. 2
      apps/remix-ide/.babelrc
  5. 9
      apps/remix-ide/project.json
  6. 15
      apps/remix-ide/src/app.js
  7. 221
      apps/remix-ide/src/app/plugins/permission-handler-plugin.tsx
  8. 3
      apps/remix-ide/src/app/providers/abstract-provider.tsx
  9. 2
      apps/remix-ide/src/app/providers/custom-vm-fork-provider.tsx
  10. 19
      apps/remix-ide/src/app/providers/injected-provider.tsx
  11. 2
      apps/remix-ide/src/app/providers/mainnet-vm-fork-provider.tsx
  12. 4
      apps/remix-ide/src/app/tabs/debugger-tab.js
  13. 6
      apps/remix-ide/src/app/tabs/locales/en/filePanel.json
  14. 2
      apps/remix-ide/src/app/tabs/locales/en/settings.json
  15. 7
      apps/remix-ide/src/app/tabs/locales/zh/filePanel.json
  16. 27
      apps/remix-ide/src/app/udapp/run-tab.js
  17. 12
      apps/remix-ide/src/assets/css/themes/bootstrap-cyborg.min.css
  18. 2
      apps/remix-ide/src/assets/css/themes/remix-dark_tvx1s2.css
  19. 4
      apps/remix-ide/src/assets/css/themes/remix-hacker_owl.css
  20. BIN
      apps/remix-ide/src/assets/img/remix-logo-blue.png
  21. 1
      apps/remix-ide/src/assets/js/loader.js
  22. 33
      apps/remix-ide/src/blockchain/providers/vm.js
  23. 13
      apps/remix-ide/src/blockchain/providers/worker-vm.ts
  24. 2
      apps/remix-ide/src/index.html
  25. 2
      apps/remix-ide/src/remixAppManager.js
  26. 45
      apps/remix-ide/src/webpack.index.html
  27. 1
      apps/remix-ide/tsconfig.app.json
  28. 2
      babel.config.js
  29. 12
      libs/ghaction-helper/package.json
  30. 8
      libs/remix-analyzer/package.json
  31. 6
      libs/remix-astwalker/package.json
  32. 1
      libs/remix-core-plugin/package.json
  33. 31
      libs/remix-core-plugin/src/lib/compiler-artefacts.ts
  34. 36
      libs/remix-core-plugin/src/lib/compiler-fetch-and-compile.ts
  35. 3
      libs/remix-core-plugin/src/types/contract.ts
  36. 5
      libs/remix-core-plugin/tsconfig.lib.json
  37. 12
      libs/remix-debug/package.json
  38. 6
      libs/remix-lib/package.json
  39. 10
      libs/remix-lib/src/util.ts
  40. 8
      libs/remix-lib/test/util.ts
  41. 6
      libs/remix-simulator/package.json
  42. 2
      libs/remix-simulator/src/provider.ts
  43. 1
      libs/remix-simulator/src/vm-context.ts
  44. 6
      libs/remix-solidity/package.json
  45. 10
      libs/remix-tests/package.json
  46. 2
      libs/remix-ui/helper/src/lib/helper-components.tsx
  47. 23
      libs/remix-ui/home-tab/src/lib/components/homeTabTitle.tsx
  48. 4
      libs/remix-ui/modal-dialog/src/lib/remix-ui-modal-dialog.tsx
  49. 2
      libs/remix-ui/permission-handler/src/lib/permission-dialog.tsx
  50. 1
      libs/remix-ui/run-tab/src/lib/components/account.tsx
  51. 3
      libs/remix-ui/run-tab/src/lib/components/contractDropdownUI.tsx
  52. 4
      libs/remix-ui/run-tab/src/lib/components/contractGUI.tsx
  53. 2
      libs/remix-ui/run-tab/src/lib/components/instanceContainerUI.tsx
  54. 1
      libs/remix-ui/run-tab/src/lib/run-tab.tsx
  55. 1
      libs/remix-ui/run-tab/src/lib/types/index.ts
  56. 11
      libs/remix-ui/solidity-compiler/src/lib/contract-selection.tsx
  57. 2
      libs/remix-ui/solidity-compiler/src/lib/css/style.css
  58. 33
      libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx
  59. 4
      libs/remix-url-resolver/package.json
  60. 5
      libs/remix-ws-templates/package.json
  61. 2
      libs/remixd/package.json
  62. 5
      package.json
  63. 46
      yarn.lock

@ -191,7 +191,7 @@ jobs:
environment:
- COMMIT_AUTHOR_EMAIL: "yann@ethereum.org"
- COMMIT_AUTHOR: "Circle CI"
- FILES_TO_PACKAGE: "dist/apps/remix-ide/index.html dist/apps/remix-ide/404.html dist/apps/remix-ide/*.js dist/apps/remix-ide/*.css dist/apps/remix-ide/assets dist/apps/remix-ide/favicon.ico"
- FILES_TO_PACKAGE: "dist/apps/remix-ide/index.html dist/apps/remix-ide/404.html dist/apps/remix-ide/*.js dist/apps/remix-ide/assets dist/apps/remix-ide/favicon.ico"
working_directory: ~/remix-project
steps:
@ -215,7 +215,7 @@ jobs:
environment:
- COMMIT_AUTHOR_EMAIL: "yann@ethereum.org"
- COMMIT_AUTHOR: "Circle CI"
- FILES_TO_PACKAGE: "dist/apps/remix-ide/index.html dist/apps/remix-ide/404.html dist/apps/remix-ide/*.js dist/apps/remix-ide/*.css dist/apps/remix-ide/assets dist/apps/remix-ide/favicon.ico"
- FILES_TO_PACKAGE: "dist/apps/remix-ide/index.html dist/apps/remix-ide/404.html dist/apps/remix-ide/*.js dist/apps/remix-ide/assets dist/apps/remix-ide/favicon.ico"
working_directory: ~/remix-project
steps:
@ -239,7 +239,7 @@ jobs:
environment:
- COMMIT_AUTHOR_EMAIL: "yann@ethereum.org"
- COMMIT_AUTHOR: "Circle CI"
- FILES_TO_PACKAGE: "dist/apps/remix-ide/index.html dist/apps/remix-ide/404.html dist/apps/remix-ide/*.js dist/apps/remix-ide/*.css dist/apps/remix-ide/assets dist/apps/remix-ide/favicon.ico"
- FILES_TO_PACKAGE: "dist/apps/remix-ide/index.html dist/apps/remix-ide/404.html dist/apps/remix-ide/*.js dist/apps/remix-ide/assets dist/apps/remix-ide/favicon.ico"
working_directory: ~/remix-project
steps:

@ -29,10 +29,9 @@ module.exports = {
.clickLaunchIcon('solidity')
.click('[data-id="compilerContainerCompileBtn"]')
.isVisible({
selector: "//span[contains(.,'not found Untitled11')]",
selector: "//span[contains(.,'not found /Untitled11')]",
locateStrategy: 'xpath',
timeout: 120000,
suppressNotFoundErrors: true
})
},

@ -213,7 +213,28 @@ module.exports = {
'uint256 num': '24'
}
})
.end()
},
'Should switch to the mainnet VM fork and execute a tx to query ENS #group5': function (browser: NightwatchBrowser) {
let addressRef
browser
.addFile('mainnet_ens.sol', sources[7]['mainnet_ens.sol'])
.clickLaunchIcon('solidity')
.setSolidityCompilerVersion('soljson-v0.8.17+commit.8df45f5f.js')
.clickLaunchIcon('udapp')
.switchEnvironment('vm-mainnet-fork')
.waitForElementPresent('select[data-id="runTabSelectAccount"] option[value="0xdD870fA1b7C4700F2BD7f44238821C26f7392148"]') // wait for the udapp to load the list of accounts
.selectContract('MyResolver')
.createContract('')
.clickInstance(0)
.getAddressAtPosition(0, (address) => {
addressRef = address
})
.clickFunction('resolve - call')
.perform((done) => {
browser.verifyCallReturnValue(addressRef, ['0:address: 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045'])
.perform(() => done())
})
}
}
@ -431,5 +452,31 @@ contract C {
}
}`
}
}, {
'mainnet_ens.sol': {
content:
`
import "https://github.com/ensdomains/ens-contracts/blob/master/contracts/utils/NameEncoder.sol";
abstract contract ENS {
function resolver(bytes32 node) public virtual view returns (Resolver);
}
abstract contract Resolver {
function addr(bytes32 node) public virtual view returns (address);
}
contract MyResolver {
// Same address for Mainet, Ropsten, Rinkerby, Gorli and other networks;
ENS ens = ENS(0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e);
function resolve() public view returns(address) {
(,bytes32 node) = NameEncoder.dnsEncodeName("vitalik.eth");
Resolver resolver = ens.resolver(node);
return resolver.addr(node);
}
}
`
}
}
]

@ -1,5 +1,5 @@
{
"presets": ["@babel/preset-env", ["@babel/preset-react",
"presets": ["@babel/preset-env", ["@nrwl/react/babel",
{"runtime": "automatic"}
]],
"plugins": ["@babel/plugin-proposal-class-properties", "@babel/plugin-transform-runtime", "@babel/plugin-proposal-nullish-coalescing-operator"],

@ -48,15 +48,18 @@
"defaultConfiguration": "development",
"options": {
"buildTarget": "remix-ide:build",
"watch": true,
"liveReload": true,
"hmr": false
},
"configurations": {
"development": {
"buildTarget": "remix-ide:build:development",
"port": 8080
},
"hot":{
"buildTarget": "remix-ide:build:development",
"port": 8080,
"hmr": true
},
"production": {
"buildTarget": "remix-ide:build:production",
"port": 8080

@ -119,8 +119,6 @@ class AppComponent {
this.engine = new RemixEngine()
this.engine.register(appManager);
const matomoDomains = {
'remix-alpha.ethereum.org': 27,
'remix-beta.ethereum.org': 25,
@ -180,7 +178,7 @@ class AppComponent {
//----- search
const search = new SearchPlugin()
//---------------- Solidity UML Generator -------------------------
const solidityumlgen = new SolidityUmlGen(appManager)
@ -450,7 +448,11 @@ class AppComponent {
if (
this.appManager.pluginLoader.current === 'queryParams' &&
this.workspace.length > 0
) { this.menuicons.select(this.workspace[this.workspace.length - 1]) }
) {
this.menuicons.select(this.workspace[this.workspace.length - 1])
} else {
this.appManager.call('tabs', 'focus', 'home')
}
}
if (params.call) {
@ -484,19 +486,16 @@ class AppComponent {
}
}
}
})
.catch(console.error)
}
const loadedElement = document.createElement('span')
loadedElement.setAttribute('data-id', 'apploaded')
document.body.appendChild(loadedElement)
})
// activate solidity plugin
this.appManager.activatePlugin(['solidity', 'udapp', 'deploy-libraries', 'link-libraries', 'openzeppelin-proxy'])
// Load and start the service who manager layout and frame
}
}

@ -6,131 +6,130 @@ import { PermissionHandlerDialog, PermissionHandlerValue } from '@remix-ui/permi
import { Profile } from '@remixproject/plugin-utils'
const profile = {
name: 'permissionhandler',
displayName: 'permissionhandler',
description: 'Plugin to handle permissions',
methods: ['askPermission']
name: 'permissionhandler',
displayName: 'permissionhandler',
description: 'Plugin to handle permissions',
methods: ['askPermission']
}
export class PermissionHandlerPlugin extends Plugin {
permissions: any
currentVersion: number
fallbackMemory: boolean
constructor() {
super(profile)
this.fallbackMemory = false
this.permissions = this._getFromLocal()
this.currentVersion = 1
// here we remove the old permissions saved before adding 'permissionVersion'
// since with v1 the structure has been changed because of new engine ^0.2.0-alpha.6 changes
if (!localStorage.getItem('permissionVersion')) {
localStorage.setItem('plugins/permissions', '')
localStorage.setItem('permissionVersion', this.currentVersion.toString())
}
permissions: any
currentVersion: number
fallbackMemory: boolean
constructor() {
super(profile)
this.fallbackMemory = false
this.permissions = this._getFromLocal()
this.currentVersion = 1
// here we remove the old permissions saved before adding 'permissionVersion'
// since with v1 the structure has been changed because of new engine ^0.2.0-alpha.6 changes
if (!localStorage.getItem('permissionVersion')) {
localStorage.setItem('plugins/permissions', '')
localStorage.setItem('permissionVersion', this.currentVersion.toString())
}
}
_getFromLocal() {
if (this.fallbackMemory) return this.permissions
const permission = localStorage.getItem('plugins/permissions')
return permission ? JSON.parse(permission) : {}
}
_getFromLocal() {
if (this.fallbackMemory) return this.permissions
const permission = localStorage.getItem('plugins/permissions')
return permission ? JSON.parse(permission) : {}
}
persistPermissions() {
const permissions = JSON.stringify(this.permissions)
try {
localStorage.setItem('plugins/permissions', permissions)
} catch (e) {
this.fallbackMemory = true
console.log(e)
}
persistPermissions() {
const permissions = JSON.stringify(this.permissions)
try {
localStorage.setItem('plugins/permissions', permissions)
} catch (e) {
this.fallbackMemory = true
console.log(e)
}
}
switchMode (from: Profile, to: Profile, method: string, set: boolean) {
set
? this.permissions[to.name][method][from.name] = {}
: delete this.permissions[to.name][method][from.name]
}
switchMode (from: Profile, to: Profile, method: string, set: boolean) {
set
? this.permissions[to.name][method][from.name] = {}
: delete this.permissions[to.name][method][from.name]
}
clear() {
localStorage.removeItem('plugins/permissions')
}
clear() {
localStorage.removeItem('plugins/permissions')
}
notAllowWarning(from: Profile, to: Profile, method: string) {
return `${from.displayName || from.name} is not allowed to call ${method} method of ${to.displayName || to.name}.`
}
notAllowWarning(from: Profile, to: Profile, method: string) {
return `${from.displayName || from.name} is not allowed to call ${method} method of ${to.displayName || to.name}.`
}
async getTheme() {
return (await this.call('theme', 'currentTheme')).quality
}
async getTheme() {
return (await this.call('theme', 'currentTheme')).quality
}
/**
* Check if a plugin has the permission to call another plugin and askPermission if needed
* @param {PluginProfile} from the profile of the plugin that make the call
* @param {ModuleProfile} to The profile of the module that receive the call
* @param {string} method The name of the function to be called
* @param {string} message from the caller plugin to add more details if needed
* @returns {Promise<boolean>}
*/
async askPermission(from: Profile, to: Profile, method: string, message: string, sensitiveCall: boolean) {
try {
this.permissions = this._getFromLocal()
if (!this.permissions[to.name]) this.permissions[to.name] = {}
if (!this.permissions[to.name][method]) this.permissions[to.name][method] = {}
if (!this.permissions[to.name][method][from.name]) return this.openPermission(from, to, method, message, sensitiveCall)
/**
* Check if a plugin has the permission to call another plugin and askPermission if needed
* @param {PluginProfile} from the profile of the plugin that make the call
* @param {ModuleProfile} to The profile of the module that receive the call
* @param {string} method The name of the function to be called
* @param {string} message from the caller plugin to add more details if needed
* @returns {Promise<boolean>}
*/
async askPermission(from: Profile, to: Profile, method: string, message: string, sensitiveCall: boolean) {
try {
this.permissions = this._getFromLocal()
if (!this.permissions[to.name]) this.permissions[to.name] = {}
if (!this.permissions[to.name][method]) this.permissions[to.name][method] = {}
if (!this.permissions[to.name][method][from.name]) return this.openPermission(from, to, method, message, sensitiveCall)
const { allow, hash } = this.permissions[to.name][method][from.name]
if (!allow) {
const warning = this.notAllowWarning(from, to, method)
this.call('notification', 'toast', warning)
return false
}
return hash === from.hash
? true // Allow
: await this.openPermission(from, to, method, message, sensitiveCall)
} catch (err) {
throw new Error(err)
}
const { allow, hash } = this.permissions[to.name][method][from.name]
if (!allow) {
const warning = this.notAllowWarning(from, to, method)
this.call('notification', 'toast', warning)
return false
}
return hash === from.hash
? true // Allow
: await this.openPermission(from, to, method, message, sensitiveCall)
} catch (err) {
throw new Error(err)
}
}
async openPermission(from: Profile, to: Profile, method: string, message: string, sensitiveCall: boolean) {
const remember = this.permissions[to.name][method][from.name]
const value: PermissionHandlerValue = {
from,
to,
method,
message,
remember,
sensitiveCall
async openPermission(from: Profile, to: Profile, method: string, message: string, sensitiveCall: boolean) {
const remember = this.permissions[to.name][method][from.name]
const value: PermissionHandlerValue = {
from,
to,
method,
message,
remember,
sensitiveCall
}
const modal: AppModal = {
id: 'PermissionHandler',
title: <FormattedMessage id='permissionHandler.permissionNeededFor' values={{ to: to.displayName || to.name }} />,
message: <PermissionHandlerDialog plugin={this} theme={await this.getTheme()} value={value}></PermissionHandlerDialog>,
okLabel: <FormattedMessage id='permissionHandler.accept' />,
cancelLabel: <FormattedMessage id='permissionHandler.decline' />
}
const result = await this.call('notification', 'modal', modal)
return new Promise((resolve, reject) => {
if (result) {
if (this.permissions[to.name][method][from.name]) {
this.permissions[to.name][method][from.name] = {
allow: true,
hash: from.hash
}
this.persistPermissions()
}
const modal: AppModal = {
id: 'PermissionHandler',
title: <FormattedMessage id='permissionHandler.permissionNeededFor' values={{ to: to.displayName || to.name }} />,
message: <PermissionHandlerDialog plugin={this} theme={await this.getTheme()} value={value}></PermissionHandlerDialog>,
okLabel: <FormattedMessage id='permissionHandler.accept' />,
cancelLabel: <FormattedMessage id='permissionHandler.decline' />
resolve(true)
} else {
if (this.permissions[to.name][method][from.name]) {
this.permissions[to.name][method][from.name] = {
allow: false,
hash: from.hash
}
this.persistPermissions()
}
const result = await this.call('notification', 'modal', modal)
return new Promise((resolve, reject) => {
if (result) {
if (this.permissions[to.name][method][from.name]) {
this.permissions[to.name][method][from.name] = {
allow: true,
hash: from.hash
}
this.persistPermissions()
}
resolve(true)
} else {
if (this.permissions[to.name][method][from.name]) {
this.permissions[to.name][method][from.name] = {
allow: false,
hash: from.hash
}
this.persistPermissions()
}
reject(this.notAllowWarning(from, to, method))
}
})
}
reject(this.notAllowWarning(from, to, method))
}
})
}
}

@ -13,7 +13,8 @@ export type JsonDataRequest = {
export type JsonDataResult = {
id: number,
jsonrpc: string // version
result: any
result?: any,
error?: any,
}
export type RejectRequest = (error: Error) => void

@ -39,7 +39,7 @@ export class CustomForkVMProvider extends BasicVMProvider {
</div>
<div>
<label className="mt-3 mb-1">EVM</label>
<select data-id="CustomForkEvmType" name="evmType" className="border form-control border-right-0">
<select data-id="CustomForkEvmType" name="evmType" defaultValue="merge" className="border form-control border-right-0">
{Object.keys(Hardfork).map((value, index) => {
return <option value={Hardfork[value]} key={index}>{value}</option>
})}

@ -35,10 +35,11 @@ export class InjectedProvider extends Plugin implements IProvider {
async init () {
const injectedProvider = (window as any).ethereum
if (injectedProvider === undefined) {
this.call('notification', 'toast', noInjectedProviderMsg)
throw new Error(noInjectedProviderMsg)
} else {
if (injectedProvider && injectedProvider._metamask && injectedProvider._metamask.isUnlocked) {
if (!await injectedProvider._metamask.isUnlocked()) throw new Error('Please make sure the injected provider is unlocked (e.g Metamask).')
if (!await injectedProvider._metamask.isUnlocked()) this.call('notification', 'toast', 'Please make sure the injected provider is unlocked (e.g Metamask).')
}
this.askPermission(true)
}
@ -56,15 +57,21 @@ export class InjectedProvider extends Plugin implements IProvider {
// This will be displayed on UI tooltip as 'cannot get account list: Environment Updated !!'
if (!this.provider) {
this.call('notification', 'toast', 'No injected provider (e.g Metamask) has been found.')
return reject(new Error('no injected provider found.'))
return resolve({ jsonrpc: '2.0', error: 'no injected provider found', id: data.id })
}
try {
if ((window as any) && typeof (window as any).ethereum.request === "function") (window as any).ethereum.request({ method: "eth_requestAccounts" });
if (!await (window as any).ethereum._metamask.isUnlocked()) this.call('notification', 'toast', 'Please make sure the injected provider is unlocked (e.g Metamask).')
const resultData = await this.provider.currentProvider.send(data.method, data.params)
resolve({ jsonrpc: '2.0', result: resultData.result, id: data.id })
let resultData = await this.provider.currentProvider.send(data.method, data.params)
if (resultData) {
if (resultData.jsonrpc && resultData.jsonrpc === '2.0') {
resultData = resultData.result
}
resolve({ jsonrpc: '2.0', result: resultData, id: data.id })
} else {
resolve({ jsonrpc: '2.0', error: 'no return data provided', id: data.id })
}
} catch (error) {
reject(error)
resolve({ jsonrpc: '2.0', error: error.message, id: data.id })
}
}
}

@ -15,7 +15,7 @@ export class MainnetForkVMProvider extends BasicVMProvider {
}, blockchain)
this.blockchain = blockchain
this.fork = 'london'
this.nodeUrl = 'https://rpc.archivenode.io/e50zmkroshle2e2e50zm0044i7ao04ym'
this.nodeUrl = 'https://mainnet.infura.io/v3/08b2a484451e4635a28b3d8234f24332'
this.blockNumber = 'latest'
}

@ -45,10 +45,6 @@ export class DebuggerTab extends DebuggerApiMixin(ViewPlugin) {
this.call('notification', 'toast', notFoundToastMsg(contractAddress))
})
this.on('fetchAndCompile', 'usingLocalCompilation', (contractAddress) => {
this.call('notification', 'toast', localCompilationToastMsg())
})
this.on('fetchAndCompile', 'sourceVerificationNotAvailable', () => {
this.call('notification', 'toast', sourceVerificationNotAvailableToastMsg())
})

@ -10,7 +10,8 @@
"filePanel.workspace.delete": "Delete Workspace",
"filePanel.workspace.deleteConfirm": "Are you sure to delete the current workspace?",
"filePanel.workspace.deleteAll": "Delete All Workspaces",
"filePanel.workspace.deleteAllConfirm": "Are you absolutely sure you want to delete all your workspaces? Deleted workspaces can not be restored in any manner.",
"filePanel.workspace.deleteAllConfirm1": "Are you absolutely sure you want to delete all your workspaces?",
"filePanel.workspace.deleteAllConfirm2": "Deleted workspaces can not be restored in any manner.",
"filePanel.workspace.name": "Workspace name",
"filePanel.workspace.chooseTemplate": "Choose a template",
"filePanel.workspace.download": "Backup Workspaces",
@ -54,5 +55,6 @@
"filePanel.customizeTemplate": "Customize template",
"filePanel.features": "Features",
"filePanel.upgradeability": "Upgradeability",
"filePanel.ok": "OK"
"filePanel.ok": "OK",
"filePanel.cancel": "Cancel"
}

@ -3,7 +3,7 @@
"settings.reset": "Reset to Default settings",
"settings.general": "General settings",
"settings.generateContractMetadataText": "Generate contract metadata. Generate a JSON file in the contract folder. Allows to specify library addresses the contract depends on. If nothing is specified, Remix deploys libraries automatically.",
"settings.ethereunVMText": "Always use Javascript VM at load",
"settings.ethereunVMText": "Always use the Remix VM at load",
"settings.wordWrapText": "Word wrap in editor",
"settings.useAutoCompleteText": "Enable code completion in editor.",
"settings.useShowGasInEditorText": "Display gas estimates in editor.",

@ -10,8 +10,8 @@
"filePanel.workspace.delete": "删除工作空间",
"filePanel.workspace.deleteConfirm": "确定要删除当前工作空间?",
"filePanel.workspace.deleteAll": "Delete All Workspaces",
"filePanel.workspace.deleteAllConfirm": "Are you absolutely sure you want to delete all your workspaces? Deleted workspaces can not be restored in any manner.",
"filePanel.workspace.name": "工作空间名称",
"filePanel.workspace.deleteAllConfirm1": "Are you absolutely sure you want to delete all your workspaces?",
"filePanel.workspace.deleteAllConfirm2": "Deleted workspaces can not be restored in any manner.", "filePanel.workspace.name": "工作空间名称",
"filePanel.workspace.chooseTemplate": "选择一个工作空间模板",
"filePanel.workspace.download": "下载工作空间",
"filePanel.workspace.restore": "恢复工作空间",
@ -54,5 +54,6 @@
"filePanel.customizeTemplate": "自定义模板",
"filePanel.features": "特点",
"filePanel.upgradeability": "可升级性",
"filePanel.ok": "确认"
"filePanel.ok": "确认",
"filePanel.cancel": "Cancel"
}

@ -131,6 +131,12 @@ export class RunTab extends ViewPlugin {
})
}
// basic injected
const displayNameInjected = `Injected Provider${(window && window.ethereum && !(window.ethereum.providers && !window.ethereum.selectedProvider)) ?
window.ethereum.isCoinbaseWallet || window.ethereum.selectedProvider?.isCoinbaseWallet ? ' - Coinbase' :
window.ethereum.isBraveWallet || window.ethereum.selectedProvider?.isBraveWallet ? ' - Brave' :
window.ethereum.isMetaMask || window.ethereum.selectedProvider?.isMetaMask ? ' - MetaMask' : '' : ''}`
await addProvider('injected', displayNameInjected, true, false)
// VM
const titleVM = 'Execution environment is local to Remix. Data is only saved to browser memory and will vanish upon reload.'
await addProvider('vm-merge', 'Remix VM (Merge)', false, true, 'merge', 'settingsVMMergeMode', titleVM)
@ -142,20 +148,17 @@ export class RunTab extends ViewPlugin {
await addProvider('vm-custom-fork', 'Remix VM - Custom fork', false, true, '', 'settingsVMCustomMode', titleVM)
// external provider
await addProvider('hardhat-provider', 'Hardhat Provider', false, false)
await addProvider('ganache-provider', 'Ganache Provider', false, false)
await addProvider('foundry-provider', 'Foundry Provider', false, false)
await addProvider('basic-http-provider', 'Custom - External Http Provider', false, false)
await addProvider('hardhat-provider', 'Dev - Hardhat Provider', false, false)
await addProvider('ganache-provider', 'Dev - Ganache Provider', false, false)
await addProvider('foundry-provider', 'Dev - Foundry Provider', false, false)
// injected provider
await addProvider('injected-optimism-provider', 'L2 - Optimism Provider', true, false)
await addProvider('injected-arbitrum-one-provider', 'L2 - Arbitrum One Provider', true, false)
await addProvider('walletconnect', 'Wallet Connect', false, false)
await addProvider('basic-http-provider', 'External Http Provider', false, false)
// injected provider
const displayNameInjected = `Injected Provider${(window && window.ethereum && !(window.ethereum.providers && !window.ethereum.selectedProvider)) ?
window.ethereum.isCoinbaseWallet || window.ethereum.selectedProvider?.isCoinbaseWallet ? ' - Coinbase' :
window.ethereum.isBraveWallet || window.ethereum.selectedProvider?.isBraveWallet ? ' - Brave' :
window.ethereum.isMetaMask || window.ethereum.selectedProvider?.isMetaMask ? ' - MetaMask' : '' : ''}`
await addProvider('injected', displayNameInjected, true, false)
await addProvider('injected-optimism-provider', 'Optimism Provider', true, false)
await addProvider('injected-arbitrum-one-provider', 'Arbitrum One Provider', true, false)
}
writeFile (fileName, content) {

@ -8611,28 +8611,28 @@ legend {
text-decoration:underline
}
.alert-primary {
background-color:#2a9fd6
background-color:#2a9fd685
}
.alert-secondary {
background-color:#555
}
.alert-success {
background-color:#77b300
background-color:#77b3007a
}
.alert-info {
background-color:#93c
background-color:#9933cc91
}
.alert-warning {
background-color:#f80
background-color:#ff8800a1
}
.alert-danger {
background-color:#c00
background-color:#cc00009c
}
.alert-light {
background-color:#222
}
.alert-dark {
background-color:#adafae
background-color:#adafae99
}
.badge-warning {
color:#fff

@ -4481,7 +4481,7 @@ a.badge-dark:focus {
}
.alert-primary {
color: #fff;
background-color: #5CBDEE;
background-color: #5cbdee94;
border-color: #5CBDEE;
}
.alert-primary hr {

@ -13,7 +13,7 @@
--cyan: #355f7d;
--white: #fff;
--gray: #8B99A6;
--gray-dark: #343a40;
--gray-dark: #8694a1;
--primary: #007aa6;
--secondary: #0E2A3E;
--success: #C4E07F;
@ -4491,7 +4491,7 @@ a.badge-dark:focus {
}
.alert-primary {
color: #fff;
background-color: #5CBDEE;
background-color: #5cbdee94;
border-color: #5CBDEE;
}
.alert-primary hr {

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

@ -54,7 +54,6 @@ function isElectron() {
const versionUrl = 'assets/version.json'
fetch(versionUrl, { cache: "no-store" }).then(response => {
response.text().then(function (data) {
const version = JSON.parse(data);
console.log(`Loading Remix ${version.version}`);
});

@ -24,27 +24,30 @@ class VMProvider {
this.worker = new Worker(new URL('./worker-vm', import.meta.url))
const provider = this.executionContext.getProviderObject()
this.worker.postMessage({ cmd: 'init', fork: this.executionContext.getCurrentFork(), nodeUrl: provider?.options['nodeUrl'], blockNumber: provider?.options['blockNumber']})
let incr = 0
const stamps = {}
this.worker.addEventListener('message', (msg) => {
if (stamps[msg.data.stamp]) {
if (msg.data.cmd === 'sendAsyncResult' && stamps[msg.data.stamp]) {
stamps[msg.data.stamp](msg.data.error, msg.data.result)
} else if (msg.data.cmd === 'initiateResult') {
if (!msg.data.error) {
this.provider = {
sendAsync: (query, callback) => {
const stamp = Date.now() + incr
incr++
stamps[stamp] = callback
this.worker.postMessage({ cmd: 'sendAsync', query, stamp })
}
}
this.web3 = new Web3(this.provider)
extend(this.web3)
this.accounts = {}
this.executionContext.setWeb3(this.executionContext.getProvider(), this.web3)
}
}
})
this.provider = {
sendAsync: (query, callback) => {
const stamp = Date.now() + incr
incr++
stamps[stamp] = callback
this.worker.postMessage({ cmd: 'sendAsync', query, stamp })
}
}
this.web3 = new Web3(this.provider)
extend(this.web3)
this.accounts = {}
this.executionContext.setWeb3(this.executionContext.getProvider(), this.web3)
this.worker.postMessage({ cmd: 'init', fork: this.executionContext.getCurrentFork(), nodeUrl: provider?.options['nodeUrl'], blockNumber: provider?.options['blockNumber']})
}
// TODO: is still here because of the plugin API

@ -7,7 +7,18 @@ self.onmessage = (e: MessageEvent) => {
case 'init':
{
provider = new Provider({ fork: data.fork, nodeUrl: data.nodeUrl, blockNumber: data.blockNumber })
if (provider) provider.init()
provider.init().then(() => {
self.postMessage({
cmd: 'initiateResult',
stamp: data.stamp
})
}).catch((error) => {
self.postMessage({
cmd: 'initiateResult',
error,
stamp: data.stamp
})
})
break
}
case 'sendAsync':

@ -26,7 +26,7 @@
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<title>Remix - Ethereum IDE</title>
<link rel="stylesheet" href="assets/css/pygment_trac.css">
<link rel="icon" type="x-icon" href="assets/img/icon.png">
<link rel="icon" type="x-icon" href="assets/img/remix-logo-blue.png">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/intro.js/4.1.0/introjs.min.css">
<link rel="stylesheet" integrity="ha384-50oBUHEmvpQ+1lW4y57PTFmhCaXp0ML5d60M1M7uH2+nqUivzIebhndOJK28anvf"
crossorigin="anonymous" href="https://use.fontawesome.com/releases/v5.8.1/css/all.css">

@ -10,7 +10,7 @@ const requiredModules = [ // services + layout views + system views
'fileManager', 'contentImport', 'blockchain', 'web3Provider', 'scriptRunner', 'fetchAndCompile', 'mainPanel', 'hiddenPanel', 'sidePanel', 'menuicons',
'filePanel', 'terminal', 'settings', 'pluginManager', 'tabs', 'udapp', 'dGitProvider', 'solidity', 'solidity-logic', 'gistHandler', 'layout',
'notification', 'permissionhandler', 'walkthrough', 'storage', 'restorebackupzip', 'link-libraries', 'deploy-libraries', 'openzeppelin-proxy',
'hardhat-provider', 'ganache-provider', 'foundry-provider', 'basic-http-provider', 'injected', 'injected-optimism-provider', 'injected-arbitrum-one-provider',
'hardhat-provider', 'ganache-provider', 'foundry-provider', 'basic-http-provider', 'injected', 'injected-optimism-provider', 'injected-arbitrum-one-provider', 'vm-custom-fork', 'vm-goerli-fork', 'vm-mainnet-fork', 'vm-sepolia-fork', 'vm-merge', 'vm-london', 'vm-berlin',
'compileAndRun', 'search', 'recorder', 'fileDecorator', 'codeParser', 'codeFormatter', 'solidityumlgen', 'contractflattener']
// dependentModules shouldn't be manually activated (e.g hardhat is activated by remixd)

@ -1,45 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<!--
The MIT License (MIT)
Copyright (c) 2014, 2015, the individual contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-->
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<title>Remix - Ethereum IDE</title>
<link rel="stylesheet" href="assets/css/pygment_trac.css">
<link rel="icon" type="x-icon" href="assets/img/icon.png">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/intro.js/4.1.0/introjs.min.css">
<link rel="stylesheet" integrity="ha384-50oBUHEmvpQ+1lW4y57PTFmhCaXp0ML5d60M1M7uH2+nqUivzIebhndOJK28anvf"
crossorigin="anonymous" href="https://use.fontawesome.com/releases/v5.8.1/css/all.css">
<script src="assets/js/browserfs.min.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/intro.js/2.7.0/introjs.min.css">
</head>
<body>
<div id="root"></div>
<script src="https://kit.fontawesome.com/41dd021e94.js" crossorigin="anonymous"></script>
<script type="text/javascript" src="assets/js/intro.min.js"></script>
</body>
</html>

@ -3,7 +3,6 @@
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"types": ["node"],
"module": "es2020"
},
"exclude": ["**/*.spec.ts", "**/*.spec.tsx", "./src/assets/**/*"],
"include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"]

@ -1,5 +1,5 @@
module.exports = {
"presets": ["@babel/preset-typescript", "@babel/preset-env", "@babel/preset-react"],
"presets": ["@babel/preset-typescript", "@babel/preset-env", "@nrwl/react/babel"],
"plugins": [
"babel-plugin-replace-ts-export-assignment",
"@babel/plugin-transform-modules-commonjs",

@ -1,6 +1,6 @@
{
"name": "@remix-project/ghaction-helper",
"version": "0.1.5",
"version": "0.1.6",
"description": "Solidity Tests GitHub Action Helper",
"main": "src/index.js",
"scripts": {
@ -19,14 +19,16 @@
},
"homepage": "https://github.com/ethereum/remix-project#readme",
"devDependencies": {
"@remix-project/remix-solidity": "^0.5.9",
"@remix-project/remix-solidity": "^0.5.10",
"@types/chai": "^4.3.4",
"typescript": "^4.9.3"
},
"dependencies": {
"@ethereum-waffle/chai": "^3.4.4",
"@remix-project/remix-simulator": "^0.2.24",
"chai": "^4.3.7",
"ethers": "^5.7.2",
"@remix-project/remix-simulator": "^0.2.21"
}
"ethers": "^5.7.2"
},
"types": "./src/index.d.ts",
"gitHead": "c1415e0c3751af8bf53292d67fedf68e15bf3b23"
}

@ -1,6 +1,6 @@
{
"name": "@remix-project/remix-analyzer",
"version": "0.5.32",
"version": "0.5.33",
"description": "Tool to perform static analysis on Solidity smart contracts",
"scripts": {
"test": "./../../node_modules/.bin/ts-node --project ../../tsconfig.base.json --require tsconfig-paths/register ./../../node_modules/.bin/tape ./test/tests.ts"
@ -25,8 +25,8 @@
"@ethereumjs/tx": "^4.0.2",
"@ethereumjs/util": "^8.0.3",
"@ethereumjs/vm": "^6.3.0",
"@remix-project/remix-astwalker": "^0.0.53",
"@remix-project/remix-lib": "^0.5.23",
"@remix-project/remix-astwalker": "^0.0.54",
"@remix-project/remix-lib": "^0.5.24",
"async": "^2.6.2",
"ethers": "^5.4.2",
"ethjs-util": "^0.1.6",
@ -50,6 +50,6 @@
"typescript": "^3.7.5"
},
"typings": "src/index.d.ts",
"gitHead": "69af4eddd1ba47f76a71c78077d453deb572b1a0",
"gitHead": "c1415e0c3751af8bf53292d67fedf68e15bf3b23",
"main": "./src/index.js"
}

@ -1,6 +1,6 @@
{
"name": "@remix-project/remix-astwalker",
"version": "0.0.53",
"version": "0.0.54",
"description": "Tool to walk through Solidity AST",
"main": "src/index.js",
"scripts": {
@ -37,7 +37,7 @@
"@ethereumjs/tx": "^4.0.2",
"@ethereumjs/util": "^8.0.3",
"@ethereumjs/vm": "^6.3.0",
"@remix-project/remix-lib": "^0.5.23",
"@remix-project/remix-lib": "^0.5.24",
"@types/tape": "^4.2.33",
"async": "^2.6.2",
"ethers": "^5.4.2",
@ -53,6 +53,6 @@
"tap-spec": "^5.0.0"
},
"typings": "src/index.d.ts",
"gitHead": "69af4eddd1ba47f76a71c78077d453deb572b1a0",
"gitHead": "c1415e0c3751af8bf53292d67fedf68e15bf3b23",
"types": "./src/index.d.ts"
}

@ -3,7 +3,6 @@
"version": "0.0.1",
"description": "This library was generated with [Nx](https://nx.dev).",
"main": "src/index.js",
"type": "module",
"author": "Remix Team",
"license": "ISC"
}

@ -5,7 +5,7 @@ import { CompilerAbstract } from '@remix-project/remix-solidity'
const profile = {
name: 'compilerArtefacts',
methods: ['get', 'addResolvedContract', 'getCompilerAbstract', 'getAllContractDatas', 'getLastCompilationResult', 'getArtefactsByContractName', 'getContractDataFromAddress'],
methods: ['get', 'addResolvedContract', 'getCompilerAbstract', 'getAllContractDatas', 'getLastCompilationResult', 'getArtefactsByContractName', 'getContractDataFromAddress', 'getContractDataFromByteCode'],
events: [],
version: '0.0.1'
}
@ -98,16 +98,17 @@ export class CompilerArtefacts extends Plugin {
filterAllContractDatas (filter) {
const contractsData = {}
Object.keys(this.compilersArtefactsPerFile).map((targetFile) => {
const contracts = this.compilersArtefactsPerFile[targetFile].getContracts()
const artefact = this.compilersArtefactsPerFile[targetFile]
const contracts = artefact.getContracts()
Object.keys(contracts).map((file) => {
if (filter(file, contracts[file])) contractsData[file] = contracts[file]
if (filter(file, contracts[file], artefact)) contractsData[file] = contracts[file]
})
})
// making sure we save last compilation result in there
if (this.compilersArtefacts.__last) {
const contracts = this.compilersArtefacts.__last.getContracts()
Object.keys(contracts).map((file) => {
if (filter(file, contracts[file])) contractsData[file] = contracts[file]
if (filter(file, contracts[file], this.compilersArtefacts.__last)) contractsData[file] = contracts[file]
})
}
return contractsData
@ -194,8 +195,20 @@ export class CompilerArtefacts extends Plugin {
}
}
getCompilerAbstract (file) {
return this.compilersArtefactsPerFile[file]
async getCompilerAbstract (file) {
if (!file) return null
if (this.compilersArtefactsPerFile[file]) return this.compilersArtefactsPerFile[file]
const path = await this.call('fileManager', 'getPathFromUrl', file)
if (path && path.file && this.compilersArtefactsPerFile[path.file]) return this.compilersArtefactsPerFile[path.file]
let artefact = null
this.filterAllContractDatas((localFile, data, parentArtefact) => {
if (localFile === file || (path && path.file && localFile === path.file)) {
artefact = parentArtefact
}
})
return artefact
}
addResolvedContract (address: string, compilerData: CompilerAbstract) {
@ -212,12 +225,16 @@ export class CompilerArtefacts extends Plugin {
async getContractDataFromAddress (address) {
const code = await this.call('blockchain', 'getCode', address)
return this.getContractDataFromByteCode(code)
}
async getContractDataFromByteCode (code) {
let found
this.filterAllContractDatas((file, contractsData) => {
for (const name of Object.keys(contractsData)) {
const contract = contractsData[name]
if (util.compareByteCode(code, '0x' + contract.evm.deployedBytecode.object)) {
found = { name, contract }
found = { name, contract, file }
return true
}
}

@ -43,7 +43,14 @@ export class FetchAndCompile extends Plugin {
async resolve (contractAddress, codeAtAddress, targetPath) {
contractAddress = toChecksumAddress(contractAddress)
const localCompilation = async () => await this.call('compilerArtefacts', 'get', contractAddress) ? await this.call('compilerArtefacts', 'get', contractAddress) : await this.call('compilerArtefacts', 'get', '__last') ? await this.call('compilerArtefacts', 'get', '__last') : null
const localCompilation = async () => {
const contractData = await this.call('compilerArtefacts', 'getContractDataFromByteCode', codeAtAddress)
if (contractData) {
return await this.call('compilerArtefacts', 'getCompilerAbstract', contractData.file)
}
else
return await this.call('compilerArtefacts', 'get', '__last')
}
const resolved = await this.call('compilerArtefacts', 'get', contractAddress)
if (resolved) return resolved
@ -87,20 +94,19 @@ export class FetchAndCompile extends Plugin {
return localCompilation()
}
if (!network) return localCompilation()
if (!this.sourceVerifierNetWork.includes(network.name)) return localCompilation()
// check if the contract if part of the local compilation result
const compilation = await localCompilation()
if (compilation) {
let found = false
compilation.visitContracts((contract) => {
found = util.compareByteCode('0x' + contract.object.evm.deployedBytecode.object, codeAtAddress)
return found
})
if (found) {
await this.call('compilerArtefacts', 'addResolvedContract', contractAddress, compilation)
setTimeout(_ => this.emit('usingLocalCompilation', contractAddress), 0)
return compilation
if (!this.sourceVerifierNetWork.includes(network.name)) {
// check if the contract if part of the local compilation result
const compilation = await localCompilation()
if (compilation) {
let found = false
compilation.visitContracts((contract) => {
found = util.compareByteCode(codeAtAddress, '0x' + contract.object.evm.deployedBytecode.object)
return found
})
if (found) {
await this.call('compilerArtefacts', 'addResolvedContract', contractAddress, compilation)
return compilation
}
}
}

@ -20,7 +20,8 @@ export interface ContractData {
getConstructorInterface: () => any,
getConstructorInputs: () => any,
isOverSizeLimit: () => boolean,
metadata: any
metadata: any,
contractName?: string
}
export interface ContractAST {

@ -1,11 +1,6 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "commonjs",
"outDir": "../../dist/out-tsc",
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"declaration": true,
"types": ["node"]
},
"exclude": [

@ -1,6 +1,6 @@
{
"name": "@remix-project/remix-debug",
"version": "0.5.23",
"version": "0.5.24",
"description": "Tool to debug Ethereum transactions",
"contributors": [
{
@ -26,10 +26,10 @@
"@ethereumjs/tx": "^4.0.2",
"@ethereumjs/util": "^8.0.3",
"@ethereumjs/vm": "^6.3.0",
"@remix-project/remix-astwalker": "^0.0.53",
"@remix-project/remix-lib": "^0.5.23",
"@remix-project/remix-simulator": "^0.2.23",
"@remix-project/remix-solidity": "^0.5.9",
"@remix-project/remix-astwalker": "^0.0.54",
"@remix-project/remix-lib": "^0.5.24",
"@remix-project/remix-simulator": "^0.2.24",
"@remix-project/remix-solidity": "^0.5.10",
"ansi-gray": "^0.1.1",
"async": "^2.6.2",
"color-support": "^1.1.3",
@ -69,6 +69,6 @@
},
"homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-debug#readme",
"typings": "src/index.d.ts",
"gitHead": "69af4eddd1ba47f76a71c78077d453deb572b1a0",
"gitHead": "c1415e0c3751af8bf53292d67fedf68e15bf3b23",
"types": "./src/index.d.ts"
}

@ -1,6 +1,6 @@
{
"name": "@remix-project/remix-lib",
"version": "0.5.23",
"version": "0.5.24",
"description": "Library to various Remix tools",
"contributors": [
{
@ -17,8 +17,8 @@
"test": "./../../node_modules/.bin/ts-node --require tsconfig-paths/register ./../../node_modules/.bin/tape ./test/tests.ts"
},
"dependencies": {
"async": "^2.1.2",
"@ethereumjs/util": "^8.0.3",
"async": "^2.1.2",
"ethers": "^4.0.40",
"ethjs-util": "^0.1.6",
"events": "^3.0.0",
@ -51,6 +51,6 @@
},
"homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-lib#readme",
"typings": "src/index.d.ts",
"gitHead": "69af4eddd1ba47f76a71c78077d453deb572b1a0",
"gitHead": "c1415e0c3751af8bf53292d67fedf68e15bf3b23",
"types": "./src/index.d.ts"
}

@ -258,6 +258,12 @@ export function compareByteCode (code1, code2) {
code2 = extractcborMetadata(code2)
if (code1 && code2) {
if (code1.length !== code2.length) {
// if the length isn't the same, we have an issue with extracting the metadata hash.
const minLength = code1.length > code2.length ? code2.length: code1.length
code1 = code1.substr(0, minLength - 10)
code2 = code2.substr(0, minLength - 10)
}
const compare = stringSimilarity.compareTwoStrings(code1, code2)
return compare == 1
}
@ -294,12 +300,12 @@ function removeByIndex (code, index, length, emptyRef) {
function removeImmutableReference (code1, code2) {
try {
const refOccurence = code2.match(/7f000000000000000000000000000000000000000000000000000000000000000073/g)
const refOccurence = code2.match(/7f0000000000000000000000000000000000000000000000000000000000000000/g)
if (!refOccurence) return code1
let offset = 0
refOccurence.map((value) => {
offset = code2.indexOf(value, offset)
code1 = removeByIndex(code1, offset, value.length, '7f000000000000000000000000000000000000000000000000000000000000000073')
code1 = removeByIndex(code1, offset, value.length, '7f0000000000000000000000000000000000000000000000000000000000000000')
offset = offset + 1
})
} catch (e) {

File diff suppressed because one or more lines are too long

@ -1,6 +1,6 @@
{
"name": "@remix-project/remix-simulator",
"version": "0.2.23",
"version": "0.2.24",
"description": "Ethereum IDE and tools for the web",
"contributors": [
{
@ -22,7 +22,7 @@
"@ethereumjs/tx": "^4.0.2",
"@ethereumjs/util": "^8.0.3",
"@ethereumjs/vm": "^6.3.0",
"@remix-project/remix-lib": "^0.5.23",
"@remix-project/remix-lib": "^0.5.24",
"ansi-gray": "^0.1.1",
"async": "^3.1.0",
"body-parser": "^1.18.2",
@ -67,6 +67,6 @@
},
"homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-simulator#readme",
"typings": "src/index.d.ts",
"gitHead": "69af4eddd1ba47f76a71c78077d453deb572b1a0",
"gitHead": "c1415e0c3751af8bf53292d67fedf68e15bf3b23",
"types": "./src/index.d.ts"
}

@ -23,7 +23,7 @@ export class Provider {
constructor (options: Record<string, string | number> = {}) {
this.options = options
this.connected = true
this.vmContext = new VMContext(options['fork'] as string, options['nodeUrl'] as string, options['blockNumber'] as number)
this.vmContext = new VMContext(options['fork'] as string, options['nodeUrl'] as string, options['blockNumber'] as (number | 'latest'))
this.Accounts = new Web3Accounts(this.vmContext)
this.Transactions = new Transactions(this.vmContext)

@ -168,7 +168,6 @@ export class VMContext {
async createVm (hardfork) {
let stateManager: StateManager
console.log('creating a new VM', hardfork, this.nodeUrl, this.blockNumber)
if (this.nodeUrl) {
let block = this.blockNumber
if (this.blockNumber === 'latest') {

@ -1,6 +1,6 @@
{
"name": "@remix-project/remix-solidity",
"version": "0.5.9",
"version": "0.5.10",
"description": "Tool to load and run Solidity compiler",
"main": "src/index.js",
"types": "src/index.d.ts",
@ -19,7 +19,7 @@
"@ethereumjs/tx": "^4.0.2",
"@ethereumjs/util": "^8.0.3",
"@ethereumjs/vm": "^6.3.0",
"@remix-project/remix-lib": "^0.5.23",
"@remix-project/remix-lib": "^0.5.24",
"async": "^2.6.2",
"eslint-scope": "^5.0.0",
"ethers": "^5.4.2",
@ -57,5 +57,5 @@
},
"homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-solidity#readme",
"typings": "src/index.d.ts",
"gitHead": "69af4eddd1ba47f76a71c78077d453deb572b1a0"
"gitHead": "c1415e0c3751af8bf53292d67fedf68e15bf3b23"
}

@ -1,6 +1,6 @@
{
"name": "@remix-project/remix-tests",
"version": "0.2.23",
"version": "0.2.24",
"description": "Tool to test Solidity smart contracts",
"main": "src/index.js",
"types": "./src/index.d.ts",
@ -41,9 +41,9 @@
"@ethereumjs/tx": "^4.0.2",
"@ethereumjs/util": "^8.0.3",
"@ethereumjs/vm": "^6.3.0",
"@remix-project/remix-lib": "^0.5.23",
"@remix-project/remix-simulator": "^0.2.23",
"@remix-project/remix-solidity": "^0.5.9",
"@remix-project/remix-lib": "^0.5.24",
"@remix-project/remix-simulator": "^0.2.24",
"@remix-project/remix-solidity": "^0.5.10",
"@remix-project/remix-url-resolver": "^0.0.42",
"ansi-gray": "^0.1.1",
"async": "^2.6.0",
@ -78,5 +78,5 @@
"typescript": "^3.3.1"
},
"typings": "src/index.d.ts",
"gitHead": "69af4eddd1ba47f76a71c78077d453deb572b1a0"
"gitHead": "c1415e0c3751af8bf53292d67fedf68e15bf3b23"
}

@ -119,7 +119,7 @@ export const upgradeWithProxyMsg = () => (
export const unavailableProxyLayoutMsg = () => (
<div>
<p>Previous contract implementation is NOT available for upgrade comparison. <br /> A new storage layout will be saved for future upgrades.</p>
<p>The previous contract implementation is NOT available for an upgrade comparison<br /> A new storage layout will be saved for future upgrades.</p>
</div>
)

@ -1,7 +1,5 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
// eslint-disable-next-line @nrwl/nx/enforce-module-boundaries
import BasicLogo from 'libs/remix-ui/vertical-icons-panel/src/lib/components/BasicLogo'
import { ThemeContext } from '../themeContext'
import React, { useEffect, useState, useRef, useContext } from 'react'
import { FormattedMessage, useIntl } from 'react-intl'
import { CustomTooltip } from '@remix-ui/helper'
@ -21,7 +19,6 @@ function HomeTabTitle() {
searchDisable: true
})
const themeFilter = useContext(ThemeContext)
const searchInputRef = useRef(null)
const remiAudioEl = useRef(null)
const intl = useIntl()
@ -52,13 +49,12 @@ function HomeTabTitle() {
return (
<div className="px-2 pb-2 pt-2 d-flex flex-column border-bottom" id="hTTitleSection">
<div className="d-flex py-2 justify-content-between">
<div className='d-flex justify-content-start'>
<span className="h-80 text-uppercase" style={{ fontSize: 'xx-large', fontFamily: "Noah, sans-serif" }}>Remix</span>
<span className="h-80 text-uppercase" style={{ fontSize: 'xx-large', fontFamily: "Noah, sans-serif" }}>Remix</span>
<div className="ml-2 d-flex">
<div onClick={() => playRemi()} >
<img className="" src="assets/img/guitarRemiCroped.webp" style={{height: "3rem"}} alt=""></img>
<img className="" src="assets/img/guitarRemiCroped.webp" style={{ height: "3rem" }} alt=""></img>
</div>
<audio
id="remiAudio"
@ -68,7 +64,7 @@ function HomeTabTitle() {
></audio>
</div>
</div>
<span>
<span className="d-flex flex-nowrap align-self-end">
<CustomTooltip
placement={'top'}
tooltipId="overlay-tooltip"
@ -81,10 +77,9 @@ function HomeTabTitle() {
openLink("https://www.youtube.com/channel/UCjTUPyFEr2xDGN6Cg8nKDaA")
_paq.push(['trackEvent', 'hometab', 'socialMedia', 'youtube'])
}}
className="border-0 h-100 btn fab fa-youtube">
className="border-0 px-1 h-100 btn fab fa-youtube">
</button>
</CustomTooltip>
<CustomTooltip
placement={'top'}
tooltipId="overlay-tooltip"
@ -97,10 +92,9 @@ function HomeTabTitle() {
openLink("https://twitter.com/EthereumRemix")
_paq.push(['trackEvent', 'hometab', 'socialMedia', 'twitter'])
}}
className="border-0 p-2 h-100 pl-2 btn fab fa-twitter">
className="border-0 px-1 h-100 btn fab fa-twitter">
</button>
</CustomTooltip>
<CustomTooltip
placement={'top'}
tooltipId="overlay-tooltip"
@ -113,10 +107,9 @@ function HomeTabTitle() {
openLink("https://www.linkedin.com/company/ethereum-remix/")
_paq.push(['trackEvent', 'hometab', 'socialmedia', 'linkedin'])
}}
className="border-0 p-2 h-100 pl-2 btn fa fa-linkedin">
className="border-0 px-1 h-100 btn fa fa-linkedin">
</button>
</CustomTooltip>
<CustomTooltip
placement={'top'}
tooltipId="overlay-tooltip"
@ -129,7 +122,7 @@ function HomeTabTitle() {
openLink("https://medium.com/remix-ide")
_paq.push(['trackEvent', 'hometab', 'socialmedia', 'medium'])
}}
className="border-0 p-2 h-100 pl-2 btn fab fa-medium">
className="border-0 h-100 px-1 btn fab fa-medium">
</button>
</CustomTooltip>
@ -145,7 +138,7 @@ function HomeTabTitle() {
openLink("https://discord.gg/mh9hFCKkEq")
_paq.push(['trackEvent', 'hometab', 'socialmedia', 'discord'])
}}
className="border-0 h-100 p-2 btn fab fa-discord">
className="border-0 h-100 pl-1 pr-0 btn fab fa-discord">
</button>
</CustomTooltip>
</span>

@ -98,7 +98,7 @@ export const ModalDialog = (props: ModalDialogProps) => {
{/* todo add autofocus ^^ */}
{ props.okLabel && <button
data-id={`${props.id}-modal-footer-ok-react`}
className={'modal-ok btn btn-sm ' + (props.okBtnClass ? props.okBtnClass : state.toggleBtn ? 'btn-dark' : 'btn-light')}
className={'modal-ok btn btn-sm ' + (props.okBtnClass ? props.okBtnClass : state.toggleBtn ? 'border-primary' : 'border-secondary')}
disabled={props.validation && !props.validation.valid}
onClick={() => {
if (props.validation && !props.validation.valid) return
@ -111,7 +111,7 @@ export const ModalDialog = (props: ModalDialogProps) => {
}
{ props.cancelLabel && <button
data-id={`${props.id}-modal-footer-cancel-react`}
className={'modal-cancel btn btn-sm ' + (props.cancelBtnClass ? props.cancelBtnClass : state.toggleBtn ? 'btn-light' : 'btn-dark')}
className={'modal-cancel btn btn-sm ' + (props.cancelBtnClass ? props.cancelBtnClass : state.toggleBtn ? 'border-secondary' : 'border-primary')}
data-dismiss="modal"
onClick={() => {
if (props.cancelFn) props.cancelFn()

@ -62,7 +62,7 @@ const PermissionHandlerDialog = (props: PermissionHandlerProps) => {
<label htmlFor='remember' className="form-check-label" data-id="permissionHandlerRememberChoice"><FormattedMessage id='permissionHandler.rememberThisChoice' /></label>
</div>
}
<button className="btn btn-sm" onClick={reset}><FormattedMessage id='permissionHandler.resetAllPermissions' /></button>
<button className="btn-secondary btn-sm" onClick={reset}><FormattedMessage id='permissionHandler.resetAllPermissions' /></button>
</article>
<div>{feedback}</div>
</section>)

@ -120,6 +120,7 @@ export function AccountUI (props: AccountProps) {
<div>
<textarea
id="prompt_text"
className='bg-light'
data-id="signMessageTextarea"
style={{ width: '100%' }}
rows={4}

@ -235,7 +235,7 @@ export function ContractDropdownUI (props: ContractDropdownProps) {
}
const isValidProxyUpgrade = (proxyAddress: string) => {
return props.isValidProxyUpgrade(proxyAddress, loadedContractData.name, loadedContractData.compiler.source, loadedContractData.compiler.data)
return props.isValidProxyUpgrade(proxyAddress, loadedContractData.contractName || loadedContractData.name, loadedContractData.compiler.source, loadedContractData.compiler.data)
}
const checkSumWarning = () => {
@ -319,6 +319,7 @@ export function ContractDropdownUI (props: ContractDropdownProps) {
isValidProxyAddress={props.isValidProxyAddress}
isValidProxyUpgrade={isValidProxyUpgrade}
modal={props.modal}
disabled={props.selectedAccount === ''}
/>
<div className="d-flex py-1 align-items-center custom-control custom-checkbox">
<input

@ -280,7 +280,7 @@ export function ContractGUI (props: ContractGUIProps) {
className={`udapp_instanceButton ${props.widthClass} btn btn-sm ${buttonOptions.classList}`}
data-id={buttonOptions.dataId}
data-title={buttonOptions.title}
disabled={toggleUpgradeImp && !proxyAddress}
disabled={(toggleUpgradeImp && !proxyAddress) || props.disabled}
>
<CustomTooltip
placement={"right-start"}
@ -415,6 +415,7 @@ export function ContractGUI (props: ContractGUIProps) {
onClick={handleExpandMultiClick}
data-id={buttonOptions.dataId}
className={`udapp_instanceButton ${buttonOptions.classList}`}
disabled={props.disabled}
>
{buttonOptions.content}
</button>
@ -537,6 +538,7 @@ export function ContractGUI (props: ContractGUIProps) {
tooltipClasses="text-nowrap"
tooltipId={`proxyAddressTooltip${index}`}
tooltipText={'Deployed ' + shortenDate(deployment.date)}
key={index}
>
<Dropdown.Item
key={index}

@ -44,7 +44,7 @@ export function InstanceContainerUI (props: InstanceContainerProps) {
{ instanceList.length > 0
? <div> { props.instances.instanceList.map((instance, index) => {
return <UniversalDappUI
key={instance.address}
key={index}
instance={instance}
context={props.getContext()}
removeInstance={props.removeInstance}

@ -223,6 +223,7 @@ export function RunTabUI (props: RunTabProps) {
passphrase={runTab.passphrase}
/>
<ContractDropdownUI
selectedAccount={runTab.accounts.selectedAccount}
syncContracts={syncContracts}
exEnvironment={runTab.selectExEnv}
contracts={runTab.contracts}

@ -224,6 +224,7 @@ export type MainnetPrompt = (
) => JSX.Element
export interface ContractDropdownProps {
selectedAccount: string,
exEnvironment: string,
contracts: {
contractList: ContractList,

@ -188,7 +188,8 @@ export const ContractSelection = (props: ContractSelectionProps) => {
}
const copyBytecode = () => {
return copyContractProperty('bytecode')
const bytecodeObj = JSON.parse(copyContractProperty('bytecode'))
return bytecodeObj.object
}
return (
@ -244,14 +245,14 @@ export const ContractSelection = (props: ContractSelectionProps) => {
<div className="remixui_contractHelperButtons">
<div className="input-group">
<div className="btn-group" role="group" aria-label="Copy to Clipboard">
<CopyToClipboard title="Copy ABI to clipboard" getContent={copyABI} direction='top'>
<button className="btn remixui_copyButton" title="Copy ABI to clipboard">
<CopyToClipboard tip="Copy ABI to clipboard" getContent={copyABI} direction='top'>
<button className="btn remixui_copyButton" >
<i className="remixui_copyIcon far fa-copy" aria-hidden="true"></i>
<span>ABI</span>
</button>
</CopyToClipboard>
<CopyToClipboard title="Copy ABI to clipboard" getContent={copyBytecode} direction='top'>
<button className="btn remixui_copyButton" title="Copy Bytecode to clipboard">
<CopyToClipboard tip="Copy Bytecode to clipboard" getContent={copyBytecode} direction='top'>
<button className="btn remixui_copyButton">
<i className="remixui_copyIcon far fa-copy" aria-hidden="true"></i>
<span>Bytecode</span>
</button>

@ -137,7 +137,7 @@
.remixui_log {
display: flex;
flex-direction: column;
margin-bottom: 5%;
margin-bottom: 0.5rem;
overflow: visible;
}
.remixui_key {

@ -73,11 +73,11 @@ export function Workspace () {
}, [currentWorkspace])
const renameCurrentWorkspace = () => {
global.modal(intl.formatMessage({ id: 'filePanel.workspace.rename' }), renameModalMessage(), intl.formatMessage({ id: 'filePanel.ok' }), onFinishRenameWorkspace, '')
global.modal(intl.formatMessage({ id: 'filePanel.workspace.rename' }), renameModalMessage(), intl.formatMessage({ id: 'filePanel.ok' }), onFinishRenameWorkspace, intl.formatMessage({ id: 'filePanel.cancel' }))
}
const createWorkspace = () => {
global.modal(intl.formatMessage({ id: 'filePanel.workspace.create' }), createModalMessage(), intl.formatMessage({ id: 'filePanel.ok' }), onFinishCreateWorkspace, '')
global.modal(intl.formatMessage({ id: 'filePanel.workspace.create' }), createModalMessage(), intl.formatMessage({ id: 'filePanel.ok' }), onFinishCreateWorkspace, intl.formatMessage({ id: 'filePanel.cancel' }))
}
const deleteCurrentWorkspace = () => {
@ -86,17 +86,22 @@ export function Workspace () {
intl.formatMessage({ id: 'filePanel.workspace.deleteConfirm' }),
intl.formatMessage({ id: 'filePanel.ok' }),
onFinishDeleteWorkspace,
''
intl.formatMessage({ id: 'filePanel.cancel' })
)
}
const deleteAllWorkspaces = () => {
global.modal(
intl.formatMessage({ id: 'filePanel.workspace.deleteAll' }),
intl.formatMessage({ id: 'filePanel.workspace.deleteAllConfirm' }),
<>
<div className="d-flex flex-column">
<span className='pb-1'>{intl.formatMessage({ id: 'filePanel.workspace.deleteAllConfirm1' })}</span>
<span>{intl.formatMessage({ id: 'filePanel.workspace.deleteAllConfirm2' })}</span>
</div>
</>,
intl.formatMessage({ id: 'filePanel.ok' }),
onFinishDeleteAllWorkspaces,
''
intl.formatMessage({ id: 'filePanel.cancel' })
)
}
@ -106,7 +111,7 @@ export function Workspace () {
cloneModalMessage(),
intl.formatMessage({ id: 'filePanel.ok' }),
handleTypingUrl,
''
intl.formatMessage({ id: 'filePanel.cancel' })
)
}
@ -146,7 +151,7 @@ export function Workspace () {
try {
await global.dispatchRenameWorkspace(currentWorkspace, workspaceName)
} catch (e) {
global.modal(intl.formatMessage({ id: 'filePanel.workspace.rename' }), e.message, intl.formatMessage({ id: 'filePanel.ok' }), () => {}, '')
global.modal(intl.formatMessage({ id: 'filePanel.workspace.rename' }), e.message, intl.formatMessage({ id: 'filePanel.ok' }), () => {}, intl.formatMessage({ id: 'filePanel.cancel' }))
console.error(e)
}
}
@ -172,7 +177,7 @@ export function Workspace () {
try {
await global.dispatchCreateWorkspace(workspaceName, workspaceTemplateName, opts, initGitRepo)
} catch (e) {
global.modal(intl.formatMessage({ id: 'filePanel.workspace.create' }), e.message, intl.formatMessage({ id: 'filePanel.ok' }), () => {}, '')
global.modal(intl.formatMessage({ id: 'filePanel.workspace.create' }), e.message, intl.formatMessage({ id: 'filePanel.ok' }), () => {}, intl.formatMessage({ id: 'filePanel.cancel' }))
console.error(e)
}
}
@ -181,7 +186,7 @@ export function Workspace () {
try {
await global.dispatchDeleteWorkspace(global.fs.browser.currentWorkspace)
} catch (e) {
global.modal(intl.formatMessage({ id: 'filePanel.workspace.delete' }), e.message, intl.formatMessage({ id: 'filePanel.ok' }), () => {}, '')
global.modal(intl.formatMessage({ id: 'filePanel.workspace.delete' }), e.message, intl.formatMessage({ id: 'filePanel.ok' }), () => {}, intl.formatMessage({ id: 'filePanel.cancel' }))
console.error(e)
}
}
@ -190,7 +195,7 @@ export function Workspace () {
try {
await global.dispatchDeleteAllWorkspaces()
} catch (e) {
global.modal(intl.formatMessage({ id: 'filePanel.workspace.deleteAll' }), e.message, intl.formatMessage({ id: 'filePanel.ok' }), () => {}, '')
global.modal(intl.formatMessage({ id: 'filePanel.workspace.deleteAll' }), e.message, intl.formatMessage({ id: 'filePanel.ok' }), () => {}, intl.formatMessage({ id: 'filePanel.cancel' }))
console.error(e)
}
}
@ -204,7 +209,7 @@ export function Workspace () {
await global.dispatchSwitchToWorkspace(name)
global.dispatchHandleExpandPath([])
} catch (e) {
global.modal(intl.formatMessage({ id: 'filePanel.workspace.switch' }), e.message, intl.formatMessage({ id: 'filePanel.ok' }), () => {}, '')
global.modal(intl.formatMessage({ id: 'filePanel.workspace.switch' }), e.message, intl.formatMessage({ id: 'filePanel.ok' }), () => {}, intl.formatMessage({ id: 'filePanel.cancel' }))
console.error(e)
}
}
@ -240,7 +245,7 @@ export function Workspace () {
intl.formatMessage({ id: 'filePanel.workspace.cloneMessage' }),
intl.formatMessage({ id: 'filePanel.ok' }),
() => {},
''
intl.formatMessage({ id: 'filePanel.cancel' })
)
}
}
@ -279,7 +284,7 @@ export function Workspace () {
}
} catch (e) {
console.error(e)
global.modal(intl.formatMessage({ id: 'filePanel.checkoutGitBranch' }), e.message, intl.formatMessage({ id: 'filePanel.ok' }), () => {})
global.modal(intl.formatMessage({ id: 'filePanel.checkoutGitBranch' }), e.message, intl.formatMessage({ id: 'filePanel.ok' }), () => {}, intl.formatMessage({ id: 'filePanel.cancel' }))
}
}
@ -288,7 +293,7 @@ export function Workspace () {
await global.dispatchCreateNewBranch(branchFilter)
_paq.push(['trackEvent', 'Workspace', 'GIT', 'switch_to_new_branch'])
} catch (e) {
global.modal(intl.formatMessage({ id: 'filePanel.checkoutGitBranch' }), e.message, intl.formatMessage({ id: 'filePanel.ok' }), () => {})
global.modal(intl.formatMessage({ id: 'filePanel.checkoutGitBranch' }), e.message, intl.formatMessage({ id: 'filePanel.ok' }), () => {}, intl.formatMessage({ id: 'filePanel.cancel' }))
}
}

@ -1,6 +1,6 @@
{
"name": "@remix-project/remix-url-resolver",
"version": "0.0.45",
"version": "0.0.46",
"description": "Solidity import url resolver engine",
"main": "src/index.js",
"types": "src/index.d.ts",
@ -40,5 +40,5 @@
"typescript": "^3.1.6"
},
"typings": "src/index.d.ts",
"gitHead": "69af4eddd1ba47f76a71c78077d453deb572b1a0"
"gitHead": "c1415e0c3751af8bf53292d67fedf68e15bf3b23"
}

@ -1,10 +1,9 @@
{
"name": "@remix-project/remix-ws-templates",
"version": "1.0.10",
"version": "1.0.11",
"description": "Create a Remix IDE workspace using different templates",
"main": "src/index.js",
"types": "src/index.d.ts",
"type": "module",
"publishConfig": {
"access": "public"
},
@ -25,5 +24,5 @@
"ethers": "^5.4.2",
"web3": "^1.5.1"
},
"gitHead": "69af4eddd1ba47f76a71c78077d453deb572b1a0"
"gitHead": "c1415e0c3751af8bf53292d67fedf68e15bf3b23"
}

@ -1,6 +1,6 @@
{
"name": "@remix-project/remixd",
"version": "0.6.11",
"version": "0.6.12",
"description": "remix server: allow accessing file system from remix.ethereum.org and start a dev environment (see help section)",
"main": "index.js",
"types": "./index.d.ts",

@ -1,6 +1,6 @@
{
"name": "remix-project",
"version": "0.31.0-dev",
"version": "0.32.0-dev",
"license": "MIT",
"description": "Ethereum Remix Monorepo",
"keywords": [
@ -28,6 +28,7 @@
"nx": "nx",
"start": "nx start",
"serve": "nx serve remix-ide --configuration=development",
"serve:hot": "nx serve remix-ide --configuration=hot",
"build": "nx build",
"test": "nx test",
"lint": "nx lint",
@ -234,6 +235,7 @@
"@nrwl/web": "15.7.1",
"@nrwl/webpack": "15.7.1",
"@nrwl/workspace": "^15.7.1",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.10",
"@openzeppelin/contracts-upgradeable": "^4.8.1",
"@svgr/webpack": "^6.5.1",
"@testing-library/react": "13.4.0",
@ -334,6 +336,7 @@
"onchange": "^3.2.1",
"os-browserify": "^0.3.0",
"process": "^0.11.10",
"react-refresh": "^0.14.0",
"react-test-renderer": "^17.0.2",
"request": "^2.83.0",
"rimraf": "^2.6.1",

@ -5476,6 +5476,21 @@
dependencies:
esquery "^1.0.1"
"@pmmmwh/react-refresh-webpack-plugin@^0.5.10":
version "0.5.10"
resolved "https://registry.yarnpkg.com/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.10.tgz#2eba163b8e7dbabb4ce3609ab5e32ab63dda3ef8"
integrity sha512-j0Ya0hCFZPd4x40qLzbhGsh9TMtdb+CJQiso+WxLOPNasohq9cc5SNUcwsZaRH6++Xh91Xkm/xHCkuIiIu0LUA==
dependencies:
ansi-html-community "^0.0.8"
common-path-prefix "^3.0.0"
core-js-pure "^3.23.3"
error-stack-parser "^2.0.6"
find-up "^5.0.0"
html-entities "^2.1.0"
loader-utils "^2.0.4"
schema-utils "^3.0.0"
source-map "^0.7.3"
"@polka/url@^1.0.0-next.20":
version "1.0.0-next.21"
resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.21.tgz#5de5a2385a35309427f6011992b544514d559aa1"
@ -10348,6 +10363,11 @@ commander@^9.2.0, commander@^9.4.1:
resolved "https://registry.yarnpkg.com/commander/-/commander-9.4.1.tgz#d1dd8f2ce6faf93147295c0df13c7c21141cfbdd"
integrity sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==
common-path-prefix@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/common-path-prefix/-/common-path-prefix-3.0.0.tgz#7d007a7e07c58c4b4d5f433131a19141b29f11e0"
integrity sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==
commondir@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
@ -10743,6 +10763,11 @@ core-js-pure@^3.19.0:
resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.20.0.tgz#7253feccf8bb05b72c153ddccdbe391ddbffbe03"
integrity sha512-qsrbIwWSEEYOM7z616jAVgwhuDDtPLwZSpUsU3vyUkHYqKTf/uwOJBZg2V7lMurYWkpVlaVOxBrfX0Q3ppvjfg==
core-js-pure@^3.23.3:
version "3.28.0"
resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.28.0.tgz#4ef2888475b6c856ef6f5aeef8b4f618b76ad048"
integrity sha512-DSOVleA9/v3LNj/vFxAPfUHttKTzrB2RXhAPvR5TPXn4vrra3Z2ssytvRyt8eruJwAfwAiFADEbrjcRdcvPLQQ==
core-js@^2.4.0, core-js@^2.6.5:
version "2.6.12"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec"
@ -12231,6 +12256,13 @@ error-ex@^1.2.0, error-ex@^1.3.1:
dependencies:
is-arrayish "^0.2.1"
error-stack-parser@^2.0.6:
version "2.1.4"
resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.1.4.tgz#229cb01cdbfa84440bfa91876285b94680188286"
integrity sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==
dependencies:
stackframe "^1.3.4"
es-abstract@^1.18.5, es-abstract@^1.19.0, es-abstract@^1.19.1:
version "1.19.1"
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.1.tgz#d4885796876916959de78edaa0df456627115ec3"
@ -15184,7 +15216,7 @@ html-encoding-sniffer@^3.0.0:
dependencies:
whatwg-encoding "^2.0.0"
html-entities@^2.3.2:
html-entities@^2.1.0, html-entities@^2.3.2:
version "2.3.3"
resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.3.3.tgz#117d7626bece327fc8baace8868fa6f5ef856e46"
integrity sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==
@ -18321,7 +18353,7 @@ loader-runner@^4.2.0:
resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1"
integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==
loader-utils@^2.0.0, loader-utils@^2.0.3:
loader-utils@^2.0.0, loader-utils@^2.0.3, loader-utils@^2.0.4:
version "2.0.4"
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c"
integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==
@ -22857,6 +22889,11 @@ react-redux@^7.2.0:
prop-types "^15.7.2"
react-is "^17.0.2"
react-refresh@^0.14.0:
version "0.14.0"
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.0.tgz#4e02825378a5f227079554d4284889354e5f553e"
integrity sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==
react-router-dom@^6.3.0:
version "6.3.0"
resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.3.0.tgz#a0216da813454e521905b5fa55e0e5176123f43d"
@ -24916,6 +24953,11 @@ stackblur-canvas@^2.0.0:
resolved "https://registry.yarnpkg.com/stackblur-canvas/-/stackblur-canvas-2.5.0.tgz#aa87bbed1560fdcd3138fff344fc6a1c413ebac4"
integrity sha512-EeNzTVfj+1In7aSLPKDD03F/ly4RxEuF/EX0YcOG0cKoPXs+SLZxDawQbexQDBzwROs4VKLWTOaZQlZkGBFEIQ==
stackframe@^1.3.4:
version "1.3.4"
resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.3.4.tgz#b881a004c8c149a5e8efef37d51b16e412943310"
integrity sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==
stacktrace-parser@^0.1.10:
version "0.1.10"
resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz#29fb0cae4e0d0b85155879402857a1639eb6051a"

Loading…
Cancel
Save