Loading, please wait...

Sunday, November 23, 2008

Chrome 扩展

Google 官方还没有为Chrome提供工具条,我们就暂时用书签栏做替代品吧. 选择你需要的链接拖放到书签栏.



Subscribe to Reader 
将当前页中的rss订阅到Google Reader


javascript:var%20b=document.body;var%20GR________bookmarklet_domain='http://www.google.com';if(b&&!document.xmlVersion){void(z=document.createElement('script'));void(z.src='http://www.google.com/reader/ui/subscribe-bookmarklet.js');void(b.appendChild(z));}else{location='http://www.google.com/reader/view/feed/'+encodeURIComponent(location.href)}
View PageRank
查看本页PageRank和Alexa 排名


javascript:void(window.open("http://pr.tracerank.com/index.php?url="+escape(location.href),"Tech%20Dreams","height=100,width=400,top=0,left=0,location=0"))
Add to Notebook
添加选中文本到Google Notebook


javascript:(function(){var%20w=window;var%20d=document;var%20g=w.open('about:blank','gnotesWin','location=0,menubar=0,scrollbars=0,status=0,toolbar=0,width=300,height=300,resizable');var%20s=d.createElement('script');s.setAttribute('src','http://www.google.com/notebook/bookmarkletPoster?zx='+(new%20Date()).valueOf());d.body.appendChild(s);w.setTimeout(function(){w.blur();g.focus();},%20100)}).call({});
Share in Reader
分享本页到Google Reader


javascript:var%20b=document.body;var%20GR________bookmarklet_domain='http://www.google.com';if(b&&!document.xmlVersion){void(z=document.createElement('script'));void(z.src='http://www.google.com/reader/ui/link-bookmarklet.js');void(b.appendChild(z));}else{}
Google Bookmark
将当前页添加到Google Bookmarks(当前窗口)


javascript:document.location%20=%20"http://www.google.com/bookmarks/mark?op=add&title="%20+%20encodeURI(document.title)%20+%20"&bkmk="%20+%20encodeURI(document.location);
Google Bookmark(Popup)
将当前页添加到Google Bookmarks(弹出窗口)


javascript:(function(){var a=window,b=document,c=encodeURIComponent,d=a.open("http://www.google.com/bookmarks/mark?op=edit&output=popup&bkmk="+c(b.location)+"&title="+c(b.title),"bkmk_popup","left="+((a.screenX||a.screenLeft)+10)+",top="+((a.screenY||a.screenTop)+10)+",height=420px,width=550px,resizable=1,alwaysRaised=1");a.setTimeout(function(){d.focus()},300)})();
小D划词
在页面启用沪江小D画词翻译


javascript:void((function(){hjelm=document.createElement('script');hjelm.setAttribute('src','http://dict.hjenglish.com/js/dict.js');document.body.appendChild(hjelm);})())
JavaScript Shell
在新窗口中打开一个可以操作本页面的JavaScript Shell


javascript:with(window.open(%22%22,%22_blank%22,%22width=%22+screen.width*.6+%22,left=%22+screen.width*.35+%22,height=%22+screen.height*.9+%22,resizable,scrollbars=yes%22)){document.write(%22%3C!DOCTYPE%20HTML%20PUBLIC%20\%22-//W3C//DTD%20HTML%204.01//EN\%22%20\%22http://www.w3.org/TR/html4/strict.dtd\%22%3E\n\n%3Chtml%20onclick=\%22keepFocusInTextbox(event)\%22%3E\n%3Chead%3E\n%3Cmeta%20http-equiv=\%22Content-Type\%22%20content=\%22text/html;%20charset=iso-8859-1\%22%3E\n%3Ctitle%3EJavaScript%20Shell%201.4%3C/title%3E\n\n%3Cscript%20type=\%22text/javascript\%22%3E\nvar%20\nhistList%20=%20[\%22\%22],%20\nhistPos%20=%200,%20\n_scope%20=%20{},%20\n_win,%20//%20a%20top-level%20context\nquestion,\n_in,\n_out,\ntooManyMatches%20=%20null,\nlastError%20=%20null;\n\nfunction%20refocus()\n{\n%20%20_in.blur();%20//%20Needed%20for%20Mozilla%20to%20scroll%20correctly.\n%20%20_in.focus();\n}\n\nfunction%20init()\n{\n%20%20_in%20=%20document.getElementById(\%22input\%22);\n%20%20_out%20=%20document.getElementById(\%22output\%22);\n\n%20%20_win%20=%20window;\n\n%20%20if%20(opener%20&&%20!opener.closed)\n%20%20{\n%20%20%20%20println(\%22Using%20bookmarklet%20version%20of%20shell:%20commands%20will%20run%20in%20opener's%20context.\%22,%20\%22message\%22);\n%20%20%20%20_win%20=%20opener;\n%20%20}\n\n%20%20initTarget();\n\n%20%20recalculateInputHeight();\n%20%20refocus();\n}\n\nfunction%20initTarget()\n{\n%20%20_win.Shell%20=%20window;\n%20%20_win.print%20=%20shellCommands.print;\n}\n\n\n//%20Unless%20the%20user%20is%20selected%20something,%20refocus%20the%20textbox.\n//%20(requested%20by%20caillon,%20brendan,%20asa)\nfunction%20keepFocusInTextbox(e)%20\n{\n%20%20var%20g%20=%20e.srcElement%20?%20e.srcElement%20:%20e.target;%20//%20IE%20vs.%20standard\n%20%20\n%20%20while%20(!g.tagName)\n%20%20%20%20g%20=%20g.parentNode;\n%20%20var%20t%20=%20g.tagName.toUpperCase();\n%20%20if%20(t==\%22A\%22%20||%20t==\%22INPUT\%22)\n%20%20%20%20return;\n%20%20%20%20\n%20%20if%20(window.getSelection)%20{\n%20%20%20%20//%20Mozilla\n%20%20%20%20if%20(String(window.getSelection()))\n%20%20%20%20%20%20return;\n%20%20}\n%20%20else%20if%20(document.getSelection)%20{\n%20%20%20%20//%20Opera?%20Netscape%204?\n%20%20%20%20if%20(document.getSelection())\n%20%20%20%20%20%20return;\n%20%20}\n%20%20else%20{\n%20%20%20%20//%20IE\n%20%20%20%20if%20(%20document.selection.createRange().text%20)\n%20%20%20%20%20%20return;\n%20%20}\n%20%20\n%20%20refocus();\n}\n\nfunction%20inputKeydown(e)%20{\n%20%20//%20Use%20onkeydown%20because%20IE%20doesn't%20support%20onkeypress%20for%20arrow%20keys\n\n%20%20//alert(e.keyCode%20+%20\%22%20^%20\%22%20+%20e.keycode);\n\n%20%20if%20(e.shiftKey%20&&%20e.keyCode%20==%2013)%20{%20//%20shift-enter\n%20%20%20%20//%20don't%20do%20anything;%20allow%20the%20shift-enter%20to%20insert%20a%20line%20break%20as%20normal\n%20%20}%20else%20if%20(e.keyCode%20==%2013)%20{%20//%20enter\n%20%20%20%20//%20execute%20the%20input%20on%20enter\n%20%20%20%20try%20{%20go();%20}%20catch(er)%20{%20alert(er);%20};\n%20%20%20%20setTimeout(function()%20{%20_in.value%20=%20\%22\%22;%20},%200);%20//%20can't%20preventDefault%20on%20input,%20so%20clear%20it%20later\n%20%20}%20else%20if%20(e.keyCode%20==%2038)%20{%20//%20up\n%20%20%20%20//%20go%20up%20in%20history%20if%20at%20top%20or%20ctrl-up\n%20%20%20%20if%20(e.ctrlKey%20||%20caretInFirstLine(_in))\n%20%20%20%20%20%20hist(true);\n%20%20}%20else%20if%20(e.keyCode%20==%2040)%20{%20//%20down\n%20%20%20%20//%20go%20down%20in%20history%20if%20at%20end%20or%20ctrl-down\n%20%20%20%20if%20(e.ctrlKey%20||%20caretInLastLine(_in))\n%20%20%20%20%20%20hist(false);\n%20%20}%20else%20if%20(e.keyCode%20==%209)%20{%20//%20tab\n%20%20%20%20tabcomplete();\n%20%20%20%20setTimeout(function()%20{%20refocus();%20},%200);%20//%20refocus%20because%20tab%20was%20hit\n%20%20}%20else%20{%20}\n\n%20%20setTimeout(recalculateInputHeight,%200);\n%20%20\n%20%20//return%20true;\n};\n\nfunction%20caretInFirstLine(textbox)\n{\n%20%20//%20IE%20doesn't%20support%20selectionStart/selectionEnd\n%20%20if%20(textbox.selectionStart%20==%20undefined)\n%20%20%20%20return%20true;\n\n%20%20var%20firstLineBreak%20=%20textbox.value.indexOf(\%22\\n\%22);\n%20%20\n%20%20return%20((firstLineBreak%20==%20-1)%20||%20(textbox.selectionStart%20%3C=%20firstLineBreak));\n}\n\nfunction%20caretInLastLine(textbox)\n{\n%20%20//%20IE%20doesn't%20support%20selectionStart/selectionEnd\n%20%20if%20(textbox.selectionEnd%20==%20undefined)\n%20%20%20%20return%20true;\n\n%20%20var%20lastLineBreak%20=%20textbox.value.lastIndexOf(\%22\\n\%22);\n%20%20\n%20%20return%20(textbox.selectionEnd%20%3E%20lastLineBreak);\n}\n\nfunction%20recalculateInputHeight()\n{\n%20%20var%20rows%20=%20_in.value.split(/\\n/).length\n%20%20%20%20+%201%20//%20prevent%20scrollbar%20flickering%20in%20Mozilla\n%20%20%20%20+%20(window.opera%20?%201%20:%200);%20//%20leave%20room%20for%20scrollbar%20in%20Opera\n%20%20\n%20%20if%20(_in.rows%20!=%20rows)%20//%20without%20this%20check,%20it%20is%20impossible%20to%20select%20text%20in%20Opera%207.60%20or%20Opera%208.0.\n%20%20%20%20_in.rows%20=%20rows;\n}\n\nfunction%20println(s,%20type)\n{\n%20%20if((s=String(s)))\n%20%20{\n%20%20%20%20var%20newdiv%20=%20document.createElement(\%22div\%22);\n%20%20%20%20newdiv.appendChild(document.createTextNode(s));\n%20%20%20%20newdiv.className%20=%20type;\n%20%20%20%20_out.appendChild(newdiv);\n%20%20%20%20return%20newdiv;\n%20%20}\n}\n\nfunction%20printWithRunin(h,%20s,%20type)\n{\n%20%20var%20div%20=%20println(s,%20type);\n%20%20var%20head%20=%20document.createElement(\%22strong\%22);\n%20%20head.appendChild(document.createTextNode(h%20+%20\%22:%20\%22));\n%20%20div.insertBefore(head,%20div.firstChild);\n}\n\n\nvar%20shellCommands%20=%20\n{\nload%20:%20function%20load(url)\n{\n%20%20var%20s%20=%20_win.document.createElement(\%22script\%22);\n%20%20s.type%20=%20\%22text/javascript\%22;\n%20%20s.src%20=%20url;\n%20%20_win.document.getElementsByTagName(\%22head\%22)[0].appendChild(s);\n%20%20println(\%22Loading%20\%22%20+%20url%20+%20\%22...\%22,%20\%22message\%22);\n},\n\nclear%20:%20function%20clear()\n{\n%20%20var%20CHILDREN_TO_PRESERVE%20=%203;\n%20%20while%20(_out.childNodes[CHILDREN_TO_PRESERVE])%20\n%20%20%20%20_out.removeChild(_out.childNodes[CHILDREN_TO_PRESERVE]);\n},\n\nprint%20:%20function%20print(s)%20{%20println(s,%20\%22print\%22);%20},\n\n//%20the%20normal%20function,%20\%22print\%22,%20shouldn't%20return%20a%20value\n//%20(suggested%20by%20brendan;%20later%20noticed%20it%20was%20a%20problem%20when%20showing%20others)\npr%20:%20function%20pr(s)%20\n{%20\n%20%20shellCommands.print(s);%20//%20need%20to%20specify%20shellCommands%20so%20it%20doesn't%20try%20window.print()!\n%20%20return%20s;\n},\n\nprops%20:%20function%20props(e,%20onePerLine)\n{\n%20%20if%20(e%20===%20null)%20{\n%20%20%20%20println(\%22props%20called%20with%20null%20argument\%22,%20\%22error\%22);\n%20%20%20%20return;\n%20%20}\n\n%20%20if%20(e%20===%20undefined)%20{\n%20%20%20%20println(\%22props%20called%20with%20undefined%20argument\%22,%20\%22error\%22);\n%20%20%20%20return;\n%20%20}\n\n%20%20var%20ns%20=%20[\%22Methods\%22,%20\%22Fields\%22,%20\%22Unreachables\%22];\n%20%20var%20as%20=%20[[],%20[],%20[]];%20//%20array%20of%20(empty)%20arrays%20of%20arrays!\n%20%20var%20p,%20j,%20i;%20//%20loop%20variables,%20several%20used%20multiple%20times\n\n%20%20var%20protoLevels%20=%200;\n\n%20%20for%20(p%20=%20e;%20p;%20p%20=%20p.__proto__)\n%20%20{\n%20%20%20%20for%20(i=0;%20i%3Cns.length;%20++i)\n%20%20%20%20%20%20as[i][protoLevels]%20=%20[];\n%20%20%20%20++protoLevels;\n%20%20}\n\n%20%20for(var%20a%20in%20e)\n%20%20{\n%20%20%20%20//%20Shortcoming:%20doesn't%20check%20that%20VALUES%20are%20the%20same%20in%20object%20and%20prototype.\n\n%20%20%20%20var%20protoLevel%20=%20-1;\n%20%20%20%20try\n%20%20%20%20{\n%20%20%20%20%20%20for%20(p%20=%20e;%20p%20&&%20(a%20in%20p);%20p%20=%20p.__proto__)\n%20%20%20%20%20%20%20%20++protoLevel;\n%20%20%20%20}\n%20%20%20%20catch(er)%20{%20protoLevel%20=%200;%20}%20//%20\%22in\%22%20operator%20throws%20when%20param%20to%20props()%20is%20a%20string\n\n%20%20%20%20var%20type%20=%201;\n%20%20%20%20try\n%20%20%20%20{\n%20%20%20%20%20%20if%20((typeof%20e[a])%20==%20\%22function\%22)\n%20%20%20%20%20%20%20%20type%20=%200;\n%20%20%20%20}\n%20%20%20%20catch%20(er)%20{%20type%20=%202;%20}\n\n%20%20%20%20as[type][protoLevel].push(a);\n%20%20}\n\n%20%20function%20times(s,%20n)%20{%20return%20n%20?%20s%20+%20times(s,%20n-1)%20:%20\%22\%22;%20}\n\n%20%20for%20(j=0;%20j%3CprotoLevels;%20++j)\n%20%20%20%20for%20(i=0;i%3Cns.length;++i)\n%20%20%20%20%20%20if%20(as[i][j].length)%20\n%20%20%20%20%20%20%20%20printWithRunin(\n%20%20%20%20%20%20%20%20%20%20ns[i]%20+%20times(\%22%20of%20prototype\%22,%20j),%20\n%20%20%20%20%20%20%20%20%20%20(onePerLine%20?%20\%22\\n\\n\%22%20:%20\%22\%22)%20+%20as[i][j].sort().join(onePerLine%20?%20\%22\\n\%22%20:%20\%22,%20\%22)%20+%20(onePerLine%20?%20\%22\\n\\n\%22%20:%20\%22\%22),%20\n%20%20%20%20%20%20%20%20%20%20\%22propList\%22\n%20%20%20%20%20%20%20%20);\n},\n\nblink%20:%20function%20blink(node)\n{\n%20%20if%20(!node)%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20throw(\%22blink:%20argument%20is%20null%20or%20undefined.\%22);\n%20%20if%20(node.nodeType%20==%20null)%20%20%20%20%20throw(\%22blink:%20argument%20must%20be%20a%20node.\%22);\n%20%20if%20(node.nodeType%20==%203)%20%20%20%20%20%20%20%20throw(\%22blink:%20argument%20must%20not%20be%20a%20text%20node\%22);\n%20%20if%20(node.documentElement)%20%20%20%20%20%20throw(\%22blink:%20argument%20must%20not%20be%20the%20document%20object\%22);\n\n%20%20function%20setOutline(o)%20{%20\n%20%20%20%20return%20function()%20{\n%20%20%20%20%20%20if%20(node.style.outline%20!=%20node.style.bogusProperty)%20{\n%20%20%20%20%20%20%20%20//%20browser%20supports%20outline%20(Firefox%201.1%20and%20newer,%20CSS3,%20Opera%208).\n%20%20%20%20%20%20%20%20node.style.outline%20=%20o;\n%20%20%20%20%20%20}\n%20%20%20%20%20%20else%20if%20(node.style.MozOutline%20!=%20node.style.bogusProperty)%20{\n%20%20%20%20%20%20%20%20//%20browser%20supports%20MozOutline%20(Firefox%201.0.x%20and%20older)\n%20%20%20%20%20%20%20%20node.style.MozOutline%20=%20o;\n%20%20%20%20%20%20}\n%20%20%20%20%20%20else%20{\n%20%20%20%20%20%20%20%20//%20browser%20only%20supports%20border%20(IE).%20border%20is%20a%20fallback%20because%20it%20moves%20things%20around.\n%20%20%20%20%20%20%20%20node.style.border%20=%20o;\n%20%20%20%20%20%20}\n%20%20%20%20}\n%20%20}%20\n%20%20\n%20%20function%20focusIt(a)%20{\n%20%20%20%20return%20function()%20{\n%20%20%20%20%20%20a.focus();%20\n%20%20%20%20}\n%20%20}\n\n%20%20if%20(node.ownerDocument)%20{\n%20%20%20%20var%20windowToFocusNow%20=%20(node.ownerDocument.defaultView%20||%20node.ownerDocument.parentWindow);%20//%20Moz%20vs.%20IE\n%20%20%20%20if%20(windowToFocusNow)\n%20%20%20%20%20%20setTimeout(focusIt(windowToFocusNow.top),%200);\n%20%20}\n\n%20%20for(var%20i=1;i%3C7;++i)\n%20%20%20%20setTimeout(setOutline((i%252)?'3px%20solid%20red':'none'),%20i*100);\n\n%20%20setTimeout(focusIt(window),%20800);\n%20%20setTimeout(focusIt(_in),%20810);\n},\n\nscope%20:%20function%20scope(sc)\n{\n%20%20if%20(!sc)%20sc%20=%20{};\n%20%20_scope%20=%20sc;\n%20%20println(\%22Scope%20is%20now%20\%22%20+%20sc%20+%20\%22.%20%20If%20a%20variable%20is%20not%20found%20in%20this%20scope,%20window%20will%20also%20be%20searched.%20%20New%20variables%20will%20still%20go%20on%20window.\%22,%20\%22message\%22);\n},\n\nmathHelp%20:%20function%20mathHelp()\n{\n%20%20printWithRunin(\%22Math%20constants\%22,%20\%22E,%20LN2,%20LN10,%20LOG2E,%20LOG10E,%20PI,%20SQRT1_2,%20SQRT2\%22,%20\%22propList\%22);\n%20%20printWithRunin(\%22Math%20methods\%22,%20\%22abs,%20acos,%20asin,%20atan,%20atan2,%20ceil,%20cos,%20exp,%20floor,%20log,%20max,%20min,%20pow,%20random,%20round,%20sin,%20sqrt,%20tan\%22,%20\%22propList\%22);\n},\n\nans%20:%20undefined\n};\n\n\nfunction%20hist(up)\n{\n%20%20//%20histList[0]%20=%20first%20command%20entered,%20[1]%20=%20second,%20etc.\n%20%20//%20type%20something,%20press%20up%20--%3E%20thing%20typed%20is%20now%20in%20\%22limbo\%22\n%20%20//%20(last%20item%20in%20histList)%20and%20should%20be%20reachable%20by%20pressing%20\n%20%20//%20down%20again.\n\n%20%20var%20L%20=%20histList.length;\n\n%20%20if%20(L%20==%201)\n%20%20%20%20return;\n\n%20%20if%20(up)\n%20%20{\n%20%20%20%20if%20(histPos%20==%20L-1)\n%20%20%20%20{\n%20%20%20%20%20%20//%20Save%20this%20entry%20in%20case%20the%20user%20hits%20the%20down%20key.\n%20%20%20%20%20%20histList[histPos]%20=%20_in.value;\n%20%20%20%20}\n\n%20%20%20%20if%20(histPos%20%3E%200)\n%20%20%20%20{\n%20%20%20%20%20%20histPos--;\n%20%20%20%20%20%20//%20Use%20a%20timeout%20to%20prevent%20up%20from%20moving%20cursor%20within%20new%20text\n%20%20%20%20%20%20//%20Set%20to%20nothing%20first%20for%20the%20same%20reason\n%20%20%20%20%20%20setTimeout(\n%20%20%20%20%20%20%20%20function()%20{\n%20%20%20%20%20%20%20%20%20%20_in.value%20=%20'';%20\n%20%20%20%20%20%20%20%20%20%20_in.value%20=%20histList[histPos];\n%20%20%20%20%20%20%20%20%20%20var%20caretPos%20=%20_in.value.length;\n%20%20%20%20%20%20%20%20%20%20if%20(_in.setSelectionRange)%20\n%20%20%20%20%20%20%20%20%20%20%20%20_in.setSelectionRange(caretPos,%20caretPos);\n%20%20%20%20%20%20%20%20},\n%20%20%20%20%20%20%20%200\n%20%20%20%20%20%20);\n%20%20%20%20}\n%20%20}%20\n%20%20else%20//%20down\n%20%20{\n%20%20%20%20if%20(histPos%20%3C%20L-1)\n%20%20%20%20{\n%20%20%20%20%20%20histPos++;\n%20%20%20%20%20%20_in.value%20=%20histList[histPos];\n%20%20%20%20}\n%20%20%20%20else%20if%20(histPos%20==%20L-1)\n%20%20%20%20{\n%20%20%20%20%20%20//%20Already%20on%20the%20current%20entry:%20clear%20but%20save\n%20%20%20%20%20%20if%20(_in.value)\n%20%20%20%20%20%20{\n%20%20%20%20%20%20%20%20histList[histPos]%20=%20_in.value;\n%20%20%20%20%20%20%20%20++histPos;\n%20%20%20%20%20%20%20%20_in.value%20=%20\%22\%22;\n%20%20%20%20%20%20}\n%20%20%20%20}\n%20%20}\n}\n\nfunction%20tabcomplete()\n{\n%20%20/*\n%20%20%20*%20Working%20backwards%20from%20s[from],%20find%20the%20spot\n%20%20%20*%20where%20this%20expression%20starts.%20%20It%20will%20scan\n%20%20%20*%20until%20it%20hits%20a%20mismatched%20(%20or%20a%20space,\n%20%20%20*%20but%20it%20skips%20over%20quoted%20strings.\n%20%20%20*%20If%20stopAtDot%20is%20true,%20stop%20at%20a%20'.'\n%20%20%20*/\n%20%20function%20findbeginning(s,%20from,%20stopAtDot)\n%20%20{\n%20%20%20%20/*\n%20%20%20%20%20*%20%20Complicated%20function.\n%20%20%20%20%20*\n%20%20%20%20%20*%20%20Return%20true%20if%20s[i]%20==%20q%20BUT%20ONLY%20IF\n%20%20%20%20%20*%20%20s[i-1]%20is%20not%20a%20backslash.\n%20%20%20%20%20*/\n%20%20%20%20function%20equalButNotEscaped(s,i,q)\n%20%20%20%20{\n%20%20%20%20%20%20if(s.charAt(i)%20!=%20q)%20//%20not%20equal%20go%20no%20further\n%20%20%20%20%20%20%20%20return%20false;\n\n%20%20%20%20%20%20if(i==0)%20//%20beginning%20of%20string\n%20%20%20%20%20%20%20%20return%20true;\n\n%20%20%20%20%20%20if(s.charAt(i-1)%20==%20'\\\\')%20//%20escaped?\n%20%20%20%20%20%20%20%20return%20false;\n\n%20%20%20%20%20%20return%20true;\n%20%20%20%20}\n\n%20%20%20%20var%20nparens%20=%200;\n%20%20%20%20var%20i;\n%20%20%20%20for(i=from;%20i%3E=0;%20i--)\n%20%20%20%20{\n%20%20%20%20%20%20if(s.charAt(i)%20==%20'%20')\n%20%20%20%20%20%20%20%20break;\n\n%20%20%20%20%20%20if(stopAtDot%20&&%20s.charAt(i)%20==%20'.')\n%20%20%20%20%20%20%20%20break;\n%20%20%20%20%20%20%20%20\n%20%20%20%20%20%20if(s.charAt(i)%20==%20')')\n%20%20%20%20%20%20%20%20nparens++;\n%20%20%20%20%20%20else%20if(s.charAt(i)%20==%20'(')\n%20%20%20%20%20%20%20%20nparens--;\n\n%20%20%20%20%20%20if(nparens%20%3C%200)\n%20%20%20%20%20%20%20%20break;\n\n%20%20%20%20%20%20//%20skip%20quoted%20strings\n%20%20%20%20%20%20if(s.charAt(i)%20==%20'\\''%20||%20s.charAt(i)%20==%20'\\\%22')\n%20%20%20%20%20%20{\n%20%20%20%20%20%20%20%20//dump(\%22skipping%20quoted%20chars:%20\%22);\n%20%20%20%20%20%20%20%20var%20quot%20=%20s.charAt(i);\n%20%20%20%20%20%20%20%20i--;\n%20%20%20%20%20%20%20%20while(i%20%3E=%200%20&&%20!equalButNotEscaped(s,i,quot))%20{\n%20%20%20%20%20%20%20%20%20%20//dump(s.charAt(i));\n%20%20%20%20%20%20%20%20%20%20i--;\n%20%20%20%20%20%20%20%20}\n%20%20%20%20%20%20%20%20//dump(\%22\\n\%22);\n%20%20%20%20%20%20}\n%20%20%20%20}\n%20%20%20%20return%20i;\n%20%20}\n\n%20%20//%20XXX%20should%20be%20used%20more%20consistently%20(instead%20of%20using%20selectionStart/selectionEnd%20throughout%20code)\n%20%20//%20XXX%20doesn't%20work%20in%20IE,%20even%20though%20it%20contains%20IE-specific%20code\n%20%20function%20getcaretpos(inp)\n%20%20{\n%20%20%20%20if(inp.selectionEnd%20!=%20null)\n%20%20%20%20%20%20return%20inp.selectionEnd;\n%20%20%20%20%20%20\n%20%20%20%20if(inp.createTextRange)\n%20%20%20%20{\n%20%20%20%20%20%20var%20docrange%20=%20_win.Shell.document.selection.createRange();\n%20%20%20%20%20%20var%20inprange%20=%20inp.createTextRange();\n%20%20%20%20%20%20if%20(inprange.setEndPoint)\n%20%20%20%20%20%20{\n%20%20%20%20%20%20%20%20inprange.setEndPoint('EndToStart',%20docrange);\n%20%20%20%20%20%20%20%20return%20inprange.text.length;\n%20%20%20%20%20%20}\n%20%20%20%20}\n\n%20%20%20%20return%20inp.value.length;%20//%20sucks,%20punt\n%20%20}\n\n%20%20function%20setselectionto(inp,pos)\n%20%20{\n%20%20%20%20if(inp.selectionStart)%20{\n%20%20%20%20%20%20inp.selectionStart%20=%20inp.selectionEnd%20=%20pos;\n%20%20%20%20}\n%20%20%20%20else%20if(inp.createTextRange)%20{\n%20%20%20%20%20%20var%20docrange%20=%20_win.Shell.document.selection.createRange();\n%20%20%20%20%20%20var%20inprange%20=%20inp.createTextRange();\n%20%20%20%20%20%20inprange.move('character',pos);\n%20%20%20%20%20%20inprange.select();\n%20%20%20%20}\n%20%20%20%20else%20{%20//%20err...\n%20%20%20%20/*\n%20%20%20%20%20%20inp.select();\n%20%20%20%20%20%20if(_win.Shell.document.getSelection())\n%20%20%20%20%20%20%20%20_win.Shell.document.getSelection()%20=%20\%22\%22;\n%20%20%20%20%20%20%20%20*/\n%20%20%20%20}\n%20%20}\n%20%20%20%20//%20get%20position%20of%20cursor%20within%20the%20input%20box\n%20%20%20%20var%20caret%20=%20getcaretpos(_in);\n\n%20%20%20%20if(caret)%20{\n%20%20%20%20%20%20//dump(\%22----\\n\%22);\n%20%20%20%20%20%20var%20dotpos,%20spacepos,%20complete,%20obj;\n%20%20%20%20%20%20//dump(\%22caret%20pos:%20\%22%20+%20caret%20+%20\%22\\n\%22);\n%20%20%20%20%20%20//%20see%20if%20there's%20a%20dot%20before%20here\n%20%20%20%20%20%20dotpos%20=%20findbeginning(_in.value,%20caret-1,%20true);\n%20%20%20%20%20%20//dump(\%22dot%20pos:%20\%22%20+%20dotpos%20+%20\%22\\n\%22);\n%20%20%20%20%20%20if(dotpos%20==%20-1%20||%20_in.value.charAt(dotpos)%20!=%20'.')%20{\n%20%20%20%20%20%20%20%20dotpos%20=%20caret;\n//dump(\%22changed%20dot%20pos:%20\%22%20+%20dotpos%20+%20\%22\\n\%22);\n%20%20%20%20%20%20}\n\n%20%20%20%20%20%20//%20look%20backwards%20for%20a%20non-variable-name%20character\n%20%20%20%20%20%20spacepos%20=%20findbeginning(_in.value,%20dotpos-1,%20false);\n%20%20%20%20%20%20//dump(\%22space%20pos:%20\%22%20+%20spacepos%20+%20\%22\\n\%22);\n%20%20%20%20%20%20//%20get%20the%20object%20we're%20trying%20to%20complete%20on\n%20%20%20%20%20%20if(spacepos%20==%20dotpos%20||%20spacepos+1%20==%20dotpos%20||%20dotpos%20==%20caret)\n%20%20%20%20%20%20{\n%20%20%20%20%20%20%20%20//%20try%20completing%20function%20args\n%20%20%20%20%20%20%20%20if(_in.value.charAt(dotpos)%20==%20'('%20||\n%20(_in.value.charAt(spacepos)%20==%20'('%20&&%20(spacepos+1)%20==%20dotpos))\n%20%20%20%20%20%20%20%20{\n%20%20%20%20%20%20%20%20%20%20var%20fn,fname;\n%20%20var%20from%20=%20(_in.value.charAt(dotpos)%20==%20'(')%20?%20dotpos%20:%20spacepos;\n%20%20%20%20%20%20%20%20%20%20spacepos%20=%20findbeginning(_in.value,%20from-1,%20false);\n\n%20%20%20%20%20%20%20%20%20%20fname%20=%20_in.value.substr(spacepos+1,from-(spacepos+1));\n%20%20//dump(\%22fname:%20\%22%20+%20fname%20+%20\%22\\n\%22);\n%20%20%20%20%20%20%20%20%20%20try%20{\n%20%20%20%20%20%20%20%20%20%20%20%20with(_win.Shell._scope)\n%20%20%20%20%20%20%20%20%20%20%20%20%20%20with(_win)\n%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20with(Shell.shellCommands)\n%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fn%20=%20eval(fname);\n%20%20%20%20%20%20%20%20%20%20}\n%20%20%20%20%20%20%20%20%20%20catch(er)%20{\n%20%20%20%20%20%20%20%20%20%20%20%20//dump('fn%20is%20not%20a%20valid%20object\\n');\n%20%20%20%20%20%20%20%20%20%20%20%20return;\n%20%20%20%20%20%20%20%20%20%20}\n%20%20%20%20%20%20%20%20%20%20if(fn%20==%20undefined)%20{\n%20%20%20%20%20%20%20%20%20%20%20%20%20//dump('fn%20is%20undefined');\n%20%20%20%20%20%20%20%20%20%20%20%20%20return;\n%20%20%20%20%20%20%20%20%20%20}\n%20%20%20%20%20%20%20%20%20%20if(fn%20instanceof%20Function)\n%20%20%20%20%20%20%20%20%20%20{\n%20%20%20%20%20%20%20%20%20%20%20%20//%20Print%20function%20definition,%20including%20argument%20names,%20but%20not%20function%20body\n%20%20%20%20%20%20%20%20%20%20%20%20if(!fn.toString().match(/function%20.+?\\(\\)%20+\\{\\n%20+\\[native%20code\\]\\n\\}/))\n%20%20%20%20%20%20%20%20%20%20%20%20%20%20println(fn.toString().match(/function%20.+?\\(.*?\\)/),%20\%22tabcomplete\%22);\n%20%20%20%20%20%20%20%20%20%20}\n\n%20%20%20%20%20%20%20%20%20%20return;\n%20%20%20%20%20%20%20%20}\n%20%20%20%20%20%20%20%20else\n%20%20%20%20%20%20%20%20%20%20obj%20=%20_win;\n%20%20%20%20%20%20}\n%20%20%20%20%20%20else\n%20%20%20%20%20%20{\n%20%20%20%20%20%20%20%20var%20objname%20=%20_in.value.substr(spacepos+1,dotpos-(spacepos+1));\n%20%20%20%20%20%20%20%20//dump(\%22objname:%20|\%22%20+%20objname%20+%20\%22|\\n\%22);\n%20%20%20%20%20%20%20%20try%20{\n%20%20%20%20%20%20%20%20%20%20with(_win.Shell._scope)\n%20%20%20%20%20%20%20%20%20%20%20%20with(_win)\n%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20obj%20=%20eval(objname);\n%20%20%20%20%20%20%20%20}\n%20%20%20%20%20%20%20%20catch(er)%20{\n%20%20%20%20%20%20%20%20%20%20printError(er);%20\n%20%20%20%20%20%20%20%20%20%20return;\n%20%20%20%20%20%20%20%20}\n%20%20%20%20%20%20%20%20if(obj%20==%20undefined)%20{\n%20%20%20%20%20%20%20%20%20%20//%20sometimes%20this%20is%20tabcomplete's%20fault,%20so%20don't%20print%20it%20:(\n%20%20%20%20%20%20%20%20%20%20//%20e.g.%20completing%20from%20\%22print(document.getElements\%22\n%20%20%20%20%20%20%20%20%20%20//%20println(\%22Can't%20complete%20from%20null%20or%20undefined%20expression%20\%22%20+%20objname,%20\%22error\%22);\n%20%20%20%20%20%20%20%20%20%20return;\n%20%20%20%20%20%20%20%20}\n%20%20%20%20%20%20}\n%20%20%20%20%20%20//dump(\%22obj:%20\%22%20+%20obj%20+%20\%22\\n\%22);\n%20%20%20%20%20%20//%20get%20the%20thing%20we're%20trying%20to%20complete\n%20%20%20%20%20%20if(dotpos%20==%20caret)\n%20%20%20%20%20%20{\n%20%20%20%20%20%20%20%20if(spacepos+1%20==%20dotpos%20||%20spacepos%20==%20dotpos)\n%20%20%20%20%20%20%20%20{\n%20%20%20%20%20%20%20%20%20%20//%20nothing%20to%20complete\n%20%20%20%20%20%20%20%20%20%20//dump(\%22nothing%20to%20complete\\n\%22);\n%20%20%20%20%20%20%20%20%20%20return;\n%20%20%20%20%20%20%20%20}\n\n%20%20%20%20%20%20%20%20complete%20=%20_in.value.substr(spacepos+1,dotpos-(spacepos+1));\n%20%20%20%20%20%20}\n%20%20%20%20%20%20else%20{\n%20%20%20%20%20%20%20%20complete%20=%20_in.value.substr(dotpos+1,caret-(dotpos+1));\n%20%20%20%20%20%20}\n%20%20%20%20%20%20//dump(\%22complete:%20\%22%20+%20complete%20+%20\%22\\n\%22);\n%20%20%20%20%20%20//%20ok,%20now%20look%20at%20all%20the%20props/methods%20of%20this%20obj\n%20%20%20%20%20%20//%20and%20find%20ones%20starting%20with%20'complete'\n%20%20%20%20%20%20var%20matches%20=%20[];\n%20%20%20%20%20%20var%20bestmatch%20=%20null;\n%20%20%20%20%20%20for(var%20a%20in%20obj)\n%20%20%20%20%20%20{\n%20%20%20%20%20%20%20%20//a%20=%20a.toString();\n%20%20%20%20%20%20%20%20//XXX:%20making%20it%20lowercase%20could%20help%20some%20cases,\n%20%20%20%20%20%20%20%20//%20but%20screws%20up%20my%20general%20logic.\n%20%20%20%20%20%20%20%20if(a.substr(0,complete.length)%20==%20complete)%20{\n%20%20%20%20%20%20%20%20%20%20matches.push(a);\n%20%20%20%20%20%20%20%20%20%20////dump(\%22match:%20\%22%20+%20a%20+%20\%22\\n\%22);\n%20%20%20%20%20%20%20%20%20%20//%20if%20no%20best%20match,%20this%20is%20the%20best%20match\n%20%20%20%20%20%20%20%20%20%20if(bestmatch%20==%20null)\n%20%20%20%20%20%20%20%20%20%20{\n%20%20%20%20%20%20%20%20%20%20%20%20bestmatch%20=%20a;\n%20%20%20%20%20%20%20%20%20%20}\n%20%20%20%20%20%20%20%20%20%20else%20{\n%20%20%20%20%20%20%20%20%20%20%20%20//%20the%20best%20match%20is%20the%20longest%20common%20string\n%20%20%20%20%20%20%20%20%20%20%20%20function%20min(a,b){%20return%20((a%3Cb)?a:b);%20}\n%20%20%20%20%20%20%20%20%20%20%20%20var%20i;\n%20%20%20%20%20%20%20%20%20%20%20%20for(i=0;%20i%3C%20min(bestmatch.length,%20a.length);%20i++)\n%20%20%20%20%20%20%20%20%20%20%20%20{\n%20%20%20%20%20%20%20%20%20%20%20%20%20%20if(bestmatch.charAt(i)%20!=%20a.charAt(i))\n%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break;\n%20%20%20%20%20%20%20%20%20%20%20%20}\n%20%20%20%20%20%20%20%20%20%20%20%20bestmatch%20=%20bestmatch.substr(0,i);\n%20%20%20%20%20%20%20%20%20%20%20%20////dump(\%22bestmatch%20len:%20\%22%20+%20i%20+%20\%22\\n\%22);\n%20%20%20%20%20%20%20%20%20%20}\n%20%20%20%20%20%20%20%20%20%20////dump(\%22bestmatch:%20\%22%20+%20bestmatch%20+%20\%22\\n\%22);\n%20%20%20%20%20%20%20%20}\n%20%20%20%20%20%20}\n%20%20%20%20%20%20bestmatch%20=%20(bestmatch%20||%20\%22\%22);\n%20%20%20%20%20%20////dump(\%22matches:%20\%22%20+%20matches%20+%20\%22\\n\%22);\n%20%20%20%20%20%20var%20objAndComplete%20=%20(objname%20||%20obj)%20+%20\%22.\%22%20+%20bestmatch;\n%20%20%20%20%20%20//dump(\%22matches.length:%20\%22%20+%20matches.length%20+%20\%22,%20tooManyMatches:%20\%22%20+%20tooManyMatches%20+%20\%22,%20objAndComplete:%20\%22%20+%20objAndComplete%20+%20\%22\\n\%22);\n%20%20%20%20%20%20if(matches.length%20%3E%201%20&&%20(tooManyMatches%20==%20objAndComplete%20||%20matches.length%20%3C=%2010))%20{\n\n%20%20%20%20%20%20%20%20printWithRunin(\%22Matches:%20\%22,%20matches.join(',%20'),%20\%22tabcomplete\%22);\n%20%20%20%20%20%20%20%20tooManyMatches%20=%20null;\n%20%20%20%20%20%20}\n%20%20%20%20%20%20else%20if(matches.length%20%3E%2010)\n%20%20%20%20%20%20{\n%20%20%20%20%20%20%20%20println(matches.length%20+%20\%22%20matches.%20%20Press%20tab%20again%20to%20see%20them%20all\%22,%20\%22tabcomplete\%22);\n%20%20%20%20%20%20%20%20tooManyMatches%20=%20objAndComplete;\n%20%20%20%20%20%20}\n%20%20%20%20%20%20else%20{\n%20%20%20%20%20%20%20%20tooManyMatches%20=%20null;\n%20%20%20%20%20%20}\n%20%20%20%20%20%20if(bestmatch%20!=%20\%22\%22)\n%20%20%20%20%20%20{\n%20%20%20%20%20%20%20%20var%20sstart;\n%20%20%20%20%20%20%20%20if(dotpos%20==%20caret)%20{\n%20%20%20%20%20%20%20%20%20%20sstart%20=%20spacepos+1;\n%20%20%20%20%20%20%20%20}\n%20%20%20%20%20%20%20%20else%20{\n%20%20%20%20%20%20%20%20%20%20sstart%20=%20dotpos+1;\n%20%20%20%20%20%20%20%20}\n%20%20%20%20%20%20%20%20_in.value%20=%20_in.value.substr(0,%20sstart)\n%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20+%20bestmatch\n%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20+%20_in.value.substr(caret);\n%20%20%20%20%20%20%20%20setselectionto(_in,caret%20+%20(bestmatch.length%20-%20complete.length));\n%20%20%20%20%20%20}\n%20%20%20%20}\n}\n\nfunction%20printQuestion(q)\n{\n%20%20println(q,%20\%22input\%22);\n}\n\nfunction%20printAnswer(a)\n{\n%20%20if%20(a%20!==%20undefined)%20{\n%20%20%20%20println(a,%20\%22normalOutput\%22);\n%20%20%20%20shellCommands.ans%20=%20a;\n%20%20}\n}\n\nfunction%20printError(er)\n{%20\n%20%20var%20lineNumberString;\n\n%20%20lastError%20=%20er;%20//%20for%20debugging%20the%20shell\n%20%20if%20(er.name)\n%20%20{\n%20%20%20%20//%20lineNumberString%20should%20not%20be%20\%22\%22,%20to%20avoid%20a%20very%20wacky%20bug%20in%20IE%206.\n%20%20%20%20lineNumberString%20=%20(er.lineNumber%20!=%20undefined)%20?%20(\%22%20on%20line%20\%22%20+%20er.lineNumber%20+%20\%22:%20\%22)%20:%20\%22:%20\%22;\n%20%20%20%20println(er.name%20+%20lineNumberString%20+%20er.message,%20\%22error\%22);%20//%20Because%20IE%20doesn't%20have%20error.toString.\n%20%20}\n%20%20else\n%20%20%20%20println(er,%20\%22error\%22);%20//%20Because%20security%20errors%20in%20Moz%20/only/%20have%20toString.\n}\n\nfunction%20go(s)\n{\n%20%20_in.value%20=%20question%20=%20s%20?%20s%20:%20_in.value;\n\n%20%20if%20(question%20==%20\%22\%22)\n%20%20%20%20return;\n\n%20%20histList[histList.length-1]%20=%20question;\n%20%20histList[histList.length]%20=%20\%22\%22;\n%20%20histPos%20=%20histList.length%20-%201;\n%20%20\n%20%20//%20Unfortunately,%20this%20has%20to%20happen%20*before*%20the%20JavaScript%20is%20run,%20so%20that%20\n%20%20//%20print()%20output%20will%20go%20in%20the%20right%20place.\n%20%20_in.value='';\n%20%20recalculateInputHeight();\n%20%20printQuestion(question);\n\n%20%20if%20(_win.closed)%20{\n%20%20%20%20printError(\%22Target%20window%20has%20been%20closed.\%22);\n%20%20%20%20return;\n%20%20}\n%20%20\n%20%20try%20{%20(\%22Shell\%22%20in%20_win)%20}\n%20%20catch(er)%20{\n%20%20%20%20printError(\%22The%20JavaScript%20Shell%20cannot%20access%20variables%20in%20the%20target%20window.%20%20The%20most%20likely%20reason%20is%20that%20the%20target%20window%20now%20has%20a%20different%20page%20loaded%20and%20that%20page%20has%20a%20different%20hostname%20than%20the%20original%20page.\%22);\n%20%20%20%20return;\n%20%20}\n\n%20%20if%20(!(\%22Shell\%22%20in%20_win))\n%20%20%20%20initTarget();%20//%20silent\n\n%20%20//%20Evaluate%20Shell.question%20using%20_win's%20eval%20(this%20is%20why%20eval%20isn't%20in%20the%20|with|,%20IIRC).\n%20%20_win.location.href%20=%20\%22javascript:try{%20Shell.printAnswer(eval('with(Shell._scope)%20with(Shell.shellCommands)%20{'%20+%20Shell.question%20+%20String.fromCharCode(10)%20+%20'}'));%20}%20catch(er)%20{%20Shell.printError(er);%20};%20setTimeout(Shell.refocus,%200);%20void%200\%22;\n}\n\n%3C/script%3E\n\n%3C!--%20for%20http://ted.mielczarek.org/code/mozilla/extensiondev/%20--%3E\n%3Cscript%20type=\%22text/javascript\%22%20src=\%22chrome://extensiondev/content/rdfhistory.js\%22%3E%3C/script%3E\n%3Cscript%20type=\%22text/javascript\%22%20src=\%22chrome://extensiondev/content/chromeShellExtras.js\%22%3E%3C/script%3E\n\n%3Cstyle%20type=\%22text/css\%22%3E\nbody%20{%20background:%20white;%20color:%20black;%20}\n\n#output%20{%20white-space:%20pre;%20white-space:%20-moz-pre-wrap;%20}%20/*%20Preserve%20line%20breaks,%20but%20wrap%20too%20if%20browser%20supports%20it%20*/\nh3%20{%20margin-top:%200;%20margin-bottom:%200em;%20}\nh3%20+%20div%20{%20margin:%200;%20}\n\nform%20{%20margin:%200;%20padding:%200;%20}\n%23input%20{%20width:%20100%25;%20border:%20none;%20padding:%200;%20overflow:%20auto;%20}\n\n.input%20{%20color:%20blue;%20background:%20white;%20font:%20inherit;%20font-weight:%20bold;%20margin-top:%20.5em;%20/*%20background:%20%23E6E6FF;%20*/%20}\n.normalOutput%20{%20color:%20black;%20background:%20white;%20}\n.print%20{%20color:%20brown;%20background:%20white;%20}\n.error%20{%20color:%20red;%20background:%20white;%20}\n.propList%20{%20color:%20green;%20background:%20white;%20}\n.message%20{%20color:%20green;%20background:%20white;%20}\n.tabcomplete%20{%20color:%20purple;%20background:%20white;%20}\n%3C/style%3E\n%3C/head%3E\n\n%3Cbody%20onload=\%22init()\%22%3E\n\n%3Cdiv%20id=\%22output\%22%3E%3Ch3%3EJavaScript%20Shell%201.4%3C/h3%3E%3Cdiv%3EFeatures:%20autocompletion%20of%20property%20names%20with%20Tab,%20multiline%20input%20with%20Shift+Enter,%20input%20history%20with%20(Ctrl+)%20Up/Down,%20%3Ca%20accesskey=\%22M\%22%20href=\%22javascript:go('scope(Math);%20mathHelp();');\%22%20title=\%22Accesskey:%20M\%22%3EMath%3C/a%3E,%20%3Ca%20accesskey=\%22H\%22%20href=\%22http://www.squarefree.com/shell/?ignoreReferrerFrom=shell1.4\%22%20%20title=\%22Accesskey:%20H\%22%3Ehelp%3C/a%3E%3C/div%3E%3Cdiv%3EValues%20and%20functions:%20ans,%20print(string),%20%3Ca%20accesskey=\%22P\%22%20href=\%22javascript:go('props(ans)')\%22%20title=\%22Accesskey:%20P\%22%3Eprops(object)%3C/a%3E,%20%3Ca%20accesskey=\%22B\%22%20href=\%22javascript:go('blink(ans)')\%22%20title=\%22Accesskey:%20B\%22%3Eblink(node)%3C/a%3E,%20%3Ca%20accesskey=\%22C\%22%20href=\%22javascript:go('clear()')\%22%20title=\%22Accesskey:%20C\%22%3Eclear()%3C/a%3E,%20load(scriptURL),%20scope(object)%3C/div%3E%3C/div%3E\n\n%3Cdiv%3E%3Ctextarea%20id=\%22input\%22%20class=\%22input\%22%20wrap=\%22off\%22%20onkeydown=\%22inputKeydown(event)\%22%20rows=\%221\%22%3E%3C/textarea%3E%3C/div%3E\n\n%3C/body%3E\n\n%3C/html%3E%22);document.close();}void%200


获取更多Bookmarklet


转载声明: 出自: Ghoul To World!作者: GreatGhoul

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.