Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
gargantext
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
humanities
gargantext
Commits
1534de8f
Commit
1534de8f
authored
Apr 23, 2015
by
PkSM3
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[UPDATE] more details for dynatable
parent
00f13afc
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
243 additions
and
202 deletions
+243
-202
views.py
gargantext_web/views.py
+1
-1
jquery.dynatable.css
static/css/jquery.dynatable.css
+1
-1
dyna_chart_and_table.js
static/js/dyna_chart_and_table.js
+220
-192
corpus.html
templates/corpus.html
+21
-8
No files found.
gargantext_web/views.py
View file @
1534de8f
...
@@ -227,7 +227,7 @@ def projects(request):
...
@@ -227,7 +227,7 @@ def projects(request):
project_type_id
=
cache
.
NodeType
[
'Project'
]
.
id
project_type_id
=
cache
.
NodeType
[
'Project'
]
.
id
date
=
datetime
.
datetime
.
now
()
date
=
datetime
.
datetime
.
now
()
print
(
Logger
.
write
(
"STATIC_ROOT"
))
#
print(Logger.write("STATIC_ROOT"))
projects
=
session
.
query
(
Node
)
.
filter
(
Node
.
user_id
==
user_id
,
Node
.
type_id
==
project_type_id
)
.
order_by
(
Node
.
date
)
.
all
()
projects
=
session
.
query
(
Node
)
.
filter
(
Node
.
user_id
==
user_id
,
Node
.
type_id
==
project_type_id
)
.
order_by
(
Node
.
date
)
.
all
()
...
...
static/css/jquery.dynatable.css
View file @
1534de8f
...
@@ -20,7 +20,7 @@ th a:hover {
...
@@ -20,7 +20,7 @@ th a:hover {
}
}
.dynatable-search
{
.dynatable-search
{
float
:
righ
t
;
float
:
lef
t
;
margin-bottom
:
10px
;
margin-bottom
:
10px
;
}
}
...
...
static/js/dyna_chart_and_table.js
View file @
1534de8f
...
@@ -70,7 +70,8 @@ function Final_UpdateTable( action ) {
...
@@ -70,7 +70,8 @@ function Final_UpdateTable( action ) {
var
UpdateTable
=
false
var
UpdateTable
=
false
if
(
(
action
==
"click"
&&
!
isCollapsed
)
||
(
action
==
"changerange"
&&
isCollapsed
)
)
{
if
(
(
action
==
"click"
&&
!
isCollapsed
)
||
(
action
==
"changerange"
&&
isCollapsed
)
)
{
UpdateTable
=
true
;
UpdateTable
=
true
;
}
$
(
"#corpusdisplayer"
).
html
(
"Close Corpus"
)
}
else
$
(
"#corpusdisplayer"
).
html
(
"Open Corpus"
)
pr
(
"update table??: "
+
UpdateTable
)
pr
(
"update table??: "
+
UpdateTable
)
...
@@ -220,205 +221,232 @@ function ulWriter(rowIndex, record, columns, cellWriter) {
...
@@ -220,205 +221,232 @@ function ulWriter(rowIndex, record, columns, cellWriter) {
}
}
// (3) Get records and metadata for paginator
// (3) Get records and metadata for paginator
$
.
ajax
({
url
:
'/tests/paginator/corpus/'
+
corpusid
,
success
:
function
(
data
){
console
.
log
(
data
)
var
justdates
=
{}
for
(
var
i
in
data
.
records
)
{
var
orig_id
=
parseInt
(
data
.
records
[
i
].
id
)
var
arr_id
=
parseInt
(
i
)
RecDict
[
orig_id
]
=
arr_id
;
data
.
records
[
i
][
"name"
]
=
'<a target="_blank" href="/nodeinfo/'
+
orig_id
+
'">'
+
data
.
records
[
i
][
"name"
]
+
'</a>'
data
.
records
[
i
][
"del"
]
=
false
var
date
=
data
.
records
[
i
][
"date"
];
if
(
!
justdates
[
date
]
)
justdates
[
date
]
=
0
;
justdates
[
date
]
++
;
// console.log(data.records[i]["date"]+" : originalRecords["+arr_id+"] <- "+orig_id+" | "+data.records[i]["name"])
}
AjaxRecords
=
data
.
records
;
// backup!!
// $("#move2trash").prop('disabled', true);
$
(
"#move2trash"
)
.
click
(
function
(){
var
ids2trash
=
[]
function
Main
()
{
for
(
var
i
in
Garbage
)
MyTable
;
RecDict
=
{};
AjaxRecords
=
[]
Garbage
=
{}
$
.
ajax
({
url
:
'/tests/paginator/corpus/'
+
corpusid
,
success
:
function
(
data
){
console
.
log
(
data
)
var
justdates
=
{}
for
(
var
i
in
data
.
records
)
{
var
orig_id
=
parseInt
(
data
.
records
[
i
].
id
)
var
arr_id
=
parseInt
(
i
)
RecDict
[
orig_id
]
=
arr_id
;
data
.
records
[
i
][
"name"
]
=
'<a target="_blank" href="/nodeinfo/'
+
orig_id
+
'">'
+
data
.
records
[
i
][
"name"
]
+
'</a>'
data
.
records
[
i
][
"del"
]
=
false
var
date
=
data
.
records
[
i
][
"date"
];
if
(
!
justdates
[
date
]
)
justdates
[
date
]
=
0
;
justdates
[
date
]
++
;
// console.log(data.records[i]["date"]+" : originalRecords["+arr_id+"] <- "+orig_id+" | "+data.records[i]["name"])
}
AjaxRecords
=
data
.
records
;
// backup!!
// $("#move2trash").prop('disabled', true);
$
(
"#move2trash"
)
.
click
(
function
(){
var
ids2trash
=
[]
for
(
var
i
in
Garbage
)
{
ids2trash
.
push
(
AjaxRecords
[
i
].
id
);
ids2trash
.
push
(
AjaxRecords
[
i
].
id
);
}
console
.
log
(
"ids to the trash:"
)
console
.
log
(
"ids to the trash:"
)
console
.
log
(
ids2trash
)
console
.
log
(
ids2trash
)
$
.
ajax
({
url
:
"/tests/move2trash/"
,
data
:
"nodeids="
+
JSON
.
stringify
(
ids2trash
),
type
:
'POST'
,
beforeSend
:
function
(
xhr
)
{
xhr
.
setRequestHeader
(
"X-CSRFToken"
,
getCookie
(
"csrftoken"
));
},
success
:
function
(
data
)
{
console
.
log
(
"in #move2trash"
)
console
.
log
(
data
)
location
.
reload
();
},
error
:
function
(
result
)
{
console
.
log
(
"Data not found in #move2trash"
);
console
.
log
(
result
)
}
});
})
.
hide
();
var
t0
=
AjaxRecords
[
0
].
date
.
split
(
"-"
).
map
(
Number
)
var
t1
=
AjaxRecords
.
slice
(
-
1
)[
0
].
date
.
split
(
"-"
).
map
(
Number
)
oldest
=
t0
;
latest
=
t1
;
TheBuffer
=
[
new
Date
(
t0
[
0
],(
t0
[
1
]
-
1
),
t0
[
2
]),
new
Date
(
t1
[
0
],(
t1
[
1
]
-
1
),
t1
[
2
])];
$
.
ajax
({
var
arrayd3
=
[]
url
:
"/tests/move2trash/"
,
for
(
var
e
in
data
.
records
)
{
data
:
"nodeids="
+
JSON
.
stringify
(
ids2trash
),
var
date
=
data
.
records
[
e
][
"date"
];
type
:
'POST'
,
if
(
justdates
[
date
]
!=
false
)
{
beforeSend
:
function
(
xhr
)
{
var
info
=
{}
xhr
.
setRequestHeader
(
"X-CSRFToken"
,
getCookie
(
"csrftoken"
));
info
.
date
=
date
info
.
dd
=
dateFormat
.
parse
(
date
)
info
.
month
=
d3
.
time
.
month
(
info
.
dd
)
info
.
volume
=
justdates
[
date
]
arrayd3
.
push
(
info
)
justdates
[
date
]
=
false
;
}
}
for
(
var
i
in
justdates
)
delete
justdates
[
i
];
delete
justdates
;
var
ndx
=
crossfilter
(
arrayd3
);
var
all
=
ndx
.
groupAll
();
//volumeChart:(1)
//moveChart:(1)
// monthly index avg fluctuation in percentage
var
moveMonths
=
ndx
.
dimension
(
function
(
d
)
{
return
d
.
month
;
});
//moveChart:(3)
var
monthlyMoveGroup
=
moveMonths
.
group
().
reduceSum
(
function
(
d
)
{
return
d
.
volume
;
//return Math.abs(+d.close - +d.open);
});
//volumeChart:(2)
var
volumeByMonthGroup
=
moveMonths
.
group
().
reduceSum
(
function
(
d
)
{
return
d
.
volume
/
500000
;
});
//moveChart:(2)
var
indexAvgByMonthGroup
=
moveMonths
.
group
().
reduce
(
function
(
p
,
v
)
{
++
p
.
days
;
p
.
total
+=
(
+
v
.
open
+
+
v
.
close
)
/
2
;
p
.
avg
=
Math
.
round
(
p
.
total
/
p
.
days
);
return
p
;
},
},
function
(
p
,
v
)
{
success
:
function
(
data
)
{
--
p
.
days
;
console
.
log
(
"in #move2trash"
)
p
.
total
-=
(
+
v
.
open
+
+
v
.
close
)
/
2
;
console
.
log
(
data
)
p
.
avg
=
p
.
days
==
0
?
0
:
Math
.
round
(
p
.
total
/
p
.
days
);
location
.
reload
();
return
p
;
},
},
function
()
{
error
:
function
(
result
)
{
return
{
days
:
0
,
total
:
0
,
avg
:
0
};
console
.
log
(
"Data not found in #move2trash"
);
}
console
.
log
(
result
)
);
}
});
})
moveChart
.
width
(
800
)
.
hide
();
.
height
(
150
)
.
transitionDuration
(
1000
)
.
margins
({
top
:
10
,
right
:
50
,
bottom
:
25
,
left
:
40
})
var
t0
=
AjaxRecords
[
0
].
date
.
split
(
"-"
).
map
(
Number
)
.
dimension
(
moveMonths
)
var
t1
=
AjaxRecords
.
slice
(
-
1
)[
0
].
date
.
split
(
"-"
).
map
(
Number
)
.
group
(
indexAvgByMonthGroup
)
oldest
=
t0
;
.
valueAccessor
(
function
(
d
)
{
latest
=
t1
;
return
d
.
value
.
avg
;
})
.
x
(
d3
.
time
.
scale
().
domain
([
new
Date
(
t0
[
0
],
t0
[
1
],
t0
[
2
]),
new
Date
(
t1
[
0
],
t1
[
1
],
t1
[
2
])]))
TheBuffer
=
[
new
Date
(
t0
[
0
],(
t0
[
1
]
-
1
),
t0
[
2
]),
new
Date
(
t1
[
0
],(
t1
[
1
]
-
1
),
t1
[
2
])];
.
round
(
d3
.
time
.
month
.
round
)
.
xUnits
(
d3
.
time
.
months
)
.
elasticY
(
true
)
var
arrayd3
=
[]
.
renderHorizontalGridLines
(
true
)
for
(
var
e
in
data
.
records
)
{
.
brushOn
(
false
)
var
date
=
data
.
records
[
e
][
"date"
];
.
compose
([
if
(
justdates
[
date
]
!=
false
)
{
dc
.
lineChart
(
moveChart
).
group
(
indexAvgByMonthGroup
)
var
info
=
{}
.
valueAccessor
(
function
(
d
)
{
info
.
date
=
date
return
d
.
value
.
avg
;
info
.
dd
=
dateFormat
.
parse
(
date
)
})
info
.
month
=
d3
.
time
.
month
(
info
.
dd
)
.
renderArea
(
true
)
info
.
volume
=
justdates
[
date
]
.
stack
(
monthlyMoveGroup
,
function
(
d
)
{
arrayd3
.
push
(
info
)
return
d
.
value
;
justdates
[
date
]
=
false
;
})
}
.
title
(
function
(
d
)
{
}
var
value
=
d
.
value
.
avg
?
d
.
value
.
avg
:
d
.
value
;
if
(
isNaN
(
value
))
value
=
0
;
for
(
var
i
in
justdates
)
return
dateFormat
(
d
.
key
)
+
"
\n
"
+
numberFormat
(
value
);
delete
justdates
[
i
];
})
delete
justdates
;
])
.
xAxis
();
var
ndx
=
crossfilter
(
arrayd3
);
var
all
=
ndx
.
groupAll
();
volumeChart
.
width
(
800
)
.
height
(
100
)
//volumeChart:(1)
.
margins
({
top
:
0
,
right
:
50
,
bottom
:
20
,
left
:
40
})
//moveChart:(1)
.
dimension
(
moveMonths
)
// monthly index avg fluctuation in percentage
.
group
(
volumeByMonthGroup
)
var
moveMonths
=
ndx
.
dimension
(
function
(
d
)
{
.
centerBar
(
true
)
return
d
.
month
;
.
gap
(
0
)
});
.
x
(
d3
.
time
.
scale
().
domain
([
new
Date
(
t0
[
0
],
t0
[
1
],
t0
[
2
]),
new
Date
(
t1
[
0
],
t1
[
1
],
t1
[
2
])]))
.
round
(
d3
.
time
.
month
.
round
)
//moveChart:(3)
.
xUnits
(
d3
.
time
.
months
)
var
monthlyMoveGroup
=
moveMonths
.
group
().
reduceSum
(
function
(
d
)
{
.
renderlet
(
function
(
chart
)
{
return
d
.
volume
;
chart
.
select
(
"g.y"
).
style
(
"display"
,
"none"
);
//return Math.abs(+d.close - +d.open);
moveChart
.
filter
(
chart
.
filter
());
});
})
.
on
(
"filtered"
,
function
(
chart
)
{
//volumeChart:(2)
dc
.
events
.
trigger
(
function
()
{
var
volumeByMonthGroup
=
moveMonths
.
group
().
reduceSum
(
function
(
d
)
{
var
chartfilt
=
chart
.
filter
()
return
d
.
volume
/
500000
;
// tricky part: identifying when the moveChart changes.
});
if
(
chartfilt
)
{
Push2Buffer
(
chart
.
filter
()
)
//moveChart:(2)
}
else
{
var
indexAvgByMonthGroup
=
moveMonths
.
group
().
reduce
(
if
(
TheBuffer
)
{
function
(
p
,
v
)
{
Push2Buffer
(
false
)
++
p
.
days
;
}
p
.
total
+=
(
+
v
.
open
+
+
v
.
close
)
/
2
;
}
p
.
avg
=
Math
.
round
(
p
.
total
/
p
.
days
);
moveChart
.
focus
(
chartfilt
);
return
p
;
});
},
});
function
(
p
,
v
)
{
--
p
.
days
;
p
.
total
-=
(
+
v
.
open
+
+
v
.
close
)
/
2
;
p
.
avg
=
p
.
days
==
0
?
0
:
Math
.
round
(
p
.
total
/
p
.
days
);
return
p
;
},
function
()
{
return
{
days
:
0
,
total
:
0
,
avg
:
0
};
}
);
moveChart
.
width
(
800
)
.
height
(
150
)
.
transitionDuration
(
1000
)
.
margins
({
top
:
10
,
right
:
50
,
bottom
:
25
,
left
:
40
})
.
dimension
(
moveMonths
)
.
group
(
indexAvgByMonthGroup
)
.
valueAccessor
(
function
(
d
)
{
return
d
.
value
.
avg
;
})
.
x
(
d3
.
time
.
scale
().
domain
([
new
Date
(
t0
[
0
],
t0
[
1
],
t0
[
2
]),
new
Date
(
t1
[
0
],
t1
[
1
],
t1
[
2
])]))
.
round
(
d3
.
time
.
month
.
round
)
.
xUnits
(
d3
.
time
.
months
)
.
elasticY
(
true
)
.
renderHorizontalGridLines
(
true
)
.
brushOn
(
false
)
.
compose
([
dc
.
lineChart
(
moveChart
).
group
(
indexAvgByMonthGroup
)
.
valueAccessor
(
function
(
d
)
{
return
d
.
value
.
avg
;
})
.
renderArea
(
true
)
.
stack
(
monthlyMoveGroup
,
function
(
d
)
{
return
d
.
value
;
})
.
title
(
function
(
d
)
{
var
value
=
d
.
value
.
avg
?
d
.
value
.
avg
:
d
.
value
;
if
(
isNaN
(
value
))
value
=
0
;
return
dateFormat
(
d
.
key
)
+
"
\n
"
+
numberFormat
(
value
);
})
])
.
xAxis
();
volumeChart
.
width
(
800
)
.
height
(
100
)
.
margins
({
top
:
0
,
right
:
50
,
bottom
:
20
,
left
:
40
})
.
dimension
(
moveMonths
)
.
group
(
volumeByMonthGroup
)
.
centerBar
(
true
)
.
gap
(
0
)
.
x
(
d3
.
time
.
scale
().
domain
([
new
Date
(
t0
[
0
],
t0
[
1
],
t0
[
2
]),
new
Date
(
t1
[
0
],
t1
[
1
],
t1
[
2
])]))
.
round
(
d3
.
time
.
month
.
round
)
.
xUnits
(
d3
.
time
.
months
)
.
renderlet
(
function
(
chart
)
{
chart
.
select
(
"g.y"
).
style
(
"display"
,
"none"
);
moveChart
.
filter
(
chart
.
filter
());
})
.
on
(
"filtered"
,
function
(
chart
)
{
dc
.
events
.
trigger
(
function
()
{
var
chartfilt
=
chart
.
filter
()
// tricky part: identifying when the moveChart changes.
if
(
chartfilt
)
{
Push2Buffer
(
chart
.
filter
()
)
}
else
{
if
(
TheBuffer
)
{
Push2Buffer
(
false
)
}
}
moveChart
.
focus
(
chartfilt
);
});
});
dc
.
renderAll
();
dc
.
renderAll
();
// var newcontent = '<table id="my-ajax-table" class="table table-bordered">'
// newcontent += ' <thead>'
// newcontent += ' <th width="100px;" data-dynatable-column="date">Date</th>'
// newcontent += ' <th data-dynatable-column="name">Title</th>'
// newcontent += ' <th data-dynatable-column="del" data-dynatable-no-sort="true">Trash</th>'
// newcontent += ' </thead>'
// newcontent += ' <tbody>'
// newcontent += ' </tbody>'
// newcontent += '</table>'
// $('#my-ajax-table').html(newcontent)
MyTable
=
$
(
'#my-ajax-table'
).
dynatable
({
dataset
:
{
records
:
data
.
records
},
features
:
{
pushState
:
false
,
sort
:
false
//i need to fix the sorting function... the current one just sucks
},
writers
:
{
_rowWriter
:
ulWriter
// _cellWriter: customCellWriter
}
});
if
(
$
(
".imadiv"
).
length
>
0
)
return
1
;
$
(
'<br><br><div class="imadiv"></div>'
).
insertAfter
(
".dynatable-per-page"
)
$
(
".dynatable-record-count"
).
insertAfter
(
".imadiv"
)
$
(
".dynatable-pagination-links"
).
insertAfter
(
".imadiv"
)
// console.log(RecDict)
}
});
}
MyTable
=
$
(
'#my-ajax-table'
).
dynatable
({
Main
();
dataset
:
{
records
:
data
.
records
},
features
:
{
sort
:
false
//i need to fix the sorting function... the current one just sucks
},
writers
:
{
_rowWriter
:
ulWriter
// _cellWriter: customCellWriter
}
});
// console.log(RecDict)
}
});
templates/corpus.html
View file @
1534de8f
...
@@ -24,6 +24,22 @@
...
@@ -24,6 +24,22 @@
-o-transition
:
height
0.1s
;
-o-transition
:
height
0.1s
;
transition
:
height
0.1s
;
transition
:
height
0.1s
;
}
}
th
{
color
:
#fff
;
}
th
a
{
color
:
#fff
;
font-weight
:
normal
;
font-style
:
italic
;
font-size
:
0.9em
;
}
.dynatable-record-count
{
font-size
:
0.7em
;
}
.dynatable-pagination-links
{
font-size
:
0.7em
;
}
</style>
</style>
{% endblock %}
{% endblock %}
...
@@ -86,22 +102,17 @@
...
@@ -86,22 +102,17 @@
<div
class=
"panel-heading"
>
<div
class=
"panel-heading"
>
<h4
class=
"panel-title"
>
<h4
class=
"panel-title"
>
<a
data-toggle=
"collapse"
data-parent=
"#accordion"
href=
"#collapseOne"
>
<a
data-toggle=
"collapse"
data-parent=
"#accordion"
href=
"#collapseOne"
>
<p
onclick=
'Final_UpdateTable("click")'
class=
"btn btn-primary btn-lg"
align=
"right"
>
Read document
s
</h2></p>
<p
id=
"corpusdisplayer"
onclick=
'Final_UpdateTable("click")'
class=
"btn btn-primary btn-lg"
style=
"width:200px; margin:0 auto; display:block;"
>
Open Corpu
s
</h2></p>
</a>
</a>
</h4>
</h4>
</div>
</div>
<div
id=
"collapseOne"
class=
"panel-collapse collapse no-transition"
role=
"tabpanel"
>
<div
id=
"collapseOne"
class=
"panel-collapse collapse no-transition"
role=
"tabpanel"
>
<div
class=
"panel-body"
>
<div
class=
"panel-body"
>
<p
align=
"right"
>
<button
id=
"move2trash"
class=
"btn btn-primary btn-lg"
>
Move to trash!
</button>
<!-- <p onclick='console.log("move to trash bitches")' class="btn btn-primary btn-lg" align="left">Move to Trash!</p> -->
</p>
<p
align=
"right"
>
<p
align=
"right"
>
<table
id=
"my-ajax-table"
class=
"table table-bordered"
>
<table
id=
"my-ajax-table"
class=
"table table-bordered"
>
<thead>
<thead>
<!-- <th data-dynatable-column="id">ID</th> -->
<!-- <th data-dynatable-column="id">ID</th> -->
<th
data-dynatable-column=
"date"
>
Date
</th>
<th
width=
"100px;"
data-dynatable-column=
"date"
>
Date
</th>
<th
data-dynatable-column=
"name"
>
Title
</th>
<th
data-dynatable-column=
"name"
>
Title
</th>
<th
data-dynatable-column=
"del"
data-dynatable-no-sort=
"true"
>
Trash
</th>
<th
data-dynatable-column=
"del"
data-dynatable-no-sort=
"true"
>
Trash
</th>
</thead>
</thead>
...
@@ -109,6 +120,9 @@
...
@@ -109,6 +120,9 @@
</tbody>
</tbody>
</table>
</table>
</p>
</p>
<p
align=
"right"
>
<button
id=
"move2trash"
class=
"btn btn-primary btn-lg"
>
Trash It!
</button>
</p>
</div>
</div>
...
@@ -163,7 +177,6 @@
...
@@ -163,7 +177,6 @@
</div>
</div>
</div>
</div>
<script
type=
"text/javascript"
src=
"{% static "
js
/
jquery
/
jquery
.
min
.
js
"
%}"
></script>
<script
type=
"text/javascript"
src=
"{% static "
js
/
jquery
/
jquery
.
min
.
js
"
%}"
></script>
<script
src=
"{% static "
js
/
charts
/
bootstrap
.
min
.
js
"
%}"
></script>
<script
src=
"{% static "
js
/
charts
/
bootstrap
.
min
.
js
"
%}"
></script>
<script
type=
"text/javascript"
src=
"{% static "
js
/
jquery
/
jquery
.
dynatable
.
js
"
%}"
></script>
<script
type=
"text/javascript"
src=
"{% static "
js
/
jquery
/
jquery
.
dynatable
.
js
"
%}"
></script>
...
...
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