Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
B
baas-ide
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
JIRA
JIRA
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
guxukai
baas-ide
Commits
beccd28a
Commit
beccd28a
authored
Nov 04, 2020
by
yann300
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
debugger: remove old unused code
parent
cfd41cb9
Show whitespace changes
Inline
Side-by-side
Showing
24 changed files
with
0 additions
and
1572 deletions
+0
-1572
debugger-tab.js
apps/remix-ide/src/app/tabs/debugger-tab.js
+0
-1
debuggerUI.js
apps/remix-ide/src/app/tabs/debugger/debuggerUI.js
+0
-279
ButtonNavigator.js
...x-ide/src/app/tabs/debugger/debuggerUI/ButtonNavigator.js
+0
-130
Slider.js
apps/remix-ide/src/app/tabs/debugger/debuggerUI/Slider.js
+0
-57
StepManager.js
...remix-ide/src/app/tabs/debugger/debuggerUI/StepManager.js
+0
-59
TxBrowser.js
apps/remix-ide/src/app/tabs/debugger/debuggerUI/TxBrowser.js
+0
-137
VmDebugger.js
.../remix-ide/src/app/tabs/debugger/debuggerUI/VmDebugger.js
+0
-179
basicStyles.js
...de/src/app/tabs/debugger/debuggerUI/styles/basicStyles.js
+0
-76
dropdownPanel.js
.../src/app/tabs/debugger/debuggerUI/styles/dropdownPanel.js
+0
-31
sliderStyles.js
...e/src/app/tabs/debugger/debuggerUI/styles/sliderStyles.js
+0
-6
treeView.js
...x-ide/src/app/tabs/debugger/debuggerUI/styles/treeView.js
+0
-30
CalldataPanel.js
.../app/tabs/debugger/debuggerUI/vmDebugger/CalldataPanel.js
+0
-17
CallstackPanel.js
...app/tabs/debugger/debuggerUI/vmDebugger/CallstackPanel.js
+0
-18
CodeListView.js
...c/app/tabs/debugger/debuggerUI/vmDebugger/CodeListView.js
+0
-75
DropdownPanel.js
.../app/tabs/debugger/debuggerUI/vmDebugger/DropdownPanel.js
+0
-189
FullStoragesChanges.js
...abs/debugger/debuggerUI/vmDebugger/FullStoragesChanges.js
+0
-21
FunctionPanel.js
.../app/tabs/debugger/debuggerUI/vmDebugger/FunctionPanel.js
+0
-17
MemoryPanel.js
...rc/app/tabs/debugger/debuggerUI/vmDebugger/MemoryPanel.js
+0
-21
SolidityLocals.js
...app/tabs/debugger/debuggerUI/vmDebugger/SolidityLocals.js
+0
-59
SolidityState.js
.../app/tabs/debugger/debuggerUI/vmDebugger/SolidityState.js
+0
-36
StackPanel.js
...src/app/tabs/debugger/debuggerUI/vmDebugger/StackPanel.js
+0
-17
StepDetail.js
...src/app/tabs/debugger/debuggerUI/vmDebugger/StepDetail.js
+0
-23
StoragePanel.js
...c/app/tabs/debugger/debuggerUI/vmDebugger/StoragePanel.js
+0
-17
SolidityTypeFormatter.js
...gger/debuggerUI/vmDebugger/utils/SolidityTypeFormatter.js
+0
-77
No files found.
apps/remix-ide/src/app/tabs/debugger-tab.js
View file @
beccd28a
...
@@ -2,7 +2,6 @@ const yo = require('yo-yo')
...
@@ -2,7 +2,6 @@ const yo = require('yo-yo')
const
css
=
require
(
'./styles/debugger-tab-styles'
)
const
css
=
require
(
'./styles/debugger-tab-styles'
)
import
toaster
from
'../ui/tooltip'
import
toaster
from
'../ui/tooltip'
import
{
DebuggerUI
}
from
'@remix-ui/debugger-ui'
import
{
DebuggerUI
}
from
'@remix-ui/debugger-ui'
// const DebuggerUI = require('./debugger/debuggerUI')
import
{
ViewPlugin
}
from
'@remixproject/engine'
import
{
ViewPlugin
}
from
'@remixproject/engine'
import
*
as
packageJson
from
'../../../../../package.json'
import
*
as
packageJson
from
'../../../../../package.json'
import
React
from
'react'
import
React
from
'react'
...
...
apps/remix-ide/src/app/tabs/debugger/debuggerUI.js
deleted
100644 → 0
View file @
cfd41cb9
var
TxBrowser
=
require
(
'./debuggerUI/TxBrowser'
)
var
StepManagerUI
=
require
(
'./debuggerUI/StepManager'
)
var
VmDebugger
=
require
(
'./debuggerUI/VmDebugger'
)
var
toaster
=
require
(
'../../ui/tooltip'
)
var
Debugger
=
require
(
'@remix-project/remix-debug'
).
TransactionDebugger
var
SourceHighlighter
=
require
(
'../../editor/sourceHighlighter'
)
var
EventManager
=
require
(
'../../../lib/events'
)
var
globalRegistry
=
require
(
'../../../global/registry'
)
var
remixDebug
=
require
(
'@remix-project/remix-debug'
)
var
init
=
remixDebug
.
init
var
yo
=
require
(
'yo-yo'
)
var
csjs
=
require
(
'csjs-inject'
)
var
css
=
csjs
`
.statusMessage {
margin-left: 15px;
}
.debuggerConfig {
display: flex;
align-items: center;
}
.debuggerConfig label {
margin: 0;
}
.debuggerSection {
padding: 12px 24px 16px;
}
.debuggerLabel {
margin-bottom: 2px;
font-size: 11px;
line-height: 12px;
text-transform: uppercase;
}
`
class
DebuggerUI
{
constructor
(
debuggerModule
,
component
,
fetchContractAndCompile
)
{
this
.
debuggerModule
=
debuggerModule
this
.
fetchContractAndCompile
=
fetchContractAndCompile
this
.
event
=
new
EventManager
()
this
.
isActive
=
false
this
.
opt
=
{
debugWithGeneratedSources
:
false
}
this
.
sourceHighlighter
=
new
SourceHighlighter
()
this
.
startTxBrowser
()
this
.
stepManager
=
null
this
.
statusMessage
=
''
this
.
currentReceipt
this
.
view
component
.
appendChild
(
this
.
render
())
this
.
setEditor
()
}
setEditor
()
{
this
.
editor
=
globalRegistry
.
get
(
'editor'
).
api
this
.
editor
.
event
.
register
(
'breakpointCleared'
,
(
fileName
,
row
)
=>
{
if
(
this
.
debugger
)
this
.
debugger
.
breakPointManager
.
remove
({
fileName
:
fileName
,
row
:
row
})
})
this
.
editor
.
event
.
register
(
'breakpointAdded'
,
(
fileName
,
row
)
=>
{
if
(
this
.
debugger
)
this
.
debugger
.
breakPointManager
.
add
({
fileName
:
fileName
,
row
:
row
})
})
this
.
editor
.
event
.
register
(
'contentChanged'
,
()
=>
{
if
(
this
.
debugger
)
this
.
debugger
.
unload
()
})
}
listenToEvents
()
{
if
(
!
this
.
debugger
)
return
this
.
debugger
.
event
.
register
(
'debuggerStatus'
,
async
(
isActive
)
=>
{
await
this
.
debuggerModule
.
call
(
'editor'
,
'discardHighlight'
)
this
.
isActive
=
isActive
})
this
.
debugger
.
event
.
register
(
'newSourceLocation'
,
async
(
lineColumnPos
,
rawLocation
,
generatedSources
)
=>
{
if
(
!
lineColumnPos
)
return
const
contracts
=
await
this
.
fetchContractAndCompile
(
this
.
currentReceipt
.
contractAddress
||
this
.
currentReceipt
.
to
,
this
.
currentReceipt
)
if
(
contracts
)
{
let
path
=
contracts
.
getSourceName
(
rawLocation
.
file
)
if
(
!
path
)
{
// check in generated sources
for
(
const
source
of
generatedSources
)
{
if
(
source
.
id
===
rawLocation
.
file
)
{
path
=
`browser/.debugger/generated-sources/
${
source
.
name
}
`
let
content
try
{
content
=
await
this
.
debuggerModule
.
call
(
'fileManager'
,
'getFile'
,
path
,
source
.
contents
)
}
catch
(
e
)
{
console
.
log
(
'unable to fetch generated sources, the file probably doesn
\'
t exist yet'
,
e
)
}
if
(
content
!==
source
.
contents
)
{
await
this
.
debuggerModule
.
call
(
'fileManager'
,
'setFile'
,
path
,
source
.
contents
)
}
break
}
}
}
if
(
path
)
{
await
this
.
debuggerModule
.
call
(
'editor'
,
'discardHighlight'
)
await
this
.
debuggerModule
.
call
(
'editor'
,
'highlight'
,
lineColumnPos
,
path
)
}
}
})
this
.
debugger
.
event
.
register
(
'debuggerUnloaded'
,
()
=>
this
.
unLoad
())
}
startTxBrowser
()
{
let
txBrowser
=
new
TxBrowser
()
this
.
txBrowser
=
txBrowser
txBrowser
.
event
.
register
(
'requestDebug'
,
(
blockNumber
,
txNumber
,
tx
)
=>
{
if
(
this
.
debugger
)
this
.
debugger
.
unload
()
this
.
startDebugging
(
blockNumber
,
txNumber
,
tx
)
})
txBrowser
.
event
.
register
(
'unloadRequested'
,
this
,
(
blockNumber
,
txIndex
,
tx
)
=>
{
if
(
this
.
debugger
)
this
.
debugger
.
unload
()
})
}
isDebuggerActive
()
{
return
this
.
isActive
}
getDebugWeb3
()
{
return
new
Promise
((
resolve
,
reject
)
=>
{
this
.
debuggerModule
.
blockchain
.
detectNetwork
((
error
,
network
)
=>
{
let
web3
if
(
error
||
!
network
)
{
web3
=
init
.
web3DebugNode
(
this
.
debuggerModule
.
blockchain
.
web3
())
}
else
{
const
webDebugNode
=
init
.
web3DebugNode
(
network
.
name
)
web3
=
!
webDebugNode
?
this
.
debuggerModule
.
blockchain
.
web3
()
:
webDebugNode
}
init
.
extendWeb3
(
web3
)
resolve
(
web3
)
})
})
}
async
startDebugging
(
blockNumber
,
txNumber
,
tx
)
{
if
(
this
.
debugger
)
this
.
unLoad
()
let
web3
=
await
this
.
getDebugWeb3
()
this
.
currentReceipt
=
await
web3
.
eth
.
getTransactionReceipt
(
txNumber
)
this
.
debugger
=
new
Debugger
({
web3
,
offsetToLineColumnConverter
:
globalRegistry
.
get
(
'offsettolinecolumnconverter'
).
api
,
compilationResult
:
async
(
address
)
=>
{
try
{
return
await
this
.
fetchContractAndCompile
(
address
,
this
.
currentReceipt
)
}
catch
(
e
)
{
console
.
error
(
e
)
}
return
null
},
debugWithGeneratedSources
:
this
.
opt
.
debugWithGeneratedSources
})
this
.
listenToEvents
()
this
.
debugger
.
debug
(
blockNumber
,
txNumber
,
tx
,
()
=>
{
this
.
stepManager
=
new
StepManagerUI
(
this
.
debugger
.
step_manager
)
this
.
vmDebugger
=
new
VmDebugger
(
this
.
debugger
.
vmDebuggerLogic
)
this
.
txBrowser
.
setState
({
blockNumber
,
txNumber
,
debugging
:
true
})
this
.
renderDebugger
()
}).
catch
((
error
)
=>
{
toaster
(
error
)
this
.
unLoad
()
})
}
getTrace
(
hash
)
{
return
new
Promise
(
async
(
resolve
,
reject
)
=>
{
const
web3
=
await
this
.
getDebugWeb3
()
this
.
currentReceipt
=
await
web3
.
eth
.
getTransactionReceipt
(
hash
)
const
debug
=
new
Debugger
({
web3
,
offsetToLineColumnConverter
:
globalRegistry
.
get
(
'offsettolinecolumnconverter'
).
api
,
compilationResult
:
async
(
address
)
=>
{
try
{
return
await
this
.
fetchContractAndCompile
(
address
,
this
.
currentReceipt
)
}
catch
(
e
)
{
console
.
error
(
e
)
}
return
null
},
debugWithGeneratedSources
:
false
})
debug
.
debugger
.
traceManager
.
traceRetriever
.
getTrace
(
hash
,
(
error
,
trace
)
=>
{
if
(
error
)
return
reject
(
error
)
resolve
(
trace
)
})
})
}
debug
(
txHash
)
{
this
.
startDebugging
(
null
,
txHash
,
null
)
}
render
()
{
this
.
debuggerPanelsView
=
yo
`<div class="px-2"></div>`
this
.
debuggerHeadPanelsView
=
yo
`<div class="px-2"></div>`
this
.
stepManagerView
=
yo
`<div class="px-2"></div>`
var
view
=
yo
`
<div>
<div class="px-2">
<div class="mt-3">
<p class="mt-2
${
css
.
debuggerLabel
}
">Debugger Configuration</p>
<div class="mt-2
${
css
.
debuggerConfig
}
custom-control custom-checkbox">
<input class="custom-control-input" id="debugGeneratedSourcesInput" onchange=
${(
event
)
=>
{
this
.
opt
.
debugWithGeneratedSources
=
event
.
target
.
checked
}}
type
=
"checkbox"
title
=
"Debug with generated sources"
>
<
label
data
-
id
=
"debugGeneratedSourcesLabel"
class
=
"form-check-label custom-control-label"
for
=
"debugGeneratedSourcesInput"
>
Use
generated
sources
(
from
Solidity
v0
.
7.2
)
<
/label
>
<
/div>
<
/div>
$
{
this
.
txBrowser
.
render
()}
${
this
.
stepManagerView
}
${
this
.
debuggerHeadPanelsView
}
<div class="
${
css
.
statusMessage
}
">
${
this
.
statusMessage
}
</div>
${
this
.
debuggerPanelsView
}
</div>
`
if
(
!
this
.
view
)
{
this
.
view
=
view
}
return
view
}
async
unLoad
()
{
yo
.
update
(
this
.
debuggerHeadPanelsView
,
yo
`<div></div>`
)
yo
.
update
(
this
.
debuggerPanelsView
,
yo
`<div></div>`
)
yo
.
update
(
this
.
stepManagerView
,
yo
`<div></div>`
)
if
(
this
.
vmDebugger
)
this
.
vmDebugger
.
remove
()
if
(
this
.
stepManager
)
this
.
stepManager
.
remove
()
if
(
this
.
txBrowser
)
this
.
txBrowser
.
setState
({
debugging
:
false
})
this
.
vmDebugger
=
null
this
.
stepManager
=
null
if
(
this
.
debugger
)
delete
this
.
debugger
this
.
event
.
trigger
(
'traceUnloaded'
)
}
async
deleteHighlights
()
{
await
this
.
debuggerModule
.
call
(
'editor'
,
'discardHighlight'
)
}
renderDebugger
()
{
yo
.
update
(
this
.
debuggerHeadPanelsView
,
this
.
vmDebugger
.
renderHead
())
yo
.
update
(
this
.
debuggerPanelsView
,
this
.
vmDebugger
.
render
())
yo
.
update
(
this
.
stepManagerView
,
this
.
stepManager
.
render
())
}
}
module
.
exports
=
DebuggerUI
apps/remix-ide/src/app/tabs/debugger/debuggerUI/ButtonNavigator.js
deleted
100644 → 0
View file @
cfd41cb9
'use strict'
var
EventManager
=
require
(
'../../../../lib/events'
)
var
yo
=
require
(
'yo-yo'
)
var
csjs
=
require
(
'csjs-inject'
)
var
css
=
csjs
`
.buttons {
display: flex;
flex-wrap: wrap;
}
.stepButtons {
width: 100%;
display: flex;
justify-content: center;
}
.stepButton {
}
.jumpButtons {
width: 100%;
display: flex;
justify-content: center;
}
.jumpButton {
}
.navigator {
}
.navigator:hover {
}
`
function
ButtonNavigator
()
{
this
.
event
=
new
EventManager
()
this
.
intoBackDisabled
=
true
this
.
overBackDisabled
=
true
this
.
intoForwardDisabled
=
true
this
.
overForwardDisabled
=
true
this
.
jumpOutDisabled
=
true
this
.
jumpNextBreakpointDisabled
=
true
this
.
jumpPreviousBreakpointDisabled
=
true
this
.
view
}
ButtonNavigator
.
prototype
.
render
=
function
()
{
var
self
=
this
var
view
=
yo
`<div class="
${
css
.
buttons
}
">
<div class="
${
css
.
stepButtons
}
btn-group py-1">
<button id='overback' class='btn btn-primary btn-sm
${
css
.
navigator
}
${
css
.
stepButton
}
fas fa-reply' title='Step over back' onclick=
${
function
()
{
self
.
event
.
trigger
(
'stepOverBack'
)
}
} disabled=
${
this
.
overBackDisabled
}
></button>
<button id='intoback' data-id="buttonNavigatorIntoBack" class='btn btn-primary btn-sm
${
css
.
navigator
}
${
css
.
stepButton
}
fas fa-level-up-alt' title='Step back' onclick=
${
function
()
{
self
.
event
.
trigger
(
'stepIntoBack'
)
}
} disabled=
${
this
.
intoBackDisabled
}
></button>
<button id='intoforward' data-id="buttonNavigatorIntoForward" class='btn btn-primary btn-sm
${
css
.
navigator
}
${
css
.
stepButton
}
fas fa-level-down-alt' title='Step into' onclick=
${
function
()
{
self
.
event
.
trigger
(
'stepIntoForward'
)
}
} disabled=
${
this
.
intoForwardDisabled
}
></button>
<button id='overforward' class='btn btn-primary btn-sm
${
css
.
navigator
}
${
css
.
stepButton
}
fas fa-share' title='Step over forward'onclick=
${
function
()
{
self
.
event
.
trigger
(
'stepOverForward'
)
}
} disabled=
${
this
.
overForwardDisabled
}
></button>
</div>
<div class="
${
css
.
jumpButtons
}
btn-group py-1">
<button class='btn btn-primary btn-sm
${
css
.
navigator
}
${
css
.
jumpButton
}
fas fa-step-backward' id='jumppreviousbreakpoint' data-id="buttonNavigatorJumpPreviousBreakpoint" title='Jump to the previous breakpoint' onclick=
${
function
()
{
self
.
event
.
trigger
(
'jumpPreviousBreakpoint'
)
}
} disabled=
${
this
.
jumpPreviousBreakpointDisabled
}
></button>
<button class='btn btn-primary btn-sm
${
css
.
navigator
}
${
css
.
jumpButton
}
fas fa-eject' id='jumpout' title='Jump out' onclick=
${
function
()
{
self
.
event
.
trigger
(
'jumpOut'
)
}
} disabled=
${
this
.
jumpOutDisabled
}
></button>
<button class='btn btn-primary btn-sm
${
css
.
navigator
}
${
css
.
jumpButton
}
fas fa-step-forward' id='jumpnextbreakpoint' data-id="buttonNavigatorJumpNextBreakpoint" title='Jump to the next breakpoint' onclick=
${
function
()
{
self
.
event
.
trigger
(
'jumpNextBreakpoint'
)
}
} disabled=
${
this
.
jumpNextBreakpointDisabled
}
></button>
</div>
<div id='reverted' style="display:none">
<button class='btn btn-danger btn-sm' id='jumptoexception' title='Jump to exception' class='
${
css
.
navigator
}
${
css
.
button
}
fas fa-exclamation-triangle' onclick=
${
function
()
{
self
.
event
.
trigger
(
'jumpToException'
)
}
} disabled=
${
this
.
jumpOutDisabled
}
>
</button>
<span>State changes made during this call will be reverted.</span>
<span id='outofgas' style="display:none">This call will run out of gas.</span>
<span id='parenthasthrown' style="display:none">The parent call will throw an exception</span>
</div>
</div>`
if
(
!
this
.
view
)
{
this
.
view
=
view
}
return
view
}
ButtonNavigator
.
prototype
.
reset
=
function
()
{
this
.
intoBackDisabled
=
true
this
.
overBackDisabled
=
true
this
.
intoForwardDisabled
=
true
this
.
overForwardDisabled
=
true
this
.
jumpOutDisabled
=
true
this
.
jumpNextBreakpointDisabled
=
true
this
.
jumpPreviousBreakpointDisabled
=
true
this
.
resetWarning
(
''
)
}
ButtonNavigator
.
prototype
.
stepChanged
=
function
(
stepState
,
jumpOutDisabled
)
{
if
(
stepState
===
'invalid'
)
{
// TODO: probably not necessary, already implicit done in the next steps
this
.
reset
()
this
.
updateAll
()
return
}
this
.
intoBackDisabled
=
(
stepState
===
'initial'
)
this
.
overBackDisabled
=
(
stepState
===
'initial'
)
this
.
jumpPreviousBreakpointDisabled
=
(
stepState
===
'initial'
)
this
.
jumpNextBreakpointDisabled
=
(
stepState
===
'end'
)
this
.
intoForwardDisabled
=
(
stepState
===
'end'
)
this
.
overForwardDisabled
=
(
stepState
===
'end'
)
this
.
jumpNextBreakpointDisabled
=
jumpOutDisabled
this
.
updateAll
()
}
ButtonNavigator
.
prototype
.
updateAll
=
function
()
{
this
.
updateDisabled
(
'intoback'
,
this
.
intoBackDisabled
)
this
.
updateDisabled
(
'overback'
,
this
.
overBackDisabled
)
this
.
updateDisabled
(
'overforward'
,
this
.
overForwardDisabled
)
this
.
updateDisabled
(
'intoforward'
,
this
.
intoForwardDisabled
)
this
.
updateDisabled
(
'jumpout'
,
this
.
jumpOutDisabled
)
this
.
updateDisabled
(
'jumptoexception'
,
this
.
jumpOutDisabled
)
this
.
updateDisabled
(
'jumpnextbreakpoint'
,
this
.
jumpNextBreakpointDisabled
)
this
.
updateDisabled
(
'jumppreviousbreakpoint'
,
this
.
jumpPreviousBreakpointDisabled
)
}
ButtonNavigator
.
prototype
.
updateDisabled
=
function
(
id
,
disabled
)
{
if
(
disabled
)
{
document
.
getElementById
(
id
).
setAttribute
(
'disabled'
,
true
)
}
else
{
document
.
getElementById
(
id
).
removeAttribute
(
'disabled'
)
}
}
ButtonNavigator
.
prototype
.
resetWarning
=
function
(
revertedReason
)
{
if
(
!
this
.
view
)
return
this
.
view
.
querySelector
(
'#reverted #outofgas'
).
style
.
display
=
(
revertedReason
===
'outofgas'
)
?
'inline'
:
'none'
this
.
view
.
querySelector
(
'#reverted #parenthasthrown'
).
style
.
display
=
(
revertedReason
===
'parenthasthrown'
)
?
'inline'
:
'none'
this
.
view
.
querySelector
(
'#reverted'
).
style
.
display
=
(
revertedReason
===
''
)
?
'none'
:
'block'
}
module
.
exports
=
ButtonNavigator
apps/remix-ide/src/app/tabs/debugger/debuggerUI/Slider.js
deleted
100644 → 0
View file @
cfd41cb9
'use strict'
var
EventManager
=
require
(
'../../../../lib/events'
)
var
yo
=
require
(
'yo-yo'
)
class
Slider
{
constructor
()
{
this
.
event
=
new
EventManager
()
this
.
max
this
.
disabled
=
true
this
.
view
this
.
previousValue
=
null
}
setSliderLength
(
length
)
{
if
(
!
this
.
view
)
return
this
.
view
.
querySelector
(
'#slider'
).
setAttribute
(
'max'
,
length
-
1
)
this
.
max
=
length
-
1
this
.
disabled
=
(
length
===
0
)
if
(
this
.
disabled
)
{
this
.
view
.
querySelector
(
'#slider'
).
setAttribute
(
'disabled'
,
true
)
}
else
{
this
.
view
.
querySelector
(
'#slider'
).
removeAttribute
(
'disabled'
)
}
this
.
setValue
(
0
)
}
onChange
(
event
)
{
if
(
!
this
.
view
)
return
var
value
=
parseInt
(
this
.
view
.
querySelector
(
'#slider'
).
value
)
if
(
value
===
this
.
previousValue
)
return
this
.
previousValue
=
value
this
.
event
.
trigger
(
'sliderMoved'
,
[
value
])
}
setValue
(
value
)
{
if
(
!
this
.
view
)
return
this
.
view
.
querySelector
(
'#slider'
).
value
=
value
}
render
()
{
var
self
=
this
var
view
=
yo
`<div>
<input id='slider' data-id="slider" class='w-100 my-0' type='range' min=0 max=
${
this
.
max
}
value=0
onchange=
${
function
()
{
self
.
onChange
()
}
} oninput=
${
function
()
{
self
.
onChange
()
}
} disabled=
${
this
.
disabled
}
/>
</div>`
if
(
!
this
.
view
)
{
this
.
view
=
view
}
return
view
}
}
module
.
exports
=
Slider
apps/remix-ide/src/app/tabs/debugger/debuggerUI/StepManager.js
deleted
100644 → 0
View file @
cfd41cb9
var
EventManager
=
require
(
'../../../../lib/events'
)
var
yo
=
require
(
'yo-yo'
)
var
ButtonNavigator
=
require
(
'./ButtonNavigator'
)
var
Slider
=
require
(
'./Slider'
)
function
StepManager
(
stepManager
)
{
this
.
event
=
new
EventManager
()
this
.
stepManager
=
stepManager
this
.
startSlider
()
this
.
startButtonNavigator
()
this
.
stepManager
.
event
.
register
(
'stepChanged'
,
this
.
updateStep
.
bind
(
this
))
}
StepManager
.
prototype
.
startSlider
=
function
()
{
this
.
slider
=
new
Slider
()
this
.
slider
.
event
.
register
(
'sliderMoved'
,
this
.
stepManager
.
jumpTo
.
bind
(
this
.
stepManager
))
this
.
stepManager
.
event
.
register
(
'traceLengthChanged'
,
this
.
slider
.
setSliderLength
.
bind
(
this
.
slider
))
}
StepManager
.
prototype
.
startButtonNavigator
=
function
()
{
this
.
buttonNavigator
=
new
ButtonNavigator
()
this
.
stepManager
.
event
.
register
(
'revertWarning'
,
this
.
buttonNavigator
.
resetWarning
.
bind
(
this
.
buttonNavigator
))
this
.
buttonNavigator
.
event
.
register
(
'stepIntoBack'
,
this
.
stepManager
.
stepIntoBack
.
bind
(
this
.
stepManager
))
this
.
buttonNavigator
.
event
.
register
(
'stepIntoForward'
,
this
.
stepManager
.
stepIntoForward
.
bind
(
this
.
stepManager
))
this
.
buttonNavigator
.
event
.
register
(
'stepOverBack'
,
this
.
stepManager
.
stepOverBack
.
bind
(
this
.
stepManager
))
this
.
buttonNavigator
.
event
.
register
(
'stepOverForward'
,
this
.
stepManager
.
stepOverForward
.
bind
(
this
.
stepManager
))
this
.
buttonNavigator
.
event
.
register
(
'jumpOut'
,
this
.
stepManager
.
jumpOut
.
bind
(
this
.
stepManager
))
this
.
buttonNavigator
.
event
.
register
(
'jumpToException'
,
this
.
stepManager
.
jumpToException
.
bind
(
this
.
stepManager
))
this
.
buttonNavigator
.
event
.
register
(
'jumpNextBreakpoint'
,
this
.
stepManager
.
jumpNextBreakpoint
.
bind
(
this
.
stepManager
))
this
.
buttonNavigator
.
event
.
register
(
'jumpPreviousBreakpoint'
,
this
.
stepManager
.
jumpPreviousBreakpoint
.
bind
(
this
.
stepManager
))
}
StepManager
.
prototype
.
updateStep
=
function
(
step
,
stepState
,
jumpOutDisabled
)
{
if
(
!
this
.
slider
)
return
this
.
slider
.
setValue
(
step
)
this
.
buttonNavigator
.
stepChanged
(
stepState
,
jumpOutDisabled
)
this
.
event
.
trigger
(
'stepChanged'
,
[
step
])
}
StepManager
.
prototype
.
remove
=
function
()
{
// used to stop listenning on event. bad and should be "refactored"
this
.
slider
.
view
=
null
this
.
slider
=
null
this
.
buttonNavigator
.
view
=
null
this
.
buttonNavigator
=
null
}
StepManager
.
prototype
.
render
=
function
()
{
return
yo
`
<div class="py-1">
${
this
.
slider
.
render
()}
${
this
.
buttonNavigator
.
render
()}
</div>`
}
module
.
exports
=
StepManager
apps/remix-ide/src/app/tabs/debugger/debuggerUI/TxBrowser.js
deleted
100644 → 0
View file @
cfd41cb9
var
EventManager
=
require
(
'../../../../lib/events'
)
var
yo
=
require
(
'yo-yo'
)
var
csjs
=
require
(
'csjs-inject'
)
var
css
=
csjs
`
.container {
display: flex;
flex-direction: column;
}
.txContainer {
display: flex;
flex-direction: column;
}
.txinput {
width: inherit;
font-size: small;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.txbutton {
width: inherit;
}
.txbutton:hover {
}
.vmargin {
margin-top: 10px;
margin-bottom: 10px;
}
`
function
TxBrowser
()
{
this
.
event
=
new
EventManager
()
this
.
state
=
{
txNumber
:
undefined
,
debugging
:
false
}
this
.
view
}
TxBrowser
.
prototype
.
submit
=
function
()
{
if
(
this
.
state
.
debugging
)
{
this
.
unload
()
}
else
{
this
.
event
.
trigger
(
'requestDebug'
,
[
undefined
,
this
.
state
.
txNumber
])
}
yo
.
update
(
this
.
view
,
this
.
render
())
}
TxBrowser
.
prototype
.
updateTxN
=
function
(
ev
)
{
this
.
state
.
txNumber
=
ev
.
target
.
value
if
(
this
.
view
)
{
yo
.
update
(
this
.
view
,
this
.
render
())
}
}
TxBrowser
.
prototype
.
load
=
function
(
txHash
,
tx
)
{
this
.
state
.
txNumber
=
txHash
}
TxBrowser
.
prototype
.
unload
=
function
()
{
this
.
event
.
trigger
(
'unloadRequested'
)
}
TxBrowser
.
prototype
.
setState
=
function
(
state
)
{
this
.
state
=
{...
this
.
state
,
...
state
}
if
(
this
.
view
)
{
yo
.
update
(
this
.
view
,
this
.
render
())
}
}
TxBrowser
.
prototype
.
render
=
function
()
{
var
self
=
this
this
.
state
.
txNumberInput
=
yo
`
<input
value="
${
this
.
state
.
txNumber
||
''
}
"
class="form-control m-0
${
css
.
txinput
}
"
id='txinput'
onkeyup=
${
function
()
{
self
.
updateTxN
(
arguments
[
0
])
}
}
type='text'
oninput=
${
this
.
txInputChanged
.
bind
(
this
)}
placeholder=
${
'Transaction hash, should start with 0x'
}
data-id="debuggerTransactionInput"
/>
`
let
txButton
=
yo
`
<button
class='btn btn-primary btn-sm
${
css
.
txbutton
}
'
id='load'
title='
${
this
.
state
.
debugging
?
'Stop'
:
'Start'
}
debugging'
onclick=
${
function
()
{
self
.
submit
()
}
}
data-id="debuggerTransactionStartButton"
>
${
this
.
state
.
debugging
?
'Stop'
:
'Start'
}
debugging
</button>
`
var
view
=
yo
`
<div class="
${
css
.
container
}
">
<div class="
${
css
.
txContainer
}
">
<div class=" py-1 d-flex justify-content-center w-100 input-group">
${
this
.
state
.
txNumberInput
}
</div>
<div class="d-flex justify-content-center w-100 btn-group py-1">
${
txButton
}
</div>
</div>
<span id='error'></span>
</div>
`
if
(
this
.
state
.
debugging
)
{
view
.
querySelectorAll
(
'input'
).
forEach
(
element
=>
{
element
.
setAttribute
(
'disabled'
,
''
)
})
}
if
(
!
this
.
state
.
txNumber
)
{
view
.
querySelector
(
"button[id='load']"
).
setAttribute
(
'disabled'
,
''
)
}
else
if
(
!
this
.
state
.
debugging
)
{
this
.
state
.
txNumberInput
.
removeAttribute
(
'disabled'
)
}
if
(
!
this
.
view
)
{
this
.
view
=
view
}
return
view
}
TxBrowser
.
prototype
.
txInputChanged
=
function
(
event
)
{
// todo check validation of txnumber in the input element, use
// required
// oninvalid="setCustomValidity('Please provide a valid transaction number, must start with 0x and have length of 22')"
// pattern="^0[x,X]+[0-9a-fA-F]{22}"
// this.state.txNumberInput.setCustomValidity('')
this
.
state
.
txNumber
=
event
.
target
.
value
yo
.
update
(
this
.
view
,
this
.
render
())
}
module
.
exports
=
TxBrowser
apps/remix-ide/src/app/tabs/debugger/debuggerUI/VmDebugger.js
deleted
100644 → 0
View file @
cfd41cb9
'use strict'
var
yo
=
require
(
'yo-yo'
)
var
CodeListView
=
require
(
'./vmDebugger/CodeListView'
)
var
CalldataPanel
=
require
(
'./vmDebugger/CalldataPanel'
)
var
MemoryPanel
=
require
(
'./vmDebugger/MemoryPanel'
)
var
CallstackPanel
=
require
(
'./vmDebugger/CallstackPanel'
)
var
FunctionPanel
=
require
(
'./vmDebugger/FunctionPanel'
)
var
StackPanel
=
require
(
'./vmDebugger/StackPanel'
)
var
StoragePanel
=
require
(
'./vmDebugger/StoragePanel'
)
var
StepDetail
=
require
(
'./vmDebugger/StepDetail'
)
var
SolidityState
=
require
(
'./vmDebugger/SolidityState'
)
var
SolidityLocals
=
require
(
'./vmDebugger/SolidityLocals'
)
var
FullStoragesChangesPanel
=
require
(
'./vmDebugger/FullStoragesChanges'
)
var
DropdownPanel
=
require
(
'./vmDebugger/DropdownPanel'
)
function
VmDebugger
(
vmDebuggerLogic
)
{
var
self
=
this
this
.
view
this
.
vmDebuggerLogic
=
vmDebuggerLogic
this
.
asmCode
=
new
CodeListView
()
this
.
vmDebuggerLogic
.
event
.
register
(
'codeManagerChanged'
,
this
.
asmCode
.
changed
.
bind
(
this
.
asmCode
))
this
.
vmDebuggerLogic
.
event
.
register
(
'traceUnloaded'
,
this
.
asmCode
.
reset
.
bind
(
this
.
asmCode
))
this
.
calldataPanel
=
new
CalldataPanel
()
this
.
vmDebuggerLogic
.
event
.
register
(
'traceManagerCallDataUpdate'
,
this
.
calldataPanel
.
update
.
bind
(
this
.
calldataPanel
))
this
.
memoryPanel
=
new
MemoryPanel
()
this
.
vmDebuggerLogic
.
event
.
register
(
'traceManagerMemoryUpdate'
,
this
.
memoryPanel
.
update
.
bind
(
this
.
memoryPanel
))
this
.
callstackPanel
=
new
CallstackPanel
()
this
.
vmDebuggerLogic
.
event
.
register
(
'traceManagerCallStackUpdate'
,
this
.
callstackPanel
.
update
.
bind
(
this
.
callstackPanel
))
this
.
stackPanel
=
new
StackPanel
()
this
.
vmDebuggerLogic
.
event
.
register
(
'traceManagerStackUpdate'
,
this
.
stackPanel
.
update
.
bind
(
this
.
stackPanel
))
this
.
functionPanel
=
new
FunctionPanel
()
this
.
vmDebuggerLogic
.
event
.
register
(
'functionsStackUpdate'
,
(
stack
)
=>
{
if
(
stack
===
null
||
stack
.
length
===
0
)
return
let
functions
=
[]
for
(
let
func
of
stack
)
{
functions
.
push
(
func
.
functionDefinition
.
name
+
'('
+
func
.
inputs
.
join
(
', '
)
+
')'
)
}
this
.
functionPanel
.
update
(
functions
)
})
this
.
storagePanel
=
new
StoragePanel
()
this
.
vmDebuggerLogic
.
event
.
register
(
'traceManagerStorageUpdate'
,
this
.
storagePanel
.
update
.
bind
(
this
.
storagePanel
))
this
.
stepDetail
=
new
StepDetail
()
this
.
vmDebuggerLogic
.
event
.
register
(
'traceUnloaded'
,
this
.
stepDetail
.
reset
.
bind
(
this
.
stepDetail
))
this
.
vmDebuggerLogic
.
event
.
register
(
'newTraceLoaded'
,
this
.
stepDetail
.
reset
.
bind
(
this
.
stepDetail
))
this
.
vmDebuggerLogic
.
event
.
register
(
'traceCurrentStepUpdate'
,
function
(
error
,
step
)
{
self
.
stepDetail
.
updateField
(
'execution step'
,
(
error
?
'-'
:
step
))
})
this
.
vmDebuggerLogic
.
event
.
register
(
'traceMemExpandUpdate'
,
function
(
error
,
addmem
)
{
self
.
stepDetail
.
updateField
(
'add memory'
,
(
error
?
'-'
:
addmem
))
})
this
.
vmDebuggerLogic
.
event
.
register
(
'traceStepCostUpdate'
,
function
(
error
,
gas
)
{
self
.
stepDetail
.
updateField
(
'gas'
,
(
error
?
'-'
:
gas
))
})
this
.
vmDebuggerLogic
.
event
.
register
(
'traceCurrentCalledAddressAtUpdate'
,
function
(
error
,
address
)
{
self
.
stepDetail
.
updateField
(
'loaded address'
,
(
error
?
'-'
:
address
))
})
this
.
vmDebuggerLogic
.
event
.
register
(
'traceRemainingGasUpdate'
,
function
(
error
,
remainingGas
)
{
self
.
stepDetail
.
updateField
(
'remaining gas'
,
(
error
?
'-'
:
remainingGas
))
})
this
.
vmDebuggerLogic
.
event
.
register
(
'indexUpdate'
,
function
(
index
)
{
self
.
stepDetail
.
updateField
(
'vm trace step'
,
index
)
})
this
.
solidityState
=
new
SolidityState
()
this
.
vmDebuggerLogic
.
event
.
register
(
'solidityState'
,
this
.
solidityState
.
update
.
bind
(
this
.
solidityState
))
this
.
vmDebuggerLogic
.
event
.
register
(
'solidityStateMessage'
,
this
.
solidityState
.
setMessage
.
bind
(
this
.
solidityState
))
this
.
vmDebuggerLogic
.
event
.
register
(
'solidityStateUpdating'
,
this
.
solidityState
.
setUpdating
.
bind
(
this
.
solidityState
))
this
.
solidityLocals
=
new
SolidityLocals
()
this
.
solidityLocals
.
event
.
register
(
'solidityLocalsLoadMore'
,
(
cursor
)
=>
{
this
.
vmDebuggerLogic
.
event
.
trigger
(
'solidityLocalsLoadMore'
,
[
cursor
])
})
this
.
vmDebuggerLogic
.
event
.
register
(
'solidityLocals'
,
this
.
solidityLocals
.
update
.
bind
(
this
.
solidityLocals
))
this
.
vmDebuggerLogic
.
event
.
register
(
'solidityLocalsMessage'
,
this
.
solidityLocals
.
setMessage
.
bind
(
this
.
solidityLocals
))
this
.
vmDebuggerLogic
.
event
.
register
(
'solidityLocalsUpdating'
,
this
.
solidityLocals
.
setUpdating
.
bind
(
this
.
solidityLocals
))
this
.
vmDebuggerLogic
.
event
.
register
(
'solidityLocalsLoadMoreCompleted'
,
this
.
solidityLocals
.
loadMore
.
bind
(
this
.
solidityLocals
))
this
.
returnValuesPanel
=
new
DropdownPanel
(
'Return Value'
,
{
json
:
true
})
this
.
returnValuesPanel
.
data
=
{}
this
.
vmDebuggerLogic
.
event
.
register
(
'traceReturnValueUpdate'
,
this
.
returnValuesPanel
.
update
.
bind
(
this
.
returnValuesPanel
))
this
.
fullStoragesChangesPanel
=
new
FullStoragesChangesPanel
()
this
.
addresses
=
[]
this
.
vmDebuggerLogic
.
event
.
register
(
'traceAddressesUpdate'
,
function
(
_addresses
)
{
self
.
fullStoragesChangesPanel
.
update
({})
})
this
.
vmDebuggerLogic
.
event
.
register
(
'traceStorageUpdate'
,
this
.
fullStoragesChangesPanel
.
update
.
bind
(
this
.
fullStoragesChangesPanel
))
this
.
vmDebuggerLogic
.
event
.
register
(
'newTrace'
,
()
=>
{
if
(
!
self
.
view
)
return
self
.
asmCode
.
basicPanel
.
show
()
self
.
stackPanel
.
basicPanel
.
show
()
self
.
functionPanel
.
basicPanel
.
show
()
self
.
storagePanel
.
basicPanel
.
show
()
self
.
memoryPanel
.
basicPanel
.
show
()
self
.
stepDetail
.
basicPanel
.
show
()
self
.
calldataPanel
.
basicPanel
.
show
()
self
.
callstackPanel
.
basicPanel
.
show
()
})
this
.
vmDebuggerLogic
.
event
.
register
(
'newCallTree'
,
()
=>
{
if
(
!
self
.
view
)
return
self
.
functionPanel
.
basicPanel
.
show
()
self
.
solidityLocals
.
basicPanel
.
show
()
self
.
solidityState
.
basicPanel
.
show
()
self
.
solidityPanel
.
hidden
=
false
})
this
.
vmDebuggerLogic
.
start
()
}
VmDebugger
.
prototype
.
renderHead
=
function
()
{
this
.
solidityPanel
=
yo
`
<div class="w-100" hidden>
${
this
.
functionPanel
.
render
()}
${
this
.
solidityLocals
.
render
()}
${
this
.
solidityState
.
render
()}
</div>
`
const
headView
=
yo
`
<div id="vmheadView" class="mt-1 px-0">
<div class="d-flex flex-column">
${
this
.
solidityPanel
}
<div class="w-100">
${
this
.
asmCode
.
render
()}
</div>
<div class="w-100">
${
this
.
stepDetail
.
render
()}
</div>
</div>
</div>
`
if
(
!
this
.
headView
)
{
this
.
headView
=
headView
}
return
headView
}
VmDebugger
.
prototype
.
remove
=
function
()
{
// used to stop listenning on event. bad and should be "refactored"
this
.
view
=
null
}
VmDebugger
.
prototype
.
render
=
function
()
{
const
view
=
yo
`
<div id="vmdebugger" class="px-2">
<div>
${
this
.
stackPanel
.
render
()}
${
this
.
memoryPanel
.
render
()}
${
this
.
storagePanel
.
render
()}
${
this
.
callstackPanel
.
render
()}
${
this
.
calldataPanel
.
render
()}
${
this
.
returnValuesPanel
.
render
()}
${
this
.
fullStoragesChangesPanel
.
render
()}
</div>
</div>
`
if
(
!
this
.
view
)
{
this
.
view
=
view
}
return
view
}
module
.
exports
=
VmDebugger
apps/remix-ide/src/app/tabs/debugger/debuggerUI/styles/basicStyles.js
deleted
100644 → 0
View file @
cfd41cb9
'use strict'
module
.
exports
=
{
truncate
:
{
'white-space'
:
'nowrap'
,
'overflow'
:
'hidden'
,
'text-overflow'
:
'ellipsis'
,
'margin-right'
:
'5px'
},
font
:
{
'font-family'
:
'arial,sans-serif'
},
statusMessage
:
{
'margin-left'
:
'15px'
},
address
:
{
'font-style'
:
'italic'
},
instructionsList
:
{
'width'
:
'52%'
,
'overflow-y'
:
'scroll'
,
'max-height'
:
'250px'
,
'margin'
:
'0'
,
'margin-left'
:
'10px'
,
'padding'
:
'2px'
},
transactionInfo
:
{
'margin-top'
:
'5px'
},
panel
:
{
container
:
{
'border'
:
'1px solid'
,
'width'
:
'70%'
},
tableContainer
:
{
'height'
:
'50%'
,
'overflow-y'
:
'auto'
},
table
:
{
'padding'
:
'5px'
},
title
:
{
'padding'
:
'5px'
,
'font-style'
:
'italic'
}
},
hidden
:
{
'display'
:
'none'
},
display
:
{
'display'
:
'block'
},
inline
:
{
'display'
:
'inline-block'
},
vmargin
:
{
'margin-top'
:
'10px'
,
'margin-bottom'
:
'10px'
},
button
:
{
'border-color'
:
'transparent'
,
'border-radius'
:
'3px'
,
'border'
:
'.3px solid hsla(0, 0%, 40%, 1)'
,
'cursor'
:
'pointer'
,
'min-height'
:
'25px'
,
'max-height'
:
'25px'
,
'padding'
:
'3px'
,
'min-width'
:
'100px'
,
'font-size'
:
'12px'
,
'overflow'
:
'hidden'
,
'word-break'
:
'normal'
,
'background-color'
:
'hsla(0, 0%, 40%, .2)'
,
'color'
:
'hsla(0, 0%, 40%, 1)'
,
'margin'
:
'3px'
,
'text-decoration'
:
'none'
}
}
apps/remix-ide/src/app/tabs/debugger/debuggerUI/styles/dropdownPanel.js
deleted
100644 → 0
View file @
cfd41cb9
'use strict'
module
.
exports
=
{
title
:
{
'border'
:
'1px solid #dadada'
,
'background-color'
:
'white'
,
'width'
:
'100%'
,
'color'
:
'#363f47'
,
'margin-top'
:
'5px'
,
'cursor'
:
'pointer'
},
titleInner
:
{
'display'
:
'inline-block'
},
content
:
{
'color'
:
'#111111'
,
'width'
:
'100%'
,
'min-height'
:
'20px'
},
inner
:
{
'padding'
:
'2px'
,
'word-break'
:
'break-all'
},
copyBtn
:
{
'float'
:
'right'
,
'margin-top'
:
'3px'
},
caret
:
{
'margin-left'
:
'10px'
,
'margin-right'
:
'10px'
}
}
apps/remix-ide/src/app/tabs/debugger/debuggerUI/styles/sliderStyles.js
deleted
100644 → 0
View file @
cfd41cb9
'use strict'
module
.
exports
=
{
rule
:
{
'width'
:
'100%'
}
}
apps/remix-ide/src/app/tabs/debugger/debuggerUI/styles/treeView.js
deleted
100644 → 0
View file @
cfd41cb9
'use strict'
module
.
exports
=
{
cssUl
:
{
'list-style-type'
:
'none'
,
'-webkit-margin-before'
:
'0px'
,
'-webkit-margin-after'
:
'0px'
,
'-webkit-margin-start'
:
'0px'
,
'-webkit-margin-end'
:
'0px'
,
'-webkit-padding-start'
:
'0px'
},
cssLi
:
{
'list-style-type'
:
'none'
,
'-webkit-margin-before'
:
'0px'
,
'-webkit-margin-after'
:
'0px'
,
'-webkit-margin-start'
:
'0px'
,
'-webkit-margin-end'
:
'0px'
,
'-webkit-padding-start'
:
'0px'
,
'margin-left'
:
'10px'
},
label
:
{
'vertical-align'
:
'top'
,
'font-family'
:
'arial,sans-serif'
},
caret
:
{
'margin-top'
:
'3px'
,
'width'
:
'10px'
},
data
:
{
}
}
apps/remix-ide/src/app/tabs/debugger/debuggerUI/vmDebugger/CalldataPanel.js
deleted
100644 → 0
View file @
cfd41cb9
'use strict'
var
DropdownPanel
=
require
(
'./DropdownPanel'
)
var
yo
=
require
(
'yo-yo'
)
function
CalldataPanel
()
{
this
.
basicPanel
=
new
DropdownPanel
(
'Call Data'
,
{
json
:
true
})
}
CalldataPanel
.
prototype
.
update
=
function
(
calldata
)
{
this
.
basicPanel
.
update
(
calldata
)
}
CalldataPanel
.
prototype
.
render
=
function
()
{
return
yo
`<div id='calldatapanel' >
${
this
.
basicPanel
.
render
()}
</div>`
}
module
.
exports
=
CalldataPanel
apps/remix-ide/src/app/tabs/debugger/debuggerUI/vmDebugger/CallstackPanel.js
deleted
100644 → 0
View file @
cfd41cb9
'use strict'
var
DropdownPanel
=
require
(
'./DropdownPanel'
)
var
yo
=
require
(
'yo-yo'
)
function
CallstackPanel
()
{
this
.
basicPanel
=
new
DropdownPanel
(
'Call Stack'
,
{
json
:
true
})
}
CallstackPanel
.
prototype
.
update
=
function
(
calldata
)
{
this
.
basicPanel
.
update
(
calldata
)
}
CallstackPanel
.
prototype
.
render
=
function
()
{
return
yo
`<div id='callstackpanel' >
${
this
.
basicPanel
.
render
()}
</div>`
}
module
.
exports
=
CallstackPanel
apps/remix-ide/src/app/tabs/debugger/debuggerUI/vmDebugger/CodeListView.js
deleted
100644 → 0
View file @
cfd41cb9
'use strict'
var
style
=
require
(
'../styles/basicStyles'
)
var
yo
=
require
(
'yo-yo'
)
var
DropdownPanel
=
require
(
'./DropdownPanel'
)
var
EventManager
=
require
(
'../../../../../lib/events'
)
var
csjs
=
require
(
'csjs-inject'
)
var
css
=
csjs
`
.instructions {
overflow-y: scroll;
max-height: 130px;
}
`
function
CodeListView
()
{
this
.
event
=
new
EventManager
()
this
.
code
this
.
address
this
.
itemSelected
this
.
basicPanel
=
new
DropdownPanel
(
'Instructions'
,
{
json
:
false
,
displayContentOnly
:
true
})
this
.
basicPanel
.
event
.
register
(
'hide'
,
()
=>
{
this
.
event
.
trigger
(
'hide'
,
[])
})
this
.
basicPanel
.
event
.
register
(
'show'
,
()
=>
{
this
.
event
.
trigger
(
'show'
,
[])
})
}
CodeListView
.
prototype
.
render
=
function
()
{
this
.
view
=
yo
`<div id='asmcodes' >
${
this
.
basicPanel
.
render
({
height
:
style
.
instructionsList
.
height
})}
</div>`
return
this
.
view
}
CodeListView
.
prototype
.
indexChanged
=
function
(
index
)
{
if
(
index
<
0
)
return
if
(
this
.
itemSelected
)
{
this
.
itemSelected
.
removeAttribute
(
'selected'
)
this
.
itemSelected
.
removeAttribute
(
'style'
)
if
(
this
.
itemSelected
.
firstChild
)
{
this
.
itemSelected
.
firstChild
.
removeAttribute
(
'style'
)
}
}
let
codeView
=
this
.
view
.
querySelector
(
'#asmitems'
)
this
.
itemSelected
=
codeView
.
children
[
index
]
this
.
itemSelected
.
style
.
setProperty
(
'border-color'
,
'var(--primary)'
)
this
.
itemSelected
.
style
.
setProperty
(
'border-style'
,
'solid'
)
this
.
itemSelected
.
setAttribute
(
'selected'
,
'selected'
)
codeView
.
scrollTop
=
this
.
itemSelected
.
offsetTop
-
parseInt
(
codeView
.
offsetTop
)
}
CodeListView
.
prototype
.
reset
=
function
()
{
this
.
changed
([],
''
,
-
1
)
}
CodeListView
.
prototype
.
changed
=
function
(
code
,
address
,
index
)
{
if
(
this
.
address
===
address
)
{
return
this
.
indexChanged
(
index
)
}
this
.
code
=
code
this
.
address
=
address
this
.
basicPanel
.
setContent
(
this
.
renderAssemblyItems
())
this
.
indexChanged
(
index
)
}
CodeListView
.
prototype
.
renderAssemblyItems
=
function
()
{
if
(
this
.
code
)
{
var
codeView
=
this
.
code
.
map
(
function
(
item
,
i
)
{
return
yo
`<div class="px-1" key=
${
i
}
value=
${
i
}
><span>
${
item
}
</span></div>`
})
return
yo
`<div class="pl-2 my-1 small
${
css
.
instructions
}
" id='asmitems' ref='itemsList'>
${
codeView
}
</div>`
}
}
module
.
exports
=
CodeListView
apps/remix-ide/src/app/tabs/debugger/debuggerUI/vmDebugger/DropdownPanel.js
deleted
100644 → 0
View file @
cfd41cb9
'use strict'
const
yo
=
require
(
'yo-yo'
)
const
copyToClipboard
=
require
(
'../../../../ui/copy-to-clipboard'
)
const
EventManager
=
require
(
'../../../../../lib/events'
)
const
TreeView
=
require
(
'../../../../ui/TreeView'
)
// TODO setup a direct reference to the UI components
const
csjs
=
require
(
'csjs-inject'
)
const
css
=
csjs
`
.title {
display: flex;
align-items: center;
}
.name {
font-weight: bold;
}
.nameDetail {
font-weight: bold;
margin-left: 3px;
}
.icon {
margin-right: 5%;
}
.eyeButton {
margin: 3px;
}
.dropdownpanel {
width: 100%;
word-break: break-word;
}
.dropdownrawcontent {
padding: 2px;
word-break: break-word;
}
.message {
padding: 2px;
word-break: break-word;
}
.refresh {
display: none;
margin-left: 4px;
margin-top: 4px;
animation: spin 2s linear infinite;
}
`
function
DropdownPanel
(
_name
,
_opts
)
{
this
.
event
=
new
EventManager
()
if
(
!
_opts
)
{
_opts
=
{}
}
this
.
name
=
_name
this
.
header
=
''
this
.
json
=
_opts
.
json
this
.
displayContentOnly
=
_opts
.
displayContentOnly
if
(
this
.
json
)
{
this
.
treeView
=
new
TreeView
(
_opts
)
}
this
.
view
}
DropdownPanel
.
prototype
.
setMessage
=
function
(
message
)
{
if
(
!
this
.
view
)
return
this
.
view
.
querySelector
(
'.dropdownpanel .dropdownrawcontent'
).
style
.
display
=
'none'
this
.
view
.
querySelector
(
'.dropdownpanel .dropdowncontent'
).
style
.
display
=
'none'
this
.
view
.
querySelector
(
'.dropdownpanel > i'
).
style
.
display
=
'none'
this
.
message
(
message
)
}
DropdownPanel
.
prototype
.
setLoading
=
function
()
{
if
(
!
this
.
view
)
return
this
.
view
.
querySelector
(
'.dropdownpanel .dropdownrawcontent'
).
style
.
display
=
'none'
this
.
view
.
querySelector
(
'.dropdownpanel .dropdowncontent'
).
style
.
display
=
'none'
this
.
view
.
querySelector
(
'.dropdownpanel > i'
).
style
.
display
=
'inline-block'
this
.
message
(
''
)
}
DropdownPanel
.
prototype
.
setUpdating
=
function
()
{
if
(
!
this
.
view
)
return
}
DropdownPanel
.
prototype
.
update
=
function
(
_data
,
_header
)
{
if
(
!
this
.
view
)
return
this
.
view
.
querySelector
(
'.dropdownpanel > i'
).
style
.
display
=
'none'
this
.
view
.
querySelector
(
'.dropdownpanel .dropdowncontent'
).
style
.
display
=
'block'
this
.
view
.
querySelector
(
'.dropdownpanel .dropdownrawcontent'
).
innerText
=
JSON
.
stringify
(
_data
,
null
,
'
\
t'
)
if
(
!
this
.
displayContentOnly
)
{
this
.
view
.
querySelector
(
'.title i.fa-copy'
).
style
.
display
=
'block'
this
.
view
.
querySelector
(
'.title span'
).
innerText
=
_header
||
' '
}
this
.
message
(
''
)
if
(
this
.
json
)
{
this
.
treeView
.
update
(
_data
)
}
}
DropdownPanel
.
prototype
.
setContent
=
function
(
node
)
{
if
(
!
this
.
view
)
return
yo
.
update
(
this
.
view
,
this
.
render
(
null
,
node
))
}
DropdownPanel
.
prototype
.
copyClipboard
=
function
()
{
const
content
=
this
.
view
.
querySelector
(
'.dropdownpanel .dropdownrawcontent'
)
return
content
.
innerText
?
content
.
innerText
:
content
.
textContent
}
DropdownPanel
.
prototype
.
render
=
function
(
overridestyle
,
node
)
{
var
content
=
yo
`<div>Empty</div>`
if
(
this
.
json
)
{
content
=
this
.
treeView
.
render
({})
}
overridestyle
===
undefined
?
{}
:
overridestyle
var
self
=
this
var
contentNode
=
yo
`
<div class='dropdownpanel
${
css
.
dropdownpanel
}
' style='display:none'>
<i class="
${
css
.
refresh
}
fas fa-sync" aria-hidden="true"></i>
<div class='dropdowncontent'>
${
node
||
content
}
</div>
<div class='dropdownrawcontent' style='display:none'></div>
<div class='message' style='display:none'></div>
</div>`
var
title
=
!
self
.
displayContentOnly
?
yo
`<div class="
${
css
.
title
}
py-0 px-1 title">
<div class="
${
css
.
icon
}
fas fa-caret-right" onclick=
${
function
()
{
self
.
toggle
()
}
} ></div>
<div class="
${
css
.
name
}
" onclick=
${
function
()
{
self
.
toggle
()
}
} >
${
this
.
name
}
</div><span class="
${
css
.
nameDetail
}
" onclick=
${
function
()
{
self
.
toggle
()
}
} ></span>
${
copyToClipboard
(()
=>
this
.
copyClipboard
())}
</div>`
:
yo
`<div></div>`
var
view
=
yo
`
<div class="border rounded px-1 mt-1 bg-light">
<style>
@-moz-keyframes spin {
to { -moz-transform: rotate(359deg); }
}
@-webkit-keyframes spin {
to { -webkit-transform: rotate(359deg); }
}
@keyframes spin {
to {transform:rotate(359deg);}
}
</style>
${
title
}
${
contentNode
}
</div>`
if
(
!
this
.
view
)
{
this
.
view
=
view
}
if
(
self
.
displayContentOnly
)
contentNode
.
style
.
display
=
'block'
return
view
}
DropdownPanel
.
prototype
.
toggle
=
function
()
{
var
el
=
this
.
view
.
querySelector
(
'.dropdownpanel'
)
var
caret
=
this
.
view
.
querySelector
(
'.title'
).
firstElementChild
if
(
el
.
style
.
display
===
''
)
{
el
.
style
.
display
=
'none'
caret
.
className
=
`
${
css
.
icon
}
fas fa-caret-right`
this
.
event
.
trigger
(
'hide'
,
[])
}
else
{
el
.
style
.
display
=
''
caret
.
className
=
`
${
css
.
icon
}
fas fa-caret-down`
this
.
event
.
trigger
(
'show'
,
[])
}
}
DropdownPanel
.
prototype
.
hide
=
function
()
{
if
(
!
(
this
.
view
&&
!
this
.
displayContentOnly
))
return
var
caret
=
this
.
view
.
querySelector
(
'.title'
).
firstElementChild
var
el
=
this
.
view
.
querySelector
(
'.dropdownpanel'
)
el
.
style
.
display
=
'none'
caret
.
className
=
`
${
css
.
icon
}
fas fa-caret-right`
this
.
event
.
trigger
(
'hide'
,
[])
}
DropdownPanel
.
prototype
.
show
=
function
()
{
if
(
!
(
this
.
view
&&
!
this
.
displayContentOnly
))
return
var
caret
=
this
.
view
.
querySelector
(
'.title'
).
firstElementChild
var
el
=
this
.
view
.
querySelector
(
'.dropdownpanel'
)
el
.
style
.
display
=
''
caret
.
className
=
`
${
css
.
icon
}
fas fa-caret-down`
this
.
event
.
trigger
(
'show'
,
[])
}
DropdownPanel
.
prototype
.
message
=
function
(
message
)
{
if
(
!
this
.
view
)
return
var
mes
=
this
.
view
.
querySelector
(
'.dropdownpanel .message'
)
mes
.
innerText
=
message
mes
.
style
.
display
=
(
message
===
''
)
?
'none'
:
'block'
}
module
.
exports
=
DropdownPanel
apps/remix-ide/src/app/tabs/debugger/debuggerUI/vmDebugger/FullStoragesChanges.js
deleted
100644 → 0
View file @
cfd41cb9
var
DropdownPanel
=
require
(
'./DropdownPanel'
)
var
yo
=
require
(
'yo-yo'
)
function
FullStoragesChanges
()
{
this
.
view
this
.
basicPanel
=
new
DropdownPanel
(
'Full Storages Changes'
,
{
json
:
true
})
}
FullStoragesChanges
.
prototype
.
update
=
function
(
storageData
)
{
this
.
basicPanel
.
update
(
storageData
)
}
FullStoragesChanges
.
prototype
.
render
=
function
()
{
var
view
=
yo
`<div id='fullstorageschangespanel' >
${
this
.
basicPanel
.
render
()}
</div>`
if
(
!
this
.
view
)
{
this
.
view
=
view
}
return
view
}
module
.
exports
=
FullStoragesChanges
apps/remix-ide/src/app/tabs/debugger/debuggerUI/vmDebugger/FunctionPanel.js
deleted
100644 → 0
View file @
cfd41cb9
'use strict'
var
DropdownPanel
=
require
(
'./DropdownPanel'
)
var
yo
=
require
(
'yo-yo'
)
function
FunctionPanel
()
{
this
.
basicPanel
=
new
DropdownPanel
(
'Function Stack'
,
{
json
:
true
,
displayContentOnly
:
false
})
}
FunctionPanel
.
prototype
.
update
=
function
(
calldata
)
{
this
.
basicPanel
.
update
(
calldata
)
}
FunctionPanel
.
prototype
.
render
=
function
()
{
return
yo
`<div id="FunctionPanel">
${
this
.
basicPanel
.
render
()}
</div>`
}
module
.
exports
=
FunctionPanel
apps/remix-ide/src/app/tabs/debugger/debuggerUI/vmDebugger/MemoryPanel.js
deleted
100644 → 0
View file @
cfd41cb9
'use strict'
var
DropdownPanel
=
require
(
'./DropdownPanel'
)
var
yo
=
require
(
'yo-yo'
)
function
MemoryPanel
()
{
this
.
basicPanel
=
new
DropdownPanel
(
'Memory'
,
{
json
:
true
,
css
:
{
'font-family'
:
'monospace'
}})
}
MemoryPanel
.
prototype
.
update
=
function
(
calldata
)
{
this
.
basicPanel
.
update
(
calldata
)
}
MemoryPanel
.
prototype
.
render
=
function
()
{
return
yo
`<div id="memorypanel">
${
this
.
basicPanel
.
render
()}
</div>`
}
module
.
exports
=
MemoryPanel
apps/remix-ide/src/app/tabs/debugger/debuggerUI/vmDebugger/SolidityLocals.js
deleted
100644 → 0
View file @
cfd41cb9
'use strict'
var
EventManager
=
require
(
'../../../../../lib/events'
)
var
DropdownPanel
=
require
(
'./DropdownPanel'
)
var
solidityTypeFormatter
=
require
(
'./utils/SolidityTypeFormatter'
)
var
yo
=
require
(
'yo-yo'
)
class
SolidityLocals
{
constructor
()
{
this
.
event
=
new
EventManager
()
this
.
basicPanel
=
new
DropdownPanel
(
'Solidity Locals'
,
{
json
:
true
,
formatSelf
:
solidityTypeFormatter
.
formatSelf
,
extractData
:
solidityTypeFormatter
.
extractData
,
loadMore
:
(
cursor
)
=>
{
this
.
event
.
trigger
(
'solidityLocalsLoadMore'
,
[
cursor
])
}
})
this
.
view
this
.
_data
=
null
}
update
(
data
)
{
this
.
_data
=
data
this
.
basicPanel
.
update
(
this
.
_data
)
}
loadMore
(
data
)
{
this
.
_data
=
this
.
mergeLocals
(
data
,
this
.
_data
)
this
.
basicPanel
.
update
(
this
.
_data
)
}
setMessage
(
message
)
{
this
.
basicPanel
.
setMessage
(
message
)
}
setUpdating
()
{
this
.
basicPanel
.
setUpdating
()
}
mergeLocals
(
locals1
,
locals2
)
{
Object
.
keys
(
locals2
).
map
(
item
=>
{
if
(
locals2
[
item
].
cursor
&&
(
parseInt
(
locals2
[
item
].
cursor
)
<
parseInt
(
locals1
[
item
].
cursor
)))
{
locals2
[
item
]
=
{
...
locals1
[
item
],
value
:
[...
locals2
[
item
].
value
,
...
locals1
[
item
].
value
]
}
}
})
return
locals2
}
render
()
{
this
.
view
=
yo
`<div id='soliditylocals' data-id="solidityLocals">
${
this
.
basicPanel
.
render
()}
</div>`
return
this
.
view
}
}
module
.
exports
=
SolidityLocals
apps/remix-ide/src/app/tabs/debugger/debuggerUI/vmDebugger/SolidityState.js
deleted
100644 → 0
View file @
cfd41cb9
var
DropdownPanel
=
require
(
'./DropdownPanel'
)
var
solidityTypeFormatter
=
require
(
'./utils/SolidityTypeFormatter'
)
var
yo
=
require
(
'yo-yo'
)
function
SolidityState
()
{
this
.
basicPanel
=
new
DropdownPanel
(
'Solidity State'
,
{
json
:
true
,
// TODO: used by TreeView ui
formatSelf
:
solidityTypeFormatter
.
formatSelf
,
extractData
:
solidityTypeFormatter
.
extractData
})
this
.
view
}
SolidityState
.
prototype
.
update
=
function
(
data
)
{
this
.
basicPanel
.
update
(
data
)
}
SolidityState
.
prototype
.
setMessage
=
function
(
message
)
{
this
.
basicPanel
.
setMessage
(
message
)
}
SolidityState
.
prototype
.
setUpdating
=
function
()
{
this
.
basicPanel
.
setUpdating
()
}
SolidityState
.
prototype
.
render
=
function
()
{
if
(
this
.
view
)
return
this
.
view
=
yo
`
<div id='soliditystate' >
${
this
.
basicPanel
.
render
()}
</div>`
return
this
.
view
}
module
.
exports
=
SolidityState
apps/remix-ide/src/app/tabs/debugger/debuggerUI/vmDebugger/StackPanel.js
deleted
100644 → 0
View file @
cfd41cb9
'use strict'
var
DropdownPanel
=
require
(
'./DropdownPanel'
)
var
yo
=
require
(
'yo-yo'
)
function
StackPanel
()
{
this
.
basicPanel
=
new
DropdownPanel
(
'Stack'
,
{
json
:
true
,
displayContentOnly
:
false
})
}
StackPanel
.
prototype
.
update
=
function
(
calldata
)
{
this
.
basicPanel
.
update
(
calldata
)
}
StackPanel
.
prototype
.
render
=
function
()
{
return
yo
`<div id="stackpanel">
${
this
.
basicPanel
.
render
()}
</div>`
}
module
.
exports
=
StackPanel
apps/remix-ide/src/app/tabs/debugger/debuggerUI/vmDebugger/StepDetail.js
deleted
100644 → 0
View file @
cfd41cb9
var
yo
=
require
(
'yo-yo'
)
var
DropdownPanel
=
require
(
'./DropdownPanel'
)
function
StepDetail
()
{
this
.
basicPanel
=
new
DropdownPanel
(
'Step details'
,
{
json
:
true
,
displayContentOnly
:
false
})
this
.
detail
=
{
'vm trace step'
:
'-'
,
'execution step'
:
'-'
,
'add memory'
:
''
,
'gas'
:
''
,
'remaining gas'
:
'-'
,
'loaded address'
:
'-'
}
}
StepDetail
.
prototype
.
reset
=
function
()
{
this
.
detail
=
{
'vm trace step'
:
'-'
,
'execution step'
:
'-'
,
'add memory'
:
''
,
'gas'
:
''
,
'remaining gas'
:
'-'
,
'loaded address'
:
'-'
}
this
.
basicPanel
.
update
(
this
.
detail
)
}
StepDetail
.
prototype
.
updateField
=
function
(
key
,
value
)
{
this
.
detail
[
key
]
=
value
this
.
basicPanel
.
update
(
this
.
detail
)
}
StepDetail
.
prototype
.
render
=
function
()
{
return
yo
`<div id='stepdetail' data-id="stepdetail">
${
this
.
basicPanel
.
render
()}
</div>`
}
module
.
exports
=
StepDetail
apps/remix-ide/src/app/tabs/debugger/debuggerUI/vmDebugger/StoragePanel.js
deleted
100644 → 0
View file @
cfd41cb9
'use strict'
var
DropdownPanel
=
require
(
'./DropdownPanel'
)
var
yo
=
require
(
'yo-yo'
)
function
StoragePanel
(
_parent
,
_traceManager
)
{
this
.
basicPanel
=
new
DropdownPanel
(
'Storage'
,
{
json
:
true
})
}
StoragePanel
.
prototype
.
update
=
function
(
storage
,
header
)
{
this
.
basicPanel
.
update
(
storage
,
header
)
}
StoragePanel
.
prototype
.
render
=
function
()
{
return
yo
`<div id='storagepanel' >
${
this
.
basicPanel
.
render
()}
</div>`
}
module
.
exports
=
StoragePanel
apps/remix-ide/src/app/tabs/debugger/debuggerUI/vmDebugger/utils/SolidityTypeFormatter.js
deleted
100644 → 0
View file @
cfd41cb9
var
yo
=
require
(
'yo-yo'
)
var
BN
=
require
(
'ethereumjs-util'
).
BN
module
.
exports
=
{
formatSelf
:
formatSelf
,
extractData
:
extractData
}
function
formatSelf
(
key
,
data
)
{
const
style
=
fontColor
(
data
)
const
keyStyle
=
data
.
isProperty
?
'color: var(--info)'
:
''
if
(
data
.
type
===
'string'
)
{
data
.
self
=
JSON
.
stringify
(
data
.
self
)
}
return
yo
`<label class="mb-0" style='
${
keyStyle
}
;white-space:pre-wrap;'>
${
' '
+
key
}
:<label class="mb-0" style=
${
style
}
>
${
' '
+
data
.
self
}
</label><label style='font-style:italic'>
${
data
.
isProperty
||
!
data
.
type
?
''
:
' '
+
data
.
type
}
</label></label>`
}
function
extractData
(
item
,
parent
,
key
)
{
var
ret
=
{}
if
(
item
.
isProperty
)
{
return
item
}
if
(
item
.
type
.
lastIndexOf
(
']'
)
===
item
.
type
.
length
-
1
)
{
ret
.
children
=
(
item
.
value
||
[]).
map
(
function
(
item
,
index
)
{
return
{
key
:
index
,
value
:
item
}
})
ret
.
children
.
unshift
({
key
:
'length'
,
value
:
{
self
:
(
new
BN
(
item
.
length
.
replace
(
'0x'
,
''
),
16
)).
toString
(
10
),
type
:
'uint'
,
isProperty
:
true
}
})
ret
.
isArray
=
true
ret
.
self
=
parent
.
isArray
?
''
:
item
.
type
ret
.
cursor
=
item
.
cursor
ret
.
hasNext
=
item
.
hasNext
}
else
if
(
item
.
type
.
indexOf
(
'struct'
)
===
0
)
{
ret
.
children
=
Object
.
keys
((
item
.
value
||
{})).
map
(
function
(
key
)
{
return
{
key
:
key
,
value
:
item
.
value
[
key
]}
})
ret
.
self
=
item
.
type
ret
.
isStruct
=
true
}
else
if
(
item
.
type
.
indexOf
(
'mapping'
)
===
0
)
{
ret
.
children
=
Object
.
keys
((
item
.
value
||
{})).
map
(
function
(
key
)
{
return
{
key
:
key
,
value
:
item
.
value
[
key
]}
})
ret
.
isMapping
=
true
ret
.
self
=
item
.
type
}
else
{
ret
.
children
=
null
ret
.
self
=
item
.
value
ret
.
type
=
item
.
type
}
return
ret
}
function
fontColor
(
data
)
{
let
color
=
'var(--primary)'
if
(
data
.
isArray
||
data
.
isStruct
||
data
.
isMapping
)
{
color
=
'var(--info)'
}
else
if
(
data
.
type
.
indexOf
(
'uint'
)
===
0
||
data
.
type
.
indexOf
(
'int'
)
===
0
||
data
.
type
.
indexOf
(
'bool'
)
===
0
||
data
.
type
.
indexOf
(
'enum'
)
===
0
)
{
color
=
'var(--green)'
}
else
if
(
data
.
type
===
'string'
)
{
color
=
'var(--teal)'
}
else
if
(
data
.
self
==
0x0
)
{
// eslint-disable-line
color
=
'var(--gray)'
}
return
'color:'
+
color
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment