Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
OpenDAS
nni
Commits
f1105409
Unverified
Commit
f1105409
authored
Oct 15, 2020
by
liuzhe-lz
Committed by
GitHub
Oct 15, 2020
Browse files
Merge pull request #2959 from microsoft/v1.9
Merge v1.9 back to master
parents
0a6c234a
88a225f8
Changes
80
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
826 additions
and
698 deletions
+826
-698
src/webui/src/static/interface.ts
src/webui/src/static/interface.ts
+1
-0
src/webui/src/static/model/trial.ts
src/webui/src/static/model/trial.ts
+10
-5
src/webui/src/static/style/loading.scss
src/webui/src/static/style/loading.scss
+12
-0
src/webui/src/static/style/logDrawer.scss
src/webui/src/static/style/logDrawer.scss
+4
-0
src/webui/src/static/style/overview.scss
src/webui/src/static/style/overview.scss
+0
-67
src/webui/src/static/style/overview/command.scss
src/webui/src/static/style/overview/command.scss
+30
-0
src/webui/src/static/style/overview/config.scss
src/webui/src/static/style/overview/config.scss
+24
-0
src/webui/src/static/style/overview/count.scss
src/webui/src/static/style/overview/count.scss
+57
-0
src/webui/src/static/style/overview/overview.scss
src/webui/src/static/style/overview/overview.scss
+126
-0
src/webui/src/static/style/overview/overviewTitle.scss
src/webui/src/static/style/overview/overviewTitle.scss
+4
-10
src/webui/src/static/style/probar.scss
src/webui/src/static/style/probar.scss
+0
-61
src/webui/src/static/style/progress.scss
src/webui/src/static/style/progress.scss
+0
-124
src/webui/src/static/style/progress/probar.scss
src/webui/src/static/style/progress/probar.scss
+33
-0
src/webui/src/static/style/progress/progress.scss
src/webui/src/static/style/progress/progress.scss
+70
-0
src/webui/src/static/style/succTable.scss
src/webui/src/static/style/succTable.scss
+4
-3
src/webui/src/static/style/table.scss
src/webui/src/static/style/table.scss
+1
-1
src/webui/src/static/style/trialsDetail.scss
src/webui/src/static/style/trialsDetail.scss
+8
-0
src/webui/yarn.lock
src/webui/yarn.lock
+436
-420
test/pipelines/pipelines-it-installation.yml
test/pipelines/pipelines-it-installation.yml
+2
-6
tools/nni_cmd/launcher.py
tools/nni_cmd/launcher.py
+4
-1
No files found.
src/webui/src/static/interface.ts
View file @
f1105409
...
@@ -33,6 +33,7 @@ interface TableObj {
...
@@ -33,6 +33,7 @@ interface TableObj {
color
?:
string
;
color
?:
string
;
startTime
?:
number
;
startTime
?:
number
;
endTime
?:
number
;
endTime
?:
number
;
intermediates
:
(
MetricDataRecord
|
undefined
)[];
parameters
(
axes
:
MultipleAxes
):
Map
<
SingleAxis
,
any
>
;
parameters
(
axes
:
MultipleAxes
):
Map
<
SingleAxis
,
any
>
;
metrics
(
axes
:
MultipleAxes
):
Map
<
SingleAxis
,
any
>
;
metrics
(
axes
:
MultipleAxes
):
Map
<
SingleAxis
,
any
>
;
}
}
...
...
src/webui/src/static/model/trial.ts
View file @
f1105409
...
@@ -60,7 +60,7 @@ function inferTrialParameters(
...
@@ -60,7 +60,7 @@ function inferTrialParameters(
class
Trial
implements
TableObj
{
class
Trial
implements
TableObj
{
private
metricsInitialized
:
boolean
=
false
;
private
metricsInitialized
:
boolean
=
false
;
private
infoField
:
TrialJobInfo
|
undefined
;
private
infoField
:
TrialJobInfo
|
undefined
;
p
rivate
intermediates
:
(
MetricDataRecord
|
undefined
)[]
=
[];
p
ublic
intermediates
:
(
MetricDataRecord
|
undefined
)[]
=
[];
public
final
:
MetricDataRecord
|
undefined
;
public
final
:
MetricDataRecord
|
undefined
;
private
finalAcc
:
number
|
undefined
;
private
finalAcc
:
number
|
undefined
;
...
@@ -224,24 +224,29 @@ class Trial implements TableObj {
...
@@ -224,24 +224,29 @@ class Trial implements TableObj {
}
}
public
parameters
(
axes
:
MultipleAxes
):
Map
<
SingleAxis
,
any
>
{
public
parameters
(
axes
:
MultipleAxes
):
Map
<
SingleAxis
,
any
>
{
const
ret
=
new
Map
<
SingleAxis
,
any
>
(
Array
.
from
(
axes
.
axes
.
values
()).
map
(
k
=>
[
k
,
null
]));
if
(
this
.
info
===
undefined
||
this
.
info
.
hyperParameters
===
undefined
)
{
if
(
this
.
info
===
undefined
||
this
.
info
.
hyperParameters
===
undefined
)
{
throw
new
Map
()
;
throw
ret
;
}
else
{
}
else
{
const
tempHyper
=
this
.
info
.
hyperParameters
;
const
tempHyper
=
this
.
info
.
hyperParameters
;
let
params
=
JSON
.
parse
(
tempHyper
[
tempHyper
.
length
-
1
]).
parameters
;
let
params
=
JSON
.
parse
(
tempHyper
[
tempHyper
.
length
-
1
]).
parameters
;
if
(
typeof
params
===
'
string
'
)
{
if
(
typeof
params
===
'
string
'
)
{
params
=
JSON
.
parse
(
params
);
params
=
JSON
.
parse
(
params
);
}
}
const
[
result
,
unexpectedEntries
]
=
inferTrialParameters
(
params
,
axes
);
const
[
updated
,
unexpectedEntries
]
=
inferTrialParameters
(
params
,
axes
);
if
(
unexpectedEntries
.
size
)
{
if
(
unexpectedEntries
.
size
)
{
throw
unexpectedEntries
;
throw
unexpectedEntries
;
}
}
return
result
;
for
(
const
[
k
,
v
]
of
updated
)
{
ret
.
set
(
k
,
v
);
}
return
ret
;
}
}
}
}
public
metrics
(
space
:
MultipleAxes
):
Map
<
SingleAxis
,
any
>
{
public
metrics
(
space
:
MultipleAxes
):
Map
<
SingleAxis
,
any
>
{
const
ret
=
new
Map
<
SingleAxis
,
any
>
();
// set default value: null
const
ret
=
new
Map
<
SingleAxis
,
any
>
(
Array
.
from
(
space
.
axes
.
values
()).
map
(
k
=>
[
k
,
null
]));
const
unexpectedEntries
=
new
Map
<
string
,
any
>
();
const
unexpectedEntries
=
new
Map
<
string
,
any
>
();
if
(
this
.
acc
===
undefined
)
{
if
(
this
.
acc
===
undefined
)
{
return
ret
;
return
ret
;
...
...
src/webui/src/static/style/loading.scss
0 → 100644
View file @
f1105409
.loading
{
width
:
80%
;
height
:
100%
;
margin
:
0
auto
;
img
{
width
:
40%
;
position
:
fixed
;
top
:
30%
;
left
:
30%
;
}
}
src/webui/src/static/style/logDrawer.scss
View file @
f1105409
...
@@ -28,3 +28,7 @@
...
@@ -28,3 +28,7 @@
text-align
:
right
;
text-align
:
right
;
}
}
}
}
.configClose
{
margin
:
45px
0
25px
0
;
}
src/webui/src/static/style/overview.scss
deleted
100644 → 0
View file @
0a6c234a
/* new style */
.overMessage
{
height
:
446px
;
}
.blockPadding
{
padding
:
10px
20px
;
}
.commonTableStyle
{
padding
:
15px
20px
;
height
:
100%
;
min-width
:
500px
;
overflow-y
:
auto
;
}
.padItem
{
padding
:
10px
20px
0
20px
;
}
.searchSpace
{
line-height
:
22px
;
font-size
:
14px
;
padding
:
15px
0
;
color
:
#212121
;
width
:
95%
;
}
.nowrap
{
overflow
:
hidden
;
white-space
:
nowrap
;
text-overflow
:
ellipsis
;
}
.main
{
margin
:
9px
0
;
}
.profile
{
pre
{
overflow
:
inherit
;
}
}
.link
{
margin-bottom
:
10px
;
}
.info
{
position
:
relative
;
top
:
15px
;
left
:
10px
;
span
{
color
:
#333
;
font-size
:
14px
;
}
}
/* overview-succeed-graph */
.showMess
{
position
:
absolute
;
top
:
50%
;
left
:
50%
;
transform
:
translate
(
-50%
,
-50%
);
}
src/webui/src/static/style/overview/command.scss
0 → 100644
View file @
f1105409
.command
{
width
:
100%
;
>
div
{
display
:
inline-block
;
}
.command1
{
width
:
46%
;
p
{
margin-top
:
0
;
}
}
.command2
{
width
:
54%
;
p
{
margin-top
:
0
;
}
}
.command1
,
.command2
{
.lineMargin
{
margin-top
:
20px
;
}
}
}
src/webui/src/static/style/overview/config.scss
0 → 100644
View file @
f1105409
.config
{
position
:
fixed
;
right
:
0
;
z-index
:
1000
;
.ms-Button--default
{
padding
:
0
;
margin
:
0
0
15px
0
;
border-radius
:
18px
0
0
18px
;
border
:
1px
solid
#ccc
;
color
:
#0573bc
;
}
.ms-Button--default
:hover
{
background-color
:
orangered
;
color
:
#fff
;
}
}
.ms-Fabric
{
.ms-Panel-commands
{
margin
:
0
;
}
}
src/webui/src/static/style/overview/count.scss
0 → 100644
View file @
f1105409
$seriesIconMargin
:
13px
;
.ExpDuration
{
margin-top
:
28px
;
span
:hover
{
cursor
:
pointer
;
}
}
.durationInput
{
width
:
42px
;
height
:
32px
;
padding-right
:
5px
;
text-align
:
right
;
outline
:
none
;
border
:
none
;
border-bottom
:
1px
solid
#ccc
;
}
.maxExecDuration
{
width
:
74px
;
}
.series
{
i
{
font-size
:
20px
;
font-weight
:
700
;
}
.confirm
{
margin
:
0
$seriesIconMargin
;
i
{
color
:
green
;
}
}
}
.cancel
i
{
color
:
red
;
}
.edit
i
{
margin-left
:
4px
;
}
.overview
input
:disabled
{
background
:
transparent
;
border
:
none
;
}
.info
{
position
:
absolute
;
z-index
:
999
;
left
:
0
;
}
src/webui/src/static/style/overview/overview.scss
0 → 100644
View file @
f1105409
$boxPadding
:
20px
42px
;
.wrapper
{
display
:
grid
;
grid-template-columns
:
repeat
(
8
,
1fr
);
grid-auto-rows
:
82px
;
grid-gap
:
18px
;
>
div
{
background
:
#fff
;
padding
:
$boxPadding
;
border-radius
:
20px
;
box-sizing
:
border-box
;
}
.overviewProgress
{
grid-column
:
2
/
5
;
grid-row
:
1
/
5
;
display
:
grid
;
grid-auto-rows
:
70px
;
padding
:
0
;
background
:
transparent
;
.duration
,
.trialCount
{
background
:
#fff
;
padding
:
$boxPadding
;
border-radius
:
20px
;
box-sizing
:
border-box
;
/* for alert message tooltip position */
position
:
relative
;
}
.duration
{
// grid-row: 1 / 3;
height
:
136px
;
}
.trialCount
{
margin-top
:
14px
;
height
:
228px
;
}
}
}
.overviewBasicInfo
{
grid-column-start
:
1
;
grid-row
:
1
/
5
;
z-index
:
2
;
}
.basic
{
line-height
:
21px
;
font-family
:
"Segoe UI"
,
Tahoma
,
Geneva
,
Verdana
,
sans-serif
;
p
{
font-size
:
14px
;
color
:
#8f8f8f
;
margin-top
:
20px
;
}
div
{
font-size
:
16px
;
color
:
#484848
;
}
.nowrap
{
overflow
:
hidden
;
white-space
:
nowrap
;
text-overflow
:
ellipsis
;
}
}
.overviewTable
{
grid-column
:
5
/
9
;
grid-row
:
1
/
10
;
overflow
:
hidden
;
.topTrialTitle
{
width
:
72%
;
}
.active
{
background
:
#f3f2f1
;
}
.max
{
margin-left
:
7px
;
}
.mincenter
{
margin
:
0
13px
0
10px
;
}
.chooseEntry
{
margin-right
:
10px
;
line-height
:
30px
;
}
}
.overviewCommand
,
.overviewChart
{
grid-column
:
1
/
5
;
}
.overviewCommand
{
height
:
144px
;
overflow
:
hidden
;
}
$circle
:
10px
;
$bgblue
:
#0071bc
;
.overviewChart
{
grid-row
:
7
/
11
;
margin-top
:
-38px
;
.circle
{
width
:
$circle
;
height
:
$circle
;
border-radius
:
50%
;
background-color
:
$bgblue
;
margin-top
:
6px
;
margin-right
:
18px
;
}
}
src/webui/src/static/style/overviewTitle.scss
→
src/webui/src/static/style/
overview/
overviewTitle.scss
View file @
f1105409
$iconPaddingVal
:
14
px
;
$iconPaddingVal
:
20
px
;
.panelTitle
{
.panelTitle
{
font-family
:
'Segoe UI'
,
Tahoma
,
Geneva
,
Verdana
,
sans-serif
;
width
:
100%
;
height
:
38px
;
padding
:
4px
$iconPaddingVal
;
box-sizing
:
border-box
;
img
{
img
{
height
:
2
2
px
;
height
:
2
3
px
;
/* (38 - 22 ) / 2 */
/* (38 - 22 ) / 2 */
margin-top
:
8px
;
margin-top
:
8px
;
...
@@ -21,11 +15,11 @@ $iconPaddingVal: 14px;
...
@@ -21,11 +15,11 @@ $iconPaddingVal: 14px;
font-size
:
18px
;
font-size
:
18px
;
font-weight
:
600
;
font-weight
:
600
;
color
:
#333
;
color
:
#333
;
line-height
:
38px
;
}
}
i
{
i
{
font-size
:
24px
;
font-size
:
24px
;
margin-right
:
20px
;
color
:
#545454
;
color
:
#545454
;
}
}
}
}
...
@@ -45,7 +39,7 @@ $iconPaddingVal: 14px;
...
@@ -45,7 +39,7 @@ $iconPaddingVal: 14px;
}
}
.minTitle
{
.minTitle
{
margin-right
:
$iconPaddingVal
;
//
margin-right: $iconPaddingVal;
border-right
:
2px
solid
#fff
;
border-right
:
2px
solid
#fff
;
}
}
...
...
src/webui/src/static/style/probar.scss
deleted
100644 → 0
View file @
0a6c234a
#barBack
{
/* status: 'INITIALIZED' | 'RUNNING' | 'ERROR' | 'STOPPING' | 'STOPPED' | 'DONE' */
/* status: 'TUNER_NO_MORE_TRIAL' | 'NO_MORE_TRIAL' */
.RUNNING
,
.STOPPING
,
.INITIALIZED
,
.NO_MORE_TRIAL
,
.TUNER_NO_MORE_TRIAL
{
/* specific status color */
color
:
#0071bc
;
/* progress- duration & trial numbers span */
.ms-ProgressIndicator-progressBar
{
background-color
:
#0071bc
;
}
}
.DONE
,
.STOPPED
{
color
:
#009245
;
.ms-ProgressIndicator-progressBar
{
background-color
:
#009245
;
}
}
.ERROR
{
color
:
#eb0716
;
.ms-ProgressIndicator-progressBar
{
background-color
:
#eb0716
;
}
}
}
.errorBtn
{
margin-left
:
15px
;
display
:
inline-block
;
width
:
18px
;
height
:
18px
;
line-height
:
18px
;
text-align
:
center
;
font-size
:
14px
;
border
:
1px
solid
#4d4d4d
;
border-radius
:
50%
;
background-color
:
#4d4d4d
;
color
:
#fff
;
}
.errorBtn
:hover
{
cursor
:
pointer
;
}
.errors
{
width
:
240px
;
font-size
:
14px
;
color
:
#212121
;
word-wrap
:
break-word
;
word-break
:
normal
;
}
src/webui/src/static/style/progress.scss
deleted
100644 → 0
View file @
0a6c234a
.progress
{
margin
:
15px
17px
;
.status
{
color
:
#0573bc
;
font-size
:
20px
;
font-weight
:
600
;
margin-top
:
5px
;
.status-text
{
display
:
inline-block
;
line-height
:
30px
;
}
}
.probar
{
width
:
100%
;
height
:
34px
;
margin-top
:
15px
;
.showProgress
{
width
:
300px
;
height
:
30px
;
}
.name
{
width
:
178px
;
box-sizing
:
border-box
;
line-height
:
30px
;
text-align
:
center
;
color
:
#fff
;
background-color
:
#999
;
border
:
2px
solid
#e6e6e6
;
border-top-left-radius
:
12px
;
border-bottom-left-radius
:
12px
;
}
.boundary
{
width
:
100%
;
line-height
:
24px
;
font-size
:
12px
;
color
:
#212121
;
.right
{
text-align
:
right
;
}
}
.description
{
line-height
:
34px
;
margin-left
:
6px
;
white-space
:
nowrap
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
}
}
&
-info
{
margin-left
:
4px
;
position
:
relative
;
top
:
2px
;
}
}
/* basic experiment message style */
.basic
{
line-height
:
24px
;
font-family
:
"Segoe UI"
,
Tahoma
,
Geneva
,
Verdana
,
sans-serif
;
p
{
font-size
:
14px
;
color
:
#212121
;
}
div
{
font-size
:
16px
;
color
:
#0573bc
;
}
}
.colorOfbasic
{
div
{
color
:
#0573bc
;
}
.time
{
overflow
:
hidden
;
white-space
:
nowrap
;
text-overflow
:
ellipsis
;
}
}
.mess
{
margin
:
10px
0
;
}
.inputBox
{
height
:
32px
;
margin-top
:
5px
;
.concurrencyInput
{
width
:
40px
;
padding-left
:
8px
;
outline
:
none
;
border
:
1px
solid
#ccc
;
}
}
.lineBasic
{
padding-bottom
:
14px
;
border-bottom
:
1px
solid
#ccc
;
}
/* office-fabric-ui progressIndicator */
.ms-ProgressIndicator-itemProgress
{
padding
:
0
;
border
:
2px
solid
#e6e6e6
;
border-radius
:
0
12px
12px
0
!
important
;
}
.cursor
,
.cursor
:hover
{
cursor
:
pointer
;
}
src/webui/src/static/style/progress/probar.scss
0 → 100644
View file @
f1105409
/* status: 'INITIALIZED' | 'RUNNING' | 'ERROR' | 'STOPPING' | 'STOPPED' | 'DONE' */
/* status: 'TUNER_NO_MORE_TRIAL' | 'NO_MORE_TRIAL' */
.RUNNING
,
.STOPPING
,
.INITIALIZED
,
.NO_MORE_TRIAL
,
.TUNER_NO_MORE_TRIAL
{
/* specific status color */
color
:
#0071bc
;
/* progress- duration & trial numbers span */
.ms-ProgressIndicator-progressBar
{
background-color
:
#0071bc
;
}
}
.DONE
,
.STOPPED
{
color
:
#009245
;
.ms-ProgressIndicator-progressBar
{
background-color
:
#009245
;
}
}
.ERROR
{
color
:
#eb0716
;
.ms-ProgressIndicator-progressBar
{
background-color
:
#eb0716
;
}
}
src/webui/src/static/style/progress/progress.scss
0 → 100644
View file @
f1105409
.status
{
color
:
#0573bc
;
font-size
:
20px
;
font-weight
:
600
;
margin-top
:
5px
;
.status-text
{
display
:
inline-block
;
line-height
:
30px
;
}
}
.probar
{
width
:
100%
;
height
:
34px
;
margin-top
:
15px
;
.showProgress
{
width
:
300px
;
height
:
30px
;
}
.name
{
width
:
178px
;
box-sizing
:
border-box
;
line-height
:
30px
;
text-align
:
center
;
color
:
#fff
;
background-color
:
#999
;
border
:
2px
solid
#e6e6e6
;
border-top-left-radius
:
12px
;
border-bottom-left-radius
:
12px
;
}
.boundary
{
width
:
100%
;
line-height
:
24px
;
font-size
:
12px
;
color
:
#212121
;
.right
{
text-align
:
right
;
}
}
.description
{
line-height
:
34px
;
margin-left
:
6px
;
white-space
:
nowrap
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
}
}
.inputBox
{
height
:
32px
;
margin-top
:
5px
;
}
/* office-fabric-ui progressIndicator */
.ms-ProgressIndicator-itemProgress
{
padding
:
0
;
border
:
2px
solid
#e6e6e6
;
}
.cursor
,
.cursor
:hover
{
cursor
:
pointer
;
}
src/webui/src/static/style/succTable.scss
View file @
f1105409
#succTable
{
#succTable
{
height
:
404px
;
min-height
:
400px
;
overflow
:
auto
;
max-height
:
1000px
;
overflow-y
:
auto
;
position
:
relative
;
position
:
relative
;
.succTable-tooltip
{
.succTable-tooltip
{
position
:
absolute
;
position
:
absolute
;
top
:
40%
;
top
:
40%
;
left
:
17
%
;
left
:
5
%
;
.link
{
.link
{
margin-left
:
15px
;
margin-left
:
15px
;
...
...
src/webui/src/static/style/table.scss
View file @
f1105409
...
@@ -58,7 +58,7 @@
...
@@ -58,7 +58,7 @@
}
}
.detail-table
{
.detail-table
{
padding
:
5px
0
0
0
;
padding
-top
:
5px
;
}
}
.columns-height
{
.columns-height
{
...
...
src/webui/src/static/style/trialsDetail.scss
View file @
f1105409
...
@@ -57,6 +57,14 @@
...
@@ -57,6 +57,14 @@
}
}
/* table list all */
/* table list all */
.bulletedList
{
background
:
#fff
;
.title
{
margin-top
:
18px
;
margin-left
:
14px
;
}
}
#tableList
{
#tableList
{
width
:
96%
;
width
:
96%
;
...
...
src/webui/yarn.lock
View file @
f1105409
This diff is collapsed.
Click to expand it.
test/pipelines/pipelines-it-installation.yml
View file @
f1105409
...
@@ -14,13 +14,9 @@ jobs:
...
@@ -14,13 +14,9 @@ jobs:
python3 -m pip install --upgrade nni --user
python3 -m pip install --upgrade nni --user
displayName
:
'
Install
nni'
displayName
:
'
Install
nni'
-
job
:
'
pip_install_macOS_python3
6
'
-
job
:
'
pip_install_macOS_python3'
pool
:
pool
:
vmImage
:
'
macOS-10.13'
vmImage
:
'
macOS-latest'
strategy
:
matrix
:
Python36
:
PYTHON_VERSION
:
'
3.6'
steps
:
steps
:
-
script
:
|
-
script
:
|
...
...
tools/nni_cmd/launcher.py
View file @
f1105409
...
@@ -138,7 +138,10 @@ def set_remote_config(experiment_config, port, config_file_name):
...
@@ -138,7 +138,10 @@ def set_remote_config(experiment_config, port, config_file_name):
'''Call setClusterMetadata to pass trial'''
'''Call setClusterMetadata to pass trial'''
#set machine_list
#set machine_list
request_data
=
dict
()
request_data
=
dict
()
request_data
[
'remote_config'
]
=
experiment_config
[
'remoteConfig'
]
if
experiment_config
.
get
(
'remoteConfig'
):
request_data
[
'remote_config'
]
=
experiment_config
[
'remoteConfig'
]
else
:
request_data
[
'remote_config'
]
=
{
'reuse'
:
False
}
request_data
[
'machine_list'
]
=
experiment_config
[
'machineList'
]
request_data
[
'machine_list'
]
=
experiment_config
[
'machineList'
]
if
request_data
[
'machine_list'
]:
if
request_data
[
'machine_list'
]:
for
i
in
range
(
len
(
request_data
[
'machine_list'
])):
for
i
in
range
(
len
(
request_data
[
'machine_list'
])):
...
...
Prev
1
2
3
4
Next
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