Created
December 20, 2008 09:13
-
-
Save azu/38271 to your computer and use it in GitHub Desktop.
ID、Pass、タグを各自ご自由に。hを三回で投稿
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name nico hatebu post | |
// @namespace http://web.zgo.jp/ | |
// @include http://www.nicovideo.jp/* | |
// @exclude http://www.nicovideo.jp/thumb* | |
// @update 2008/12/07 | |
// @version 0.3.3 | |
// ==/UserScript== | |
(function(){ | |
var w = (this.unsafeWindow || window), document = w.document; | |
if(!window.Hateda)return; //ポスト機構ができていなかったら終了する | |
var userID = ""//ID | |
var passWD = "" //パスワード | |
var atom = new window.Hateda( | |
userID, //ID | |
passWD //パスワード | |
).include(this); | |
// NicoVideo_mark original | |
//xpath | |
function xpath(query) { | |
var results = document.evaluate(query, document, null, | |
XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null); | |
var nodes = new Array(); | |
for(var i=0; i<results.snapshotLength; i++){ | |
nodes.push(results.snapshotItem(i)); | |
} | |
return nodes; | |
} | |
// location page | |
var what_pg = ""; | |
if(/http:\/\/.*?\.nicovideo\.jp\/([^\/]*)\/?/.test(location.href))what_pg = RegExp.$1; | |
// class of clickable space | |
var coc = ""; | |
function main(context) { | |
var $clickable = []; | |
var $clickable_search = []; | |
if(context && what_pg == "ranking"){ | |
for(var i=0;i<context.length;i++){ | |
$clickable.push($x("descendant::a[contains(concat(' ',normalize-space(@class),' '), ' video ')][contains(@href, 'watch')]/../..[not(contains(@class, 'mb16p4'))]/..", context[i])[0]); | |
$clickable_search.push($x("descendant::div[contains(concat(' ',normalize-space(@class),' '), ' thumb_frm ')]", context[i])[0]); | |
} | |
} else { | |
var context = (context) ? context[0] : document; | |
$clickable = $x("descendant::a[contains(concat(' ',normalize-space(@class),' '), ' video ')][contains(@href, 'watch')]/../..[not(contains(@class, 'mb16p4'))]/..", context); | |
$clickable_search = $x("descendant::div[contains(concat(' ',normalize-space(@class),' '), ' thumb_frm ')]", context); | |
switch (what_pg){ | |
case "watch": return; | |
case "ranking": | |
coc = "thumb_frm"; | |
$clickable = $clickable_search; break; | |
case "static": | |
$clickable = $x("descendant::a[contains(concat(' ',normalize-space(@class),' '), ' video ')]/../../../..", context); break; | |
case "tag": | |
coc = "thumb_frm"; | |
$clickable = $clickable_search; break; | |
case "search": | |
coc = "thumb_frm"; | |
$clickable = $clickable_search; break; | |
case "newarrival": | |
coc = "thumb_frm"; | |
$clickable = $clickable_search; break; | |
case "recent": | |
coc = "thumb_frm"; | |
$clickable = $clickable_search; break; | |
case "myvideo": | |
coc = "thumb_frm"; | |
$clickable = $clickable_search; break; | |
case "hotlist": | |
coc = "thumb_frm"; | |
$clickable = $clickable_search; break; | |
case "user": | |
var $clickable = $x("descendant::a[contains(concat(' ',normalize-space(@class),' '), ' video ')][contains(@href, 'watch')]/../..", context); break; | |
case "mymemory": | |
$clickable = $clickable.map(parent); break; | |
case "history": | |
$clickable = $clickable.map(parent); break; | |
case "mylist": break; | |
case "my": break; | |
case "mylist_edit": break; | |
// channel & community video page | |
case "video": break; | |
// toppage | |
default : | |
coc = "thumb_frm"; | |
$clickable = $clickable_search; break; | |
} | |
if($clickable)$clickable.forEach(click); | |
} | |
function click(elem){ | |
var self = elem; | |
elem.addEventListener("click", function(e){ | |
if(e.target.tagName == "A" || e.target.tagName == "INPUT")return; | |
if(e.target.tagName == "IMG")e.preventDefault(); | |
toggleClass(self); | |
if(init != 0)clip_board.copy()}, false); | |
} | |
function toggleClass(elem){ | |
if(coc == "thumb_frm"){ | |
elem.setAttribute("class", (elem.className == "thumb_frm") ? "marked" : "thumb_frm"); | |
elem.style.border = "2px solid #CCCCCC"; | |
elem.style.padding = "6px"; | |
}else{ | |
elem.setAttribute("class", (elem.className == "marked") ? "" : "marked"); | |
} | |
} | |
} | |
main(); | |
addFilter(main); | |
// and below, Extension/NicoClip | |
var init = 0; | |
var DefaultClipStyle = [ | |
{ | |
name : "HTML", | |
body : "<a href='%URL%'>%TITLE%</a>" | |
}, | |
{ | |
name : "iframe", | |
body : "<iframe width='312' height='176' src='http://www.nicovideo.jp/thumb/%ID%' scrolling='no' style='border:solid 1px #CCC;' frameborder='0'><a href='%URL%'>%TITLE%</a></iframe>" | |
}, | |
{ | |
name : "Hatena", | |
body : "[niconico:%ID%]" | |
} | |
]; | |
function ClipBoard(){this.initialize.apply(this, arguments);} | |
ClipBoard.prototype = { | |
initialize : function(){ | |
this.name = "NicoClip"; | |
this.timer = 0; | |
this.clipStyle = eval(GM_getValue("clipStyle")) || DefaultClipStyle; | |
this.styleNum = parseInt(GM_getValue("styleNum")) || 0; | |
this.styleSet = this.clipStyle[this.styleNum]; | |
this.clip_space = document.createElement("div"); | |
this.clip_space.id = "gm_clip"; | |
this.modeView = document.createElement("p"); | |
this.modeView.id = "cb_mode"; | |
document.body.appendChild(this.clip_space); | |
document.body.appendChild(this.modeView); | |
}, | |
getStyleNum : function(){ | |
return this.styleNum; | |
}, | |
getList : function(){ | |
if(what_pg != "watch"){ | |
var video = $x("//*[contains(concat(' ',normalize-space(@class),' '), ' marked ')]/descendant::a[contains(concat(' ',normalize-space(@class),' '), ' video ')]", document) || ""; | |
var title_a = video.map(text) || [""]; | |
var url_a = video.map(url) || [""]; | |
var id_a = video.map(function(item){return url(item).substr(30);}) || [""]; | |
var img_a = video.map(function(item){return "http://tn-skr2.smilevideo.jp/smile?i=" + url(item).substr(32);}) || [""]; | |
var page_title = [document.title]; | |
var page_url = [location.href]; | |
return {title : title_a, url : url_a, id : id_a, img : img_a, pagetitle : page_title, pageurl : page_url}; | |
} else { | |
var t = [w.Video.title]; | |
var u = [location.href]; | |
var i = [location.href.substr(30)]; | |
var im = ["http://tn-skr2.smilevideo.jp/smile?i=" + i[0].substr(2)]; | |
var p_t = [document.title]; | |
var p_u = [location.href]; | |
return {title : t, url : u, id : i, img : im, pagetitle : p_t, pageurl : p_u}; | |
} | |
}, | |
parse : function(video){ | |
var self = this; | |
var a = []; | |
var len = video.title.length || 1; | |
for(var i = 0;i < len;i++){ | |
a.push(self.styleSet.body.replace(/%(TITLE)%|%(URL)%|%(ID)%|%(IMG)%|%(PAGETITLE)%|%(PAGEURL)%/gi, | |
function(matched){ | |
var low = matched.substring(1, matched.length-1); | |
return video[low.toLowerCase()][i] || ""}) | |
); | |
} | |
var result = a.join("\r\n"); | |
result = result.replace(/(%%[\w\W]*?%%)/, function(matched){return matched.substring(2, matched.length-2)}); | |
result = result.replace(/(%%[\w\W]*?%%)/gi, ""); | |
return result; | |
}, | |
copy : function(){ | |
var info = this.getList(); | |
var text = this.parse(info); | |
//GM_log(info +" "+text); | |
var class = { | |
"src" : "http://kojim71.googlepages.com/_clipboard.swf", | |
"FlashVars" : "clipboard=" + encodeURIComponent(text), | |
"type" : "application/x-shockwave-flash", | |
"width" : 0, | |
"height": 0 | |
} | |
var _clip = $N("embed", class); | |
var space = this.clip_space; | |
while(space.hasChildNodes()){ | |
space.removeChild(space.firstChild); | |
} | |
space.appendChild(_clip); | |
}, | |
update : function(){ | |
this.styleSet = this.clipStyle[this.styleNum]; | |
this.save(); | |
this.mode(); | |
this.copy(); | |
var box = $("box_clipConf") ? $("box_clipConf") : 0; | |
if(box){ | |
$("styleName_form").value = this.styleSet.name; | |
$("style_form").value = this.styleSet.body; | |
if($("clip_item_"+ this.styleNum))$("clip_item_"+ this.styleNum).className = "clip_selected"; | |
} | |
}, | |
save : function(){ | |
GM_setValue("styleNum", this.styleNum); | |
GM_setValue("clipStyle", uneval(this.clipStyle)); | |
}, | |
post : function(){ | |
var info = this.getList(); | |
var text = this.parse(info); | |
var title = xpath('//h1[1]/text()'); | |
atom.post( | |
["test"], //タグ ["test","*"]とか配列にもできる | |
title[0].data, //title | |
text, //コメント | |
function (){ //ポストが完了時実行される | |
console.log("post!") | |
} | |
) | |
document.getElementsByTagName("H1")[0].style.backgroundColor ="#ddd"; | |
}, | |
prev : function(){ | |
var num = this.styleNum; | |
var box = $("box_clipConf") ? $("box_clipConf") : 0; | |
if(box)$("clip_item_"+ num).className = "clip_item"; | |
this.styleNum = (num > 0) ? num - 1: this.clipStyle.length -1; | |
this.update(); | |
}, | |
next : function(){ | |
var num = this.styleNum; | |
var box = $("box_clipConf") ? $("box_clipConf") : 0; | |
if(box)$("clip_item_"+ num).className = "clip_item"; | |
this.styleNum = (num + 1 < this.clipStyle.length) ? num + 1: 0; | |
this.update(); | |
}, | |
add : function(){ | |
// max of format : 5 | |
if(this.clipStyle.length > 4){ | |
alert("\u6700\u5927\u6570\u3067\u3059\u3002\u3053\u308c\u4ee5\u4e0a\u5897\u3084\u3059\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093"); | |
return; | |
} | |
this.clipStyle.splice(this.styleNum + 1, 0, {name : "", body : ""}); | |
this.styleNum = this.styleNum + 1; | |
this.update(); | |
}, | |
delete : function(){ | |
// minimum of format : 1 | |
if(this.clipStyle.length < 2){ | |
alert( | |
"\u6700\u4f4e\u6570\u3067\u3059\u3002\u524a\u9664\u3067\u304d\u307e\u305b\u3093"); | |
return; | |
} | |
if(confirm("\u672c\u5f53\u306b\u524a\u9664\u3057\u307e\u3059\u304b\uff1f\uff08\u524a\u9664\u3057\u305f\u9805\u76ee\u306f\u5143\u306b\u623b\u308a\u307e\u305b\u3093\uff09")){ | |
this.clipStyle.splice(this.styleNum, 1); | |
if(this.styleNum != 0)this.styleNum = this.styleNum - 1; | |
this.update(); | |
} | |
}, | |
mode : function(){ | |
var mode = $("cb_mode"); | |
mode.innerHTML = "<a href='javascript:void(0)'onclick='clip.makeView();this.blur()'style='text-decoration:none;color:#c03;'>" + this.name + "</a>\u3000" + this.styleSet.name; | |
}, | |
} | |
function ClipBoardConfig(){this.initialize.apply(this, arguments);} | |
ClipBoardConfig.prototype = { | |
initialize : function(cb){ | |
this.cb = cb; | |
}, | |
makeView : function(bool, clip){ | |
var self = this; | |
var cb = this.cb || clip; | |
var box = $("box_clipConf") ? $("box_clipConf") : 0; | |
if(box && box.style.visibility == "visible" && !bool){ | |
box.style.visibility = "hidden"; | |
return; | |
}else if(box && !bool){ | |
box.style.visibility = "visible"; | |
return; | |
}else{ | |
var box = $N("div", {id : "box_clipConf"}); | |
box.style.visibility = "visible" | |
} | |
var attr = { | |
header : { | |
id : "head_clipConf" | |
}, | |
controls : { | |
style : "position : absolute; top : 11px; left : 75px;" | |
}, | |
ctrl_tab : { | |
style : "position :absolute; top : 11px; right : 20px;" | |
}, | |
item : { | |
class : "clip_item", | |
href : "javascript:void(0)" | |
}, | |
plus : { | |
id : "plus_clipConf", | |
href : "javascript:void(0)" | |
}, | |
del : { | |
id : "del_clipConf", | |
href : "javascript:void(0)" | |
}, | |
body : { | |
id : "config_body" | |
}, | |
np : { | |
margin : "3px" | |
}, | |
styleName : { | |
for : "styleName_form" | |
}, | |
nameform : { | |
type : "text", | |
id : "styleName_form", | |
size : "12", | |
name : "styleName_form", | |
value : cb.styleSet.name | |
}, | |
sp : { | |
margin : "3px" | |
}, | |
style : { | |
for : "style_form" | |
}, | |
styleform : { | |
id : "style_form", | |
cols : "33", | |
rows : "10", | |
name : "style_form" | |
}, | |
buttons : { | |
style : "text-align : right; margin : 3px;" | |
}, | |
cancel : { | |
id : "cancel_clipConf", | |
type : "button", | |
class : "submit", | |
style : "margin : 5px; width : 6em;", | |
value : "\u30ad\u30e3\u30f3\u30bb\u30eb" | |
}, | |
apply : { | |
id : "apply_clipConf", | |
type : "button", | |
class : "submit", | |
style : "margin : 5px; width : 5em;", | |
value : "\u9069\u7528" | |
}, | |
ok : { | |
id : "ok_clipConf", | |
type : "button", | |
class : "submit", | |
style : "margin : 5px; width : 5em;", | |
value : "OK" | |
}, | |
} | |
var header = $N("p", attr.header, "Edit"); | |
var controls = $N("span", attr.controls); | |
var ctrl_tab = $N("span", attr.ctrl_tab); | |
var plus = $N("a", attr.plus, "\u3000\uff0b\u3000"); // + | |
var del = $N("a", attr.del, "\u3000\u2212\u3000"); // - | |
var config_body = $N("p", attr.body); | |
var np = $N("p", attr.np); | |
var styleName = $N("label", attr.styleName, "Name\u3000 : "); | |
var Name_form = $N("input", attr.nameform); | |
var sp = $N("p", attr.sp); | |
var Style = $N("label", attr.style, "Format : "); | |
var Style_form = $N("textarea", attr.styleform, cb.styleSet.body); | |
var footer = $N("p", {}); | |
var buttons = $N("div", attr.buttons); | |
var cancel = $N("input", attr.cancel); | |
var apply = $N("input", attr.apply); | |
var ok = $N("input", attr.ok); | |
box.appendChild(header); | |
header.appendChild(controls); | |
for(var i = 0;i < cb.clipStyle.length; i++){ | |
var item = $N("a", attr.item, "\u3000" + (i+1) + "\u3000"); | |
item.id = "clip_item_" + i; | |
(function(n){ | |
item.addEventListener("click", function(){self.select(n)}, false); | |
} | |
)(i); | |
if(i == cb.styleNum){ | |
item.className = "clip_selected" | |
} | |
controls.appendChild(item); | |
} | |
header.appendChild(ctrl_tab); | |
ctrl_tab.appendChild(plus); | |
ctrl_tab.appendChild(del); | |
plus.addEventListener("click", function(){self.add()}, false); | |
del.addEventListener("click", function(){self.delete()}, false); | |
box.appendChild(config_body); | |
config_body.appendChild(np); | |
np.appendChild(styleName); | |
styleName.appendChild(Name_form); | |
config_body.appendChild(sp); | |
sp.appendChild(Style); | |
Style.appendChild(Style_form); | |
Name_form.addEventListener("keyup", stop, false); | |
Style_form.addEventListener("keyup", stop, false); | |
box.appendChild(footer); | |
footer.appendChild(buttons); | |
buttons.appendChild(cancel); | |
buttons.appendChild(apply); | |
buttons.appendChild(ok); | |
cancel.addEventListener("click", function(){self.cancel()}, false); | |
apply.addEventListener("click", function(){self.apply()}, false); | |
ok.addEventListener("click", function(){self.ok()}, false); | |
if(bool)return box; | |
document.body.appendChild(box); | |
}, | |
select : function(num){ | |
var cb = this.cb; | |
var pre = cb.getStyleNum(); | |
var box = $("box_clipConf") ? $("box_clipConf") : 0; | |
if(box)$("clip_item_"+ pre).className = "clip_item"; | |
cb.styleNum = num; | |
cb.update(); | |
}, | |
add : function(){ | |
var cb = this.cb; | |
var box = $("box_clipConf") ? $("box_clipConf") : 0; | |
cb.add(); | |
box.parentNode.replaceChild(this.makeView(1, cb), box); | |
}, | |
delete : function(){ | |
var cb = this.cb; | |
var box = $("box_clipConf") ? $("box_clipConf") : 0; | |
cb.delete(); | |
box.parentNode.replaceChild(this.makeView(1, cb), box); | |
}, | |
cancel : function(){ | |
var cb = this.cb; | |
var box = $("box_clipConf") ? $("box_clipConf") : 0; | |
box.parentNode.replaceChild(this.makeView(1, cb), box); | |
$("box_clipConf").style.visibility = "hidden"; | |
}, | |
apply : function(){ | |
var cb = this.cb; | |
var box = $("box_clipConf") ? $("box_clipConf") : 0; | |
cb.styleSet.name = $("styleName_form").value; | |
cb.styleSet.body = $("style_form").value; | |
cb.update(); | |
box.parentNode.replaceChild(this.makeView(1, cb), box); | |
}, | |
ok : function(){ | |
this.apply(); | |
this.cancel(); | |
}, | |
} | |
var clip_board = new ClipBoard(); | |
var clip_conf = new ClipBoardConfig(clip_board); | |
w.clip = clip_conf; | |
var c_count = 0; | |
var pre_key = 0; | |
var post_check = false; | |
document.addEventListener("keyup", function(e){KeyUpCommand(e.which);},false); | |
function clearCount(){return setTimeout(function(){c_count = 0}, 5000);} | |
function KeyUpCommand(key){ | |
if(key > 67 && key < 73){ | |
if(c_count != 1){ | |
c_count++; | |
pre_key = key; | |
clip_board.timer = clearCount(); | |
}else{ | |
clearTimeout(clip_board.timer); | |
if(init != 0 && key == pre_key){ | |
switch(key){ | |
case 68 : { // D key | |
clip_board.prev(); | |
break; | |
} | |
case 69 : { // E key | |
clip_conf.makeView(); | |
break; | |
} | |
case 70 : { // F key | |
clip_board.next(); | |
break; | |
} | |
case 72 : { // Hkey | |
if(!post_check){ | |
post_check = true; | |
clip_board.post(); | |
} | |
break; | |
} | |
} | |
}else{ | |
init = 1; | |
pre_key = key; | |
clip_board.update(); | |
} | |
clip_board.timer = clearCount(); | |
} | |
} | |
} | |
//prevent event in input area | |
var inputs = $x("descendant::input[@name='s']", document); | |
for(var i =0; i < inputs.length; i++){ | |
inputs[i].addEventListener("keyup", stop, false); | |
} | |
//add trigger to NicoVideo HEADER_BAR | |
var header = document.getElementById("PAGEHEADER"); | |
if(header){ | |
var trigger_pos = document.getElementById("topline_menu"); | |
if(trigger_pos){ | |
var bd = document.createTextNode(" | ");; | |
var trigger = document.createElement("a"); | |
var trigger_txt = document.createTextNode("Clip!"); | |
trigger.href = "javascript:void(0)"; | |
trigger.style.color = "yellow"; | |
trigger.addEventListener("click", function(e){ | |
init = 1; | |
clip_board.update(); | |
e.target.blur(); | |
},false); | |
trigger_pos.appendChild(bd); | |
trigger_pos.appendChild(trigger); | |
trigger.appendChild(trigger_txt); | |
} | |
} | |
//utility function | |
function stop(e){e.stopPropagation();} | |
function parent(elem){return elem.parentNode;} | |
function text(elem){return elem.textContent;} | |
function url(elem){return elem.href;} | |
function $(elem){return document.getElementById(elem);} | |
function $x(xpath, context){ | |
var x = document.evaluate(xpath, context, null, 7, null); | |
var array = []; | |
for(var i = 0;i < x.snapshotLength;i++){ | |
array.push(x.snapshotItem(i)); | |
} | |
return array; | |
} | |
function $N(name, attr, childs) { | |
var ret = document.createElement(name); | |
for(var k in attr) { | |
if(!attr.hasOwnProperty(k)) continue; | |
if(k == 'class') { | |
ret.className = attr[k]; | |
} else if(k == 'style' && typeof(attr[k]) == 'object') { | |
for(var j in attr[k]) ret.style[j] = attr[k][j]; | |
} else { | |
ret.setAttribute(k, attr[k]); | |
} | |
} | |
switch(typeof childs) { | |
case 'string': { | |
ret.appendChild(document.createTextNode(childs)); | |
break; | |
} | |
case 'object': { | |
for(var i=0,len=childs.length; i<len; i++) { | |
var child = childs[i]; | |
if(typeof child == 'string') { | |
ret.appendChild(document.createTextNode(child)); | |
} else { | |
ret.appendChild(child); | |
} | |
} | |
break; | |
} | |
} | |
return ret; | |
} | |
function addFilter(filter, i) { | |
i = i || 4 | |
if (window.AutoPagerize && window.AutoPagerize.addFilter) { | |
window.AutoPagerize.addFilter(filter); | |
} | |
else if (i > 1) { | |
setTimeout(arguments.callee, 1000, filter, i - 1); | |
} | |
} | |
var ClipCSS = [ | |
".marked {", | |
"background:#FFCCCC none repeat scroll 0%;", | |
"}", | |
".edit {", | |
"font-style : italic;", | |
"}", | |
"a.clip_item {", | |
"margin : 3px 3px 0px 3px;", | |
"color : #000;", | |
"text-decoration : none;", | |
"border : 1px solid #000;", | |
"border-bottom : none;", | |
"background-color : #FFF;", | |
"}", | |
"a.clip_item:hover {", | |
"background-color : #AAA;", | |
"}", | |
"a.clip_selected {", | |
"background-color : #555;", | |
"color : #FFF;", | |
"cursor : default;", | |
"margin : 3px 3px 0px 3px;", | |
"text-decoration : none;", | |
"border : 1px solid #000;", | |
"}", | |
"#cb_mode {", | |
"position : fixed;", | |
"top : 5px;", | |
"left : 5px;", | |
"color : #c03;", | |
"font-style : italic;", | |
"font-size : 90%", | |
"}", | |
"#box_clipConf {", | |
"padding : 5px;", | |
"position : fixed;", | |
"top : 30px;", | |
"left : -1px;", | |
"width : 400px;", | |
"background-color : #EEE;", | |
"border : 1px solid #000;", | |
"}", | |
"#head_clipConf {", | |
"padding : 3px;", | |
"border-bottom : 1px solid;", | |
"font-weight : bold;", | |
"}", | |
"#plus_clipConf {", | |
"margin : 3px 3px 0px 3px;", | |
"color : #063;", | |
"text-decoration : none;", | |
"border : 1px solid;", | |
"border-bottom : none;", | |
"background-color : #FFF;", | |
"}", | |
"#del_clipConf {", | |
"margin : 3px 3px 0px 3px;", | |
"color : #D00;", | |
"text-decoration : none;", | |
"border : 1px solid;", | |
"border-bottom : none;", | |
"background-color : #FFF;", | |
"}", | |
"#plus_clipConf:hover {", | |
"background-color : #CFC;", | |
"}", | |
"#del_clipConf:hover {", | |
"background-color : #FCC;", | |
"}", | |
"#config_body {", | |
"margin : 3px;", | |
"}", | |
"#styleName_form {", | |
"margin : 5px", | |
"}", | |
"#style_form {", | |
"margin : 3px;", | |
"}" | |
].join("\n"); | |
GM_addStyle(ClipCSS); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment