Background: #fff
Foreground: #000
PrimaryPale: #8cf
PrimaryLight: #18f
PrimaryMid: #04b
PrimaryDark: #014
SecondaryPale: #ffc
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #841
TertiaryPale: #eee
TertiaryLight: #ccc
TertiaryMid: #999
TertiaryDark: #666
Error: #f88
/*{{{*/
body {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}

a {color:[[ColorPalette::PrimaryMid]];}
a:hover {background-color:[[ColorPalette::PrimaryMid]]; color:[[ColorPalette::Background]];}
a img {border:0;}

h1,h2,h3,h4,h5,h6 {color:[[ColorPalette::SecondaryDark]]; background:transparent;}
h1 {border-bottom:2px solid [[ColorPalette::TertiaryLight]];}
h2,h3 {border-bottom:1px solid [[ColorPalette::TertiaryLight]];}

.button {color:[[ColorPalette::PrimaryDark]]; border:1px solid [[ColorPalette::Background]];}
.button:hover {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::SecondaryLight]]; border-color:[[ColorPalette::SecondaryMid]];}
.button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::SecondaryDark]];}

.header {background:[[ColorPalette::PrimaryMid]];}
.headerShadow {color:[[ColorPalette::Foreground]];}
.headerShadow a {font-weight:normal; color:[[ColorPalette::Foreground]];}
.headerForeground {color:[[ColorPalette::Background]];}
.headerForeground a {font-weight:normal; color:[[ColorPalette::PrimaryPale]];}

.tabSelected{color:[[ColorPalette::PrimaryDark]];
	background:[[ColorPalette::TertiaryPale]];
	border-left:1px solid [[ColorPalette::TertiaryLight]];
	border-top:1px solid [[ColorPalette::TertiaryLight]];
	border-right:1px solid [[ColorPalette::TertiaryLight]];
}
.tabUnselected {color:[[ColorPalette::Background]]; background:[[ColorPalette::TertiaryMid]];}
.tabContents {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::TertiaryPale]]; border:1px solid [[ColorPalette::TertiaryLight]];}
.tabContents .button {border:0;}

#sidebar {}
#sidebarOptions input {border:1px solid [[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel {background:[[ColorPalette::PrimaryPale]];}
#sidebarOptions .sliderPanel a {border:none;color:[[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel a:hover {color:[[ColorPalette::Background]]; background:[[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel a:active {color:[[ColorPalette::PrimaryMid]]; background:[[ColorPalette::Background]];}

.wizard {background:[[ColorPalette::PrimaryPale]]; border:1px solid [[ColorPalette::PrimaryMid]];}
.wizard h1 {color:[[ColorPalette::PrimaryDark]]; border:none;}
.wizard h2 {color:[[ColorPalette::Foreground]]; border:none;}
.wizardStep {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];
	border:1px solid [[ColorPalette::PrimaryMid]];}
.wizardStep.wizardStepDone {background:[[ColorPalette::TertiaryLight]];}
.wizardFooter {background:[[ColorPalette::PrimaryPale]];}
.wizardFooter .status {background:[[ColorPalette::PrimaryDark]]; color:[[ColorPalette::Background]];}
.wizard .button {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryLight]]; border: 1px solid;
	border-color:[[ColorPalette::SecondaryPale]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryPale]];}
.wizard .button:hover {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Background]];}
.wizard .button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::Foreground]]; border: 1px solid;
	border-color:[[ColorPalette::PrimaryDark]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryDark]];}

#messageArea {border:1px solid [[ColorPalette::SecondaryMid]]; background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]];}
#messageArea .button {color:[[ColorPalette::PrimaryMid]]; background:[[ColorPalette::SecondaryPale]]; border:none;}

.popupTiddler {background:[[ColorPalette::TertiaryPale]]; border:2px solid [[ColorPalette::TertiaryMid]];}

.popup {background:[[ColorPalette::TertiaryPale]]; color:[[ColorPalette::TertiaryDark]]; border-left:1px solid [[ColorPalette::TertiaryMid]]; border-top:1px solid [[ColorPalette::TertiaryMid]]; border-right:2px solid [[ColorPalette::TertiaryDark]]; border-bottom:2px solid [[ColorPalette::TertiaryDark]];}
.popup hr {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::PrimaryDark]]; border-bottom:1px;}
.popup li.disabled {color:[[ColorPalette::TertiaryMid]];}
.popup li a, .popup li a:visited {color:[[ColorPalette::Foreground]]; border: none;}
.popup li a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border: none;}
.popup li a:active {background:[[ColorPalette::SecondaryPale]]; color:[[ColorPalette::Foreground]]; border: none;}
.popupHighlight {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
.listBreak div {border-bottom:1px solid [[ColorPalette::TertiaryDark]];}

.tiddler .defaultCommand {font-weight:bold;}

.shadow .title {color:[[ColorPalette::TertiaryDark]];}

.title {color:[[ColorPalette::SecondaryDark]];}
.subtitle {color:[[ColorPalette::TertiaryDark]];}

.toolbar {color:[[ColorPalette::PrimaryMid]];}
.toolbar a {color:[[ColorPalette::TertiaryLight]];}
.selected .toolbar a {color:[[ColorPalette::TertiaryMid]];}
.selected .toolbar a:hover {color:[[ColorPalette::Foreground]];}

.tagging, .tagged {border:1px solid [[ColorPalette::TertiaryPale]]; background-color:[[ColorPalette::TertiaryPale]];}
.selected .tagging, .selected .tagged {background-color:[[ColorPalette::TertiaryLight]]; border:1px solid [[ColorPalette::TertiaryMid]];}
.tagging .listTitle, .tagged .listTitle {color:[[ColorPalette::PrimaryDark]];}
.tagging .button, .tagged .button {border:none;}

.footer {color:[[ColorPalette::TertiaryLight]];}
.selected .footer {color:[[ColorPalette::TertiaryMid]];}

.sparkline {background:[[ColorPalette::PrimaryPale]]; border:0;}
.sparktick {background:[[ColorPalette::PrimaryDark]];}

.error, .errorButton {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Error]];}
.warning {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryPale]];}
.lowlight {background:[[ColorPalette::TertiaryLight]];}

.zoomer {background:none; color:[[ColorPalette::TertiaryMid]]; border:3px solid [[ColorPalette::TertiaryMid]];}

.imageLink, #displayArea .imageLink {background:transparent;}

.annotation {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border:2px solid [[ColorPalette::SecondaryMid]];}

.viewer .listTitle {list-style-type:none; margin-left:-2em;}
.viewer .button {border:1px solid [[ColorPalette::SecondaryMid]];}
.viewer blockquote {border-left:3px solid [[ColorPalette::TertiaryDark]];}

.viewer table, table.twtable {border:2px solid [[ColorPalette::TertiaryDark]];}
.viewer th, .viewer thead td, .twtable th, .twtable thead td {background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::Background]];}
.viewer td, .viewer tr, .twtable td, .twtable tr {border:1px solid [[ColorPalette::TertiaryDark]];}

.viewer pre {border:1px solid [[ColorPalette::SecondaryLight]]; background:[[ColorPalette::SecondaryPale]];}
.viewer code {color:[[ColorPalette::SecondaryDark]];}
.viewer hr {border:0; border-top:dashed 1px [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::TertiaryDark]];}

.highlight, .marked {background:[[ColorPalette::SecondaryLight]];}

.editor input {border:1px solid [[ColorPalette::PrimaryMid]];}
.editor textarea {border:1px solid [[ColorPalette::PrimaryMid]]; width:100%;}
.editorFooter {color:[[ColorPalette::TertiaryMid]];}

#backstageArea {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::TertiaryMid]];}
#backstageArea a {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
#backstageArea a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; }
#backstageArea a.backstageSelTab {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
#backstageButton a {background:none; color:[[ColorPalette::Background]]; border:none;}
#backstageButton a:hover {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
#backstagePanel {background:[[ColorPalette::Background]]; border-color: [[ColorPalette::Background]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]];}
.backstagePanelFooter .button {border:none; color:[[ColorPalette::Background]];}
.backstagePanelFooter .button:hover {color:[[ColorPalette::Foreground]];}
#backstageCloak {background:[[ColorPalette::Foreground]]; opacity:0.6; filter:'alpha(opacity:60)';}
/*}}}*/
/*{{{*/
* html .tiddler {height:1%;}

body {font-size:.75em; font-family:arial,helvetica; margin:0; padding:0;}

h1,h2,h3,h4,h5,h6 {font-weight:bold; text-decoration:none;}
h1,h2,h3 {padding-bottom:1px; margin-top:1.2em;margin-bottom:0.3em;}
h4,h5,h6 {margin-top:1em;}
h1 {font-size:1.35em;}
h2 {font-size:1.25em;}
h3 {font-size:1.1em;}
h4 {font-size:1em;}
h5 {font-size:.9em;}

hr {height:1px;}

a {text-decoration:none;}

dt {font-weight:bold;}

ol {list-style-type:decimal;}
ol ol {list-style-type:lower-alpha;}
ol ol ol {list-style-type:lower-roman;}
ol ol ol ol {list-style-type:decimal;}
ol ol ol ol ol {list-style-type:lower-alpha;}
ol ol ol ol ol ol {list-style-type:lower-roman;}
ol ol ol ol ol ol ol {list-style-type:decimal;}

.txtOptionInput {width:11em;}

#contentWrapper .chkOptionInput {border:0;}

.externalLink {text-decoration:underline;}

.indent {margin-left:3em;}
.outdent {margin-left:3em; text-indent:-3em;}
code.escaped {white-space:nowrap;}

.tiddlyLinkExisting {font-weight:bold;}
.tiddlyLinkNonExisting {font-style:italic;}

/* the 'a' is required for IE, otherwise it renders the whole tiddler in bold */
a.tiddlyLinkNonExisting.shadow {font-weight:bold;}

#mainMenu .tiddlyLinkExisting,
	#mainMenu .tiddlyLinkNonExisting,
	#sidebarTabs .tiddlyLinkNonExisting {font-weight:normal; font-style:normal;}
#sidebarTabs .tiddlyLinkExisting {font-weight:bold; font-style:normal;}

.header {position:relative;}
.header a:hover {background:transparent;}
.headerShadow {position:relative; padding:4.5em 0em 1em 1em; left:-1px; top:-1px;}
.headerForeground {position:absolute; padding:4.5em 0em 1em 1em; left:0px; top:0px;}

.siteTitle {font-size:3em;}
.siteSubtitle {font-size:1.2em;}

#mainMenu {position:absolute; left:0; width:10em; text-align:right; line-height:1.6em; padding:1.5em 0.5em 0.5em 0.5em; font-size:1.1em;}

#sidebar {position:absolute; right:3px; width:16em; font-size:.9em;}
#sidebarOptions {padding-top:0.3em;}
#sidebarOptions a {margin:0em 0.2em; padding:0.2em 0.3em; display:block;}
#sidebarOptions input {margin:0.4em 0.5em;}
#sidebarOptions .sliderPanel {margin-left:1em; padding:0.5em; font-size:.85em;}
#sidebarOptions .sliderPanel a {font-weight:bold; display:inline; padding:0;}
#sidebarOptions .sliderPanel input {margin:0 0 .3em 0;}
#sidebarTabs .tabContents {width:15em; overflow:hidden;}

.wizard {padding:0.1em 1em 0em 2em;}
.wizard h1 {font-size:2em; font-weight:bold; background:none; padding:0em 0em 0em 0em; margin:0.4em 0em 0.2em 0em;}
.wizard h2 {font-size:1.2em; font-weight:bold; background:none; padding:0em 0em 0em 0em; margin:0.4em 0em 0.2em 0em;}
.wizardStep {padding:1em 1em 1em 1em;}
.wizard .button {margin:0.5em 0em 0em 0em; font-size:1.2em;}
.wizardFooter {padding:0.8em 0.4em 0.8em 0em;}
.wizardFooter .status {padding:0em 0.4em 0em 0.4em; margin-left:1em;}
.wizard .button {padding:0.1em 0.2em 0.1em 0.2em;}

#messageArea {position:fixed; top:2em; right:0em; margin:0.5em; padding:0.5em; z-index:2000; _position:absolute;}
.messageToolbar {display:block; text-align:right; padding:0.2em 0.2em 0.2em 0.2em;}
#messageArea a {text-decoration:underline;}

.tiddlerPopupButton {padding:0.2em 0.2em 0.2em 0.2em;}
.popupTiddler {position: absolute; z-index:300; padding:1em 1em 1em 1em; margin:0;}

.popup {position:absolute; z-index:300; font-size:.9em; padding:0; list-style:none; margin:0;}
.popup .popupMessage {padding:0.4em;}
.popup hr {display:block; height:1px; width:auto; padding:0; margin:0.2em 0em;}
.popup li.disabled {padding:0.4em;}
.popup li a {display:block; padding:0.4em; font-weight:normal; cursor:pointer;}
.listBreak {font-size:1px; line-height:1px;}
.listBreak div {margin:2px 0;}

.tabset {padding:1em 0em 0em 0.5em;}
.tab {margin:0em 0em 0em 0.25em; padding:2px;}
.tabContents {padding:0.5em;}
.tabContents ul, .tabContents ol {margin:0; padding:0;}
.txtMainTab .tabContents li {list-style:none;}
.tabContents li.listLink { margin-left:.75em;}

#contentWrapper {display:block;}
#splashScreen {display:none;}

#displayArea {margin:1em 17em 0em 14em;}

.toolbar {text-align:right; font-size:.9em;}

.tiddler {padding:1em 1em 0em 1em;}

.missing .viewer,.missing .title {font-style:italic;}

.title {font-size:1.6em; font-weight:bold;}

.missing .subtitle {display:none;}
.subtitle {font-size:1.1em;}

.tiddler .button {padding:0.2em 0.4em;}

.tagging {margin:0.5em 0.5em 0.5em 0; float:left; display:none;}
.isTag .tagging {display:block;}
.tagged {margin:0.5em; float:right;}
.tagging, .tagged {font-size:0.9em; padding:0.25em;}
.tagging ul, .tagged ul {list-style:none; margin:0.25em; padding:0;}
.tagClear {clear:both;}

.footer {font-size:.9em;}
.footer li {display:inline;}

.annotation {padding:0.5em; margin:0.5em;}

* html .viewer pre {width:99%; padding:0 0 1em 0;}
.viewer {line-height:1.4em; padding-top:0.5em;}
.viewer .button {margin:0em 0.25em; padding:0em 0.25em;}
.viewer blockquote {line-height:1.5em; padding-left:0.8em;margin-left:2.5em;}
.viewer ul, .viewer ol {margin-left:0.5em; padding-left:1.5em;}

.viewer table, table.twtable {border-collapse:collapse; margin:0.8em 1.0em;}
.viewer th, .viewer td, .viewer tr,.viewer caption,.twtable th, .twtable td, .twtable tr,.twtable caption {padding:3px;}
table.listView {font-size:0.85em; margin:0.8em 1.0em;}
table.listView th, table.listView td, table.listView tr {padding:0px 3px 0px 3px;}

.viewer pre {padding:0.5em; margin-left:0.5em; font-size:1.2em; line-height:1.4em; overflow:auto;}
.viewer code {font-size:1.2em; line-height:1.4em;}

.editor {font-size:1.1em;}
.editor input, .editor textarea {display:block; width:100%; font:inherit;}
.editorFooter {padding:0.25em 0em; font-size:.9em;}
.editorFooter .button {padding-top:0px; padding-bottom:0px;}

.fieldsetFix {border:0; padding:0; margin:1px 0px 1px 0px;}

.sparkline {line-height:1em;}
.sparktick {outline:0;}

.zoomer {font-size:1.1em; position:absolute; overflow:hidden;}
.zoomer div {padding:1em;}

* html #backstage {width:99%;}
* html #backstageArea {width:99%;}
#backstageArea {display:none; position:relative; overflow: hidden; z-index:150; padding:0.3em 0.5em 0.3em 0.5em;}
#backstageToolbar {position:relative;}
#backstageArea a {font-weight:bold; margin-left:0.5em; padding:0.3em 0.5em 0.3em 0.5em;}
#backstageButton {display:none; position:absolute; z-index:175; top:0em; right:0em;}
#backstageButton a {padding:0.1em 0.4em 0.1em 0.4em; margin:0.1em 0.1em 0.1em 0.1em;}
#backstage {position:relative; width:100%; z-index:50;}
#backstagePanel {display:none; z-index:100; position:absolute; margin:0em 3em 0em 3em; padding:1em 1em 1em 1em;}
.backstagePanelFooter {padding-top:0.2em; float:right;}
.backstagePanelFooter a {padding:0.2em 0.4em 0.2em 0.4em;}
#backstageCloak {display:none; z-index:20; position:absolute; width:100%; height:100px;}

.whenBackstage {display:none;}
.backstageVisible .whenBackstage {display:block;}
/*}}}*/
/***
StyleSheet for use when a translation requires any css style changes.
This StyleSheet can be used directly by languages such as Chinese, Japanese and Korean which use a logographic writing system and need larger font sizes.
***/

/*{{{*/
body {font-size:0.8em;}

#sidebarOptions {font-size:1.05em;}
#sidebarOptions a {font-style:normal;}
#sidebarOptions .sliderPanel {font-size:0.95em;}

.subtitle {font-size:0.8em;}

.viewer table.listView {font-size:0.95em;}

.htmlarea .toolbarHA table {border:1px solid ButtonFace; margin:0em 0em;}
/*}}}*/
/*{{{*/
@media print {
#mainMenu, #sidebar, #messageArea, .toolbar, #backstageButton, #backstageArea {display: none ! important;}
#displayArea {margin: 1em 1em 0em 1em;}
/* Fixes a feature in Firefox 1.5.0.2 where print preview displays the noscript content */
noscript {display:none;}
}
/*}}}*/
<!--{{{-->
<div class='header' macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryMid]]'>
<div class='headerShadow'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
<div class='headerForeground'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
</div>
<div id='mainMenu' refresh='content' tiddler='MainMenu'></div>
<div id='sidebar'>
<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>
<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>
</div>
<div id='displayArea'>
<div id='messageArea'></div>
<div id='tiddlerDisplay'></div>
</div>
<!--}}}-->
<!--{{{-->
<div class='toolbar' macro='toolbar closeTiddler closeOthers +editTiddler > fields syncing permalink references jump'></div>
<div class='title' macro='view title'></div>
<div class='subtitle'><span macro='view modifier link'></span>, <span macro='view modified date'></span> (<span macro='message views.wikified.createdPrompt'></span> <span macro='view created date'></span>)</div>
<div class='tagging' macro='tagging'></div>
<div class='tagged' macro='tags'></div>
<div class='viewer' macro='view text wikified'></div>
<div class='tagClear'></div>
<!--}}}-->
<!--{{{-->
<div class='toolbar' macro='toolbar +saveTiddler -cancelTiddler deleteTiddler'></div>
<div class='title' macro='view title'></div>
<div class='editor' macro='edit title'></div>
<div macro='annotations'></div>
<div class='editor' macro='edit text'></div>
<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser'></span></div>
<!--}}}-->
To get started with this blank TiddlyWiki, you'll need to modify the following tiddlers:
* SiteTitle & SiteSubtitle: The title and subtitle of the site, as shown above (after saving, they will also appear in the browser title bar)
* MainMenu: The menu (usually on the left)
* DefaultTiddlers: Contains the names of the tiddlers that you want to appear when the TiddlyWiki is opened
You'll also need to enter your username for signing your edits: <<option txtUserName>>
These InterfaceOptions for customising TiddlyWiki are saved in your browser

Your username for signing your edits. Write it as a WikiWord (eg JoeBloggs)

<<option txtUserName>>
<<option chkSaveBackups>> SaveBackups
<<option chkAutoSave>> AutoSave
<<option chkRegExpSearch>> RegExpSearch
<<option chkCaseSensitiveSearch>> CaseSensitiveSearch
<<option chkAnimate>> EnableAnimations

----
Also see AdvancedOptions
http://science.tiddlyspot.com/
plugins
http://tiddlywiki.abego-software.de/
http://twt-blackicity.tiddlyspot.com/index.html
<script>
 var tiddlerName = story.findContainingTiddler(place).id.substr(7);
 var title = tiddlerName;
 var t=store.getTiddler(tiddlerName);
 var tag = "";
 document.write("<b>"+tiddlerName+"</b><br>");
 document.write(t.tags+"<br>")
 if (!t || !t.tags) return;
 if (t.tags.find(tag)==null)
    {t.tags.push(tag)}
 document.write(t.tags+"<br>")
 document.write("tag.length="+tag.length)

</script>
<html>
<form action="tableaddrow_nw.html" method="get">
<p>
<input type="button" value="Add" onclick="addRowToTable();" />
<input type="button" value="Insert [I]" onclick="insertRowToTable();" />
<input type="button" value="Delete [D]" onclick="deleteChecked();" />
<input type="button" value="Submit" onclick="openInNewWindow(this.form);" />
</p>
<table border="0" cellspacing="0" id="tblSample22">
  <thead>
  <tr>
    <th colspan="5">Sample table</th>
  </tr>
  <tr>
    <th>#</th><th>Input Text</th><th>Delete</th><th>D</th><th>I</th>
  </tr>
  </thead>
  <tbody></tbody>
</table>
</form>
</html>

<script>
// tabledeleterow.js version 1.2 2006-02-21
// mredkj.com

// CONFIG notes. Below are some comments that point to where this script can be customized.
// Note: Make sure to include a <tbody></tbody> in your table's HTML

var INPUT_NAME_PREFIX = 'inputName'; // this is being set via script
var RADIO_NAME = 'totallyrad'; // this is being set via script
var TABLE_NAME = 'tblSample22'; // this should be named in the HTML
var ROW_BASE = 1; // first number (for display)
var hasLoaded = false;

window.onload=fillInRows;

function fillInRows()
{
	hasLoaded = true;
	addRowToTable();
	addRowToTable();
}

// CONFIG:
// myRowObject is an object for storing information about the table rows
function myRowObject(one, two, three, four)
{
	this.one = one; // text object
	this.two = two; // input text object
	this.three = three; // input checkbox object
	this.four = four; // input radio object
}

/*
 * insertRowToTable
 * Insert and reorder
 */
insertRowToTable = function ()
{
	if (hasLoaded) {
		var tbl = document.getElementById(TABLE_NAME);
		var rowToInsertAt = tbl.tBodies[0].rows.length;
		for (var i=0; i<tbl.tBodies[0].rows.length; i++) {
			if (tbl.tBodies[0].rows[i].myRow && tbl.tBodies[0].rows[i].myRow.four.getAttribute('type') == 'radio' && tbl.tBodies[0].rows[i].myRow.four.checked) {
				rowToInsertAt = i;
				break;
			}
		}
		addRowToTable(rowToInsertAt);
		reorderRows(tbl, rowToInsertAt);
	}
}

/*
 * addRowToTable
 * Inserts at row 'num', or appends to the end if no arguments are passed in. Don't pass in empty strings.
 */
addRowToTable = function(num)
{
	if (hasLoaded) {
		var tbl = document.getElementById(TABLE_NAME);
		var nextRow = tbl.tBodies[0].rows.length;
		var iteration = nextRow + ROW_BASE;
		if (num == null) { 
			num = nextRow;
		} else {
			iteration = num + ROW_BASE;
		}
		
		// add the row
		var row = tbl.tBodies[0].insertRow(num);
		
		// CONFIG: requires classes named classy0 and classy1
		row.className = 'classy' + (iteration % 2);
	
		// CONFIG: This whole section can be configured
		
		// cell 0 - text
		var cell0 = row.insertCell(0);
		var textNode = document.createTextNode(iteration);
		cell0.appendChild(textNode);
		
		// cell 1 - input text
		var cell1 = row.insertCell(1);
		var txtInp = document.createElement('input');
		txtInp.setAttribute('type', 'text');
		txtInp.setAttribute('name', INPUT_NAME_PREFIX + iteration);
		txtInp.setAttribute('size', '40');
		txtInp.setAttribute('value', iteration); // iteration included for debug purposes
		cell1.appendChild(txtInp);
		
		// cell 2 - input button
		var cell2 = row.insertCell(2);
		var btnEl = document.createElement('input');
		btnEl.setAttribute('type', 'button');
		btnEl.setAttribute('value', 'Delete');
		btnEl.onclick = function () {deleteCurrentRow(this)};
		cell2.appendChild(btnEl);
		
		// cell 3 - input checkbox
		var cell3 = row.insertCell(3);
		var cbEl = document.createElement('input');
		cbEl.setAttribute('type', 'checkbox');
		cell3.appendChild(cbEl);
		
		// cell 4 - input radio
		var cell4 = row.insertCell(4);
		var raEl;
		try {
			raEl = document.createElement('<input type="radio" name="' + RADIO_NAME + '" value="' + iteration + '">');
			var failIfNotIE = raEl.name.length;
		} catch(ex) {
			raEl = document.createElement('input');
			raEl.setAttribute('type', 'radio');
			raEl.setAttribute('name', RADIO_NAME);
			raEl.setAttribute('value', iteration);
		}
		cell4.appendChild(raEl);
		
		// Pass in the elements you want to reference later
		// Store the myRow object in each row
		row.myRow = new myRowObject(textNode, txtInp, cbEl, raEl);
	}
}

// CONFIG: this entire function is affected by myRowObject settings
// If there isn't a checkbox in your row, then this function can't be used.
deleteChecked =function()
{
	if (hasLoaded) {
		var checkedObjArray = new Array();
		var cCount = 0;
	
		var tbl = document.getElementById(TABLE_NAME);
		for (var i=0; i<tbl.tBodies[0].rows.length; i++) {
			if (tbl.tBodies[0].rows[i].myRow && tbl.tBodies[0].rows[i].myRow.three.getAttribute('type') == 'checkbox' && tbl.tBodies[0].rows[i].myRow.three.checked) {
				checkedObjArray[cCount] = tbl.tBodies[0].rows[i];
				cCount++;
			}
		}
		if (checkedObjArray.length > 0) {
			var rIndex = checkedObjArray[0].sectionRowIndex;
			deleteRows(checkedObjArray);
			reorderRows(tbl, rIndex);
		}
	}
}

// If there isn't an element with an onclick event in your row, then this function can't be used.
function deleteCurrentRow(obj)
{
	if (hasLoaded) {
		var delRow = obj.parentNode.parentNode;
		var tbl = delRow.parentNode.parentNode;
		var rIndex = delRow.sectionRowIndex;
		var rowArray = new Array(delRow);
		deleteRows(rowArray);
		reorderRows(tbl, rIndex);
	}
}

function reorderRows(tbl, startingIndex)
{
	if (hasLoaded) {
		if (tbl.tBodies[0].rows[startingIndex]) {
			var count = startingIndex + ROW_BASE;
			for (var i=startingIndex; i<tbl.tBodies[0].rows.length; i++) {
			
				// CONFIG: next line is affected by myRowObject settings
				tbl.tBodies[0].rows[i].myRow.one.data = count; // text
				
				// CONFIG: next line is affected by myRowObject settings
				tbl.tBodies[0].rows[i].myRow.two.name = INPUT_NAME_PREFIX + count; // input text
				
				// CONFIG: next line is affected by myRowObject settings
				var tempVal = tbl.tBodies[0].rows[i].myRow.two.value.split(' '); // for debug purposes
				tbl.tBodies[0].rows[i].myRow.two.value = count + ' was' + tempVal[0]; // for debug purposes
				
				// CONFIG: next line is affected by myRowObject settings
				tbl.tBodies[0].rows[i].myRow.four.value = count; // input radio
				
				// CONFIG: requires class named classy0 and classy1
				tbl.tBodies[0].rows[i].className = 'classy' + (count % 2);
				
				count++;
			}
		}
	}
}

function deleteRows(rowObjArray)
{
	if (hasLoaded) {
		for (var i=0; i<rowObjArray.length; i++) {
			var rIndex = rowObjArray[i].sectionRowIndex;
			rowObjArray[i].parentNode.deleteRow(rIndex);
		}
	}
}

function openInNewWindow(frm)
{
	// open a blank window
	var aWindow = window.open('', 'TableAddRow2NewWindow',
	'scrollbars=yes,menubar=yes,resizable=yes,toolbar=no,width=400,height=400');
	
	// set the target to the blank window
	frm.target = 'TableAddRow2NewWindow';
	
	// submit
	frm.submit();
}
</script>
<<newTiddler label:'New' title:'New' text:{{"<<formTiddler InstrumentTemplate\>\>"}} tag: testing >>
<script show>
 alert('InlineJavascriptPlugin: this is a demonstration message');
</script>
<<tiddler PopupTiddlersByAuthor>>
http://tiddlyhome.bidix.info/systemServer/NewsWiki.html
/%
|Name|AutoRefresh|
|Source|http://www.TiddlyTools.com/#AutoRefresh|
|Version|0.6.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <<br>>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|script|
|Requires|InlineJavascriptPlugin|
|Overrides||
|Description|enable/disable auto-refresh of selected content to force/prevent re-rendering when tiddler changes occur|

usage:
	<<tiddler AutoRefresh with: mode id>>

where:
	mode - (optional) is one of:
		off (or disable) - prevent refresh of rendered content (except when PageTemplate is changed!)
		on (or enable)- re-render content whenever corresponding tiddler source is changed
		force - re-render content whenever ANY tiddler content is changes (or refreshDisplay() is triggered)
	id - (optional)
		is a unique DOM element identifier on which to operate.
		If not specified, the current tiddler (or containing parent if not in a tiddler) is used.

%/<script>
	var here=story.findContainingTiddler(place);
	if (here) { // in a tiddler, get containing viewer element
		var here=place; while (here && here.className!='viewer') here=here.parentNode;
		if (!here) return; // no 'viewer' element (perhaps a custom template?)
	}
	else here=place.parentNode; // not in a tiddler, use immediate parent container

	// if DOM id param, get element by ID instead of using container
	if ("$2"!="$"+"2") var here=document.getElementById("$2");

	if (!here) return; // safety check

	var mode="$1"; if (mode=="$"+"1") mode="on";

	switch (mode.toLowerCase()) {
		case 'on':
		case 'enable':
		case 'force':
			var title=here.getAttribute("tiddler");
			if (!title) { // find source tiddler title
				var tid=story.findContainingTiddler(place);
				if (!tid) return; // can't determine source tiddler
				title=tid.getAttribute("tiddler");
			}
			here.setAttribute("tiddler",title);
			here.setAttribute("refresh","content");
			here.setAttribute("force",(mode=='force')?"true":"");
			break;
		case 'off':
		case 'disable':
			here.setAttribute("refresh","");
			here.setAttribute("force","");
			break;
	}
</script>
{{niceTable{
|!r1c1|r1c2|
|!r2c1|r2c2|
|!r3c1|r3c2|
|!r4c1|r4c2|
}}}
[[Continents]]
<script src="demo.js" show>
 return "loading demo.js..."
</script>

<script label="click to execute demo() function" show>
 demo()
</script>
<<tiddlerTweaker>>
<script>
changeText=function ()
{
var x=document.getElementById("mySelect");
x.options[x.selectedIndex].text="Melon";
}
</script>
<html>
<head>
</head>
<body>

<form>
Select your favorite fruit:
<select id="mySelect">
  <option>Apple</option>
  <option>Orange</option>
  <option>Pineapple</option>
  <option>Banana</option>
</select>
<br /><br />
<input type="button" onclick="changeText()" value="Set text of selected option">
</form>

</body>
</html>
<html>
<form name="txtComboForm2">
<input type="text" id="mySelect" size="25" name="txtBox">
<input type="button"  name="B1" value="..." onclick="changeText('new Text')">
<input type="reset" name="B2" value="Reset">
</form>
</html>

<script>
popText = function(str)
{
//document.example.answer.value = "100"
//eval(document.example.calculator.value)
alert(str);
document.txtComboForm2.txtBox.value = str;
//a = popup(MainMenu, "MainMenu$");
// <<popup MainMenu [[<<tiddler MainMenu$))]]>>
}

changeText=function (str)
{
var x=document.getElementById("mySelect");
x.value=str;
}


</script>
[[ChangeText]]
<html>
<form name="txtComboForm2">
<input type="text" id="mySelect" size="25" name="txtBox">
<input type="button" name="B1" value="..." onclick="changeText('1234567890')">
<input type="button" name="B2" value="Reset" onclick="changeText('')">
</form>
</html>

<script>
popText = function(str)
{
//document.example.answer.value = "100"
//eval(document.example.calculator.value)
alert(str);
document.txtComboForm2.txtBox.value = str;
//a = popup(MainMenu, "MainMenu$");
// <<popup MainMenu [[<<tiddler MainMenu$))]]>>
}

changeText=function(str)
{
var x=document.getElementById("mySelect");
//x.value=str;
//document.txtBox.value="yyyy";
var tid=story.findContainingTiddler(place);
title=tid.getAttribute("tiddler");
DataTiddler.setData(title,"txtBox",str)
story.refreshTiddler(title,null,true);
}
</script><data>{"txtBox":"1234567890"}</data>
    * [[checkbox group]]
    * [[checkboxGroupTemplate]]
/***
|Name|CheckboxPlugin|
|Source|http://www.TiddlyTools.com/#CheckboxPlugin|
|Documentation|http://www.TiddlyTools.com/#CheckboxPluginInfo|
|Version|2.4.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|Add checkboxes to your tiddler content|
This plugin extends the TiddlyWiki syntax to allow definition of checkboxes that can be embedded directly in tiddler content.  Checkbox states are preserved by:
* by setting/removing tags on specified tiddlers,
* or, by setting custom field values on specified tiddlers,
* or, by saving to a locally-stored cookie ID,
* or, automatically modifying the tiddler content (deprecated)
When an ID is assigned to the checkbox, it enables direct programmatic access to the checkbox DOM element, as well as creating an entry in TiddlyWiki's config.options[ID] internal data.  In addition to tracking the checkbox state, you can also specify custom javascript for programmatic initialization and onClick event handling for any checkbox, so you can provide specialized side-effects in response to state changes.
!!!!!Documentation
>see [[CheckboxPluginInfo]]
!!!!!Revision History
<<<
2008.01.08 [*.*.*] plugin size reduction: documentation moved to [[CheckboxPluginInfo]]
2008.01.05 [2.4.0] set global "window.place" to current checkbox element when processing checkbox clicks.  This allows init/beforeClick/afterClick handlers to reference RELATIVE elements, including using "story.findContainingTiddler(place)".  Also, wrap handlers in "function()" so "return" can be used within handler code.
|please see [[CheckboxPluginHistory]] for additional revision details|
2005.12.07 [0.9.0] initial BETA release
<<<
!!!!!Code
***/
//{{{
version.extensions.CheckboxPlugin = {major: 2, minor: 4, revision:0 , date: new Date(2008,1,5)};
//}}}
//{{{
config.checkbox = { refresh: { tagged:true, tagging:true, container:true } };
config.formatters.push( {
	name: "checkbox",
	match: "\\[[xX_ ][\\]\\=\\(\\{]",
	lookahead: "\\[([xX_ ])(=[^\\s\\(\\]{]+)?(\\([^\\)]*\\))?({[^}]*})?({[^}]*})?({[^}]*})?\\]",
	handler: function(w) {
		var lookaheadRegExp = new RegExp(this.lookahead,"mg");
		lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = lookaheadRegExp.exec(w.source)
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
			// get params
			var checked=(lookaheadMatch[1].toUpperCase()=="X");
			var id=lookaheadMatch[2];
			var target=lookaheadMatch[3];
			if (target) target=target.substr(1,target.length-2).trim(); // trim off parentheses
			var fn_init=lookaheadMatch[4];
			var fn_clickBefore=lookaheadMatch[5];
			var fn_clickAfter=lookaheadMatch[6];
			var tid=story.findContainingTiddler(w.output);  if (tid) tid=tid.getAttribute("tiddler");
			var srctid=w.tiddler?w.tiddler.title:null;
			config.macros.checkbox.create(w.output,tid,srctid,w.matchStart+1,checked,id,target,config.checkbox.refresh,fn_init,fn_clickBefore,fn_clickAfter);
			w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
		}
	}
} );
config.macros.checkbox = {
	handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		if(!(tiddler instanceof Tiddler)) { // if no tiddler passed in try to find one
			var here=story.findContainingTiddler(place);
			if (here) tiddler=store.getTiddler(here.getAttribute("tiddler"))
		}
		var srcpos=0; // "inline X" not applicable to macro syntax
		var target=params.shift(); if (!target) target="";
		var defaultState=params[0]=="checked"; if (defaultState) params.shift();
		var id=params.shift(); if (id && !id.length) id=null;
		var fn_init=params.shift(); if (fn_init && !fn_init.length) fn_init=null;
		var fn_clickBefore=params.shift();
		if (fn_clickBefore && !fn_clickBefore.length) fn_clickBefore=null;
		var fn_clickAfter=params.shift();
		if (fn_clickAfter && !fn_clickAfter.length) fn_clickAfter=null;
		var refresh={ tagged:true, tagging:true, container:false };
		this.create(place,tiddler.title,tiddler.title,0,defaultState,id,target,refresh,fn_init,fn_clickBefore,fn_clickAfter);
	},
	create: function(place,tid,srctid,srcpos,defaultState,id,target,refresh,fn_init,fn_clickBefore,fn_clickAfter) {
		// create checkbox element
		var c = document.createElement("input");
		c.setAttribute("type","checkbox");
		c.onclick=this.onClickCheckbox;
		c.srctid=srctid; // remember source tiddler
		c.srcpos=srcpos; // remember location of "X"
		c.container=tid; // containing tiddler (may be null if not in a tiddler)
		c.tiddler=tid; // default target tiddler 
		c.refresh = {};
		c.refresh.container = refresh.container;
		c.refresh.tagged = refresh.tagged;
		c.refresh.tagging = refresh.tagging;
		place.appendChild(c);
		// set default state
		c.checked=defaultState;
		// track state in config.options.ID
		if (id) {
			c.id=id.substr(1); // trim off leading "="
			if (config.options[c.id]!=undefined)
				c.checked=config.options[c.id];
			else
				config.options[c.id]=c.checked;
		}
		// track state in (tiddlername|tagname) or (fieldname@tiddlername)
		if (target) {
			var pos=target.indexOf("@");
			if (pos!=-1) {
				c.field=pos?target.substr(0,pos):"checked"; // get fieldname (or use default "checked")
				c.tiddler=target.substr(pos+1); // get specified tiddler name (if any)
				if (!c.tiddler || !c.tiddler.length) c.tiddler=tid; // if tiddler not specified, default == container
				if (store.getValue(c.tiddler,c.field)!=undefined)
					c.checked=(store.getValue(c.tiddler,c.field)=="true"); // set checkbox from saved state
			} else {
				var pos=target.indexOf("|"); if (pos==-1) var pos=target.indexOf(":");
				c.tag=target;
				if (pos==0) c.tag=target.substr(1); // trim leading "|" or ":"
				if (pos>0) { c.tiddler=target.substr(0,pos); c.tag=target.substr(pos+1); }
				if (!c.tag.length) c.tag="checked";
				var t=store.getTiddler(c.tiddler);
				if (t && t.tags)
					c.checked=t.isTagged(c.tag); // set checkbox from saved state
			}
		}
		// trim off surrounding { and } delimiters from init/click handlers
		if (fn_init) c.fn_init="(function(){"+fn_init.trim().substr(1,fn_init.length-2)+"})()";
		if (fn_clickBefore) c.fn_clickBefore="(function(){"+fn_clickBefore.trim().substr(1,fn_clickBefore.length-2)+"})()";
		if (fn_clickAfter) c.fn_clickAfter="(function(){"+fn_clickAfter.trim().substr(1,fn_clickAfter.length-2)+"})()";
		c.init=true; c.onclick(); c.init=false; // compute initial state and save in tiddler/config/cookie
	},
	onClickCheckbox: function(event) {
		window.place=this;
		if (this.init && this.fn_init) // custom function hook to set initial state (run only once)
			{ try { eval(this.fn_init); } catch(e) { displayMessage("Checkbox init error: "+e.toString()); } }
		if (!this.init && this.fn_clickBefore) // custom function hook to override changes in checkbox state
			{ try { eval(this.fn_clickBefore) } catch(e) { displayMessage("Checkbox onClickBefore error: "+e.toString()); } }
		if (this.id)
			// save state in config AND cookie (only when ID starts with 'chk')
			{ config.options[this.id]=this.checked; if (this.id.substr(0,3)=="chk") saveOptionCookie(this.id); }
		if (this.srctid && this.srcpos>0 && (!this.id || this.id.substr(0,3)!="chk") && !this.tag && !this.field) {
			// save state in tiddler content only if not using cookie, tag or field tracking
			var t=store.getTiddler(this.srctid); // put X in original source tiddler (if any)
			if (t && this.checked!=(t.text.substr(this.srcpos,1).toUpperCase()=="X")) { // if changed
				t.set(null,t.text.substr(0,this.srcpos)+(this.checked?"X":"_")+t.text.substr(this.srcpos+1),null,null,t.tags);
				if (!story.isDirty(t.title)) story.refreshTiddler(t.title,null,true);
				store.setDirty(true);
			}
		}
		if (this.field) {
			if (this.checked && !store.tiddlerExists(this.tiddler))
				store.saveTiddler(this.tiddler,this.tiddler,"",config.options.txtUserName,new Date());
			// set the field value in the target tiddler
			store.setValue(this.tiddler,this.field,this.checked?"true":"false");
			// DEBUG: displayMessage(this.field+"@"+this.tiddler+" is "+this.checked);
		}
		if (this.tag) {
			if (this.checked && !store.tiddlerExists(this.tiddler))
				store.saveTiddler(this.tiddler,this.tiddler,"",config.options.txtUserName,new Date());
			var t=store.getTiddler(this.tiddler);
			if (t) {
				var tagged=(t.tags && t.tags.indexOf(this.tag)!=-1);
				if (this.checked && !tagged) { t.tags.push(this.tag); store.setDirty(true); }
				if (!this.checked && tagged) { t.tags.splice(t.tags.indexOf(this.tag),1); store.setDirty(true); }
			}
			// if tag state has been changed, update display of corresponding tiddlers (unless they are in edit mode...)
			if (this.checked!=tagged) {
				if (this.refresh.tagged) {
					if (!story.isDirty(this.tiddler)) // the TAGGED tiddler in view mode
						story.refreshTiddler(this.tiddler,null,true); 
					else // the TAGGED tiddler in edit mode (with tags field)
						config.macros.checkbox.refreshEditorTagField(this.tiddler,this.tag,this.checked);
				}
				if (this.refresh.tagging)
					if (!story.isDirty(this.tag)) story.refreshTiddler(this.tag,null,true); // the TAGGING tiddler
			}
		}
		if (!this.init && this.fn_clickAfter) // custom function hook to react to changes in checkbox state
			{ try { eval(this.fn_clickAfter) } catch(e) { displayMessage("Checkbox onClickAfter error: "+e.toString()); } }
		// refresh containing tiddler (but not during initial rendering, or we get an infinite loop!) (and not when editing container)
		if (!this.init && this.refresh.container && this.container!=this.tiddler)
			if (!story.isDirty(this.container)) story.refreshTiddler(this.container,null,true); // the tiddler CONTAINING the checkbox
		return true;
	},
	refreshEditorTagField: function(title,tag,set) {
		var tagfield=story.getTiddlerField(title,"tags");
		if (!tagfield||tagfield.getAttribute("edit")!="tags") return; // if no tags field in editor (i.e., custom template)
		var tags=tagfield.value.readBracketedList();
		if (tags.contains(tag)==set) return; // if no change needed
		if (set) tags.push(tag); // add tag
		else tags.splice(tags.indexOf(tag),1); // remove tag
		for (var t=0;t<tags.length;t++) tags[t]=String.encodeTiddlyLink(tags[t]);
		tagfield.value=tags.join(" "); // reassemble tag string (with brackets as needed)
		return;
	}
}
//}}}
|Name|CheckboxPluginInfo|
|Source|http://www.TiddlyTools.com/#CheckboxPlugin|
|Documentation|http://www.TiddlyTools.com/#CheckboxPluginInfo|
|Version|2.4.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|documentation|
|Requires||
|Overrides||
|Description|documentation for CheckboxPlugin|
This plugin extends the TiddlyWiki syntax to allow definition of checkboxes that can be embedded directly in tiddler content.  Checkbox states are preserved by:
* setting/removing tags on specified tiddlers,
* or, setting custom field values on specified tiddlers,
* or, saving to a locally-stored cookie ID,
* or, automatically modifying the tiddler source content (deprecated).
When an ID is assigned to the checkbox, it enables direct programmatic access to the checkbox DOM element, as well as creating an entry in TiddlyWiki's config.options[ID] internal data.  In addition to tracking the checkbox state, you can also specify custom javascript for programmatic initialization and onClick event handling for any checkbox, so you can provide specialized side-effects in response to state changes.
!!!!!Inline (wiki syntax) Usage
<<<
//{{{
[ ]or[_] and [x]or[X]
//}}}
Simple checkboxes using 'Inline X' storage.  The current unchecked/checked state is indicated by the character between the {{{[}}} and {{{]}}} brackets ("_" means unchecked, "X" means checked).  When you click on a checkbox, the current state is retained by directly modifying the tiddler content to place the corresponding "_" or "X" character in between the brackets.
>//''NOTE: 'Inline X' syntax has been deprecated...''  This storage format only works properly for checkboxes that are directly embedded and accessed from content in a single tiddler.  However, if that tiddler is 'transcluded' into another (by using the {{{<<tiddler TiddlerName>>}}} macro), the 'Inline X' will be ''erroneously stored in the containing tiddler's source content, resulting in corrupted content in that tiddler.''  For anything but the most simple of "to do list" uses, you should select from the various alternative storage methods described below...//
//{{{
[x=id]
//}}}
Assign an optional ID to the checkbox so you can use {{{document.getElementByID("id")}}} to manipulate the checkbox DOM element, as well as tracking the current checkbox state in {{{config.options["id"]}}}.  If the ID starts with "chk" the checkbox state will also be saved in a cookie, so it can be automatically restored whenever the checkbox is re-rendered (overrides any default {{{[x]}}} or {{{[_]}}} value).  If a cookie value is kept, the "_" or "X" character in the tiddler content remains unchanged, and is only applied as the default when a cookie-based value is not currently defined.
//{{{
[x(title|tag)] or [x(title:tag)]
//}}}
Initializes and tracks the current checkbox state by setting or removing a particular tag value from a specified tiddler.  If you omit the tiddler title (and the | or : separator), the specified tag is assigned to the current tiddler.  If you omit the tag value, as in {{{(title|)}}}, the default tag, {{{checked}}}, is assumed.  Omitting both the title and tag, {{{()}}}, tracks the checkbox state by setting the "checked" tag on the current tiddler.  When tag tracking is used, the "_" or "X" character in the tiddler content remains unchanged, and is not used to set or track the checkbox state.  If a tiddler title named in the tag does not exist, the checkbox state defaults to the "inline X" value.  If this value is //checked//, or is subsequently changed to //checked//, it will automatically create the missing tiddler and then add the tag to it.  //''NOTE: beginning with version 2.1.2 of this plugin, the "|" separator is the preferred separator between the title and tag name, as it avoids syntactic ambiguity when ":" is used within tiddler titles or tag names.''//
//{{{
[x(field@tiddler)]
//}}}
Initializes and tracks the current checkbox state by setting a particular custom field value from a specified tiddler.  If you omit the tiddler title (but not the "@" separator), the specified field on the current tiddler is used.  If you omit the field name, as in {{{(@tiddler)}}}, a default fieldname of {{{checked}}} is assumed.  Omitting both the field and the tiddler title, {{{(@)}}}, defaults to setting the "checked" field on the current tiddler.  When field tracking is used, the "_" or "X" character in the tiddler content remains unchanged, and is not used to set or track the checkbox state.  If the tiddler title named in the parameter does not exist, the checkbox state defaults to the "inline X" value.  If this value is //checked// or is subsequently changed to //checked//, it will automatically create the missing tiddler and then add the field to it.
//{{{
[x{javascript}{javascript}{javascript}]
//}}}
You can define optional javascript code segments to add custom initialization and/or 'onClick' handlers to a checkbox.  The current checkbox state (and it's other DOM attributes) can be set or read from within these code segments by reference to a globally-defined context object, "place" (which can also be referenced as "window.place").

The first code segment will be executed when the checkbox is initially displayed, so that you can programmatically determine it's starting checked/unchecked state.  The second code segment (if present) is executed whenever the checkbox is clicked, but //before the regular checkbox processing in performed// ("onClickBefore"), so that you can apply programmed responses or intercept and override the checkbox state based on custom logic.  The third code segment (if present) is executed whenver the checkbox is clicked, //after the regular checkbox processing has completed// ("onClickAfter"), so that you can include "side-effect" processing based on the checkbox state just applied.

>Note: if you want to use the default checkbox initialization processing with a custom onClickBefore/After function, use this syntax:
>{{{[x(tag){}{javascript}]}}} or {{{[x(tag){}{}{javascript}]}}}
<<<
!!!!!Macro usage
<<<
In addition to embedded checkboxes using the wiki syntax described above, a ''macro-based syntax'' is also provided, for use in templates where wiki syntax cannot be directly used.  This macro syntax can also be used in tiddler content, as an alternative to the wiki syntax.  When embedded in [[PageTemplate]], [[ViewTemplate]], or [[EditTemplate]] (or custom alternative templates), use the following macro syntax:
//{{{
<span macro="checkbox target checked id onInit onClickBefore onClickAfter"></span>
//}}}
or, when embedded in tiddler content, use the following macro syntax:
//{{{
<<checkbox target checked id onInit onClickBefore onClickAfter>>
//}}}
where:
''target''
>is either a tag reference (e.g., ''tagname|tiddlername'') or a field reference (e.g. ''fieldname@tiddlername''), as described above.
''checked'' (optional)
>is a keyword that sets the initial state of the checkbox to "checked".  When omitted, the default checkbox state is "unchecked".
''id'' (optional)
>specifies an internal config.options.* ID, as described above.  If the ID begins with "chk", a cookie-based persistent value will be created to track the checkbox state in between sessions.
''onInit'' (optional)
>contains a javascript event handler to be performed when the checkbox is initially rendered (see details above).
''onClickBefore'' and/or ''onClickAfter'' (optional)
>contains a javascript event handler to be performed each time the checkbox is clicked (see details above).  //note: to use the default onInit handler with a custom onClickBefore/After handler, use "" (empty quotes) or {} (empty function) as a placeholder for the onInit and/or onClickBefore parameters//
<<<
!!!!!Examples
<<<
''checked and unchecked static default ("inline X") values:''
//{{{
[X] label
[_] label
//}}}
>[_] label
>[_] label
''document-based value (id='demo', no cookie):''
//{{{
[_=demo] label
//}}}
>[_=demo] label
''cookie-based value  (id='chkDemo'):''
//{{{
[_=chkDemo] label
//}}}
>[_=chkDemo] label
''tag-based value (TogglyTagging):''
//{{{
[_(CheckboxPluginInfo|demotag)]
[_(CheckboxPluginInfo|demotag){place.refresh.tagged=place.refresh.container=false}]
//}}}
>[_(CheckboxPluginInfo|demotag)] toggle 'demotag' (and refresh tiddler display)
>[_(CheckboxPluginInfo|demotag){place.refresh.tagged=place.refresh.container=false}] toggle 'demotag' (no refresh)
''field-based values:''
//{{{
[_(demofield@CheckboxPluginInfo)] demofield@CheckboxPluginInfo
[_(demofield@)] demofield@ (equivalent to demonfield@ current tiddler)
[_(checked@CheckboxPluginInfo)] checked@CheckboxPluginInfo
[_(@CheckboxPluginInfo)] @CheckboxPluginInfo
[_(@)] @ (equivalent to checked@ current tiddler)
//}}}
>[_(demofield@CheckboxPluginInfo)] demofield@CheckboxPluginInfo
>[_(demofield@)] demofield@ (current tiddler)
>[_(checked@CheckboxPluginInfo)] checked@CheckboxPluginInfo
>[_(@CheckboxPluginInfo)] @CheckboxPluginInfo
>[_(@)] toggle field: @ (defaults to "checked@here")
>click to view current: <<toolbar fields>>
''custom init and onClick functions:''
//{{{
[X{place.checked=true}{alert(place.checked?"on":"off")}] message box with checkbox state
//}}}
>[X{place.checked=true}{alert(place.checked?"on":"off")}] message box with checkbox state
''retrieving option values:''
>config.options['demo']=<script>return config.options['demo']?"true":"false";</script>
>config.options['chkDemo']=<script>return config.options['chkDemo']?"true":"false";</script>
<<<
!!!!!Configuration
<<<
Normally, when a checkbox state is changed, the affected tiddlers are automatically re-rendered, so that any checkbox-dependent dynamic content can be updated.  There are three possible tiddlers to be re-rendered, depending upon where the checkbox is placed, and what kind of storage method it is using.
*''container'': the tiddler in which the checkbox is displayed. (e.g., this tiddler)
*''tagged'': the tiddler that is being tagged (e.g., "~MyTask" when tagging "~MyTask:done")
*''tagging'': the "tag tiddler" (e.g., "~done" when tagging "~MyTask:done")
You can set the default refresh handling for all checkboxes in your document by using the following javascript syntax either in a systemConfig plugin, or as an inline script.  (Substitute true/false values as desired):
{{{config.checkbox.refresh = { tagged:true, tagging:true, container:true };}}}

You can also override these defaults for any given checkbox by using an initialization function to set one or more of the refresh options.  For example:
{{{[_{place.refresh.container=false}]}}}
<<<
/%
|Name|ChecklistScript|
|Source|http://www.TiddlyTools.com/#ChecklistScript|
|Version|1.0.1|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <<br>>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|script|
|Requires|InlineJavascriptPlugin, CheckboxPlugin|
|Overrides||
|Description|demonstration using CheckboxPlugin to create simple tag-based daily checklist|

%/
!!!!!Demonstration using CheckboxPlugin to create simple tag-based daily checklist:
5 things to do every day:
<<<
[x(questions)] Ask questions
[x(answers)] Seek answers
[x(fun)] Have fun
[x(difference)] Make a difference
[x(smile)] Smile
<<<
<script label="reset checklist">
	var t=store.getTiddler(story.findContainingTiddler(place).id.substr(7));
	if (t && t.tags) {
		var newTags=[];
		for (var i=0; i<t.tags.length; i++) {
			switch (t.tags[i]) {
				case "questions":
				case "answers":
				case "fun":
				case "difference":
				case "smile":
					break;
				default:
					newTags.push(t.tags[i]);
			}
		}
		store.saveTiddler(t.title,t.title,t.text,t.modifier,t.modified,newTags,t.fields);
		story.refreshTiddler(t.title,null,true); // force
	}
	return false;
</script>
<part BAX98>Baxter, Ira D. et al: //Clone Detection Using Abstract Syntax Trees.// 
in //Proc. ICSM//, 1998.</part>

<part BEL02>Bellon, Stefan: //Vergleich von Techniken zur Erkennung duplizierten Quellcodes.// 
Thesis, Uni Stuttgart, 2002.</part>

<part DUC99>Ducasse, Stéfane et al: //A Language Independent Approach for Detecting Duplicated Code.// 
in //Proc. ICSM//, 1999.</part>
<html>
<input type="button" value="Back" title="back" onclick = "try{goB()} catch(e) {goB()}" > <nobr><!--
--><input type="button" value="Forward" title="back" onclick="try{goF()} catch(e) {goF()}" >
</nobr></html>

<script>
goB = function() {
alert("backwards");
}

goF = function() {
alert("forward");
}
</script>
<html>
<input type="button" value="Back" title="back" onclick="try{goB()} catch(e) {goB()}" >
</html>

<script>
goB = function() {
alert("backwards");
//story.refreshTiddler("Copy 2 of MiniBrowser",1,true);
//store.setDirty(true);
}

</script>
<html>
<input type="button" value="Back" title="back" onclick="goB()" >
</html>

<script>
goB = function() {
alert("backwards");
//story.refreshTiddler("Copy 2 of MiniBrowser",1,true);
//store.setDirty(true);
}

</script>
http://mptw2.tiddlyspot.com/#Clock2
/***
| Name|CloseOnCancelPlugin|
| Description|Closes the tiddler if you click new tiddler then cancel. Default behaviour is to leave it open|
| Version|3.0 ($Rev: 1845 $)|
| Date|$Date: 2007-03-16 15:19:22 +1000 (Fri, 16 Mar 2007) $|
| Source|http://mptw.tiddlyspot.com/#CloseOnCancelPlugin|
| Author|Simon Baird <simon.baird@gmail.com>|
| License|http://mptw.tiddlyspot.com/#TheBSDLicense|
***/
//{{{
merge(config.commands.cancelTiddler,{

	handler_orig_closeUnsaved: config.commands.cancelTiddler.handler,

	handler: function(event,src,title) {
		this.handler_orig_closeUnsaved(event,src,title);
		if (!store.tiddlerExists(title) && !store.isShadowTiddler(title))
			story.closeTiddler(title,true);
	 	return false;
	}

});

//}}}
config.formatters.push(
{
keywords : {
	"var":"blue",
	"try":"blue",
	"catch":"blue",
	"if":"blue",
	"else":"blue",
	"for":"blue",
	"while":"blue",
	"do":"blue",
	"function":"blue",
	"Function":"blue",
	"String":"blue",
	"Object":"blue",
	"RegExp":"blue",
	"Array":"blue",
	"Math":"blue",
	"Date":"blue",
	"store":"blue",
	"story":"blue",
	"tag":"brown",
	"place":"brown",
	"push":"brown",
	"config":"orange",
	"options":"orange",
	"macros":"orange",
	"handler":"orange",
	";":"blue",
	"+":"red",
	"-":"red",
	"*":"red",
	"/":"red",
	"%":"red",
	"^":"red",
	"&":"red",
	"|":"red",
	"!":"red",
	"~":"red",
	"=":"red",
	"<":"red",
	">":"red",
	"false":"DarkBlue",
	"true":"DarkBlue",
	"window":"DarkBlue",
	"document":"DarkBlue",
	"alert":"IndianRed",
	"eval":"IndianRed",
	"setInterval":"IndianRed",
	"setTimeout":"IndianRed",
	"toString":"IndianRed",
	"write":"IndianRed"
},
	match: "<[Cc][Oo][Dd][Ee]>\\n",
	lookahead: "<[Cc][Oo][Dd][Ee]>\\n((?:.|\\n)*?)\\n</[Cc][Oo][Dd][Ee]>",
	handler: function(w)
	{
		var lookaheadRegExp = new RegExp(this.lookahead,"mg");
		lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = lookaheadRegExp.exec(w.source)
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart)
			{
			var e = createTiddlyElement(w.output,"pre");
			var str = lookaheadMatch[1];
var Reg = /(\/\/.*?$)|(\/\*(.|\n)*?\*\/)|[&#39;]{2}|(&#39;.*?[^\\]&#39;)|["]{2}|(".*?[^\\]")|\w+|[\s\n]+|./mg;
var parts = str.match(Reg);
for(var i = 0; i < parts.length; i++){
if(parts[i].match(/^[\s\n]/))parts[i] = parts[i].replace(/\t/g,"&nbsp;&nbsp;&nbsp;&nbsp;").replace(/\n/g,"<br/>").replace(/\r/g,"");
else if(parts[i].match(/^(?:\/\/)|(?:\/\*)/))parts[i] = "<span style=\"color:green;\">"+parts[i].htmlEncode().replace(/\\n/g,"&lt;br/&gt;")+"</span>";
else if(parts[i].charAt(0)=="\""||parts[i].charAt(0)=="&#39;")parts[i] = "<span style=\"color:teal;\">"+parts[i].htmlEncode()+"</span>";
else if(this.keywords[parts[i]])parts[i] = "<span style=\"color:"+this.keywords[parts[i]]+";\">"+parts[i].htmlEncode()+"</span>";
}
e.innerHTML = parts.join("");
			w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
			}
	}
}
);
/***
!Colors Used
*@@bgcolor(#8cf): #8cf - Background blue@@
*@@bgcolor(#18f): #18f - Top blue@@
*@@bgcolor(#04b): #04b - Mid blue@@
*@@bgcolor(#014):color(#fff): #014 - Bottom blue@@
*@@bgcolor(#ffc): #ffc - Bright yellow@@
*@@bgcolor(#fe8): #fe8 - Highlight yellow@@
*@@bgcolor(#db4): #db4 - Background yellow@@
*@@bgcolor(#841): #841 - Border yellow@@
*@@bgcolor(#700):color(#fff): #700 - Title red@@
*@@bgcolor(#866): #866 - Subtitle grey@@
*@@bgcolor(#B5D1DF): #B5D1DF - Primary Pale@@
*@@bgcolor(#ffc): #ffc - Secondary Pale@@
*@@bgcolor(#618FA9): #618FA9 - Primary Light@@
*@@bgcolor(#1a3844): #1a3844- Primary Mid@@
*@@bgcolor(#000):color(#fff): #000- Primary Dark@@
*@@bgcolor(#f8f8f8): #f8f8f8- Tertiary Pale@@
*@@bgcolor(#bbb): #bbb- Tertiary Light@@
*@@bgcolor(#999): #999- Tertiary Mid@@
***/
Name: Blue
Background: #fff
Foreground: #000
PrimaryPale: #cdf
PrimaryLight: #57c
PrimaryMid: #114
PrimaryDark: #012
SecondaryPale: #ffc
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #841
TertiaryPale: #eee
TertiaryLight: #ccc
TertiaryMid: #999
TertiaryDark: #666
Error: #f88
//{{{
config.options.chkHttpReadOnly = false; // means web visitors can experiment with your site by clicking edit
config.options.chkInsertTabs = true;    // tab inserts a tab when editing a tiddler
config.views.wikified.defaultText = ""; // don't need message when a tiddler doesn't exist
config.views.editor.defaultText = "";   // don't need message when creating a new tiddler 
//}}}
PageTemplate
|>|>|SiteTitle - SiteSubtitle|
|MainMenu|DefaultTiddlers<<br>><<br>><<br>><<br>>ViewTemplate<<br>><<br>>EditTemplate|SideBarOptions|
|~|~|OptionsPanel|
|~|~|AdvancedOptions|
|~|~|<<tiddler Configuration.SideBarTabs>>|

''StyleSheet:'' StyleSheetColors - StyleSheetLayout - StyleSheetPrint

SiteUrl
SideBarTabs
|[[Timeline|TabTimeline]]|[[All|TabAll]]|[[Tags|TabTags]]|>|>|[[More|TabMore]] |
|>|>||[[Missing|TabMoreMissing]]|[[Orphans|TabMoreOrphans]]|[[Shadowed|TabMoreShadowed]]|
Geology
Reservoir
Production
{{{
Add json.js before code.
}}}


<script>
/*
    json.js
    2007-12-02

    Public Domain

    No warranty expressed or implied. Use at your own risk.

    This file has been superceded by http://www.JSON.org/json2.js

    See http://www.JSON.org/js.html

    This file adds these methods to JavaScript:

        array.toJSONString(whitelist)
        boolean.toJSONString()
        date.toJSONString()
        number.toJSONString()
        object.toJSONString(whitelist)
        string.toJSONString()
            These methods produce a JSON text from a JavaScript value.
            It must not contain any cyclical references. Illegal values
            will be excluded.

            The default conversion for dates is to an ISO string. You can
            add a toJSONString method to any date object to get a different
            representation.

            The object and array methods can take an optional whitelist
            argument. A whitelist is an array of strings. If it is provided,
            keys in objects not found in the whitelist are excluded.

        string.parseJSON(filter)
            This method parses a JSON text to produce an object or
            array. It can throw a SyntaxError exception.

            The optional filter parameter is a function which can filter and
            transform the results. It receives each of the keys and values, and
            its return value is used instead of the original value. If it
            returns what it received, then structure is not modified. If it
            returns undefined then the member is deleted.

            Example:

            // Parse the text. If a key contains the string 'date' then
            // convert the value to a date.

            myData = text.parseJSON(function (key, value) {
                return key.indexOf('date') >= 0 ? new Date(value) : value;
            });

    It is expected that these methods will formally become part of the
    JavaScript Programming Language in the Fourth Edition of the
    ECMAScript standard in 2008.

    This file will break programs with improper for..in loops. See
    http://yuiblog.com/blog/2006/09/26/for-in-intrigue/

    This is a reference implementation. You are free to copy, modify, or
    redistribute.

    Use your own copy. It is extremely unwise to load untrusted third party
    code into your pages.
*/

/*jslint evil: true */

/*members "\b", "\t", "\n", "\f", "\r", "\"", "\\", apply, charCodeAt,
    floor, getUTCDate, getUTCFullYear, getUTCHours, getUTCMinutes,
    getUTCMonth, getUTCSeconds, hasOwnProperty, join, length, parseJSON,
    prototype, push, replace, test, toJSONString, toString
*/

// Augment the basic prototypes if they have not already been augmented.

if (!Object.prototype.toJSONString) {

    Array.prototype.toJSONString = function (w) {
        var a = [],     // The array holding the partial texts.
            i,          // Loop counter.
            l = this.length,
            v;          // The value to be stringified.

// For each value in this array...

        for (i = 0; i < l; i += 1) {
            v = this[i];
            switch (typeof v) {
            case 'object':

// Serialize a JavaScript object value. Treat objects thats lack the
// toJSONString method as null. Due to a specification error in ECMAScript,
// typeof null is 'object', so watch out for that case.

                if (v && typeof v.toJSONString === 'function') {
                    a.push(v.toJSONString(w));
                } else {
                    a.push('null');
                }
                break;

            case 'string':
            case 'number':
            case 'boolean':
                a.push(v.toJSONString());
                break;
            default:
                a.push('null');
            }
        }

// Join all of the member texts together and wrap them in brackets.

        return '[' + a.join(',') + ']';
    };


    Boolean.prototype.toJSONString = function () {
        return String(this);
    };


    Date.prototype.toJSONString = function () {

// Eventually, this method will be based on the date.toISOString method.

        function f(n) {

// Format integers to have at least two digits.

            return n < 10 ? '0' + n : n;
        }

        return '"' + this.getUTCFullYear()   + '-' +
                   f(this.getUTCMonth() + 1) + '-' +
                   f(this.getUTCDate())      + 'T' +
                   f(this.getUTCHours())     + ':' +
                   f(this.getUTCMinutes())   + ':' +
                   f(this.getUTCSeconds())   + 'Z"';
    };


    Number.prototype.toJSONString = function () {

// JSON numbers must be finite. Encode non-finite numbers as null.

        return isFinite(this) ? String(this) : 'null';
    };


    Object.prototype.toJSONString = function (w) {
        var a = [],     // The array holding the partial texts.
            k,          // The current key.
            i,          // The loop counter.
            v;          // The current value.

// If a whitelist (array of keys) is provided, use it assemble the components
// of the object.

        if (w) {
            for (i = 0; i < w.length; i += 1) {
                k = w[i];
                if (typeof k === 'string') {
                    v = this[k];
                    switch (typeof v) {
                    case 'object':

// Serialize a JavaScript object value. Ignore objects that lack the
// toJSONString method. Due to a specification error in ECMAScript,
// typeof null is 'object', so watch out for that case.

                        if (v) {
                            if (typeof v.toJSONString === 'function') {
                                a.push(k.toJSONString() + ':' +
                                       v.toJSONString(w));
                            }
                        } else {
                            a.push(k.toJSONString() + ':null');
                        }
                        break;

                    case 'string':
                    case 'number':
                    case 'boolean':
                        a.push(k.toJSONString() + ':' + v.toJSONString());

// Values without a JSON representation are ignored.

                    }
                }
            }
        } else {

// Iterate through all of the keys in the object, ignoring the proto chain
// and keys that are not strings.

            for (k in this) {
                if (typeof k === 'string' &&
                        Object.prototype.hasOwnProperty.apply(this, [k])) {
                    v = this[k];
                    switch (typeof v) {
                    case 'object':

// Serialize a JavaScript object value. Ignore objects that lack the
// toJSONString method. Due to a specification error in ECMAScript,
// typeof null is 'object', so watch out for that case.

                        if (v) {
                            if (typeof v.toJSONString === 'function') {
                                a.push(k.toJSONString() + ':' +
                                       v.toJSONString());
                            }
                        } else {
                            a.push(k.toJSONString() + ':null');
                        }
                        break;

                    case 'string':
                    case 'number':
                    case 'boolean':
                        a.push(k.toJSONString() + ':' + v.toJSONString());

// Values without a JSON representation are ignored.

                    }
                }
            }
        }

// Join all of the member texts together and wrap them in braces.

        return '{' + a.join(',') + '}';
    };


    (function (s) {

// Augment String.prototype. We do this in an immediate anonymous function to
// avoid defining global variables.

// m is a table of character substitutions.

        var m = {
            '\b': '\\b',
            '\t': '\\t',
            '\n': '\\n',
            '\f': '\\f',
            '\r': '\\r',
            '"' : '\\"',
            '\\': '\\\\'
        };


        s.parseJSON = function (filter) {
            var j;

            function walk(k, v) {
                var i, n;
                if (v && typeof v === 'object') {
                    for (i in v) {
                        if (Object.prototype.hasOwnProperty.apply(v, [i])) {
                            n = walk(i, v[i]);
                            if (n !== undefined) {
                                v[i] = n;
                            }
                        }
                    }
                }
                return filter(k, v);
            }


// Parsing happens in three stages. In the first stage, we run the text against
// a regular expression which looks for non-JSON characters. We are especially
// concerned with '()' and 'new' because they can cause invocation, and '='
// because it can cause mutation. But just to be safe, we will reject all
// unexpected characters.

// We split the first stage into 4 regexp operations in order to work around
// crippling inefficiencies in IE's and Safari's regexp engines. First we
// replace all backslash pairs with '@' (a non-JSON character). Second, we
// replace all simple value tokens with ']' characters. Third, we delete all
// open brackets that follow a colon or comma or that begin the text. Finally,
// we look to see that the remaining characters are only whitespace or ']' or
// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.

            if (/^[\],:{}\s]*$/.test(this.replace(/\\./g, '@').
                    replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(:?[eE][+\-]?\d+)?/g, ']').
                    replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {

// In the second stage we use the eval function to compile the text into a
// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
// in JavaScript: it can begin a block or an object literal. We wrap the text
// in parens to eliminate the ambiguity.

                j = eval('(' + this + ')');

// In the optional third stage, we recursively walk the new structure, passing
// each name/value pair to a filter function for possible transformation.

                return typeof filter === 'function' ? walk('', j) : j;
            }

// If the text is not JSON parseable, then a SyntaxError is thrown.

            throw new SyntaxError('parseJSON');
        };


        s.toJSONString = function () {

// If the string contains no control characters, no quote characters, and no
// backslash characters, then we can simply slap some quotes around it.
// Otherwise we must also replace the offending characters with safe
// sequences.

            if (/["\\\x00-\x1f]/.test(this)) {
                return '"' + this.replace(/[\x00-\x1f\\"]/g, function (a) {
                    var c = m[a];
                    if (c) {
                        return c;
                    }
                    c = a.charCodeAt();
                    return '\\u00' + Math.floor(c / 16).toString(16) +
                                               (c % 16).toString(16);
                }) + '"';
            }
            return '"' + this + '"';
        };
    })(String.prototype);
}


// json.js must be included prior to this point


var continents = new Array();
continents.push("Europe");
continents.push("Asia");
continents.push("Australia");
continents.push("Antarctica");
continents.push("North America");
continents.push("South America");
continents.push("Africa");

alert("The JSON representation of the continents array is: " +
 continents.toJSONString());


</script>
PageTemplate
|>|>|SiteTitle - SiteSubtitle|
|MainMenu|DefaultTiddlers<<br>><<br>><<br>><<br>>ViewTemplate<<br>><<br>>EditTemplate|SideBarOptions|
|~|~|OptionsPanel|
|~|~|AdvancedOptions|
|~|~|<<tiddler Configuration.SideBarTabs>>|

''StyleSheet:'' StyleSheetColors - StyleSheetLayout - StyleSheetPrint

SiteUrl
[[Welcome]] GettingStarted [[Configuration]] 
<<LaunchApplication "LinuxAdmin" "Linux Admin" "file:///C:/Documents%20and%20Settings/All%20Users.WINX64/Documents/LinuxAdmin-ts.html">>
<<LaunchApplication "Programming" "Programming" "file:///C:/Documents%20and%20Settings/All%20Users.WINX64/Documents/arprogs-ts.html">>
<<tiddler MiniBrowser with: 3>>
{{consoleClass{
msfz751@a3800xp64 /cygdrive/f/PortableEclipse/jython_osp/code
$ tree -L 2
.
|-- META-INF
|   `-- MANIFEST.MF
|-- SurfaceArrayApp.java
|-- SurfaceArrayApp.py
|-- demo
|   |-- FirstPlotApp.class
|   `-- HelloWorldApp.class
|-- launcher_default.xset
|-- org
|   |-- jibble
|   `-- opensourcephysics
|-- osp.jar
`-- osp_title.html

5 directories, 8 files
}}}
<html>
<form target="browser_$1" style="margin:0;padding:0"
	onsubmit="this.action=this.url.value; this.form.done.disabled=false" style="margin:0;padding:0"><nobr>
<select name="bookmarks" id="browser_bookmarks_$1" size="1" style="font-size:8pt;width:21%"
	onchange="var f=document.getElementById('browser_$1'); this.form.url.value=this.value; this.form.action=this.value; this.form.done.disabled=false">
<option value="">bookmarks...</option>
</select>
<input type="text" name="url" size="60" value="" style="font-size:8pt;width:35%">

</html>
<script>
	// load bookmarks droplist from tag
	var here = document.getElementById("browser_bookmarks_$1");
	while (here.length) here.options[0] = null; // remove current list items
	here.options[here.length] = new Option("bookmarks...","",true,true);

	valueSrc = "javascript";
	tiddler = store.getTiddler(valueSrc);
	var tagged = store.getTaggedTiddlers(tiddler.title);

	if (tagged) {

		// show content in "tagged" array
		for (var i=0; i < tagged.length; i++) {
			//wikify("values(" + i + ") "  + tagged[i].title + '\n', place);  
			indent="";
			label = tagged[i].title;
			value = tagged[i].title;
			here.options[here.length] = new Option(indent+label,value,false,false);
		}
	}
</script>
<script> 
var example.options = []; 
example.options[1] ="Technology Sites"
example.options[2] ="News Sites"
example.options[3] ="Search Engines"
</script> 
<html>
<form name="doublecombo">
<p><select size="1" name="example"><option value=\"\">sites...</option>
</select>
<select name="stage2" size="1">
<option value="http://javascriptkit.com">JavaScript Kit</option>
<option value="http://www.news.com">News.com</option>
<option value="http://www.wired.com">Wired News</option>
</select>

<input type="button" name="test" value="Go!"
onClick="go()">
</p>
</form>

<p align="center"><font face="arial" size="-2">This free script provided by</font><br>
<font face="arial, helvetica" size="-2"><a href="http://javascriptkit.com">JavaScript
Kit</a></font></p>
</html>



<script>
/*
Double Combo Script Credit
By JavaScript Kit (www.javascriptkit.com)
Over 200+ free JavaScripts here!
*/

var groups=document.doublecombo.example.options.length
var group=new Array(groups)
for (i=0; i<groups; i++)
group[i]=new Array()

group[0][0]=new Option("JavaScript Kit","http://javascriptkit.com")
group[0][1]=new Option("News.com","http://www.news.com")
group[0][2]=new Option("Wired News","http://www.wired.com")

group[1][0]=new Option("CNN","http://www.cnn.com")
group[1][1]=new Option("ABC News","http://www.abcnews.com")

group[2][0]=new Option("Hotbot","http://www.hotbot.com")
group[2][1]=new Option("Infoseek","http://www.infoseek.com")
group[2][2]=new Option("Excite","http://www.excite.com")
group[2][3]=new Option("Lycos","http://www.lycos.com")

var temp=document.doublecombo.stage2

function redirect(x){
  for (m=temp.options.length-1;m>0;m--)
  temp.options[m]=null
  for (i=0;i<group[x].length;i++){
  temp.options[i]=new Option(group[x][i].text,group[x][i].value)
}
temp.options[0].selected=true
}

function go(){
  location=temp.options[temp.selectedIndex].value
}
//-->
</script>
<code>
 var parsedParams = paramString.parseParams("tags",null,true);
</code>

    * [[New Tiddler (7)]]
    * [[parsing - main()]]
    * [[parsing - newTiddler macro]]
    * [[parsing: getParam() - function]]
    * [[parsing: parseParams() - function]]
    * [[parsing: tiddler macro]]
<script>
WriteToFile = function() {
set fso = CreateObject("Scripting.FileSystemObject");  
set s = fso.CreateTextFile("m:\test.txt", True);
s.writeline("HI");
s.writeline("Bye");
s.writeline("-----------------------------");
s.Close();
}
</script>

<html>
</head>
<body>
<p>To sign up for the Excel workshop please fill out the form below:
</p>
<form>
Type your first name:
<input type="text" name="FirstName" size="20">
<br>Type your last name:
<input type="text" name="LastName" size="20">
<br>
<input type="button" value="write" onClick="WriteToFile()">
</form> 
</html>
/***
|Name|CopyTiddlerPlugin|
|Source|http://www.TiddlyTools.com/#CopyTiddlerPlugin|
|Version|3.0.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <<br>>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|Quickly create a copy of any existing tiddler|

!!!!!Usage
<<<
View a tiddler and select the "copy" toolbar item.  A new tiddler editor is opened with a title of "Copy of TiddlerName" containing copies of the text/tags from the original tiddler.  Note: If select the "copy" toolbar item while //editing// a tiddler, the current values of the text/tags that are displayed in the existing tiddler editor are used (including any unsaved changes you may have made to those values).
<<<
!!!!!Installation
<<<
import (or copy/paste) the following tiddlers into your document:
''CopyTiddlerPlugin'' (tagged with <<tag systemConfig>>)

* When using the default (shadow) EditTemplate, the plugin automatically updates the template to include the ''copyTiddler'' toolbar command.
* If you have created a custom EditTemplate tiddler, you will need to manually add the ''copyTiddler'' toolbar command to your existing template toolbar definition.
* If you add ''copyTiddler'' to the ViewTemplate toolbar definition, the ''copy'' toolbar command will also appear when viewing a tiddler.
{{{
<!-- add 'copyTiddler' command to existing toolbar definition -->
<div class='toolbar' macro='toolbar ... copyTiddler ... '>
}}}
<<<
!!!!!Revisions
<<<
''2007.06.28 [3.0.0]'' complete re-write to handle custom fields and alternative view/edit templates
''2007.05.17 [2.1.2]'' use store.getTiddlerText() to retrieve tiddler content, so that SHADOW tiddlers can be copied correctly when in VIEW mode
''2007.04.01 [2.1.1]'' in copyTiddler.handler(), fix check for editor fields by ensuring that found field actually has edit=="text" attribute
''2007.02.05 [2.1.0]'' in copyTiddler.handler(), if editor fields (textfield and/or tagsfield) can't be found (i.e., tiddler is in VIEW mode, not EDIT mode), then get text/tags values from stored tiddler instead of active editor fields.  Allows use of COPY toolbar directly from VIEW mode (based on a request from LaurentCharles)
''2006.12.12 [2.0.0]'' completely rewritten so plugin just creates a new tiddler EDITOR with a copy of the current tiddler EDITOR contents, instead of creating the new tiddler in the STORE by copying the current tiddler values from the STORE.
''2005.xx.xx [1.0.0]'' original version by Tim Morgan
<<<
!!!!!Credits
>This feature was originally developed by Tim Morgan.  Current version developed by EricShulman from [[ELS Design Studios|http://www.elsdesign.com]]
!!!!!Code
***/
//{{{
version.extensions.copyTiddler= {major: 3, minor: 0, revision: 0, date: new Date(2007,6,28)};

// automatically tweak shadow EditTemplate to add "copyTiddler" toolbar command (following "cancelTiddler")
config.shadowTiddlers.EditTemplate=config.shadowTiddlers.EditTemplate.replace(/cancelTiddler/,"cancelTiddler copyTiddler");

config.commands.copyTiddler = {
	text: 'copy',
	hideReadOnly: true,
	tooltip: 'Make a copy of this tiddler',
	prefix: "Copy of ",
	handler: function(event,src,title) {
		var tiddlerElem=document.getElementById(story.idPrefix+title); // current tiddler element
		var template=tiddlerElem.getAttribute("template") // current tiddler template
		var newTitle = this.prefix+title; // add "copy of" to create new tiddler title
		if (!story.isDirty(title)) { // if existing tiddler is being VIEWED (not EDITED)
			// duplicate existing stored tiddler (and clear "changecount")
			var tid=store.getTiddler(title);
	                store.saveTiddler(newTitle,newTitle,tid.text,config.options.txtUserName,new Date(),tid.tags, tid.fields, true);
			// display new tiddler using same view template as current tiddler
			story.displayTiddler(story.findContainingTiddler(src),newTitle,template);
		} else {
			// display new tiddler editor using same editor template as current tiddler
			story.displayTiddler(story.findContainingTiddler(src),newTitle,template);
			// get fields from current tiddler editor
			var fields=config.commands.copyTiddler.gatherFields(tiddlerElem);
			// set fields in new editor
			var newTiddlerElem = document.getElementById(story.idPrefix+newTitle);
			for (var f=0; f<fields.length; f++) { 
				if (fields[f].name=="title") fields[f].value=newTitle; // rename title in new tiddler
				var fieldElem=config.commands.copyTiddler.findField(newTiddlerElem,fields[f].name);
				if (fieldElem) {
					if (fieldElem.getAttribute("type")=="checkbox")
						fieldElem.checked=fields[f].value;
					else 
						fieldElem.value=fields[f].value;
				}
			}
		}
		story.focusTiddler(newTitle,"title");
		return false;
	},
	findField: function(tiddlerElem,field) {
		var inputs=tiddlerElem.getElementsByTagName("input");
		for (var i=0; i<inputs.length; i++) {
			if (inputs[i].getAttribute("type")=="checkbox" && inputs[i].field == field) return inputs[i];
			if (inputs[i].getAttribute("type")=="text" && inputs[i].getAttribute("edit") == field) return inputs[i];
		}
		var tas=tiddlerElem.getElementsByTagName("textarea");
		for (var i=0; i<tas.length; i++) if (tas[i].getAttribute("edit") == field) return tas[i];
		var sels=tiddlerElem.getElementsByTagName("select");
		for (var i=0; i<sels.length; i++) if (sels[i].getAttribute("edit") == field) return sels[i];
		return null;
	},
	gatherFields: function(tiddlerElem) { // get field names and values from current tiddler editor
		var fields=[];
		// get checkboxes and edit fields
		var inputs=tiddlerElem.getElementsByTagName("input");
		for (var i=0; i<inputs.length; i++) {
			if (inputs[i].getAttribute("type")=="checkbox")
				if (inputs[i].field) fields.push({name:inputs[i].field,value:inputs[i].checked});
			if (inputs[i].getAttribute("type")=="text")
				if (inputs[i].getAttribute("edit")) fields.push({name:inputs[i].getAttribute("edit"),value:inputs[i].value});
		}
		// get textareas (multi-line edit fields)
		var tas=tiddlerElem.getElementsByTagName("textarea");
		for (var i=0; i<tas.length; i++)
			if (tas[i].getAttribute("edit")) fields.push({name:tas[i].getAttribute("edit"),value:tas[i].value});
		// get selection lists (droplist or listbox)
		var sels=tiddlerElem.getElementsByTagName("select");
		for (var i=0; i<sels.length; i++)
			if (sels[i].getAttribute("edit")) fields.push({name:sels[i].getAttribute("edit"),value:sels[i].value});
		return fields;
	}
};
//}}}
<html><p>&nbsp;</p><p><table width="374" cellspacing="1" cellpadding="1" border="0"><tbody><tr><td width="150" valign="top" bordercolor="#ffffcc"><strong>Materials:</strong></td><td width="150" valign="top" bordercolor="#ffffcc"><p>H2S resistant</p><p>13% Cr steel</p><p>Stainless Steel</p><p>Ni alloys</p></td></tr><tr><td width="150" valign="top" bordercolor="#ffffcc"><strong>Operation:</strong></td><td width="150" valign="top" bordercolor="#ffffcc"><p>Separation</p><p>Dehydration</p><p>Temperature control</p><p>Pressure Control</p></td></tr><tr><td width="150" valign="top" bordercolor="#ffffcc"><strong>Inhibition:</strong></td><td width="150" valign="top" bordercolor="#ffffcc"><p>Oxygen scavenger</p><p>Bactericide</p><p>pH control</p><p>Film forming</p></td></tr><tr><td width="150" valign="top" bordercolor="#ffffcc"><strong>Coating:</strong></td><td width="150" valign="top" bordercolor="#ffffcc">in-situ coating</td></tr></tbody></table></p></html>
{{{
<<forEachTiddler
 write 
 'tiddler.title+"\n"' 

 toFile 'file:///c:/MyTiddlerList.txt' withLineSeparator '\r\n'
>>
}}}
<<forEachTiddler
 write 
 'tiddler.title+"\n"' 

 toFile 'file://c:MyTiddlerList.txt' withLineSeparator '\r\n'
>>
http://creations.tiddlyspot.com/

Features:
* left and right long sidebars
* customizable main page (left sidebar)
* advanced options on bottom of right sidebar
* download wiki link
* wikibar works
{{{
var Person = Class.create();
Person.prototype = {
  initialize: function(name, age) {
    this.name = name;
    this.age = age;
  },  
  toJSON: function() {
    return ('My name is ' + this.name + 
      ' and I am ' + this.age + ' years old.').toJSON();
  }
};
var john = new Person('John', 49);
Object.toJSON(john);
//-> '"My name is John and I am 49 years old."'
}}}

<script>
var Person = Class.create();
Person.prototype = {
  initialize: function(name, age) {
    this.name = name;
    this.age = age;
  },  
  toJSON: function() {
    return ('My name is ' + this.name + 
      ' and I am ' + this.age + ' years old.').toJSON();
  }
};
var john = new Person('John', 49);
Object.toJSON(john);
//-> '"My name is John and I am 49 years old."'
</script>
<script>
// tabledeleterow.js version 1.2 2006-02-21
// mredkj.com

// CONFIG notes. Below are some comments that point to where this script can be customized.
// Note: Make sure to include a <tbody></tbody> in your table's HTML

var INPUT_NAME_PREFIX = 'inputName3'; // this is being set via script
var RADIO_NAME = 'totallyrad'; // this is being set via script
var TABLE_NAME = 'tblSample3'; // this should be named in the HTML
var ROW_BASE = 1; // first number (for display)
var hasLoaded = false;

window.onload = fillInRows;

fillInRows = function() {
	hasLoaded = true;
	addRowToTable();
	addRowToTable();
}


// CONFIG:
// myRowObject is an object for storing information about the table rows
myRowObject = function (one, two, three, four)
{
	this.one = one; // text object
	this.two = two; // input text object
	this.three = three; // input checkbox object
	this.four = four; // input radio object
}

/*
 * insertRowToTable
 * Insert and reorder
 */
insertRowToTable = function ()
{
	if (hasLoaded) {
		var tbl = document.getElementById(TABLE_NAME);
		var rowToInsertAt = tbl.tBodies[0].rows.length;
		for (var i=0; i<tbl.tBodies[0].rows.length; i++) {
			if (tbl.tBodies[0].rows[i].myRow && tbl.tBodies[0].rows[i].myRow.four.getAttribute('type') == 'radio' && tbl.tBodies[0].rows[i].myRow.four.checked) {
				rowToInsertAt = i;
				break;
			}
		}
		addRowToTable(rowToInsertAt);
		reorderRows(tbl, rowToInsertAt);
	}
}

/*
 * addRowToTable
 * Inserts at row 'num', or appends to the end if no arguments are passed in. Don't pass in empty strings.
 */
addRowToTable = function (num)
{
	if (hasLoaded) {
		var tbl = document.getElementById(TABLE_NAME);
		var nextRow = tbl.tBodies[0].rows.length;
		var iteration = nextRow + ROW_BASE;
		if (num == null) { 
			num = nextRow;
		} else {
			iteration = num + ROW_BASE;
		}
		
		// add the row
		var row = tbl.tBodies[0].insertRow(num);
		
		// CONFIG: requires classes named classy0 and classy1
		row.className = 'classy' + (iteration % 2);
	
		// CONFIG: This whole section can be configured
		
		// cell 0 - text
		var cell0 = row.insertCell(0);
		var textNode = document.createTextNode(iteration);
		cell0.appendChild(textNode);
		
		// cell 1 - input text
		var cell1 = row.insertCell(1);
		var txtInp = document.createElement('input');
		txtInp.setAttribute('type', 'text');
		txtInp.setAttribute('name', INPUT_NAME_PREFIX + iteration);
		txtInp.setAttribute('size', '40');
		txtInp.setAttribute('value', iteration); // iteration included for debug purposes
		cell1.appendChild(txtInp);
		
		// cell 2 - input button
		var cell2 = row.insertCell(2);
		var btnEl = document.createElement('input');
		btnEl.setAttribute('type', 'button');
		btnEl.setAttribute('value', 'Delete');
		btnEl.onclick = function () {deleteCurrentRow(this)};
		cell2.appendChild(btnEl);
		
		// cell 3 - input checkbox
		var cell3 = row.insertCell(3);
		var cbEl = document.createElement('input');
		cbEl.setAttribute('type', 'checkbox');
		cell3.appendChild(cbEl);
		
		// cell 4 - input radio
		var cell4 = row.insertCell(4);
		var raEl;
		try {
			raEl = document.createElement('<input type="radio" name="' + RADIO_NAME + '" value="' + iteration + '">');
			var failIfNotIE = raEl.name.length;
		} catch(ex) {
			raEl = document.createElement('input');
			raEl.setAttribute('type', 'radio');
			raEl.setAttribute('name', RADIO_NAME);
			raEl.setAttribute('value', iteration);
		}
		cell4.appendChild(raEl);
		
		// Pass in the elements you want to reference later
		// Store the myRow object in each row
		row.myRow = new myRowObject(textNode, txtInp, cbEl, raEl);
	}
}

// CONFIG: this entire function is affected by myRowObject settings
// If there isn't a checkbox in your row, then this function can't be used.
deleteChecked = function ()
{
	if (hasLoaded) {
		var checkedObjArray = new Array();
		var cCount = 0;
	
		var tbl = document.getElementById(TABLE_NAME);
		for (var i=0; i<tbl.tBodies[0].rows.length; i++) {
			if (tbl.tBodies[0].rows[i].myRow && tbl.tBodies[0].rows[i].myRow.three.getAttribute('type') == 'checkbox' && tbl.tBodies[0].rows[i].myRow.three.checked) {
				checkedObjArray[cCount] = tbl.tBodies[0].rows[i];
				cCount++;
			}
		}
		if (checkedObjArray.length > 0) {
			var rIndex = checkedObjArray[0].sectionRowIndex;
			deleteRows(checkedObjArray);
			reorderRows(tbl, rIndex);
		}
	}
}

// If there isn't an element with an onclick event in your row, then this function can't be used.
deleteCurrentRow = function (obj)
{
	if (hasLoaded) {
		var delRow = obj.parentNode.parentNode;
		var tbl = delRow.parentNode.parentNode;
		var rIndex = delRow.sectionRowIndex;
		var rowArray = new Array(delRow);
		deleteRows(rowArray);
		reorderRows(tbl, rIndex);
	}
}

reorderRows = function (tbl, startingIndex)
{
	if (hasLoaded) {
		if (tbl.tBodies[0].rows[startingIndex]) {
			var count = startingIndex + ROW_BASE;
			for (var i=startingIndex; i<tbl.tBodies[0].rows.length; i++) {
			
				// CONFIG: next line is affected by myRowObject settings
				tbl.tBodies[0].rows[i].myRow.one.data = count; // text
				
				// CONFIG: next line is affected by myRowObject settings
				tbl.tBodies[0].rows[i].myRow.two.name = INPUT_NAME_PREFIX + count; // input text
				
				// CONFIG: next line is affected by myRowObject settings
				var tempVal = tbl.tBodies[0].rows[i].myRow.two.value.split(' '); // for debug purposes
				tbl.tBodies[0].rows[i].myRow.two.value = count + ' was' + tempVal[0]; // for debug purposes
				
				// CONFIG: next line is affected by myRowObject settings
				tbl.tBodies[0].rows[i].myRow.four.value = count; // input radio
				
				// CONFIG: requires class named classy0 and classy1
				tbl.tBodies[0].rows[i].className = 'classy' + (count % 2);
				
				count++;
			}
		}
	}
}

deleteRows = function (rowObjArray)
{
	if (hasLoaded) {
		for (var i=0; i<rowObjArray.length; i++) {
			var rIndex = rowObjArray[i].sectionRowIndex;
			rowObjArray[i].parentNode.deleteRow(rIndex);
		}
	}
}

openInNewWindow = function (frm)
{
	// open a blank window
	var aWindow = window.open('', 'TableAddRow3NewWindow',
	'scrollbars=yes,menubar=yes,resizable=yes,toolbar=no,width=400,height=400');
	
	// set the target to the blank window
	frm.target = 'TableAddRow3NewWindow';
	
	// submit
	frm.submit();
}
</script>
<html>
<form action="tableaddrow3.html" method="get">
<p>
<input type="button" value="Add" onclick="addRowToTable();" />
<input type="button" value="Insert [I]" onclick="insertRowToTable();" />
<input type="button" value="Delete [D]" onclick="deleteChecked();" />
<input type="button" value="Submit" onclick="openInNewWindow(this.form);" />
</p>
<table border="0" cellspacing="0" id="tblSample3">
  <thead>
  <tr>
    <th colspan="5">Sample table</th>
  </tr>
  <tr>
    <th>#</th><th>Input Text</th><th>Delete</th><th>D</th><th>I</th>
  </tr>
  </thead>
  <tbody></tbody>
</table>
</form>
</html>
    * Return data
    * setData
/***
|''Name:''|DataTiddlerPlugin|
|''Version:''|1.0.6 (2006-08-26)|
|''Source:''|http://tiddlywiki.abego-software.de/#DataTiddlerPlugin|
|''Author:''|UdoBorkowski (ub [at] abego-software [dot] de)|
|''Licence:''|[[BSD open source license]]|
|''TiddlyWiki:''|1.2.38+, 2.0|
|''Browser:''|Firefox 1.0.4+; InternetExplorer 6.0|
!Description
Enhance your tiddlers with structured data (such as strings, booleans, numbers, or even arrays and compound objects) that can be easily accessed and modified through named fields (in JavaScript code).

Such tiddler data can be used in various applications. E.g. you may create tables that collect data from various tiddlers. 

''//Example: "Table with all December Expenses"//''
{{{
<<forEachTiddler
 where
 'tiddler.tags.contains("expense") && tiddler.data("month") == "Dec"'
 write
 '"|[["+tiddler.title+"]]|"+tiddler.data("descr")+"| "+tiddler.data("amount")+"|\n"'
>>
}}}
//(This assumes that expenses are stored in tiddlers tagged with "expense".)//
<<forEachTiddler
 where
 'tiddler.tags.contains("expense") && tiddler.data("month") == "Dec"'
 write
 '"|[["+tiddler.title+"]]|"+tiddler.data("descr")+"| "+tiddler.data("amount")+"|\n"'
>>
For other examples see DataTiddlerExamples.




''Access and Modify Tiddler Data''

You can "attach" data to every tiddler by assigning a JavaScript value (such as a string, boolean, number, or even arrays and compound objects) to named fields. 

These values can be accessed and modified through the following Tiddler methods:
|!Method|!Example|!Description|
|{{{data(field)}}}|{{{t.data("age")}}}|Returns the value of the given data field of the tiddler. When no such field is defined or its value is undefined {{{undefined}}} is returned.|
|{{{data(field,defaultValue)}}}|{{{t.data("isVIP",false)}}}|Returns the value of the given data field of the tiddler. When no such field is defined or its value is undefined the defaultValue is returned.|
|{{{data()}}}|{{{t.data()}}}|Returns the data object of the tiddler, with a property for every field. The properties of the returned data object may only be read and not be modified. To modify the data use DataTiddler.setData(...) or the corresponding Tiddler method.|
|{{{setData(field,value)}}}|{{{t.setData("age",42)}}}|Sets the value of the given data field of the tiddler to the value. When the value is {{{undefined}}} the field is removed.|
|{{{setData(field,value,defaultValue)}}}|{{{t.setData("isVIP",flag,false)}}}|Sets the value of the given data field of the tiddler to the value. When the value is equal to the defaultValue no value is set (and the field is removed).|

Alternatively you may use the following functions to access and modify the data. In this case the tiddler argument is either a tiddler or the name of a tiddler.
|!Method|!Description|
|{{{DataTiddler.getData(tiddler,field)}}}|Returns the value of the given data field of the tiddler. When no such field is defined or its value is undefined {{{undefined}}} is returned.|
|{{{DataTiddler.getData(tiddler,field,defaultValue)}}}|Returns the value of the given data field of the tiddler. When no such field is defined or its value is undefined the defaultValue is returned.|
|{{{DataTiddler.getDataObject(tiddler)}}}|Returns the data object of the tiddler, with a property for every field. The properties of the returned data object may only be read and not be modified. To modify the data use DataTiddler.setData(...) or the corresponding Tiddler method.|
|{{{DataTiddler.setData(tiddler,field,value)}}}|Sets the value of the given data field of the tiddler to the value. When the value is {{{undefined}}} the field is removed.|
|{{{DataTiddler.setData(tiddler,field,value,defaultValue)}}}|Sets the value of the given data field of the tiddler to the value. When the value is equal to the defaultValue no value is set (and the field is removed).|
//(For details on the various functions see the detailed comments in the source code.)//


''Data Representation in a Tiddler''

The data of a tiddler is stored as plain text in the tiddler's content/text, inside a "data" section that is framed by a {{{<data>...</data>}}} block. Inside the data section the information is stored in the [[JSON format|http://www.crockford.com/JSON/index.html]]. 

//''Data Section Example:''//
{{{
<data>{"isVIP":true,"user":"John Brown","age":34}</data>
}}}

The data section is not displayed when viewing the tiddler (see also "The showData Macro").

Beside the data section a tiddler may have all kind of other content.

Typically you will not access the data section text directly but use the methods given above. Nevertheless you may retrieve the text of the data section's content through the {{{DataTiddler.getDataText(tiddler)}}} function.


''Saving Changes''

The "setData" methods respect the "ForceMinorUpdate" and "AutoSave" configuration values. I.e. when "ForceMinorUpdate" is true changing a value using setData will not affect the "modifier" and "modified" attributes. With "AutoSave" set to true every setData will directly save the changes after a setData.


''Notifications''

No notifications are sent when a tiddler's data value is changed through the "setData" methods. 

''Escape Data Section''
In case that you want to use the text {{{<data>}}} or {{{</data>}}} in a tiddler text you must prefix the text with a tilde ('~'). Otherwise it may be wrongly considered as the data section. The tiddler text {{{~<data>}}} is displayed as {{{<data>}}}.


''The showData Macro''

By default the data of a tiddler (that is stored in the {{{<data>...</data>}}} section of the tiddler) is not displayed. If you want to display this data you may used the {{{<<showData ...>>}}} macro:

''Syntax:'' 
|>|{{{<<}}}''showData '' [''JSON''] [//tiddlerName//] {{{>>}}}|
|''JSON''|By default the data is rendered as a table with a "Name" and "Value" column. When defining ''JSON'' the data is rendered in JSON format|
|//tiddlerName//|Defines the tiddler holding the data to be displayed. When no tiddler is given the tiddler containing the showData macro is used. When the tiddler name contains spaces you must quote the name (or use the {{{[[...]]}}} syntax.)|
|>|~~Syntax formatting: Keywords in ''bold'', optional parts in [...]. 'or' means that exactly one of the two alternatives must exist.~~|


!Revision history
* v1.0.6 (2006-08-26) 
** Removed misleading comment
* v1.0.5 (2006-02-27) (Internal Release Only)
** Internal
*** Make "JSLint" conform
* v1.0.4 (2006-02-05)
** Bugfix: showData fails in TiddlyWiki 2.0
* v1.0.3 (2006-01-06)
** Support TiddlyWiki 2.0
* v1.0.2 (2005-12-22)
** Enhancements:
*** Handle texts "<data>" or "</data>" more robust when used in a tiddler text or as a field value.
*** Improved (JSON) error messages.
** Bugs fixed: 
*** References are not updated when using the DataTiddler.
*** Changes to compound objects are not always saved.
*** "~</data>" is not rendered correctly (expected "</data>")
* v1.0.1 (2005-12-13)
** Features: 
*** The showData macro supports an optional "tiddlername" argument to specify the tiddler containing the data to be displayed
** Bugs fixed: 
*** A script immediately following a data section is deleted when the data is changed. (Thanks to GeoffS for reporting.)
* v1.0.0 (2005-12-12)
** initial version

!Code
***/
//{{{
//============================================================================
//============================================================================
// DataTiddlerPlugin
//============================================================================
//============================================================================

// Ensure that the DataTiddler Plugin is only installed once.
//
if (!version.extensions.DataTiddlerPlugin) {



version.extensions.DataTiddlerPlugin = {
 major: 1, minor: 0, revision: 6,
 date: new Date(2006, 7, 26), 
 type: 'plugin',
 source: "http://tiddlywiki.abego-software.de/#DataTiddlerPlugin"
};

// For backward compatibility with v1.2.x
//
if (!window.story) window.story=window; 
if (!TiddlyWiki.prototype.getTiddler) {
 TiddlyWiki.prototype.getTiddler = function(title) { 
 var t = this.tiddlers[title]; 
 return (t !== undefined && t instanceof Tiddler) ? t : null; 
 };
}

//============================================================================
// DataTiddler Class
//============================================================================

// ---------------------------------------------------------------------------
// Configurations and constants 
// ---------------------------------------------------------------------------

function DataTiddler() {
}

DataTiddler = {
 // Function to stringify a JavaScript value, producing the text for the data section content.
 // (Must match the implementation of DataTiddler.parse.)
 //
 stringify : null,
 

 // Function to parse the text for the data section content, producing a JavaScript value.
 // (Must match the implementation of DataTiddler.stringify.)
 //
 parse : null
};

// Ensure access for IE
window.DataTiddler = DataTiddler;

// ---------------------------------------------------------------------------
// Data Accessor and Mutator
// ---------------------------------------------------------------------------


// Returns the value of the given data field of the tiddler.
// When no such field is defined or its value is undefined
// the defaultValue is returned.
// 
// @param tiddler either a tiddler name or a tiddler
//
DataTiddler.getData = function(tiddler, field, defaultValue) {
 var t = (typeof tiddler == "string") ? store.getTiddler(tiddler) : tiddler;
 if (!(t instanceof Tiddler)) {
 throw "Tiddler expected. Got "+tiddler;
 }

 return DataTiddler.getTiddlerDataValue(t, field, defaultValue);
};


// Sets the value of the given data field of the tiddler to
// the value. When the value is equal to the defaultValue
// no value is set (and the field is removed)
//
// Changing data of a tiddler will not trigger notifications.
// 
// @param tiddler either a tiddler name or a tiddler
//
DataTiddler.setData = function(tiddler, field, value, defaultValue) {
 var t = (typeof tiddler == "string") ? store.getTiddler(tiddler) : tiddler;
 if (!(t instanceof Tiddler)) {
 throw "Tiddler expected. Got "+tiddler+ "("+t+")";
 }

 DataTiddler.setTiddlerDataValue(t, field, value, defaultValue);
};


// Returns the data object of the tiddler, with a property for every field.
//
// The properties of the returned data object may only be read and
// not be modified. To modify the data use DataTiddler.setData(...) 
// or the corresponding Tiddler method.
//
// If no data section is defined a new (empty) object is returned.
//
// @param tiddler either a tiddler name or a Tiddler
//
DataTiddler.getDataObject = function(tiddler) {
 var t = (typeof tiddler == "string") ? store.getTiddler(tiddler) : tiddler;
 if (!(t instanceof Tiddler)) {
 throw "Tiddler expected. Got "+tiddler;
 }

 return DataTiddler.getTiddlerDataObject(t);
};

// Returns the text of the content of the data section of the tiddler.
//
// When no data section is defined for the tiddler null is returned 
//
// @param tiddler either a tiddler name or a Tiddler
// @return [may be null]
//
DataTiddler.getDataText = function(tiddler) {
 var t = (typeof tiddler == "string") ? store.getTiddler(tiddler) : tiddler;
 if (!(t instanceof Tiddler)) {
 throw "Tiddler expected. Got "+tiddler;
 }

 return DataTiddler.readDataSectionText(t);
};


// ---------------------------------------------------------------------------
// Internal helper methods (must not be used by code from outside this plugin)
// ---------------------------------------------------------------------------

// Internal.
//
// The original JSONError is not very user friendly, 
// especially it does not define a toString() method
// Therefore we extend it here.
//
DataTiddler.extendJSONError = function(ex) {
 if (ex.name == 'JSONError') {
 ex.toString = function() {
 return ex.name + ": "+ex.message+" ("+ex.text+")";
 };
 }
 return ex;
};

// Internal.
//
// @param t a Tiddler
//
DataTiddler.getTiddlerDataObject = function(t) {
 if (t.dataObject === undefined) {
 var data = DataTiddler.readData(t);
 t.dataObject = (data) ? data : {};
 }
 
 return t.dataObject;
};


// Internal.
//
// @param tiddler a Tiddler
//
DataTiddler.getTiddlerDataValue = function(tiddler, field, defaultValue) {
 var value = DataTiddler.getTiddlerDataObject(tiddler)[field];
 return (value === undefined) ? defaultValue : value;
};


// Internal.
//
// @param tiddler a Tiddler
//
DataTiddler.setTiddlerDataValue = function(tiddler, field, value, defaultValue) {
 var data = DataTiddler.getTiddlerDataObject(tiddler);
 var oldValue = data[field];
 
 if (value == defaultValue) {
 if (oldValue !== undefined) {
 delete data[field];
 DataTiddler.save(tiddler);
 }
 return;
 }
 data[field] = value;
 DataTiddler.save(tiddler);
};

// Internal.
//
// Reads the data section from the tiddler's content and returns its text
// (as a String).
//
// Returns null when no data is defined.
//
// @param tiddler a Tiddler
// @return [may be null]
//
DataTiddler.readDataSectionText = function(tiddler) {
 var matches = DataTiddler.getDataTiddlerMatches(tiddler);
 if (matches === null || !matches[2]) {
 return null;
 }
 return matches[2];
};

// Internal.
//
// Reads the data section from the tiddler's content and returns it
// (as an internalized object).
//
// Returns null when no data is defined.
//
// @param tiddler a Tiddler
// @return [may be null]
//
DataTiddler.readData = function(tiddler) {
 var text = DataTiddler.readDataSectionText(tiddler);
 try {
 return text ? DataTiddler.parse(text) : null;
 } catch(ex) {
 throw DataTiddler.extendJSONError(ex);
 }
};

// Internal.
// 
// Returns the serialized text of the data of the given tiddler, as it
// should be stored in the data section.
//
// @param tiddler a Tiddler
//
DataTiddler.getDataTextOfTiddler = function(tiddler) {
 var data = DataTiddler.getTiddlerDataObject(tiddler);
 return DataTiddler.stringify(data);
};


// Internal.
// 
DataTiddler.indexOfNonEscapedText = function(s, subString, startIndex) {
 var index = s.indexOf(subString, startIndex);
 while ((index > 0) && (s[index-1] == '~')) { 
 index = s.indexOf(subString, index+1);
 }
 return index;
};

// Internal.
//
DataTiddler.getDataSectionInfo = function(text) {
 // Special care must be taken to handle "<data>" and "</data>" texts inside
 // a data section. 
 // Also take care not to use an escaped <data> (i.e. "~<data>") as the start 
 // of a data section. (Same for </data>)

 // NOTE: we are explicitly searching for a data section that contains a JSON
 // string, i.e. framed with braces. This way we are little bit more robust in
 // case the tiddler contains unescaped texts "<data>" or "</data>". This must
 // be changed when using a different stringifier.

 var startTagText = "<data>{";
 var endTagText = "}</data>";

 var startPos = 0;

 // Find the first not escaped "<data>".
 var startDataTagIndex = DataTiddler.indexOfNonEscapedText(text, startTagText, 0);
 if (startDataTagIndex < 0) {
 return null;
 }

 // Find the *last* not escaped "</data>".
 var endDataTagIndex = text.indexOf(endTagText, startDataTagIndex);
 if (endDataTagIndex < 0) {
 return null;
 }
 var nextEndDataTagIndex;
 while ((nextEndDataTagIndex = text.indexOf(endTagText, endDataTagIndex+1)) >= 0) {
 endDataTagIndex = nextEndDataTagIndex;
 }

 return {
 prefixEnd: startDataTagIndex, 
 dataStart: startDataTagIndex+(startTagText.length)-1, 
 dataEnd: endDataTagIndex, 
 suffixStart: endDataTagIndex+(endTagText.length)
 };
};

// Internal.
// 
// Returns the "matches" of a content of a DataTiddler on the
// "data" regular expression. Return null when no data is defined
// in the tiddler content.
//
// Group 1: text before data section (prefix)
// Group 2: content of data section
// Group 3: text behind data section (suffix)
//
// @param tiddler a Tiddler
// @return [may be null] null when the tiddler contains no data section, otherwise see above.
//
DataTiddler.getDataTiddlerMatches = function(tiddler) {
 var text = tiddler.text;
 var info = DataTiddler.getDataSectionInfo(text);
 if (!info) {
 return null;
 }

 var prefix = text.substr(0,info.prefixEnd);
 var data = text.substr(info.dataStart, info.dataEnd-info.dataStart+1);
 var suffix = text.substr(info.suffixStart);
 
 return [text, prefix, data, suffix];
};


// Internal.
//
// Saves the data in a <data> block of the given tiddler (as a minor change). 
//
// The "chkAutoSave" and "chkForceMinorUpdate" options are respected. 
// I.e. the TiddlyWiki *file* is only saved when AutoSave is on.
//
// Notifications are not send. 
//
// This method should only be called when the data really has changed. 
//
// @param tiddler
// the tiddler to be saved.
//
DataTiddler.save = function(tiddler) {

 var matches = DataTiddler.getDataTiddlerMatches(tiddler);

 var prefix;
 var suffix;
 if (matches === null) {
 prefix = tiddler.text;
 suffix = "";
 } else {
 prefix = matches[1];
 suffix = matches[3];
 }

 var dataText = DataTiddler.getDataTextOfTiddler(tiddler);
 var newText = 
 (dataText !== null) 
 ? prefix + "<data>" + dataText + "</data>" + suffix
 : prefix + suffix;
 if (newText != tiddler.text) {
 // make the change in the tiddlers text
 
 // ... see DataTiddler.MyTiddlerChangedFunction
 tiddler.isDataTiddlerChange = true;
 
 // ... do the action change
 tiddler.set(
 tiddler.title,
 newText,
 config.options.txtUserName, 
 config.options.chkForceMinorUpdate? undefined : new Date(),
 tiddler.tags);

 // ... see DataTiddler.MyTiddlerChangedFunction
 delete tiddler.isDataTiddlerChange;

 // Mark the store as dirty.
 store.dirty = true;
 
 // AutoSave if option is selected
 if(config.options.chkAutoSave) {
 saveChanges();
 }
 }
};

// Internal.
//
DataTiddler.MyTiddlerChangedFunction = function() {
 // Remove the data object from the tiddler when the tiddler is changed
 // by code other than DataTiddler code. 
 //
 // This is necessary since the data object is just a "cached version" 
 // of the data defined in the data section of the tiddler and the 
 // "external" change may have changed the content of the data section.
 // Thus we are not sure if the data object reflects the data section 
 // contents. 
 // 
 // By deleting the data object we ensure that the data object is 
 // reconstructed the next time it is needed, with the data defined by
 // the data section in the tiddler's text.
 
 // To indicate that a change is a "DataTiddler change" a temporary
 // property "isDataTiddlerChange" is added to the tiddler.
 if (this.dataObject && !this.isDataTiddlerChange) {
 delete this.dataObject;
 }
 
 // call the original code.
 DataTiddler.originalTiddlerChangedFunction.apply(this, arguments);
};


//============================================================================
// Formatters
//============================================================================

// This formatter ensures that "~<data>" is rendered as "<data>". This is used to 
// escape the "<data>" of a data section, just in case someone really wants to use
// "<data>" as a text in a tiddler and not start a data section.
//
// Same for </data>.
//
config.formatters.push( {
 name: "data-escape",
 match: "~<\\/?data>",

 handler: function(w) {
 w.outputText(w.output,w.matchStart + 1,w.nextMatch);
 }
} );


// This formatter ensures that <data>...</data> sections are not rendered.
//
config.formatters.push( {
 name: "data",
 match: "<data>",

 handler: function(w) {
 var info = DataTiddler.getDataSectionInfo(w.source);
 if (info && info.prefixEnd == w.matchStart) {
 w.nextMatch = info.suffixStart;
 } else {
 w.outputText(w.output,w.matchStart,w.nextMatch);
 }
 }
} );


//============================================================================
// Tiddler Class Extension
//============================================================================

// "Hijack" the changed method ---------------------------------------------------

DataTiddler.originalTiddlerChangedFunction = Tiddler.prototype.changed;
Tiddler.prototype.changed = DataTiddler.MyTiddlerChangedFunction;

// Define accessor methods -------------------------------------------------------

// Returns the value of the given data field of the tiddler. When no such field 
// is defined or its value is undefined the defaultValue is returned.
//
// When field is undefined (or null) the data object is returned. (See 
// DataTiddler.getDataObject.)
//
// @param field [may be null, undefined]
// @param defaultValue [may be null, undefined]
// @return [may be null, undefined]
//
Tiddler.prototype.data = function(field, defaultValue) {
 return (field) 
 ? DataTiddler.getTiddlerDataValue(this, field, defaultValue)
 : DataTiddler.getTiddlerDataObject(this);
};

// Sets the value of the given data field of the tiddler to the value. When the 
// value is equal to the defaultValue no value is set (and the field is removed).
//
// @param value [may be null, undefined]
// @param defaultValue [may be null, undefined]
//
Tiddler.prototype.setData = function(field, value, defaultValue) {
 DataTiddler.setTiddlerDataValue(this, field, value, defaultValue);
};


//============================================================================
// showData Macro
//============================================================================

config.macros.showData = {
 // Standard Properties
 label: "showData",
 prompt: "Display the values stored in the data section of the tiddler"
};

config.macros.showData.handler = function(place,macroName,params) {
 // --- Parsing ------------------------------------------

 var i = 0; // index running over the params
 // Parse the optional "JSON"
 var showInJSONFormat = false;
 if ((i < params.length) && params[i] == "JSON") {
 i++;
 showInJSONFormat = true;
 }
 
 var tiddlerName = story.findContainingTiddler(place).id.substr(7);
 if (i < params.length) {
 tiddlerName = params[i];
 i++;
 }

 // --- Processing ------------------------------------------
 try {
 if (showInJSONFormat) {
 this.renderDataInJSONFormat(place, tiddlerName);
 } else {
 this.renderDataAsTable(place, tiddlerName);
 }
 } catch (e) {
 this.createErrorElement(place, e);
 }
};

config.macros.showData.renderDataInJSONFormat = function(place,tiddlerName) {
 var text = DataTiddler.getDataText(tiddlerName);
 if (text) {
 createTiddlyElement(place,"pre",null,null,text);
 }
};

config.macros.showData.renderDataAsTable = function(place,tiddlerName) {
 var text = "|!Name|!Value|\n";
 var data = DataTiddler.getDataObject(tiddlerName);
 if (data) {
 for (var i in data) {
 var value = data[i];
 text += "|"+i+"|"+DataTiddler.stringify(value)+"|\n";
 }
 }
 
 wikify(text, place);
};


// Internal.
//
// Creates an element that holds an error message
// 
config.macros.showData.createErrorElement = function(place, exception) {
 var message = (exception.description) ? exception.description : exception.toString();
 return createTiddlyElement(place,"span",null,"showDataError","<<showData ...>>: "+message);
};

// ---------------------------------------------------------------------------
// Stylesheet Extensions (may be overridden by local StyleSheet)
// ---------------------------------------------------------------------------
//
setStylesheet(
 ".showDataError{color: #ffffff;background-color: #880000;}",
 "showData");


} // of "install only once"
// Used Globals (for JSLint) ==============

// ... TiddlyWiki Core
/*global createTiddlyElement, saveChanges, store, story, wikify */
// ... DataTiddler
/*global DataTiddler */
// ... JSON
/*global JSON */
 

/***
!JSON Code, used to serialize the data
***/
/*
Copyright (c) 2005 JSON.org

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The Software shall be used for Good, not Evil.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/

/*
 The global object JSON contains two methods.

 JSON.stringify(value) takes a JavaScript value and produces a JSON text.
 The value must not be cyclical.

 JSON.parse(text) takes a JSON text and produces a JavaScript value. It will
 throw a 'JSONError' exception if there is an error.
*/
var JSON = {
 copyright: '(c)2005 JSON.org',
 license: 'http://www.crockford.com/JSON/license.html',
/*
 Stringify a JavaScript value, producing a JSON text.
*/
 stringify: function (v) {
 var a = [];

/*
 Emit a string.
*/
 function e(s) {
 a[a.length] = s;
 }

/*
 Convert a value.
*/
 function g(x) {
 var c, i, l, v;

 switch (typeof x) {
 case 'object':
 if (x) {
 if (x instanceof Array) {
 e('[');
 l = a.length;
 for (i = 0; i < x.length; i += 1) {
 v = x[i];
 if (typeof v != 'undefined' &&
 typeof v != 'function') {
 if (l < a.length) {
 e(',');
 }
 g(v);
 }
 }
 e(']');
 return;
 } else if (typeof x.toString != 'undefined') {
 e('{');
 l = a.length;
 for (i in x) {
 v = x[i];
 if (x.hasOwnProperty(i) &&
 typeof v != 'undefined' &&
 typeof v != 'function') {
 if (l < a.length) {
 e(',');
 }
 g(i);
 e(':');
 g(v);
 }
 }
 return e('}');
 }
 }
 e('null');
 return;
 case 'number':
 e(isFinite(x) ? +x : 'null');
 return;
 case 'string':
 l = x.length;
 e('"');
 for (i = 0; i < l; i += 1) {
 c = x.charAt(i);
 if (c >= ' ') {
 if (c == '\\' || c == '"') {
 e('\\');
 }
 e(c);
 } else {
 switch (c) {
 case '\b':
 e('\\b');
 break;
 case '\f':
 e('\\f');
 break;
 case '\n':
 e('\\n');
 break;
 case '\r':
 e('\\r');
 break;
 case '\t':
 e('\\t');
 break;
 default:
 c = c.charCodeAt();
 e('\\u00' + Math.floor(c / 16).toString(16) +
 (c % 16).toString(16));
 }
 }
 }
 e('"');
 return;
 case 'boolean':
 e(String(x));
 return;
 default:
 e('null');
 return;
 }
 }
 g(v);
 return a.join('');
 },
/*
 Parse a JSON text, producing a JavaScript value.
*/
 parse: function (text) {
 var p = /^\s*(([,:{}\[\]])|"(\\.|[^\x00-\x1f"\\])*"|-?\d+(\.\d*)?([eE][+-]?\d+)?|true|false|null)\s*/,
 token,
 operator;

 function error(m, t) {
 throw {
 name: 'JSONError',
 message: m,
 text: t || operator || token
 };
 }

 function next(b) {
 if (b && b != operator) {
 error("Expected '" + b + "'");
 }
 if (text) {
 var t = p.exec(text);
 if (t) {
 if (t[2]) {
 token = null;
 operator = t[2];
 } else {
 operator = null;
 try {
 token = eval(t[1]);
 } catch (e) {
 error("Bad token", t[1]);
 }
 }
 text = text.substring(t[0].length);
 } else {
 error("Unrecognized token", text);
 }
 } else {
 token = operator = undefined;
 }
 }


 function val() {
 var k, o;
 switch (operator) {
 case '{':
 next('{');
 o = {};
 if (operator != '}') {
 for (;;) {
 if (operator || typeof token != 'string') {
 error("Missing key");
 }
 k = token;
 next();
 next(':');
 o[k] = val();
 if (operator != ',') {
 break;
 }
 next(',');
 }
 }
 next('}');
 return o;
 case '[':
 next('[');
 o = [];
 if (operator != ']') {
 for (;;) {
 o.push(val());
 if (operator != ',') {
 break;
 }
 next(',');
 }
 }
 next(']');
 return o;
 default:
 if (operator !== null) {
 error("Missing value");
 }
 k = token;
 next();
 return k;
 }
 }
 next();
 return val();
 }
};

/***
!Setup the data serialization
***/

DataTiddler.format = "JSON";
DataTiddler.stringify = JSON.stringify;
DataTiddler.parse = JSON.parse;

//}}}
[[SIteMap2]]
http://devpad.tiddlyspot.com/#TiddlerPopupMacro
http://distortedreality.tiddlyspot.com/

Features:
* uses SiteMap plugin
* ideal to present site map at first glance
|!Format|!Markup|!Example|
|''Headings''|{{{!!Heading 2}}}<<br>>{{{!!!Heading 3}}}<<br>>{{{!!!!Heading 4}}}<<br>>{{{!!!!!Heading 5}}}<<br>><<br>>Usually avoid Heading1 as Tiddler titles are nominally Heading1.|<html><h2>Heading 2</h2><h3>Heading 3</h3><h4>Heading 4</h4><h5>Heading 5</h5></html>|
|''Lists''|{{{*Bulleted list}}}|<html><ul><li>Bulleted List</li></ul></html>|
|~|{{{#Numbered list}}}|<html><ol><li>Numbered List</li></ol></html>|
|~|Definition list<<br>>{{{;Term}}}<<br>>{{{:definition}}}|<html><dl><dt>Term</dt><dd>definition</dd></dl></html>|
|~|Lists can be mixed and nested<<br>>{{{*}}}Bullet<<br>>{{{*#}}}Number<<br>>{{{*#;}}}Item<<br>>{{{*#:}}}Definition|<html><ul><li>Bullet<ol><li>Numbered<dl><dt></dt>Item<dd>Definition</dd></dl></li></ol></li></ul></html>|
|''Block quotes''|{{{>Blockquote}}}<<br>>{{{>>Nested quote}}}|<html><blockquote>Blockquote<blockquote>Nested<br/> quote</blockquote></blockquote></html>|
|~|{{{<<<}}}<<br>>{{{multi-line}}}<<br>>{{{blockquote}}}<<br>>{{{<<<}}}|<html><blockquote>multi-line<br/>blockquote</blockquote></html>|
|''Horizontal Rule''|{{{----}}} (4 dashes on a line of their own)|<html><hr></html>|
|''Links''|Any {{{WikiWord}}} creates a link to a tiddler (whether it exists or not).<<br>>Note that a WikiWord has to start with a capital letter and have a further mix of upper and lower case.|[[WikiWord]]|
|~|Manual link<<br>>{{{[[Table of Contents]]}}} (Especially for tiddlers with spaces in their titles)|[[Table of Contents]]|
|~|{{{[[Pretty Link|Link]]}}}|[[Pretty Link|Link]]|
|~|Automatic external link {{{http://www.tiddlywiki.com}}}|http://www.tiddlywiki.com|
|~|Pretty external link<<br>>{{{[[My Home Page|http://www.tiddlywiki.com]]}}}|[[My Home Page|http://www.tiddlywiki.com]]|
|~|OS Folder link<<br>>Windows Share: {{{file://///server/share}}}<<br>>Windows Local: {{{file:///c:/folder/file}}}<<br>>Un*x Local File: {{{file://folder/file}}}<<br>>Relative File: {{{[[folder/file]]}}}<<br>>File with spaces: {{{file:///c:/My Documents/file}}} |file://///server/share <<br>>file:///c:/folder/file <<br>>file://folder/file <<br>><<br>> [[folder/file]]<<br>>file:///c:/My%20Documents/file |
|''Images''|{{{[img[favicon.ico]]}}}<<br>>Note that image files are always external to the TW file|[img[http://www.tiddlywiki.com/favicon.ico]]|
|~|Right aligned<<br>>{{{[>img[favicon.ico]]}}}|[>img[http://www.tiddlywiki.com/favicon.ico]]|
|~|Left aligned<<br>>{{{[<img[favicon.ico]]}}}|[<img[http://www.tiddlywiki.com/favicon.ico]]|
|''Image Links''|{{{[img[fav.ico][TiddlerName]]}}}|[img[http://www.tiddlywiki.com/favicon.ico][TiddlerName]]|
|~|{{{[img[fav.ico][Alias|TiddlerName]]}}}|[img[http://www.tiddlywiki.com/favicon.ico][Alias|TiddlerName]]|
|~|{{{[img[fav.ico][http://www.aa.com]]}}}|[img[http://www.tiddlywiki.com/favicon.ico][http://www.tiddlywiki.com]]|
|~|>|also see ''Links'' and ''Images'' sections in this table|
|''Inline''<<br>>''Comments''|{{{Not shown: /% hidden comment %/}}}<<br>>Text between the markers will not be shown|Not shown:/% hidden text %/|
|[[StatusDefinitions]]|<<ValueSwitcher dropdown StatusDefinitions>>|
|[[WellType]]|<<ValueSwitcher dropdown WellType>>|
<data>{"WellType":"Vertical","StatusDefinitions":"Pending"}</data>
/***
|''Name:''|DropdownByTagPlugin|
|''Description:''|Gather values from a definition tiddler, and present the user with a UI for setting a value from those available options as an extende field |
|''Version:''|0.1|
|''Date:''|02 Feb, 2008|
|''Author:''|AlfonsoReyes ( (at) gmail (dot) com)|
|''License:''|[[BSD open source license]]|
|''CoreVersion:''|2.2|
***/

//{{{
// Ensure that this Plugin is only installed once.
if(!version.extensions.DropdownByTag) 
{
	version.extensions.DropdownByTag = {installed:true};
	config.macros.DropdownByTag = {
	
		handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		
			var taskTiddler = story.findContainingTiddler(place);
			if(!(taskTiddler && taskTiddler != 'undefined')) {
				return;
			}
			
			var ctrlType = params[0];
			var valueSrc = params[1]; //this can be used for DataTiddler
			var id = taskTiddler.id;
			var title = id.substr(7);
			var tiddler = store.getTiddler(title);
			
			// build a drop down control
			if(ctrlType == 'dropdown') {
				var selected = valueSrc + '_' + store.getValue(tiddler,valueSrc);
				
				var values = this.getDefValues(valueSrc);
				var options = [];
				//DataTiddler.setData(title,valueSrc,option)
				options.push({'caption': 'Please select', 'name': null});
				for (var i=0; i < values.length; i++) {
					options.push({'caption': values[i], 'name': valueSrc + '_' + values[i]});
				}

				var cTDD = createTiddlyDropDown(place,this.setDropDownMetaData,options,selected);	
				//alert(cTDD.value);

			}
			//build a date control
			else if(ctrlType == 'date'){
				//TODO: Build in deadline support
			}
		},
		
		getDefValues: function(src) {
			var text = store.getTiddlerText(src);
			return (text.split('\n'));	
		},
		
	};
}
//}}}
<<tiddler NewDropdownRecord>>
|status|<<ValueSwitcher dropdown StatusDefinitions>>|
<div class="toolbar" macro="toolbar -closeTiddler closeOthers +editTiddler permalink references jump newHere"></div>
<div class="tagglyTagged" ></div>
<div><span class="title" macro="view title"></span><span class="miniTag" macro="miniTag"></span></div>
<div class='subtitle'>Created <span macro='view created date [[DD/MM/YY]]'></span>, updated <span macro='view modified date [[DD/MM/YY]]'></span></div>
<div class="viewer" macro="view text wikified"></div>
<div class='viewer'>
<span macro='select status rows:1 allowOther "not started" "in progress" "on hold" "completed"'></span><data>{}</data></div>

<<ValueSwitcher dropdown StatusDefinitions>>
<<ValueSwitcher dropdown WellType>>
<script show>
 return (new Date()).toString();
</script>
http://mit.edu/apg/

Features:
* main page with image
* simple and neat presentation
* use tabs within pages
* ideal for small website
[[MptwEditTemplate]]
<<toolbar editTiddler>> 
https://wesfiles.wesleyan.edu/home/espringer/web/

Features:
* mouse-over effect on tiddlers
* neat presentation
* ideal for a web page or web site presentation
* nice graphics
* tiddler with line drop on left
* references link
If you put this HTML in a tiddler, you can embed webpages in TiddlyWiki
{{{
<html><a href="http://www.flickr.com/photos/giffmex/104273681/" 
title="Photo Sharing"><img 
src="http://farm1.static.flickr.com/38/104273681_fa9947a962_m.jpg" 
width="240" height="160" alt="100_1474b" /></a></html>
}}}
<html><a href="http://www.flickr.com/photos/giffmex/104273681/" title="Photo Sharing"><img src="http://farm1.static.flickr.com/38/104273681_fa9947a962_m.jpg" width="240" height="160" alt="100_1474b" /></a></html>
{{{
<html>
<object width="425" height="350"><param name="movie" 
value="http://www.youtube.com/v/FfMUwCKtWMI"></param>
<param name="wmode" value="transparent"></param>
<embed src="http://www.youtube.com/v/FfMUwCKtWMI"
type="application/x-shockwave-flash" wmode="transparent" 
width="425" height="350"></embed></object>
</html>
}}}
<html>
<object width="425" height="350"><param name="movie" value="http://www.youtube.com/v/FfMUwCKtWMI"></param><param name="wmode" value="transparent"></param><embed src="http://www.youtube.com/v/FfMUwCKtWMI" type="application/x-shockwave-flash" wmode="transparent" width="425" height="350"></embed></object>
</html>
{{{
<html>
<iframe src="http://www.google.com/search?hl=en&
client=ig&q=weather+60565" width=528 height=270">
</iframe>
</html>
}}}
<html>
<iframe src="http://www.google.com/search?hl=en&
client=ig&q=weather+60565" width=528 height=270">
</iframe>
</html>

Source: 
{{wrappingClass{
Text that is now accentuated
Hello. This is kind of blueish gray color
}}}
{{{
var employees = { "accounting" : [   // accounting is an array in employees.
                                    { "firstName" : "John",  // First element
                                      "lastName"  : "Doe",
                                      "age"       : 23 },
                                    
                                    { "firstName" : "Mary",  // Second Element
                                      "lastName"  : "Smith",
                                      "age"       : 32 }
                                  ], // End "accounting" array.                                  
                  "sales"       : [ // Sales is another array in employees.
                                    { "firstName" : "Sally", // First Element
                                      "lastName"  : "Green",
                                      "age"       : 27 },
                                    
                                    { "firstName" : "Jim",   // Second Element
                                      "lastName"  : "Galley",
                                      "age"       : 41 }
                                  ] // End "sales" Array.
                } // End Employees
document.write(employees.sales[0].firstName + ' ' + employees.sales[0].lastName);
}}}
<script>
var employees = { "accounting" : [   // accounting is an array in employees.
                                    { "firstName" : "John",  // First element
                                      "lastName"  : "Doe",
                                      "age"       : 23 },
                                    
                                    { "firstName" : "Mary",  // Second Element
                                      "lastName"  : "Smith",
                                      "age"       : 32 }
                                  ], // End "accounting" array.                                  
                  "sales"       : [ // Sales is another array in employees.
                                    { "firstName" : "Sally", // First Element
                                      "lastName"  : "Green",
                                      "age"       : 27 },
                                    
                                    { "firstName" : "Jim",   // Second Element
                                      "lastName"  : "Galley",
                                      "age"       : 41 }
                                  ] // End "sales" Array.
                } // End Employees
document.write(employees.sales[0].firstName + ' ' + employees.sales[0].lastName + '<BR>');
document.write(employees.sales[1].firstName + ' ' + employees.sales[1].lastName);

</script>
<<slider AtEg ./atEg 'Extended example ...'>>
{{makeMeRed{Text accentuated}}}
/***
| Name:|ExtentTagButtonPlugin|
| Description:|Adds a New tiddler button in the tag drop down|
| Version:|3.2 ($Rev: 2406 $)|
| Date:|$Date: 2007-08-08 22:50:23 +1000 (Wed, 08 Aug 2007) $|
| Source:|http://mptw.tiddlyspot.com/#ExtendTagButtonPlugin|
| Author:|Simon Baird <simon.baird@gmail.com>|
| License|http://mptw.tiddlyspot.com/#TheBSDLicense|
***/
//{{{

window.onClickTag_mptw_orig = window.onClickTag;
window.onClickTag = function(e) {
	window.onClickTag_mptw_orig.apply(this,arguments);
	var tag = this.getAttribute("tag");
	var title = this.getAttribute("tiddler");
	// Saq, you're a genius :)
	var popup = Popup.stack[Popup.stack.length-1].popup;
	createTiddlyElement(createTiddlyElement(popup,"li",null,"listBreak"),"div");
	wikify("<<newTiddler label:'New tiddler' tag:'"+tag+"'>>",createTiddlyElement(popup,"li"));
	return false;
}

//}}}
/***
|''Name:''|FieldsEditorPlugin|
|''Description:''|//create//, //edit//, //view// and //delete// commands in toolbar <<toolbar fields>>.|
|''Version:''|1.0.2|
|''Date:''|Dec 21,2007|
|''Source:''|http://visualtw.ouvaton.org/VisualTW.html|
|''Author:''|Pascal Collin|
|''License:''|[[BSD open source license|License]]|
|''~CoreVersion:''|2.2.0|
|''Browser:''|Firefox 2.0; InternetExplorer 6.0, others|
!Demo:
On [[homepage|http://visualtw.ouvaton.org/VisualTW.html]], see [[FieldEditor example]]
!Installation:
*import this tiddler from [[homepage|http://visualtw.ouvaton.org/VisualTW.html]] (tagged as systemConfig)
*save and reload
*optionnaly : add the following css text in your StyleSheet : {{{#popup tr.fieldTableRow td {padding:1px 3px 1px 3px;}}}}
!Code
***/

//{{{

config.commands.fields.handlePopup = function(popup,title) {
	var tiddler = store.fetchTiddler(title);
	if(!tiddler)
		return;
	var fields = {};
	store.forEachField(tiddler,function(tiddler,fieldName,value) {fields[fieldName] = value;},true);
	var items = [];
	for(var t in fields) {
		var editCommand = "<<untiddledCall editFieldDialog "+escape(title)+" "+escape(t)+">>";
		var deleteCommand = "<<untiddledCall deleteField "+escape(title)+" "+escape(t)+">>";
		var renameCommand = "<<untiddledCall renameField "+escape(title)+" "+escape(t)+">>";
		items.push({field: t,value: fields[t], actions: editCommand+renameCommand+deleteCommand});
	}
	items.sort(function(a,b) {return a.field < b.field ? -1 : (a.field == b.field ? 0 : +1);});
	var createNewCommand = "<<untiddledCall createField "+escape(title)+">>";
	items.push({field : "", value : "", actions:createNewCommand });
	if(items.length > 0)
		ListView.create(popup,items,this.listViewTemplate);
	else
		createTiddlyElement(popup,"div",null,null,this.emptyText);
}

config.commands.fields.listViewTemplate = {
	columns: [
		{name: 'Field', field: 'field', title: "Field", type: 'String'},
		{name: 'Actions', field: 'actions', title: "Actions", type: 'WikiText'},
		{name: 'Value', field: 'value', title: "Value", type: 'WikiText'}
	],
	rowClasses: [
			{className: 'fieldTableRow', field: 'actions'}
	],
	buttons: [	//can't use button for selected then delete, because click on checkbox will hide the popup
	]
}

config.macros.untiddledCall = {  // when called from listview, tiddler is unset, so we need to pass tiddler as parameter
	handler : function(place,macroName,params,wikifier,paramString) {
		var macroName = params.shift();
		if (macroName) var macro = config.macros[macroName];
		var title = params.shift();
		if (title) var tiddler = store.getTiddler(unescape(title));
		if (macro) macro.handler(place,macroName,params,wikifier,paramString,tiddler);		
	}
}

config.macros.deleteField = {
	handler : function(place,macroName,params,wikifier,paramString,tiddler) {
		if(!readOnly && params[0]) {
			fieldName = unescape(params[0]);
			var btn = createTiddlyButton(place,"delete", "delete "+fieldName,this.onClickDeleteField);
			btn.setAttribute("title",tiddler.title);
			btn.setAttribute("fieldName", fieldName);
		}
	},
	onClickDeleteField : function() {
		var title=this.getAttribute("title");
		var fieldName=this.getAttribute("fieldName");
		var tiddler = store.getTiddler(title);
		if (tiddler && fieldName && confirm("delete field " + fieldName+" from " + title +" tiddler ?")) {
			delete tiddler.fields[fieldName];
			store.saveTiddler(tiddler.title,tiddler.title,tiddler.text,tiddler.modifier,tiddler.modified,tiddler.tags,tiddler.fields);
			story.refreshTiddler(title,"ViewTemplate",true);
		}
		return false;
	}
}

config.macros.createField = {
	handler : function(place,macroName,params,wikifier,paramString,tiddler) {
		if(!readOnly) {
			var btn = createTiddlyButton(place,"create new", "create a new field",this.onClickCreateField);
			btn.setAttribute("title",tiddler.title);
		}
	},
	onClickCreateField : function() {
		var title=this.getAttribute("title");
		var tiddler = store.getTiddler(title);
		if (tiddler) {
			var fieldName = prompt("Field name","");
			if (store.getValue(tiddler,fieldName)) {
				window.alert("This field already exists.");
			}
			else if (fieldName) {
				var v = prompt("Field value","");
				tiddler.fields[fieldName]=v;
				store.saveTiddler(tiddler.title,tiddler.title,tiddler.text,tiddler.modifier,tiddler.modified,tiddler.tags,tiddler.fields);
				story.refreshTiddler(title,"ViewTemplate",true);
			}
		}
		return false;
	}
}

config.macros.editFieldDialog = {
	handler : function(place,macroName,params,wikifier,paramString,tiddler) {
		if(!readOnly && params[0]) {
			fieldName = unescape(params[0]);
			var btn = createTiddlyButton(place,"edit", "edit this field",this.onClickEditFieldDialog);
			btn.setAttribute("title",tiddler.title);
			btn.setAttribute("fieldName", fieldName);
		}
	},
	onClickEditFieldDialog : function() {
		var title=this.getAttribute("title");
		var tiddler = store.getTiddler(title);
		var fieldName=this.getAttribute("fieldName");
		if (tiddler && fieldName) {
			var value = tiddler.fields[fieldName];
			value = value ? value : "";
			var lines = value.match(/\n/mg);
			lines = lines ? true : false;
			if (!lines || confirm("This field contains more than one line. Only the first line will be kept if you edit it here. Proceed ?")) {
				var v = prompt("Field value",value);
				tiddler.fields[fieldName]=v;
				store.saveTiddler(tiddler.title,tiddler.title,tiddler.text,tiddler.modifier,tiddler.modified,tiddler.tags,tiddler.fields);
				story.refreshTiddler(title,"ViewTemplate",true);
			}
		}
		return false;
	}
}

config.macros.renameField = {
	handler : function(place,macroName,params,wikifier,paramString,tiddler) {
		if(!readOnly && params[0]) {
			fieldName = unescape(params[0]);
			var btn = createTiddlyButton(place,"rename", "rename "+fieldName,this.onClickRenameField);
			btn.setAttribute("title",tiddler.title);
			btn.setAttribute("fieldName", fieldName);
		}
	},
	onClickRenameField : function() {
		var title=this.getAttribute("title");
		var fieldName=this.getAttribute("fieldName");
		var tiddler = store.getTiddler(title);
		if (tiddler && fieldName) {
			var newName = prompt("Rename " + fieldName + " as ?", fieldName);
			if (newName) {
				tiddler.fields[newName]=tiddler.fields[fieldName];
				delete tiddler.fields[fieldName];
				store.saveTiddler(tiddler.title,tiddler.title,tiddler.text,tiddler.modifier,tiddler.modified,tiddler.tags,tiddler.fields);
				story.refreshTiddler(title,"ViewTemplate",true);
			}
		}
		return false;
	}
}

config.shadowTiddlers.StyleSheetFieldsEditor = "/*{{{*/\n";
config.shadowTiddlers.StyleSheetFieldsEditor += ".fieldTableRow td {padding : 1px 3px}\n";
config.shadowTiddlers.StyleSheetFieldsEditor += ".fieldTableRow .button {border:0; padding : 0 0.2em}\n";
config.shadowTiddlers.StyleSheetFieldsEditor +="/*}}}*/";
store.addNotification("StyleSheetFieldsEditor", refreshStyles);

//}}}
    * [[Create File with list of all tiddlers]]
    * [[List all Tiddlers that contain 'script' tag]]
    * [[List all Tiddlers that contain either a 'TaskToDo' or a 'TaskOpen' or 'TaskDone' tag]]
    * [[show all tiddlers with word "macro"]]
    * [[showScriptExamples]]
    * [[showScripts]]
* [[Create File with list of all tiddlers]]
* [[List all Tiddlers that contain 'script' tag]]
* [[List all Tiddlers that contain either a 'TaskToDo' or a 'TaskOpen' or 'TaskDone' tag]]
* [[List all tiddlers that have no tag]]
* [[show all tiddlers with word "macro"]]
* [[showScriptExamples]]
* [[showScripts]]
* [[List all tiddlers that have no tag]]
/***
|''Name:''|ForEachTiddlerPlugin|
|''Version:''|1.0.8 (2007-04-12)|
|''Source:''|http://tiddlywiki.abego-software.de/#ForEachTiddlerPlugin|
|''Author:''|UdoBorkowski (ub [at] abego-software [dot] de)|
|''Licence:''|[[BSD open source license (abego Software)|http://www.abego-software.de/legal/apl-v10.html]]|
|''Copyright:''|&copy; 2005-2007 [[abego Software|http://www.abego-software.de]]|
|''TiddlyWiki:''|1.2.38+, 2.0|
|''Browser:''|Firefox 1.0.4+; Firefox 1.5; InternetExplorer 6.0|
!Description

Create customizable lists, tables etc. for your selections of tiddlers. Specify the tiddlers to include and their order through a powerful language.

''Syntax:'' 
|>|{{{<<}}}''forEachTiddler'' [''in'' //tiddlyWikiPath//] [''where'' //whereCondition//] [''sortBy'' //sortExpression// [''ascending'' //or// ''descending'']] [''script'' //scriptText//] [//action// [//actionParameters//]]{{{>>}}}|
|//tiddlyWikiPath//|The filepath to the TiddlyWiki the macro should work on. When missing the current TiddlyWiki is used.|
|//whereCondition//|(quoted) JavaScript boolean expression. May refer to the build-in variables {{{tiddler}}} and {{{context}}}.|
|//sortExpression//|(quoted) JavaScript expression returning "comparable" objects (using '{{{<}}}','{{{>}}}','{{{==}}}'. May refer to the build-in variables {{{tiddler}}} and {{{context}}}.|
|//scriptText//|(quoted) JavaScript text. Typically defines JavaScript functions that are called by the various JavaScript expressions (whereClause, sortClause, action arguments,...)|
|//action//|The action that should be performed on every selected tiddler, in the given order. By default the actions [[addToList|AddToListAction]] and [[write|WriteAction]] are supported. When no action is specified [[addToList|AddToListAction]] is used.|
|//actionParameters//|(action specific) parameters the action may refer while processing the tiddlers (see action descriptions for details). <<tiddler [[JavaScript in actionParameters]]>>|
|>|~~Syntax formatting: Keywords in ''bold'', optional parts in [...]. 'or' means that exactly one of the two alternatives must exist.~~|

See details see [[ForEachTiddlerMacro]] and [[ForEachTiddlerExamples]].

!Revision history
* v1.0.8 (2007-04-12)
** Adapted to latest TiddlyWiki 2.2 Beta importTiddlyWiki API (introduced with changeset 2004). TiddlyWiki 2.2 Beta builds prior to changeset 2004 are no longer supported (but TiddlyWiki 2.1 and earlier, of cause)
* v1.0.7 (2007-03-28)
** Also support "pre" formatted TiddlyWikis (introduced with TW 2.2) (when using "in" clause to work on external tiddlers)
* v1.0.6 (2006-09-16)
** Context provides "viewerTiddler", i.e. the tiddler used to view the macro. Most times this is equal to the "inTiddler", but when using the "tiddler" macro both may be different.
** Support "begin", "end" and "none" expressions in "write" action
* v1.0.5 (2006-02-05)
** Pass tiddler containing the macro with wikify, context object also holds reference to tiddler containing the macro ("inTiddler"). Thanks to SimonBaird.
** Support Firefox 1.5.0.1
** Internal
*** Make "JSLint" conform
*** "Only install once"
* v1.0.4 (2006-01-06)
** Support TiddlyWiki 2.0
* v1.0.3 (2005-12-22)
** Features: 
*** Write output to a file supports multi-byte environments (Thanks to Bram Chen) 
*** Provide API to access the forEachTiddler functionality directly through JavaScript (see getTiddlers and performMacro)
** Enhancements:
*** Improved error messages on InternetExplorer.
* v1.0.2 (2005-12-10)
** Features: 
*** context object also holds reference to store (TiddlyWiki)
** Fixed Bugs: 
*** ForEachTiddler 1.0.1 has broken support on win32 Opera 8.51 (Thanks to BrunoSabin for reporting)
* v1.0.1 (2005-12-08)
** Features: 
*** Access tiddlers stored in separated TiddlyWikis through the "in" option. I.e. you are no longer limited to only work on the "current TiddlyWiki".
*** Write output to an external file using the "toFile" option of the "write" action. With this option you may write your customized tiddler exports.
*** Use the "script" section to define "helper" JavaScript functions etc. to be used in the various JavaScript expressions (whereClause, sortClause, action arguments,...).
*** Access and store context information for the current forEachTiddler invocation (through the build-in "context" object) .
*** Improved script evaluation (for where/sort clause and write scripts).
* v1.0.0 (2005-11-20)
** initial version

!Code
***/
//{{{

 
//============================================================================
//============================================================================
// ForEachTiddlerPlugin
//============================================================================
//============================================================================

// Only install once
if (!version.extensions.ForEachTiddlerPlugin) {

if (!window.abego) window.abego = {};

version.extensions.ForEachTiddlerPlugin = {
 major: 1, minor: 0, revision: 8, 
 date: new Date(2007,3,12), 
 source: "http://tiddlywiki.abego-software.de/#ForEachTiddlerPlugin",
 licence: "[[BSD open source license (abego Software)|http://www.abego-software.de/legal/apl-v10.html]]",
 copyright: "Copyright (c) abego Software GmbH, 2005-2007 (www.abego-software.de)"
};

// For backward compatibility with TW 1.2.x
//
if (!TiddlyWiki.prototype.forEachTiddler) {
 TiddlyWiki.prototype.forEachTiddler = function(callback) {
 for(var t in this.tiddlers) {
 callback.call(this,t,this.tiddlers[t]);
 }
 };
}

//============================================================================
// forEachTiddler Macro
//============================================================================

version.extensions.forEachTiddler = {
 major: 1, minor: 0, revision: 8, date: new Date(2007,3,12), provider: "http://tiddlywiki.abego-software.de"};

// ---------------------------------------------------------------------------
// Configurations and constants 
// ---------------------------------------------------------------------------

config.macros.forEachTiddler = {
 // Standard Properties
 label: "forEachTiddler",
 prompt: "Perform actions on a (sorted) selection of tiddlers",

 // actions
 actions: {
 addToList: {},
 write: {}
 }
};

// ---------------------------------------------------------------------------
// The forEachTiddler Macro Handler 
// ---------------------------------------------------------------------------

config.macros.forEachTiddler.getContainingTiddler = function(e) {
 while(e && !hasClass(e,"tiddler"))
 e = e.parentNode;
 var title = e ? e.getAttribute("tiddler") : null; 
 return title ? store.getTiddler(title) : null;
};

config.macros.forEachTiddler.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
 // config.macros.forEachTiddler.traceMacroCall(place,macroName,params,wikifier,paramString,tiddler);

 if (!tiddler) tiddler = config.macros.forEachTiddler.getContainingTiddler(place);
 // --- Parsing ------------------------------------------

 var i = 0; // index running over the params
 // Parse the "in" clause
 var tiddlyWikiPath = undefined;
 if ((i < params.length) && params[i] == "in") {
 i++;
 if (i >= params.length) {
 this.handleError(place, "TiddlyWiki path expected behind 'in'.");
 return;
 }
 tiddlyWikiPath = this.paramEncode((i < params.length) ? params[i] : "");
 i++;
 }

 // Parse the where clause
 var whereClause ="true";
 if ((i < params.length) && params[i] == "where") {
 i++;
 whereClause = this.paramEncode((i < params.length) ? params[i] : "");
 i++;
 }

 // Parse the sort stuff
 var sortClause = null;
 var sortAscending = true; 
 if ((i < params.length) && params[i] == "sortBy") {
 i++;
 if (i >= params.length) {
 this.handleError(place, "sortClause missing behind 'sortBy'.");
 return;
 }
 sortClause = this.paramEncode(params[i]);
 i++;

 if ((i < params.length) && (params[i] == "ascending" || params[i] == "descending")) {
 sortAscending = params[i] == "ascending";
 i++;
 }
 }

 // Parse the script
 var scriptText = null;
 if ((i < params.length) && params[i] == "script") {
 i++;
 scriptText = this.paramEncode((i < params.length) ? params[i] : "");
 i++;
 }

 // Parse the action. 
 // When we are already at the end use the default action
 var actionName = "addToList";
 if (i < params.length) {
 if (!config.macros.forEachTiddler.actions[params[i]]) {
 this.handleError(place, "Unknown action '"+params[i]+"'.");
 return;
 } else {
 actionName = params[i]; 
 i++;
 }
 } 
 
 // Get the action parameter
 // (the parsing is done inside the individual action implementation.)
 var actionParameter = params.slice(i);


 // --- Processing ------------------------------------------
 try {
 this.performMacro({
 place: place, 
 inTiddler: tiddler,
 whereClause: whereClause, 
 sortClause: sortClause, 
 sortAscending: sortAscending, 
 actionName: actionName, 
 actionParameter: actionParameter, 
 scriptText: scriptText, 
 tiddlyWikiPath: tiddlyWikiPath});

 } catch (e) {
 this.handleError(place, e);
 }
};

// Returns an object with properties "tiddlers" and "context".
// tiddlers holds the (sorted) tiddlers selected by the parameter,
// context the context of the execution of the macro.
//
// The action is not yet performed.
//
// @parameter see performMacro
//
config.macros.forEachTiddler.getTiddlersAndContext = function(parameter) {

 var context = config.macros.forEachTiddler.createContext(parameter.place, parameter.whereClause, parameter.sortClause, parameter.sortAscending, parameter.actionName, parameter.actionParameter, parameter.scriptText, parameter.tiddlyWikiPath, parameter.inTiddler);

 var tiddlyWiki = parameter.tiddlyWikiPath ? this.loadTiddlyWiki(parameter.tiddlyWikiPath) : store;
 context["tiddlyWiki"] = tiddlyWiki;
 
 // Get the tiddlers, as defined by the whereClause
 var tiddlers = this.findTiddlers(parameter.whereClause, context, tiddlyWiki);
 context["tiddlers"] = tiddlers;

 // Sort the tiddlers, when sorting is required.
 if (parameter.sortClause) {
 this.sortTiddlers(tiddlers, parameter.sortClause, parameter.sortAscending, context);
 }

 return {tiddlers: tiddlers, context: context};
};

// Returns the (sorted) tiddlers selected by the parameter.
//
// The action is not yet performed.
//
// @parameter see performMacro
//
config.macros.forEachTiddler.getTiddlers = function(parameter) {
 return this.getTiddlersAndContext(parameter).tiddlers;
};

// Performs the macros with the given parameter.
//
// @param parameter holds the parameter of the macro as separate properties.
// The following properties are supported:
//
// place
// whereClause
// sortClause
// sortAscending
// actionName
// actionParameter
// scriptText
// tiddlyWikiPath
//
// All properties are optional. 
// For most actions the place property must be defined.
//
config.macros.forEachTiddler.performMacro = function(parameter) {
 var tiddlersAndContext = this.getTiddlersAndContext(parameter);

 // Perform the action
 var actionName = parameter.actionName ? parameter.actionName : "addToList";
 var action = config.macros.forEachTiddler.actions[actionName];
 if (!action) {
 this.handleError(parameter.place, "Unknown action '"+actionName+"'.");
 return;
 }

 var actionHandler = action.handler;
 actionHandler(parameter.place, tiddlersAndContext.tiddlers, parameter.actionParameter, tiddlersAndContext.context);
};

// ---------------------------------------------------------------------------
// The actions 
// ---------------------------------------------------------------------------

// Internal.
//
// --- The addToList Action -----------------------------------------------
//
config.macros.forEachTiddler.actions.addToList.handler = function(place, tiddlers, parameter, context) {
 // Parse the parameter
 var p = 0;

 // Check for extra parameters
 if (parameter.length > p) {
 config.macros.forEachTiddler.createExtraParameterErrorElement(place, "addToList", parameter, p);
 return;
 }

 // Perform the action.
 var list = document.createElement("ul");
 place.appendChild(list);
 for (var i = 0; i < tiddlers.length; i++) {
 var tiddler = tiddlers[i];
 var listItem = document.createElement("li");
 list.appendChild(listItem);
 createTiddlyLink(listItem, tiddler.title, true);
 }
};

abego.parseNamedParameter = function(name, parameter, i) {
 var beginExpression = null;
 if ((i < parameter.length) && parameter[i] == name) {
 i++;
 if (i >= parameter.length) {
 throw "Missing text behind '%0'".format([name]);
 }
 
 return config.macros.forEachTiddler.paramEncode(parameter[i]);
 }
 return null;
}

// Internal.
//
// --- The write Action ---------------------------------------------------
//
config.macros.forEachTiddler.actions.write.handler = function(place, tiddlers, parameter, context) {
 // Parse the parameter
 var p = 0;
 if (p >= parameter.length) {
 this.handleError(place, "Missing expression behind 'write'.");
 return;
 }

 var textExpression = config.macros.forEachTiddler.paramEncode(parameter[p]);
 p++;

 // Parse the "begin" option
 var beginExpression = abego.parseNamedParameter("begin", parameter, p);
 if (beginExpression !== null) 
 p += 2;
 var endExpression = abego.parseNamedParameter("end", parameter, p);
 if (endExpression !== null) 
 p += 2;
 var noneExpression = abego.parseNamedParameter("none", parameter, p);
 if (noneExpression !== null) 
 p += 2;

 // Parse the "toFile" option
 var filename = null;
 var lineSeparator = undefined;
 if ((p < parameter.length) && parameter[p] == "toFile") {
 p++;
 if (p >= parameter.length) {
 this.handleError(place, "Filename expected behind 'toFile' of 'write' action.");
 return;
 }
 
 filename = config.macros.forEachTiddler.getLocalPath(config.macros.forEachTiddler.paramEncode(parameter[p]));
 p++;
 if ((p < parameter.length) && parameter[p] == "withLineSeparator") {
 p++;
 if (p >= parameter.length) {
 this.handleError(place, "Line separator text expected behind 'withLineSeparator' of 'write' action.");
 return;
 }
 lineSeparator = config.macros.forEachTiddler.paramEncode(parameter[p]);
 p++;
 }
 }
 
 // Check for extra parameters
 if (parameter.length > p) {
 config.macros.forEachTiddler.createExtraParameterErrorElement(place, "write", parameter, p);
 return;
 }

 // Perform the action.
 var func = config.macros.forEachTiddler.getEvalTiddlerFunction(textExpression, context);
 var count = tiddlers.length;
 var text = "";
 if (count > 0 && beginExpression)
 text += config.macros.forEachTiddler.getEvalTiddlerFunction(beginExpression, context)(undefined, context, count, undefined);
 
 for (var i = 0; i < count; i++) {
 var tiddler = tiddlers[i];
 text += func(tiddler, context, count, i);
 }
 
 if (count > 0 && endExpression)
 text += config.macros.forEachTiddler.getEvalTiddlerFunction(endExpression, context)(undefined, context, count, undefined);

 if (count == 0 && noneExpression) 
 text += config.macros.forEachTiddler.getEvalTiddlerFunction(noneExpression, context)(undefined, context, count, undefined);
 

 if (filename) {
 if (lineSeparator !== undefined) {
 lineSeparator = lineSeparator.replace(/\\n/mg, "\n").replace(/\\r/mg, "\r");
 text = text.replace(/\n/mg,lineSeparator);
 }
 saveFile(filename, convertUnicodeToUTF8(text));
 } else {
 var wrapper = createTiddlyElement(place, "span");
 wikify(text, wrapper, null/* highlightRegExp */, context.inTiddler);
 }
};


// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------

// Internal.
//
config.macros.forEachTiddler.createContext = function(placeParam, whereClauseParam, sortClauseParam, sortAscendingParam, actionNameParam, actionParameterParam, scriptText, tiddlyWikiPathParam, inTiddlerParam) {
 return {
 place : placeParam, 
 whereClause : whereClauseParam, 
 sortClause : sortClauseParam, 
 sortAscending : sortAscendingParam, 
 script : scriptText,
 actionName : actionNameParam, 
 actionParameter : actionParameterParam,
 tiddlyWikiPath : tiddlyWikiPathParam,
 inTiddler : inTiddlerParam, // the tiddler containing the <<forEachTiddler ...>> macro call.
 viewerTiddler : config.macros.forEachTiddler.getContainingTiddler(placeParam) // the tiddler showing the forEachTiddler result
 };
};

// Internal.
//
// Returns a TiddlyWiki with the tiddlers loaded from the TiddlyWiki of 
// the given path.
//
config.macros.forEachTiddler.loadTiddlyWiki = function(path, idPrefix) {
 if (!idPrefix) {
 idPrefix = "store";
 }
 var lenPrefix = idPrefix.length;
 
 // Read the content of the given file
 var content = loadFile(this.getLocalPath(path));
 if(content === null) {
 throw "TiddlyWiki '"+path+"' not found.";
 }
 
 var tiddlyWiki = new TiddlyWiki();

 // Starting with TW 2.2 there is a helper function to import the tiddlers
 if (tiddlyWiki.importTiddlyWiki) {
 if (!tiddlyWiki.importTiddlyWiki(content))
 throw "File '"+path+"' is not a TiddlyWiki.";
 tiddlyWiki.dirty = false;
 return tiddlyWiki;
 }
 
 // The legacy code, for TW < 2.2
 
 // Locate the storeArea div's
 var posOpeningDiv = content.indexOf(startSaveArea);
 var posClosingDiv = content.lastIndexOf(endSaveArea);
 if((posOpeningDiv == -1) || (posClosingDiv == -1)) {
 throw "File '"+path+"' is not a TiddlyWiki.";
 }
 var storageText = content.substr(posOpeningDiv + startSaveArea.length, posClosingDiv);
 
 // Create a "div" element that contains the storage text
 var myStorageDiv = document.createElement("div");
 myStorageDiv.innerHTML = storageText;
 myStorageDiv.normalize();
 
 // Create all tiddlers in a new TiddlyWiki
 // (following code is modified copy of TiddlyWiki.prototype.loadFromDiv)
 var store = myStorageDiv.childNodes;
 for(var t = 0; t < store.length; t++) {
 var e = store[t];
 var title = null;
 if(e.getAttribute)
 title = e.getAttribute("tiddler");
 if(!title && e.id && e.id.substr(0,lenPrefix) == idPrefix)
 title = e.id.substr(lenPrefix);
 if(title && title !== "") {
 var tiddler = tiddlyWiki.createTiddler(title);
 tiddler.loadFromDiv(e,title);
 }
 }
 tiddlyWiki.dirty = false;

 return tiddlyWiki;
};


 
// Internal.
//
// Returns a function that has a function body returning the given javaScriptExpression.
// The function has the parameters:
// 
// (tiddler, context, count, index)
//
config.macros.forEachTiddler.getEvalTiddlerFunction = function (javaScriptExpression, context) {
 var script = context["script"];
 var functionText = "var theFunction = function(tiddler, context, count, index) { return "+javaScriptExpression+"}";
 var fullText = (script ? script+";" : "")+functionText+";theFunction;";
 return eval(fullText);
};

// Internal.
//
config.macros.forEachTiddler.findTiddlers = function(whereClause, context, tiddlyWiki) {
 var result = [];
 var func = config.macros.forEachTiddler.getEvalTiddlerFunction(whereClause, context);
 tiddlyWiki.forEachTiddler(function(title,tiddler) {
 if (func(tiddler, context, undefined, undefined)) {
 result.push(tiddler);
 }
 });
 return result;
};

// Internal.
//
config.macros.forEachTiddler.createExtraParameterErrorElement = function(place, actionName, parameter, firstUnusedIndex) {
 var message = "Extra parameter behind '"+actionName+"':";
 for (var i = firstUnusedIndex; i < parameter.length; i++) {
 message += " "+parameter[i];
 }
 this.handleError(place, message);
};

// Internal.
//
config.macros.forEachTiddler.sortAscending = function(tiddlerA, tiddlerB) {
 var result = 
 (tiddlerA.forEachTiddlerSortValue == tiddlerB.forEachTiddlerSortValue) 
 ? 0
 : (tiddlerA.forEachTiddlerSortValue < tiddlerB.forEachTiddlerSortValue)
 ? -1 
 : +1; 
 return result;
};

// Internal.
//
config.macros.forEachTiddler.sortDescending = function(tiddlerA, tiddlerB) {
 var result = 
 (tiddlerA.forEachTiddlerSortValue == tiddlerB.forEachTiddlerSortValue) 
 ? 0
 : (tiddlerA.forEachTiddlerSortValue < tiddlerB.forEachTiddlerSortValue)
 ? +1 
 : -1; 
 return result;
};

// Internal.
//
config.macros.forEachTiddler.sortTiddlers = function(tiddlers, sortClause, ascending, context) {
 // To avoid evaluating the sortClause whenever two items are compared 
 // we pre-calculate the sortValue for every item in the array and store it in a 
 // temporary property ("forEachTiddlerSortValue") of the tiddlers.
 var func = config.macros.forEachTiddler.getEvalTiddlerFunction(sortClause, context);
 var count = tiddlers.length;
 var i;
 for (i = 0; i < count; i++) {
 var tiddler = tiddlers[i];
 tiddler.forEachTiddlerSortValue = func(tiddler,context, undefined, undefined);
 }

 // Do the sorting
 tiddlers.sort(ascending ? this.sortAscending : this.sortDescending);

 // Delete the temporary property that holds the sortValue. 
 for (i = 0; i < tiddlers.length; i++) {
 delete tiddlers[i].forEachTiddlerSortValue;
 }
};


// Internal.
//
config.macros.forEachTiddler.trace = function(message) {
 displayMessage(message);
};

// Internal.
//
config.macros.forEachTiddler.traceMacroCall = function(place,macroName,params) {
 var message ="<<"+macroName;
 for (var i = 0; i < params.length; i++) {
 message += " "+params[i];
 }
 message += ">>";
 displayMessage(message);
};


// Internal.
//
// Creates an element that holds an error message
// 
config.macros.forEachTiddler.createErrorElement = function(place, exception) {
 var message = (exception.description) ? exception.description : exception.toString();
 return createTiddlyElement(place,"span",null,"forEachTiddlerError","<<forEachTiddler ...>>: "+message);
};

// Internal.
//
// @param place [may be null]
//
config.macros.forEachTiddler.handleError = function(place, exception) {
 if (place) {
 this.createErrorElement(place, exception);
 } else {
 throw exception;
 }
};

// Internal.
//
// Encodes the given string.
//
// Replaces 
// "$))" to ">>"
// "$)" to ">"
//
config.macros.forEachTiddler.paramEncode = function(s) {
 var reGTGT = new RegExp("\\$\\)\\)","mg");
 var reGT = new RegExp("\\$\\)","mg");
 return s.replace(reGTGT, ">>").replace(reGT, ">");
};

// Internal.
//
// Returns the given original path (that is a file path, starting with "file:")
// as a path to a local file, in the systems native file format.
//
// Location information in the originalPath (i.e. the "#" and stuff following)
// is stripped.
// 
config.macros.forEachTiddler.getLocalPath = function(originalPath) {
 // Remove any location part of the URL
 var hashPos = originalPath.indexOf("#");
 if(hashPos != -1)
 originalPath = originalPath.substr(0,hashPos);
 // Convert to a native file format assuming
 // "file:///x:/path/path/path..." - pc local file --> "x:\path\path\path..."
 // "file://///server/share/path/path/path..." - FireFox pc network file --> "\\server\share\path\path\path..."
 // "file:///path/path/path..." - mac/unix local file --> "/path/path/path..."
 // "file://server/share/path/path/path..." - pc network file --> "\\server\share\path\path\path..."
 var localPath;
 if(originalPath.charAt(9) == ":") // pc local file
 localPath = unescape(originalPath.substr(8)).replace(new RegExp("/","g"),"\\");
 else if(originalPath.indexOf("file://///") === 0) // FireFox pc network file
 localPath = "\\\\" + unescape(originalPath.substr(10)).replace(new RegExp("/","g"),"\\");
 else if(originalPath.indexOf("file:///") === 0) // mac/unix local file
 localPath = unescape(originalPath.substr(7));
 else if(originalPath.indexOf("file:/") === 0) // mac/unix local file
 localPath = unescape(originalPath.substr(5));
 else // pc network file
 localPath = "\\\\" + unescape(originalPath.substr(7)).replace(new RegExp("/","g"),"\\"); 
 return localPath;
};

// ---------------------------------------------------------------------------
// Stylesheet Extensions (may be overridden by local StyleSheet)
// ---------------------------------------------------------------------------
//
setStylesheet(
 ".forEachTiddlerError{color: #ffffff;background-color: #880000;}",
 "forEachTiddler");

//============================================================================
// End of forEachTiddler Macro
//============================================================================


//============================================================================
// String.startsWith Function
//============================================================================
//
// Returns true if the string starts with the given prefix, false otherwise.
//
version.extensions["String.startsWith"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
String.prototype.startsWith = function(prefix) {
 var n = prefix.length;
 return (this.length >= n) && (this.slice(0, n) == prefix);
};



//============================================================================
// String.endsWith Function
//============================================================================
//
// Returns true if the string ends with the given suffix, false otherwise.
//
version.extensions["String.endsWith"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
String.prototype.endsWith = function(suffix) {
 var n = suffix.length;
 return (this.length >= n) && (this.right(n) == suffix);
};


//============================================================================
// String.contains Function
//============================================================================
//
// Returns true when the string contains the given substring, false otherwise.
//
version.extensions["String.contains"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
String.prototype.contains = function(substring) {
 return this.indexOf(substring) >= 0;
};

//============================================================================
// Array.indexOf Function
//============================================================================
//
// Returns the index of the first occurance of the given item in the array or 
// -1 when no such item exists.
//
// @param item [may be null]
//
version.extensions["Array.indexOf"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
Array.prototype.indexOf = function(item) {
 for (var i = 0; i < this.length; i++) {
 if (this[i] == item) {
 return i;
 }
 }
 return -1;
};

//============================================================================
// Array.contains Function
//============================================================================
//
// Returns true when the array contains the given item, otherwise false. 
//
// @param item [may be null]
//
version.extensions["Array.contains"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
Array.prototype.contains = function(item) {
 return (this.indexOf(item) >= 0);
};

//============================================================================
// Array.containsAny Function
//============================================================================
//
// Returns true when the array contains at least one of the elements 
// of the item. Otherwise (or when items contains no elements) false is returned.
//
version.extensions["Array.containsAny"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
Array.prototype.containsAny = function(items) {
 for(var i = 0; i < items.length; i++) {
 if (this.contains(items[i])) {
 return true;
 }
 }
 return false;
};


//============================================================================
// Array.containsAll Function
//============================================================================
//
// Returns true when the array contains all the items, otherwise false.
// 
// When items is null false is returned (even if the array contains a null).
//
// @param items [may be null] 
//
version.extensions["Array.containsAll"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
Array.prototype.containsAll = function(items) {
 for(var i = 0; i < items.length; i++) {
 if (!this.contains(items[i])) {
 return false;
 }
 }
 return true;
};


} // of "install only once"

// Used Globals (for JSLint) ==============
// ... DOM
/*global document */
// ... TiddlyWiki Core
/*global convertUnicodeToUTF8, createTiddlyElement, createTiddlyLink, 
 displayMessage, endSaveArea, hasClass, loadFile, saveFile, 
 startSaveArea, store, wikify */
//}}}


/***
!Licence and Copyright
Copyright (c) abego Software ~GmbH, 2005 ([[www.abego-software.de|http://www.abego-software.de]])

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.

Neither the name of abego Software nor the names of its contributors may be
used to endorse or promote products derived from this software without specific
prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
***/
/***
<<checkForDataTiddlerPlugin>>
|''Name:''|FormTiddlerPlugin|
|''Version:''|1.0.5 (2006-02-24)|
|''Source:''|http://tiddlywiki.abego-software.de/#FormTiddlerPlugin|
|''Author:''|UdoBorkowski (ub [at] abego-software [dot] de)|
|''Licence:''|[[BSD open source license]]|
|''Macros:''|formTiddler, checkForDataTiddlerPlugin, newTiddlerWithForm|
|''Requires:''|DataTiddlerPlugin|
|''TiddlyWiki:''|1.2.38+, 2.0|
|''Browser:''|Firefox 1.0.4+; InternetExplorer 6.0|
!Description
Use form-based tiddlers to enter your tiddler data using text fields, listboxes, checkboxes etc. (All standard HTML Form input elements supported).

''Syntax:'' 
|>|{{{<<}}}''formTiddler'' //tiddlerName//{{{>>}}}|
|//tiddlerName//|The name of the FormTemplate tiddler to be used to edit the data of the tiddler containing the macro.|

|>|{{{<<}}}''newTiddlerWithForm'' //formTemplateName// //buttonLabel// [//titleExpression// [''askUser'']] {{{>>}}}|
|//formTemplateName//|The name of the tiddler that defines the form the new tiddler should use.|
|//buttonLabel//|The label of the button|
|//titleExpression//|A (quoted) JavaScript String expression that defines the title (/name) of the new tiddler.|
|''askUser''|Typically the user is not asked for the title when a title is specified (and not yet used). When ''askUser'' is given the user will be asked in any case. This may be used when the calculated title is just a suggestion that must be confirmed by the user|
|>|~~Syntax formatting: Keywords in ''bold'', optional parts in [...]. 'or' means that exactly one of the two alternatives must exist.~~|

For details and how to use the macros see the [[introduction|FormTiddler Introduction]] and the [[examples|FormTiddler Examples]].

!Revision history
* v1.0.5 (2006-02-24)
** Removed "debugger;" instruction
* v1.0.4 (2006-02-07)
** Bug: On IE no data is written to data section when field values changed (thanks to KenGirard for reporting)
* v1.0.3 (2006-02-05)
** Bug: {{{"No form template specified in <<formTiddler>>"}}} when using formTiddler macro on InternetExplorer (thanks to KenGirard for reporting)
* v1.0.2 (2006-01-06)
** Support TiddlyWiki 2.0
* v1.0.1 (2005-12-22)
** Features: 
*** Support InternetExplorer
*** Added newTiddlerWithForm Macro
* v1.0.0 (2005-12-14)
** initial version

!Code
***/
//{{{

//============================================================================
//============================================================================
// FormTiddlerPlugin
//============================================================================
//============================================================================


version.extensions.FormTiddlerPlugin = {
 major: 1, minor: 0, revision: 5,
 date: new Date(2006, 2, 24), 
 type: 'plugin',
 source: "http://tiddlywiki.abego-software.de/#FormTiddlerPlugin"
};

// For backward compatibility with v1.2.x
//
if (!window.story) window.story=window; 
if (!TiddlyWiki.prototype.getTiddler) TiddlyWiki.prototype.getTiddler = function(title) { return t = this.tiddlers[title]; return (t != undefined && t instanceof Tiddler) ? t : null; } 

//============================================================================
// formTiddler Macro
//============================================================================

// -------------------------------------------------------------------------------
// Configurations and constants 
// -------------------------------------------------------------------------------

config.macros.formTiddler = {
 // Standard Properties
 label: "formTiddler",
 version: {major: 1, minor: 0, revision: 4, date: new Date(2006, 2, 7)},
 prompt: "Edit tiddler data using forms",

 // Define the "setters" that set the values of INPUT elements of a given type
 // (must match the corresponding "getter")
 setter: { 
 button: function(e, value) {/*contains no data */ },
 checkbox: function(e, value) {e.checked = value;},
 file: function(e, value) {try {e.value = value;} catch(e) {/* ignore, possibly security error*/}},
 hidden: function(e, value) {e.value = value;},
 password: function(e, value) {e.value = value;},
 radio: function(e, value) {e.checked = (e.value == value);},
 reset: function(e, value) {/*contains no data */ },
 "select-one": function(e, value) {config.macros.formTiddler.setSelectOneValue(e,value);},
 "select-multiple": function(e, value) {config.macros.formTiddler.setSelectMultipleValue(e,value);},
 submit: function(e, value) {/*contains no data */},
 text: function(e, value) {e.value = value;},
 textarea: function(e, value) {e.value = value;}
 },

 // Define the "getters" that return the value of INPUT elements of a given type
 // Return undefined to not store any data.
 getter: { 
 button: function(e, value) {return undefined;},
 checkbox: function(e, value) {return e.checked;},
 file: function(e, value) {return e.value;},
 hidden: function(e, value) {return e.value;},
 password: function(e, value) {return e.value;},
 radio: function(e, value) {return e.checked ? e.value : undefined;},
 reset: function(e, value) {return undefined;},
 "select-one": function(e, value) {return config.macros.formTiddler.getSelectOneValue(e);},
 "select-multiple": function(e, value) {return config.macros.formTiddler.getSelectMultipleValue(e);},
 submit: function(e, value) {return undefined;},
 text: function(e, value) {return e.value;},
 textarea: function(e, value) {return e.value;}
 }
};


// -------------------------------------------------------------------------------
// The formTiddler Macro Handler 
// -------------------------------------------------------------------------------

config.macros.formTiddler.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
 if (!config.macros.formTiddler.checkForExtensions(place, macroName)) {
 return;
 }
 
 // --- Parsing ------------------------------------------

 var i = 0; // index running over the params

 // get the name of the form template tiddler
 var formTemplateName = undefined;
 if (i < params.length) {
 formTemplateName = params[i];
 i++;
 }

 if (!formTemplateName) {
 config.macros.formTiddler.createErrorElement(place, "No form template specified in <<" + macroName + ">>.");
 return;
 }


 // --- Processing ------------------------------------------

 // Get the form template text. 
 // (This contains the INPUT elements for the form.)
 var formTemplateTiddler = store.getTiddler(formTemplateName);
 if (!formTemplateTiddler) {
 config.macros.formTiddler.createErrorElement(place, "Form template '" + formTemplateName + "' not found.");
 return;
 }
 var templateText = formTemplateTiddler.text;
 if(!templateText) {
 // Shortcut: when template text is empty we do nothing.
 return;
 }

 // Get the name of the tiddler containing this "formTiddler" macro
 // (i.e. the tiddler, that will be edited and that contains the data)
 var tiddlerName = config.macros.formTiddler.getContainingTiddlerName(place);

 // Append a "form" element. 
 var formName = "form"+formTemplateName+"__"+tiddlerName;
 var e = document.createElement("form");
 e.setAttribute("name", formName);
 place.appendChild(e);

 // "Embed" the elements defined by the templateText (i.e. the INPUT elements) 
 // into the "form" element we just created
 wikify(templateText, e);

 // Initialize the INPUT elements.
 config.macros.formTiddler.initValuesAndHandlersInFormElements(formName, DataTiddler.getDataObject(tiddlerName));
}


// -------------------------------------------------------------------------------
// Form Data Access 
// -------------------------------------------------------------------------------

// Internal.
//
// Initialize the INPUT elements of the form with the values of their "matching"
// data fields in the tiddler. Also setup the onChange handler to ensure that
// changes in the INPUT elements are stored in the tiddler's data.
//
config.macros.formTiddler.initValuesAndHandlersInFormElements = function(formName, data) {
 // config.macros.formTiddler.trace("initValuesAndHandlersInFormElements(formName="+formName+", data="+data+")");

 // find the form
 var form = config.macros.formTiddler.findForm(formName);
 if (!form) {
 return;
 }

 try {
 var elems = form.elements;
 for (var i = 0; i < elems.length; i++) {
 var c = elems[i];
 
 var setter = config.macros.formTiddler.setter[c.type];
 if (setter) {
 var value = data[c.name];
 if (value != null) {
 setter(c, value);
 }
 c.onchange = onFormTiddlerChange;
 } else {
 config.macros.formTiddler.displayFormTiddlerError("No setter defined for INPUT element of type '"+c.type+"'. (Element '"+c.name+"' in form '"+formName+"')");
 }
 }
 } catch(e) {
 config.macros.formTiddler.displayFormTiddlerError("Error when updating elements with new formData. "+e);
 }
}


// Internal.
//
// @return [may be null]
//
config.macros.formTiddler.findForm = function(formName) {
 // We must manually iterate through the document's forms, since
 // IE does not support the "document[formName]" approach

 var forms = window.document.forms;
 for (var i = 0; i < forms.length; i++) {
 var form = forms[i];
 if (form.name == formName) {
 return form;
 }
 }

 return null;
}


// Internal.
//
config.macros.formTiddler.setSelectOneValue = function(element,value) {
 var n = element.options.length;
 for (var i = 0; i < n; i++) {
 element.options[i].selected = element.options[i].value == value;
 }
}

// Internal.
//
config.macros.formTiddler.setSelectMultipleValue = function(element,value) {
 var values = {};
 for (var i = 0; i < value.length; i++) {
 values[value[i]] = true;
 }
 
 var n = element.length;
 for (var i = 0; i < n; i++) {
 element.options[i].selected = !(!values[element.options[i].value]);
 }
}

// Internal.
//
config.macros.formTiddler.getSelectOneValue = function(element) {
 var i = element.selectedIndex;
 return (i >= 0) ? element.options[i].value : null;
}

// Internal.
//
config.macros.formTiddler.getSelectMultipleValue = function(element) {
 var values = [];
 var n = element.length;
 for (var i = 0; i < n; i++) {
 if (element.options[i].selected) {
 values.push(element.options[i].value);
 }
 }
 return values;
}



// -------------------------------------------------------------------------------
// Helpers 
// -------------------------------------------------------------------------------

// Internal.
//
config.macros.formTiddler.checkForExtensions = function(place,macroName) {
 if (!version.extensions.DataTiddlerPlugin) {
 config.macros.formTiddler.createErrorElement(place, "<<" + macroName + ">> requires the DataTiddlerPlugin. (You can get it from http://tiddlywiki.abego-software.de/#DataTiddlerPlugin)");
 return false;
 }
 return true;
}

// Internal.
//
// Displays a trace message in the "TiddlyWiki" message pane.
// (used for debugging)
//
config.macros.formTiddler.trace = function(s) {
 displayMessage("Trace: "+s);
}

// Internal.
//
// Display some error message in the "TiddlyWiki" message pane.
//
config.macros.formTiddler.displayFormTiddlerError = function(s) {
 alert("FormTiddlerPlugin Error: "+s);
}

// Internal.
//
// Creates an element that holds an error message
// 
config.macros.formTiddler.createErrorElement = function(place, message) {
 return createTiddlyElement(place,"span",null,"formTiddlerError",message);
}

// Internal.
//
// Returns the name of the tiddler containing the given element.
// 
config.macros.formTiddler.getContainingTiddlerName = function(element) {
 return story.findContainingTiddler(element).id.substr(7);
}

// -------------------------------------------------------------------------------
// Event Handlers 
// -------------------------------------------------------------------------------

// This function must be called by the INPUT elements whenever their
// data changes. Typically this is done through an "onChange" handler.
//
function onFormTiddlerChange (e) {
 // config.macros.formTiddler.trace("onFormTiddlerChange "+e);

 if (!e) var e = window.event;

 var target = resolveTarget(e);
 var tiddlerName = config.macros.formTiddler.getContainingTiddlerName(target);
 var getter = config.macros.formTiddler.getter[target.type];
 if (getter) {
 var value = getter(target);
 DataTiddler.setData(tiddlerName, target.name, value);
 } else {
 config.macros.formTiddler.displayFormTiddlerError("No getter defined for INPUT element of type '"+target.type+"'. (Element '"+target.name+"' used in tiddler '"+tiddlerName+"')");
 }
}

// ensure that the function can be used in HTML event handler
window.onFormTiddlerChange = onFormTiddlerChange;


// -------------------------------------------------------------------------------
// Stylesheet Extensions (may be overridden by local StyleSheet)
// -------------------------------------------------------------------------------

setStylesheet(
 ".formTiddlerError{color: #ffffff;background-color: #880000;}",
 "formTiddler");


//============================================================================
// checkForDataTiddlerPlugin Macro
//============================================================================

config.macros.checkForDataTiddlerPlugin = {
 // Standard Properties
 label: "checkForDataTiddlerPlugin",
 version: {major: 1, minor: 0, revision: 0, date: new Date(2005, 12, 14)},
 prompt: "Check if the DataTiddlerPlugin exists"
}

config.macros.checkForDataTiddlerPlugin.handler = function(place,macroName,params) {
 config.macros.formTiddler.checkForExtensions(place, config.macros.formTiddler.label);
}



//============================================================================
// newTiddlerWithForm Macro
//============================================================================

config.macros.newTiddlerWithForm = {
 // Standard Properties
 label: "newTiddlerWithForm",
 version: {major: 1, minor: 0, revision: 1, date: new Date(2006, 1, 6)},
 prompt: "Creates a new Tiddler with a <<formTiddler ...>> macro"
}

config.macros.newTiddlerWithForm.handler = function(place,macroName,params) {
 // --- Parsing ------------------------------------------

 var i = 0; // index running over the params

 // get the name of the form template tiddler
 var formTemplateName = undefined;
 if (i < params.length) {
 formTemplateName = params[i];
 i++;
 }

 if (!formTemplateName) {
 config.macros.formTiddler.createErrorElement(place, "No form template specified in <<" + macroName + ">>.");
 return;
 }

 // get the button label
 var buttonLabel = undefined;
 if (i < params.length) {
 buttonLabel = params[i];
 i++;
 }

 if (!buttonLabel) {
 config.macros.formTiddler.createErrorElement(place, "No button label specified in <<" + macroName + ">>.");
 return;
 }

 // get the (optional) tiddlerName script and "askUser"
 var tiddlerNameScript = undefined;
 var askUser = false;
 if (i < params.length) {
 tiddlerNameScript = params[i];
 i++;

 if (i < params.length && params[i] == "askUser") {
 askUser = true;
 i++;
 }
 }

 // --- Processing ------------------------------------------

 if(!readOnly) {
 var onClick = function() {
 var tiddlerName;
 if (tiddlerNameScript) {
 try {
 tiddlerName = eval(tiddlerNameScript);
 } catch (ex) {
 }
 }
 if (!tiddlerName || askUser) {
 tiddlerName = prompt("Please specify a tiddler name.", askUser ? tiddlerName : "");
 }
 while (tiddlerName && store.getTiddler(tiddlerName)) {
 tiddlerName = prompt("A tiddler named '"+tiddlerName+"' already exists.\n\n"+"Please specify a tiddler name.", tiddlerName);
 }

 // tiddlerName is either null (user canceled) or a name that is not yet in the store.
 if (tiddlerName) {
 var body = "<<formTiddler [["+formTemplateName+"]]>>";
 var tags = [];
 store.saveTiddler(tiddlerName,tiddlerName,body,config.options.txtUserName,new Date(),tags);
 story.displayTiddler(null,tiddlerName,1);
 }
 }

 createTiddlyButton(place,buttonLabel,buttonLabel,onClick);
 }
}

//}}}


/***
!Licence and Copyright
Copyright (c) abego Software ~GmbH, 2005 ([[www.abego-software.de|http://www.abego-software.de]])

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.

Neither the name of abego Software nor the names of its contributors may be
used to endorse or promote products derived from this software without specific
prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
***/
|!Format|!It will look like this...|!...if you format it like this...|
|Bold-faced type|''text''|{{{''text''}}}|
|Italic text|//text//|{{{//text//}}}|
|Underlined text|__text__|{{{__text__}}}|
|Strike-through text|--text--|{{{--text--}}}|
|Links with wikiwords|EnchiLada (inactive link - no tiddler yet)<br>WikiWord (active link to tiddler)|{{{EnchiLada}}}<br>{{{WikiWord}}}|
|~De-Wikify a ~WikiWord|~WikiWord, ~EnchiLada|{{{~WikiWord, ~EnchiLada}}}|
|Links with brackets|[[How to add background images]]|{{{[[How to add background images]]}}}|
|Pretty links|[[display text|ColorSchemes]] - links to the tiddler of color schemes|{{{[[display text|ColorSchemes]]}}}|
|External links work the same way:|http://groups.google.com/group/TiddlyWiki <br><br>[[TiddlyWiki Google group|http://groups.google.com/group/TiddlyWiki]]|{{{http://groups.google.com/group/TiddlyWiki}}} <br><br> {{{[[TiddlyWiki Google group|http://groups.google.com/group/TiddlyWiki]]}}}|
|Links to local files|To a file on a CD in your D drive: <br><br>To a file on your USB stick on your e drive: <br><br>To a file in your hard drive:|{{{file:///D:/filename.doc/}}}<br><br>{{{file:///E:/filename.doc/}}}<br><br>{{{file:///C:/filepath/filename.doc/}}}|
|Colored text|@@color(green):green colored@@|{{{@@color(green):green colored@@}}}|
|Text with colored background|@@bgcolor(#ff0000):color(#ffffff):red colored@@|{{{@@bgcolor(#ff0000):color(#ffffff):red colored@@}}}|
|Highlighting|@@text@@|{{{@@text@@}}}|
|Superscript|2^^3^^=8|{{{2^^3^^=8}}}|
|Subscript|a~~ij~~ = -a~~ji~~|{{{a~~ij~~ = -a~~ji~~}}}|

''Simple indenting:''
{{{ {{indent{text }}} produces:

{{indent{text

''Numbered lists:''
{{{#item one }}}
{{{##Item 1a}}}
{{{###Item 1ai}}} 

produces:
#item one   
##Item 1a 
###Item 1ai 
''Bulleted lists:''
{{{*Bullet one}}}
{{{**Bullet two}}}
{{{***Bullet three}}}
 
produces:
*Bullet one    
**Bullet two    
***Bullet level three    
''Headlines''

{{{!Text}}} produces:
!Text
{{{!!Text}}} produces:
!!Text
{{{!!!Text}}} produces:
!!!Text
and so on.

''Tables:''
This is the formatting:

{{{|!Table header|!Column Two|}}}
{{{|>| colspan |}}}
{{{| rowspan |left aligned|}}}
{{{|~| right aligned|}}}
{{{|bgcolor(#DC1A1A):colored| centered |}}}
{{{||*lists<br>*within<br>*tables<br><br>and double-spaced too|}}}
{{{|caption|c}}}

This is the result:

|!Table header|!Column Two|
|>| colspan |
| rowspan |left aligned|
|~| right aligned|
|bgcolor(#DC1A1A):colored| centered |
||*lists<br>*within<br>*tables<br><br>and double-spaced too|
|caption|c

To align a cell so that its text displays at the top rather than the center, add {{{vertical-align:top;}}} at the beginning of the cell.

''Images:''
{{{[img[http://farm1.static.flickr.com/39/122259544_6913ca58f3_m.jpg]]}}} is the formatting for:

[img[http://farm1.static.flickr.com/39/122259544_6913ca58f3_m.jpg]]

''Dotted horizontal lines:'' 
{{{----}}} produces:
----

''Line-by-line blockquotes:''
{{{>level 1}}}
{{{>level 1}}}
{{{>>level 2}}}
{{{>>level 2}}}
{{{>>>level 3}}}
{{{>>>level 3}}}
{{{>>level 2}}}
{{{>level 1}}}

produces:
>level 1
>level 1
>>level 2
>>level 2
>>>level 3
>>>level 3
>>level 2
>level 1

''Extended blockquotes:''
{{{<<<}}}
{{{Extended blockquotesExtended blockquotesExtended blockquotesExtended blockquotesExtended blockquotesExtended blockquotesExtended blockquotesExtended blockquotesExtended blockquotesExtended blockquotesExtended blockquotesExtended blockquotesExtended blockquotesExtended blockquotesExtended blockquotesExtended blockquotesExtended blockquotesExtended blockquotes}}}
{{{<<<}}} 

produces:
<<<
Extended blockquotesExtended blockquotesExtended blockquotesExtended blockquotesExtended blockquotesExtended blockquotesExtended blockquotesExtended blockquotesExtended blockquotesExtended blockquotesExtended blockquotesExtended blockquotesExtended blockquotesExtended blockquotesExtended blockquotesExtended blockquotesExtended blockquotesExtended blockquotes
<<<

/%
|Name|FramedLink|
|Source|http://www.TiddlyTools.com/#FramedLink|
|Version|1.0.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|script|
|Requires||
|Overrides||
|Description|create an external link that, when clicked, is displayed in an iframe |

Usage:
	<<tiddler FramedLink with: label URL>>

%/{{externalLink{<script label="$1" title="$2">
	var f=place.nextSibling.firstChild;
	try { f.src="$2"; f.style.display='block'; }
	catch(e) { f.style.display='none'; alert(e.description?e.description:e.toString()); }
	return false;
</script><html><iframe src="" style="display:none;background:#fff;width:100%;height:500px"></iframe></html>}}}
<script show>
function hello(who) {
   alert('Hello '+who);   // outputs "Hello world"
}

hello('world');
</script>
<script show>
var myFunc = function() {
   document.write("length="+arguments.length+'<BR>');   // displays 10
   for(i=0; i<arguments.length; i++) {
      document.write(arguments[i]+',');       // displays: 1,2,3,4,5,6,7,8,9,10,
   }
}
myFunc(1,2,3,4,5,6,7,8,9,10);
</script>

[[test FunctionArguments()]]
{{{
var hello = function (who) {
   alert('Hello '+who);      // outputs "Hello world"
}

hello('world');
}}}
<script>
var hello = function (who) {
   alert('Hello '+who);      // outputs "Hello world"
}

hello('world');
</script>
http://tiddlywikiguides.org/index.php?title=Getting_started_with_MonkeyGTD_2.1_alpha
@@color:#aaa;font-size:90%;[[By Matt Vance|http://www.minezone.org/wiki/MVance/GettingThingsDone]]@@
!!Notes from [[Getting Things Done|http://www.amazon.com/exec/obidos/ASIN/0142000280/minezoneorg-20/ref%3Dnosim/103-9510267-6974266]] by David Allen
# capture all the things that need to get done into a logical and trusted system outside of your head and off your mind
# disciplining yourself to make decisions about all the inputs you let into your life, so that you will always have a plan for next actions that you can implement or renegotiate at any moment 

!!Outcomes & Actions
# describe in a single sentence the intended successful outcome for the problem or situation
# write down the very next physical action required to move the situation forward 

!!Horizontal & Vertical Control (Get Things Off Your Mind and Get Them Done)
# horizontal maintains coherence across all activities in which you are involved
# vertical manages thinking up and down the track of individual topics and projects 

!!Five Stages of Workflow (Horizontal)
# ''collect'' things that command our attention (anything personal or professional, big or little, that you think should be different than it currently is and that you have any level of internal commitment to changing)
## get it all out of your head
## minimize your collection buckets
*** physical in-basket
*** writing paper and pads
*** electronic note taking
*** auditory capture (answering machines, voicemail, dictating equipment)
*** email 
## empty the buckets regularly 
# ''process'' what they mean and what to do about them
## what is it?
## is it actionable? YES or NO
*** ''No''
#### trash
#### incubate
##### someday/maybe list
##### tickler file (suspended or follow-on file; a 3D calendar)
****** 43 folders: 31 daily files, 12 monthly files, tomorrow's date at the front 
#### reference (reference should be information that can be easily referred to when needed) 
*** ''Yes''
#### What is the next action?
***** ''do'' it
***** ''delegate'' it
***** ''defer'' it
***** [[Project]] (anything requiring more than one step to accomplish the desired outcome) 
#### actionable tracking
##### list of projects
##### storage or files for project plans and materials
##### calendar (time specific actions [appointments], day specific actions, day specific information)
##### list of reminders of next actions
##### a list of reminders of things you're waiting for (only review as often as they have to be in order to stop wondering about them) 
# ''organize'' the results
# ''review'' the options
# ''do''
## choosing actions in the moment
### context
### time available
### energy available
### priority 

!!Weekly Review
# Loose Papers
** business cards, receipts, etc. - put in in basket for processing 
# Process Your Notes
# Previous Calendar Data
** review for remaining action items, reference information, etc. 
# Upcoming Calendar
# Empty Your Head
** write down any new projects, action items, etc. 
# Review "Projects" (and Larger Outcome) Lists
** ensure that at least one kick-start action is in your system for each 
# Review "Next Actions" Lists
** Mark off completed actions & review for reminders of further action steps to capture 
# Review "Waiting For" List
** Records appropriate actions for any needed follow-up & check off received items 
# Review Any Relevant Checklists
# Review "Someday/Maybe" List
** Check for any projects that may have become active and transfer them to "Projects" & delete items no longer of interest 
# Review "Pending" and Support Files
** Browse through all work-in-progress support material to trigger new actions, completions, and waiting-fors 

!!Models for Making Action Choices ([[The Three-fold Nature of Work|http://www.effectivemeetings.com/productivity/timemanagement/natureofwork.asp]])
# predefined
# work as it shows up
# defining work 

!!Six Level Model for Reviewing Your Own Work
# current actions
# current projects
# areas of responsibility
# 1-2 year goals
# 3-5 year vision
# big picture view 
* ''projects'': clearly defined outcomes and the next actions to move them towards closure
* ''horizontal focus'': reminders placed in a trusted system that is reviewed regularly
* ''vertical focus'': informal back of the envelope planning 

!!Five Steps to Accomplish Any Task (Project Planning)
# defining purpose and principles
# outcome visioning
# brainstorming
# organizing
# identifying next actions 

!!Five Phases of Natural Planning Techniques
# purpose / guiding principles (Why are we doing this?)
# mission / vision / goals / sucessful outcome (What would wild success look, sound, or feel like?)
# brainstorming (How would we accomplish it?)
## view the project from beyond the completion date
## envision wild success (suspend "Yeah, but. . .")
## capture features, aspects, and qualities you imagine in place 
# organizing (identify components, subcomponents, sequences, events, and/or priorities; what must occur and in what order? When do we do these things?)
# next actions (Where do we start?) 

"If the project is off your mind, your planning is sufficient. If it's still on your mind, keep applying the model until it's clear."

!![[Critical Factor of Filing System]]


!!Dealing with un-met agreements:
# lower standards
# do it
# renegotiate agreement 

"What is the next action?"
"The better you get, the better you'd better get."

![[SUMMARY GTD]]
# keep everything out of your head
# decide actions and outcomes when things first emerge on your radar, instead of later
# regularly review and update the complete inventory of open loops of your life and work 
----
Pick up anything around you that you're wondering what to do with, and apply a simple set of formulae:
* I don't need or want it = trash
* I still need to decide what this means to me = IN basket item
* I might need to know this information = reference
* I use it = equipment and supplies
* I like to see it = decoration
* When I could possibly move on it, I want to see the action as an option = next action reminder, reviewed when and where it could be done
* I need to be reminded of this short-term outcome I've committed to = project list item, reviewed weekly
* I need to have this when I focus on a project = support material
* I might want to commit to this at any time in the future = Someday/maybe list item
* I might want to commit to this on or after a specific time in the future = calendared or "tickled" item incubated for review on a specific future date
* I want to achieve this "bigger" outcome = goals, objectives, visions that you review on some longer interval
* It's something someone else is doing that I care about = item on Waiting-For list, reviewed at least weekly
* I need to consider it when I do certain recurring activities = item on a checklist 
 - from [[David Allen|http://www.davidco.com/]]'s Productivity Principles newsletter 
----
!!!See Also:
* [[Book Notes|http://www.minezone.org/wiki/MVance/BookNotes]] -- MVance's notes on lots of other books
* [[Notes from "Now Habit"|http://www.minezone.org/wiki/MVance/NowHabit]] -- notes from a book on productivity, motivation, etc.
* [[Getting Things Done When You're Only a Grunt|http://www.joelonsoftware.com/articles/fog0000000332.html]] -- taking charge when you're not in charge (check out the comments too)
* [[The PigPog Method|http://pigpog.com/michael/blog/2004/08/productivity-gtd-pigpog-method.php]] -- a useful hack for those using PDAs
* [[Cascading Next Actions|http://www.marktaw.com/blog/CascadingNextActions.html]] -- good information on breaking projects down into manageable chunks
* [[One-Page Workflow Chart|http://www.davidco.com/pdfs/gtd_workflow_advanced.pdf]] (PDF) -- a visual flowchart for dealing with incoming information
* [[43 Folders: GTD on a Mac|http://www.43folders.com/]] -- a great resource related to Lifehacks and Getting Things Done
* [[Getting Things Done Zone on OfficeZealot.com|http://www.officezealot.com/gtd/]] -- lots of articles related to Getting Things Done 
<html>
<iframe src="http://www.google.com/news" width=528 height=270">
</iframe>
</html>
{{niceTable{
|alpha	|&alpha;	|&Alpha;	|
|beta	|&Beta;		|&beta;		|
|gamma	|&gamma;	|&Gamma;	|
|eta|&eta;|&Eta;|
|Theta|&theta;|&Theta; |
|iota|&iota;|&Iota; |
|kappa;|&kappa;|&Kappa; |
|lambda;|&lambda;|&Lambda; |
|mu|&mu;|&Mu; |
|nu|&nu;|&Nu; |
|xi|&xi;|&Xi; |
|omicron|&omicron;|&Omicron; |
|pi|&pi;|&Pi; |
|rho|&rho;|&Rho; |
|sigma|&sigma;|&Sigma; |
|tau|&tau;|&Tau; |
|upsilon|&upsilon;|&Upsilon; |
|phi|&phi;|&Phi; |
|chi|&chi;|&Chi; |
|psi|&psi;|&Psi; |
|omega|&omega;|&Omega; |
}}}
<html>
<body>

<script type="text/javascript">
document.write("<h1>Hello World!</h1>")
</script>

</body>
</html>
/***
|Name|HelloWorldMacro|
|Created by|SimonBaird|
|Location|http://simonbaird.com/mptw/#HelloWorldMacro|
|Version|1.0.3|
|Requires|~TW2.x|
!Description
It's a Hello World TiddlyWiki macro.

!History
* 03-Mar-06, version 1.0.3, added version.extensions data
* 13-Jan-06, version 1.0.2, added shout macro example
* 11-Jan-06, version 1.0.1, updated for ~TW2.0

!Examples
|!Source|!Output|h
|{{{<<helloWorld dude>>}}}|<<helloWorld dude>>|
|{{{<<helloWorld 'to everyone'>>}}}|<<helloWorld 'to everyone'>>|
(You can use (single or double) quotes or double square brackets for params with spaces)

!Notes
This is intended to help you get started with customising your TW. To make the macro work you have to give this tiddler a tag of systemConfig then save and reload. To learn more about customising Tiddlywiki you can look at other people's plugins or click View, Source in your browser and start reading. :)

!Code
***/
//{{{

// this part is not actually required but useful to other people using your plugin
version.extensions.HelloWorldMacro = { major: 1, minor: 0, revision: 3, date: new Date(2006,3,3),
 source: "http://simonbaird.com/mptw/#HelloWorldMacro"
};

config.macros.helloWorld = {
	label: "helloWorld",
	prompt: "This will send a message" 
};
config.macros.helloWorld.handler = function (place,macroName,params,wikifier,paramString,tiddler) {
	var who = params.length > 0 ? params[0] : "world";
	params = paramString.parseParams("name",null,true,false,true);
	var names = params[0]["name"];

	para1 = names[0]
	para2 = names[1] ? names[1] : null;
	para3 = names[2] ? names[2] : null;
	
	who = para1;
	wikify("Hello //" + who + "// from the '" + macroName + "' macro in tiddler [[" + tiddler.title + "]].", place);

wikify(para1+"\n", place);
wikify(para2+"\n", place);
wikify(para3+"\n", place);
}

// a one liner...
config.macros.shout = { handler: function(place,name,params) { wikify("//''@@font-size:5em;color:#696;"+ params[0] + "!@@''//", place); } };


//}}}

/***

!Another example
{{{<<shout Yeah>>}}}


<<helloWorld first second>>

<<shout Yeah>>


***/
/***
| Name|HideWhenPlugin|
| Description|Allows conditional inclusion/exclusion in templates|
| Version|3.0 ($Rev: 1845 $)|
| Date|$Date: 2007-03-16 15:19:22 +1000 (Fri, 16 Mar 2007) $|
| Source|http://mptw.tiddlyspot.com/#HideWhenPlugin|
| Author|Simon Baird <simon.baird@gmail.com>|
| License|http://mptw.tiddlyspot.com/#TheBSDLicense|
For use in ViewTemplate and EditTemplate. Example usage:
{{{<div macro="showWhenTagged Task">[[TaskToolbar]]</div>}}}
{{{<div macro="showWhen tiddler.modifier == 'BartSimpson'"><img src="bart.gif"/></div>}}}
***/
//{{{

window.removeElementWhen = function(test,place) {
	if (test) {
		removeChildren(place);
		place.parentNode.removeChild(place);
	}
};

merge(config.macros,{

	hideWhen: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( eval(paramString), place);
	}},

	showWhen: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( !eval(paramString), place);
	}},

	hideWhenTagged: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( tiddler.tags.containsAll(params), place);
	}},

	showWhenTagged: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( !tiddler.tags.containsAll(params), place);
	}},

	hideWhenTaggedAny: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( tiddler.tags.containsAny(params), place);
	}},

	showWhenTaggedAny: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( !tiddler.tags.containsAny(params), place);
	}},

	hideWhenTaggedAll: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( tiddler.tags.containsAll(params), place);
	}},

	showWhenTaggedAll: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( !tiddler.tags.containsAll(params), place);
	}},

	hideWhenExists: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( store.tiddlerExists(params[0]) || store.isShadowTiddler(params[0]), place);
	}},

	showWhenExists: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( !(store.tiddlerExists(params[0]) || store.isShadowTiddler(params[0])), place);
	}}

});

//}}}
* computers
* programming
When you specify a link to a tiddler a tiddler with that title is searched at the following locations:
* In the "normal" tiddlers of the main TiddlyWiki
* In the "shadow" tiddlers of the main TiddlyWiki
* In the "normal" tiddlers of all included TiddlyWikis, in the order of the include macros.<<br>>//(You may use [[The "includeState" Macro]] to check the order)//
The first tiddler found this way is used.

''Note:'' If two tiddlers in two TiddlyWikis have the same name, the one from the first TiddlyWiki is used, i.e. the other is "hidden".
Examples:
* Opening the folder within the browser: [[GM Xu Li Folder|/////houic-na-p010\Epw_sure_proj\Engineering_R&D\NFT\GM Surveillance]]

* Using the plugin LaunchApplication to open the folder with Explorer: <<LaunchApplication "GM Xu Li Folder" "Folder_R&D" "//houic-na-p010/Epw_sure_proj/Engineering_R&D/NFT/GM Surveillance">>	
!Step 1: Get the Plugin
Import the IncludePlugin (from http://tiddlywiki.abego-software.de), e.g. using the ImportTiddlers, and make sure the "systemConfig" tag is defined. 
!Step 2: Include ~TiddlyWikis
To include TiddlyWikis add an „include“ macro into the tiddler „IncludeList“:
{{{
<<include "shared/TiddlyWikiHelp.html">>
<<include "journals/2007-01.html">>
}}}
For details see [[The "include" Macro]].

''Notes''
* You need to reload your TiddlyWiki after you added or changed any "include" macro in the "IncludeList" tiddler.
!Step 3: Access included Tiddlers
To access an included tiddler you just need to create a link to that tiddler (with the tiddler's title). If you click that link the included tiddler will be displayed. To "find" an included tiddler, just search for it with the standard search feature.

You only can edit included tiddlers in their "original" TiddlyWiki. Hence included Tiddlers are readonly in a "main" TiddlyWiki.


See also [[How Tiddlers are found]].

!Using the "include" macro without the "IncludeList" Tiddler
The {{{<<include ...>>}}} macro is typically used in the "IncludeList" (as described above). The TiddlyWikis listed in the "IncludeList" are included at TiddlyWiki startup.

But you may put the {{{<<include ...>>}}} macro in any tiddler. The include process starts when the tiddler containing the {{{<<include ...>>}}} macro is displayed (or after delayDuration milliseconds). This way you may include TiddlyWikis/Tiddlers "on demand", i.e. the TiddlyWiki is only loaded when a certain tiddler is displayed.

When using the include macro in a tiddler different than the "IncludeList" you may want to use the "hide: true" parameter to avoid the include macro is displayed to the user.
<script>
var d = new Date()
var time = d.getHours()

if (time < 10) 
{
document.write("<b>Good morning</b>")
}
else 
{
document.write("<b>Good afternoon</b>")
}
</script>

<html><p>This example demonstrates the If statement.</p>
<p>If the time on your browser is less than 10,
you will get a "Good morning" greeting.</p></html>
http://reyesaguayo.com/osp/images/
/***
|Name|ImagePathPlugin|
|Source|http://www.TiddlyTools.com/#ImagePathPlugin|
|Version|0.7.1|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin,formatter|
|Requires||
|Overrides|'image' formatter|
|Description|Tell TiddlyWiki where to look for image files.  Permits multiple 'fallback' locations|
|Status|ALPHA - initial development/testing only - may be unstable - do not distribute|

!!!!!Usage
<<<
This plugin adds "resolvePath()" fallback processing to the {{{[img[...]]}}} formatter's handler, so that local image file references can be successfully resolved, even if the files cannot be located on the local filesystem.

The plugin tries alternative file "paths" that are listed, one per line, in an optional tiddler, [[ImagePathList]].  Each path in the list is combined with the image filename, which is then checked for existence, until the file is located.  If no alternative is found, or [[ImagePathList]] is not present, then a 'last-ditch' fallback is attempted using the remote system and path specified in [[SiteUrl]] (if present).

If no fallback attempt is successful (i.e., because no [[ImagePathList]] OR [[SiteUrl]] tiddlers have been defined), the plugin simply passes the original image file value along for default handling by the browser without any "path resolution" being applied.(i.e, the current TW core behavior occurs).

| ''Important note: This plugin may cause one or more security alert messages to appear, because it uses browser-specific functions that can require security permission in order to access the local filesystem to check for the existence of a given image file.  If you block local access, the 'last-ditch' fallback using the remote [[SiteUrl]] (if present) will be attempted.'' |

Note: the image formatter code contained here also includes support for AttachFilePlugin extensions (if installed).  AttachFilePlugin includes its own fallback mechanism for handling embedded vs. local file vs. remote URL references to the attached binary file.  Both methods may be used: ImagePathPlugin provides fallback for images contained in tiddler content, while AttachFilePlugin works well for access to non-image binary files (or images used in CSS as backgrounds, textures, etc.)
<<<
!!!!!Examples
<<<
coming soon...
<<<
!!!!!Revisions
<<<
''2007.04.13 [0.7.1]'' in testFile(), convert any file:// references to local native format before checking for existence.
''2007.03.26 [0.7.0]'' for IE, use onError handling to trigger call to resolvePath() so it will only be invoked if the original path/file is not found by the browser-native lookup.  This avoids an unneeded call to fileExists() and the accompanying ActiveX security alert message box (as well as being slightly more efficient...)
''2007.03.25 [0.6.0]'' code cleanup (moved global functions into config.formatterHelpers) plus documentation re-write
''2007.03.24 [0.5.0]'' initial implementation - ALPHA - do not distribute
<<<
!!!!!Code
***/
//{{{
version.extensions.ImagePathPlugin= {major: 0, minor: 7, revision: 1, date: new Date(2007,4,13)};
//}}}
//{{{
// name of path definition tiddler
if (config.options.txtPathTiddler==undefined) config.options.txtPathTiddler="ImagePathList";
//}}}
//{{{
// low-level wrapper for platform-specific tests for local file existence
// returns true/false without visible error display
// Uses Components for FF and ActiveX FSO object for MSIE
// NOTE: this can cause a security warning on some browsers
config.formatterHelpers.fileExists=function(theFile) {
	var found=false;
	// DEBUG: alert('testing fileExists('+theFile+')...');
	if(window.Components) {
		try { netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); }
		catch(e) { return false; } // security access denied
		var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
		try { file.initWithPath(theFile); }
		catch(e) { return false; } // invalid directory
		found = file.exists();
	}
	else { // use ActiveX FSO object for MSIE 
		var fso = new ActiveXObject("Scripting.FileSystemObject");
		found = fso.FileExists(theFile)
	}
	// DEBUG: alert(theFile+" "+(found?"exists":"not found"));
	return found;
}
//}}}
//{{{
// higher-level logic for checking local file existence.
// with secondary check for finding relative file references
// and automatic OK of http-based references without checking local filesystem
config.formatterHelpers.testFile=function(theFile) {
	if (document.location.protocol!="file:") return true; // viewing remote document, can't test local filesystem... assume OK
	if (theFile.substr(0,5)=="http:") return true; // remote HTTP reference... assume OK
	if (theFile.substr(0,5)=="file:") theFile=getLocalPath(theFile); // convert local FILE reference to native format
	if (this.fileExists(theFile)) return true; // file exists locally... OK to use!
	// file might have been relative, add path from current document and try again
	var docPath=document.location.href;
	var slashpos=docPath.lastIndexOf("/"); if (slashpos==-1) slashpos=docPath.lastIndexOf("\\"); 
	if (slashpos!=-1 && slashpos!=docPath.length-1) docPath=docPath.substr(0,slashpos+1); // trim off filename
	if (this.fileExists(getLocalPath(docPath+theFile)))
		return true; // ah ha!... file exists relative to current document... OK to use!
	return false; // file not found on local system
}
//}}}
//{{{
// given a path/file string, check for existence and
// try alternatives (if any) defined in a tiddler
// with last-ditch using system/path from SiteUrl (if any)
config.formatterHelpers.resolvePath=function(theFile,testoriginal) {
	if (testoriginal && this.testFile(theFile)) return theFile; // FOUND FILE - use specified path/file without modification
	// get the filename portion only
	var slashpos=theFile.lastIndexOf("/"); if (slashpos==-1) slashpos=theFile.lastIndexOf("\\"); 
	var theName=(slashpos==-1)?theFile:theFile.substr(slashpos+1);
	// get list of fallbacks (if any)
	var pathText=store.getTiddlerText(config.options.txtPathTiddler);
	if (pathText && pathText.length) {
		var paths=pathText.split("\n");
		for (p=0; p<paths.length; p++) // combine path+filename until one works...
			if (this.testFile(paths[p]+theName))
				return paths[p]+theName; // FOUND FILE - use alternative path+filename
	}
	// try "last ditch" fallback using SiteURL - assumes that original path/file was relative to document location
	var siteURL=store.getTiddlerText("SiteUrl");
	if (!siteURL||!siteURL.length) return theFile; // NO FALLBACK - use original path/file and hope for the best
	// trim filename (if any) from site URL
	var slashpos=siteURL.lastIndexOf("/"); if (slashpos==-1) slashpos=siteURL.lastIndexOf("\\"); 
	if (slashpos!=-1 && slashpos!=siteURL.length-1) siteURL=siteURL.substr(0,slashpos+1);
	return siteURL+theFile; // LAST DITCH: use system/path from SiteUrl combined with original file/path
}
//}}}
//{{{
// replace standard handler for image formatter
// adds call to resolvePath() to handle fallback processing
// includes support for AttachFilePlugin as well
config.formatters[config.formatters.findByField("name","image")].handler=function(w) {
	if (!this.lookaheadRegExp)  // fixup for TW2.0.x
		this.lookaheadRegExp = new RegExp(this.lookahead,"mg");
	this.lookaheadRegExp.lastIndex = w.matchStart;
	var lookaheadMatch = this.lookaheadRegExp.exec(w.source)
	if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
		// Simple bracketted link
		var e = w.output;
		if(lookaheadMatch[5]) {
			var link = lookaheadMatch[5];
			if (!config.formatterHelpers.isExternalLink) // fixup for TW2.0.x
				var external=!store.tiddlerExists(link)&&!store.isShadowTiddler(link);
			else
				var external=config.formatterHelpers.isExternalLink(link);
			if (external) {
				if (config.macros.attach && config.macros.attach.isAttachment(link)) { // ELS - attachments
					e = createExternalLink(w.output,link);
					e.href=config.macros.attach.getAttachment(link);
					e.title = config.macros.attach.linkTooltip + link;
				} else
					e = createExternalLink(w.output,link);
			} else 
				e = createTiddlyLink(w.output,link,false,null,w.isStatic);
			addClass(e,"imageLink");
		}
		var img = createTiddlyElement(e,"img");
		if(lookaheadMatch[1])
			img.align = "left";
		else if(lookaheadMatch[2])
			img.align = "right";
		if(lookaheadMatch[3])
			img.title = lookaheadMatch[3];
		if (config.macros.attach!=undefined && config.macros.attach.isAttachment(lookaheadMatch[4])) // ELS - attachments
			img.src=config.macros.attach.getAttachment(lookaheadMatch[4]);
		else {
			if (config.browser.isIE || config.browser.isSafari) { // ELS - path processing
				// IE and Safari use browser's onError handling to check the original file...
				// avoids extra security alert messages due to use of Components/ActiveX for filesystem access
				img.onerror=(function(){this.src=config.formatterHelpers.resolvePath(this.src,false);return false;});
				img.src=lookaheadMatch[4]; // ELS - path processing
			} else {
				// if NOT IE or Safari, always check the original path/file before rendering
				img.src=config.formatterHelpers.resolvePath(lookaheadMatch[4],true);
			}
		}
		w.nextMatch = this.lookaheadRegExp.lastIndex;
	}
}
//}}}
/***
|''Name:''|abego.IncludePlugin|
|''Version:''|1.0.0 (2007-02-08)|
|''Type:''|plugin|
|''Source:''|http://tiddlywiki.abego-software.de/#IncludePlugin|
|''Author:''|Udo Borkowski (ub [at] abego-software [dot] de)|
|''Documentation:''|[[IncludePlugin Documentation|http://tiddlywiki.abego-software.de/#%5B%5BIncludePlugin%20Documentation%5D%5D]]|
|''Community:''|([[del.icio.us|http://del.icio.us/post?url=http://tiddlywiki.abego-software.de/index.html%23IncludePlugin]]) ([[Support|http://groups.google.com/group/TiddlyWiki]])|
|''Copyright:''|&copy; 2007 [[abego Software|http://www.abego-software.de]]|
|''Licence:''|[[BSD open source license (abego Software)|http://www.abego-software.de/legal/apl-v10.html]]|
|''~CoreVersion:''|2.1.3|
|''Browser:''|Firefox 1.5.0.9 or better; Internet Explorer 6.0|
***/
//{{{

// Ensure the global abego namespace is set up.
if (!window.abego) window.abego = {};

var invokeLater = function(func, delay, priority) {
	return abego.invokeLater ? abego.invokeLater(func, delay, priority) : setTimeout(func,delay);
};

// Asynchronously load the given (local or remote) file.
// 
// @param url 		either an URL or a local file path to a file
//					Examples:
//						* http://www.abego-software.de/index.html
//						* file:///C:/abegoWebSite-Copy/index.html
//						* C:\abegoWebSite-Copy\index.html    (for Windows machines)
//							(Notice: backslashes in JavaScript string constants must be escaped, 
//							 i.e. the last example must be written as: "C:\\abegoWebSite-Copy\\index.html"
//							 when "hardcoded" in JavaScript source code)
// 
// @param callback 
//					function(content,url,params,errorMessage) 
//					called at the end of the operation. 
//					On success content holds the content of the loaded file. 
//					On error content is undefined and errorMessage holds an error message. 
//					params is the params passed into abego.loadFile.
//
// @param params 	passed through to the callback function
// 
abego.loadFile = function(url,callback,params) {

	var onLoad = function(status,params,responseText,url,xhr) {
		return status 
				? callback(responseText, url, params)
				: callback(undefined, url, params, "Error loading %0".format([url]));
	};
	
	// Make sure the URL is a real URL, with protocol prefix etc.
	if (url.search(/^((http(s)?)|(file)):/) != 0) {
		
		// no protocol specified. 
		if (url.search(/^((.\:\\)|(\\\\)|(\/))/) == 0) {
			// "url" is an "absolute" path to a local file. Prefix it with file://
			url = "file://"+url;
			
		} else {
			// "url" is a "relative" URL. Make it absolute
			
			// prefix the url with the directory containing the current document
			// (This also includes the protocol prefix)
			var documentPath = document.location.toString();
			var i = documentPath.lastIndexOf("/");
			url = documentPath.substr(0,i+1)+url;
		}
		// replace every \ by a /, to cover Windows style pathes
		url = url.replace(/\\/mg,"/");
	}
	
	loadRemoteFile(url,onLoad,params);

};

// Asynchronously load the given (local or remote) TiddlyWiki store.
// 
// @param url 		either an URL or a local file path to a TiddlyWiki file (absolute or relative)
//					Examples:
//						* http://www.abego-software.de/index.html
//						* file:///C:/abegoWebSite-Copy/index.html
//						* include/beta.html
//						* C:\abegoWebSite-Copy\index.html    (for Windows machines)
//							(Notice: backslashes in JavaScript string constants must be escaped, 
//							 i.e. the last example must be written as: "C:\\abegoWebSite-Copy\\index.html"
//							 when "hardcoded" in JavaScript source code)
// 
// @param callbackWithStore 
//					function(theStore,url,params,errorMessage) 
//					called at the end of the operation. 
//					On success theStore holds the loaded store (a TiddlyWiki object). 
//					On error theStore is undefined and errorMessage holds an error message. 
//					params is the params passed into abego.loadTiddlyWikiStore
//
// @param params 	passed through to the callbackWithStore
//
// @progress		[optional] function(message, sender, state, url, params) called in various situations during the operation,
//								typically used to show "the progress" of the operation.
//								sender: the constant "abego.loadTiddlyWikiStore"
//								state: one of these: "Started", "Processing", "Done", "Failed"
//									"Processing" means the data has been received and in now processed.
// 
abego.loadTiddlyWikiStore = function(url,callbackWithStore,params,progress) {
	
	var sendProgress = function(message, state) {
		if (progress)
			progress(message,"abego.loadTiddlyWikiStore",state,url,params);
	};
	
	// Load contents of a TiddlyWiki from a string
	//# Returns null on success, an error message otherwise.
	//# based on code from TiddlyWiki 2.2 alpha
	var importTiddlyWiki = function(store,text)
	{
		// Crack out the content - will be refactored to share code with saveChanges()
		var posOpeningDiv = text.indexOf(startSaveArea);
		var limitClosingDiv = text.indexOf("<!--POST-BODY-END--"+">");
		var posClosingDiv = text.lastIndexOf(endSaveArea,limitClosingDiv == -1 ? text.length : limitClosingDiv);
		if((posOpeningDiv == -1) || (posClosingDiv == -1))
			return config.messages.invalidFileError.format([url]);
		var content = "<html><body>" + text.substring(posOpeningDiv,posClosingDiv + endSaveArea.length) + "</body></html>";
		// Create the iframe
		var iframe = document.createElement("iframe");
		iframe.style.display = "none";
		document.body.appendChild(iframe);
		var doc = iframe.document;
		if(iframe.contentDocument)
			doc = iframe.contentDocument; // For NS6
		else if(iframe.contentWindow)
			doc = iframe.contentWindow.document; // For IE5.5 and IE6
		// Put the content in the iframe
		doc.open();
		doc.writeln(content);
		doc.close();
		// Load the content into a TiddlyWiki() object
		var storeArea = doc.getElementById("storeArea");
		store.loadFromDiv(storeArea,"store");
		// Get rid of the iframe
		iframe.parentNode.removeChild(iframe);
		return null;
	};
	
	var sendError = function(message) {
		sendProgress("Error when loading %0".format([url]),"Failed");
		callbackWithStore(undefined, url,params, message);
		return message;
	};
	
	var sendStore = function(store) {
		sendProgress("Loaded %0".format([url]),"Done");
		callbackWithStore(store, url, params);
		return null;
	};
	
	
	var callback = function(content,theURL,params,errorMessage) {
		if (content === undefined) {
			sendError(errorMessage);
			return;
		}
		
		sendProgress("Processing %0".format([url]),"Processing");
		var orig_invalidFileError = config.messages.invalidFileError;
		config.messages.invalidFileError = "The file '%0' does not appear to be a valid TiddlyWiki file";
		try {
			// Load the content into a TiddlyWiki() object
			var importStore = new TiddlyWiki();
			var errorText = importTiddlyWiki(importStore,content);
			if (errorText)
				sendError(errorText);
			else
				sendStore(importStore);

		} catch (ex) {
			sendError(exceptionText(ex));
		} finally {
			config.messages.invalidFileError = orig_invalidFileError;
		}
	};
	
	sendProgress("Start loading %0".format([url]),"Started");
	abego.loadFile(url,callback,params);
};


//==============================================================================
// Include Plugin 

(function(){

// only install once
if (abego.TiddlyWikiIncluder) return;


// --------------------------------------------------
// Constants

var WAITING = "waiting";
var LOADING = "loading";

var ANI_DURATION_HIDE_STATE = 1000;

var REFRESH_PRIORITY = -200;
var ANIMATION_PRIORITY = -100;
var UPDATE_STATE_PRIORITY = -300;

// --------------------------------------------------
// Variables

var useInclude;
var includes = []; // [] of Strings. the urls of the stores to include, in the sequence of the calls.
var includedStores = {}; // url(String) -> TiddlyWiki or String; when not (yet) loaded a status or error string.
var pendingOnLoadURLs = []; // [] of String. a list of urls that should be passed with the next "notifyListeners".
var refreshTiddlyWikiTimerID; // for delayed refresh
var listeners = [];
var progress;

// --------------------------------------------------
// Helper functions

var isIncludeEnabled = function() {
	if (useInclude === undefined)
		useInclude = config.options.chkUseInclude === undefined || config.options.chkUseInclude;
	return useInclude;
};

var getMissingIncludeMsg = function(url) {
	return "No include specified for %0".format([url])
};

// Called after one or more included TiddlyWikis are loaded
//
var notifyListeners = function() {
	var urls = pendingOnLoadURLs;
	pendingOnLoadURLs = [];
	if (urls.length) {
		for (var i= 0; i < listeners.length; i++)
			listeners[i](urls);
	}
};

var idleCount; // Reset to 0 when the system is "not idle", incremented inside refreshTiddlyWiki

var refreshTiddlyWiki = function() {
	// To avoid to much refreshing/flickering don't refresh immediately 
	// but wait until the system was idle for a certain time.
	
	if (refreshTiddlyWikiTimerID !== undefined) clearInterval(refreshTiddlyWikiTimerID);
	
	idleCount = 0;
	
	var sendDone = function() {
		abego.TiddlyWikiIncluder.sendProgress("","","Done");
	};
	
	refreshTiddlyWikiTimerID = setInterval(function() {
		idleCount++;
		if (idleCount <= 10)
			return;
			
		clearInterval(refreshTiddlyWikiTimerID);
		refreshTiddlyWikiTimerID = undefined;
			
		abego.TiddlyWikiIncluder.sendProgress("Refreshing...","","");
		refreshDisplay();
		invokeLater(sendDone,0,REFRESH_PRIORITY);
	},0);
};

// Calls callback for every loaded store and returns the first non-false/null.. value returned by callback.
//
// @param callback  function(store, url)
//
var forEachLoadedStore = function(callback) {
	var result;
	for (var i = 0; i < includes.length; i++) {
		var theStore = abego.TiddlyWikiIncluder.getStore(includes[i]);
		if (theStore && (result = callback(theStore, includes[i])))
			return result;
	}
};

var attachToStore = function() {
	if (!window.store)
		return invokeLater(attachToStore,100);
		
	var orig_fetchTiddler = store.fetchTiddler;
	
	store.fetchTiddler = function(title) {
		var t = orig_fetchTiddler.apply(this,arguments);
		if (t) return t;
		
		// When there is a shadowtiddler with that name done look for
		// any included tiddler since these would hide the shadow
		if (config.shadowTiddlers[title] !== undefined) return undefined;
		
		// Don't look for the "New Tiddler" tiddler in the included TiddlyWikis,
		// since returning such a tiddler (that is readonly) will make it impossible
		// in the Main TiddlyWiki to create new tiddlers.
		if (title == config.macros.newTiddler.title) return undefined;

		return forEachLoadedStore(
				function(theStore, url) {
					var t = theStore.fetchTiddler(title);
					if (t) 
						t.includeURL = url;
					return t;
				});
	};

	// We also refresh TiddlyWiki to reflect the new included Tiddlers (if we have any).
	if (includes.length)
		refreshTiddlyWiki();
};

var includeFromIncludeList = function() {
	if (!window.store)
		return invokeLater(includeFromIncludeList,100);
		
	var includeListText = store.getTiddlerText("IncludeList");
	if (includeListText) 
		wikify(includeListText,document.createElement("div"));
};

var getFunctionUsingForReallyEachTiddler = function(func) {
	var wrapper = function() {
		var orig_forEachTiddler = store.forEachTiddler;

		var forEachTiddlerWithIncludes = function(callback) {
			var done = {};
			var includeURL;

			var callbackWrapper = function(title, tiddler) {
				// ensure every title is only processed once
				if (done[title]) 
					return;
				done[title] = 1;
				
				// for "included tiddlers" set the includeURL;
				if (includeURL)
					tiddler.includeURL = includeURL;
				
				callback.apply(this,arguments);
			};
			
			// forEachTiddler over the original tiddlers
			orig_forEachTiddler.call(store, callbackWrapper);
			
			// add all shadowTiddler titles to done 
			// (to avoid an included store hides a shadow tiddler)
			for (var n in config.shadowTiddlers)
				done[n] = 1;

			// add all the "New Tiddler" tiddlerto done 
			// (to avoid an included store (with "New Tiddler") makes it impossible to create new tiddlers)
			done[config.macros.newTiddler.title] = 1;

			// forEachTiddler over every included store
			forEachLoadedStore(
					function(theStore, url) {
						includeURL = url;
						theStore.forEachTiddler(callbackWrapper);
					});
		};
		
		store.forEachTiddler = forEachTiddlerWithIncludes;
		try {
			return func.apply(this,arguments);
		} finally {
			store.forEachTiddler = orig_forEachTiddler;
		}
	};
	
	return wrapper;
};

var useForReallyEachTiddler = function(object,property) {
	return object[property] = getFunctionUsingForReallyEachTiddler(object[property]);
};


//================================================================================
// abego.TiddlyWikiIncluder

abego.TiddlyWikiIncluder = {};

abego.TiddlyWikiIncluder.setProgressFunction = function(func) {
	progress = func;
};

abego.TiddlyWikiIncluder.getProgressFunction = function(func) {
	return progress;
};

abego.TiddlyWikiIncluder.sendProgress = function(message, sender, state) {
	if (progress)
		progress.apply(this,arguments);
};


// Called when an included TiddlyWiki could not be loaded.
//
// By default an error message is displayed.
//
abego.TiddlyWikiIncluder.onError = function(url, errorMessage) {
	displayMessage("Error when including '%0':\n%1".format([url, errorMessage]));
};


// Returns true when there are "pending" includes, i.e. TiddlyWiki that are not yet loaded.
//
// A TiddlyWiki that failed loading is not pending.
//
abego.TiddlyWikiIncluder.hasPendingIncludes = function() {
	for (var i = 0; i < includes.length; i++) {
		var state = abego.TiddlyWikiIncluder.getState(includes[i]);
		if (state == WAITING || state == LOADING)
			return true;
	}
	return false;
};


// @return [] of Strings, the URLs of the includes
//
abego.TiddlyWikiIncluder.getIncludes = function() {
	return includes.slice();
};


// @return [may be null] a state/error text of the store with the given URL, or null when the store is already loaded
//
abego.TiddlyWikiIncluder.getState = function(url) {
	var s = includedStores[url];
	if (!s)
		return getMissingIncludeMsg(url);
	return typeof s == "string" ? s : null;
};


// @return [may be null] the (TiddlyWiki) store  with the given URL, null if not (yet) loaded.
//
abego.TiddlyWikiIncluder.getStore = function(url) {
	var s = includedStores[url];
	if (!s)
		return getMissingIncludeMsg(url);
	return s instanceof TiddlyWiki ? s : null;
};


// Includes the (local or remote) TiddlyWiki store with the given url.
// 
// stores with urls already already included are ignored.
//
// @param url	see url@abego.loadTiddlyWikiStore
// @param delayMilliSeconds [optional] if defined loading starts delayMilliSeconds later, otherwise "immediately"
//
abego.TiddlyWikiIncluder.include = function(url, delayMilliSeconds) {
	if (!isIncludeEnabled() || includedStores[url])
		return;
	var self = this;
	
	includes.push(url);
	includedStores[url] = WAITING;

	var loadStoreCallback = function(theStore,urlInCallback,params,errorMessage) {
		if (theStore === undefined) {
			includedStores[url] = errorMessage;
			self.onError(url, errorMessage);
			return;
		}
		includedStores[url] = theStore;
		pendingOnLoadURLs.push(url);
		invokeLater(notifyListeners);
	};
	
	var loadStore = function() {
		includedStores[url] = LOADING;
		abego.loadTiddlyWikiStore(url,loadStoreCallback,null,progress);
	};
	
	if (delayMilliSeconds)
		invokeLater(loadStore, delayMilliSeconds);
	else
		loadStore();
};


// iterates over all tiddlers of "the store" and all tiddlers of included (and loaded) stores
//
abego.TiddlyWikiIncluder.forReallyEachTiddler = function(callback) {
	var caller = function() {
		store.forEachTiddler(callback);
	};
	
	getFunctionUsingForReallyEachTiddler(caller).call(store);
};


// function abego.TiddlyWikiIncluder.getFunctionUsingForReallyEachTiddler(func)
//
// Returns a function that behaves as func, but every call to store.forEachTiddler will actually 
// be a call to forReallyEachTiddler, i.e. iterate over the tiddlers the main store and of the 
// included TiddlyWikis
//
// @return the patched function
//
abego.TiddlyWikiIncluder.getFunctionUsingForReallyEachTiddler = getFunctionUsingForReallyEachTiddler;


// function abego.TiddlyWikiIncluder.useForReallyEachTiddler(object,property)
//
// Patches the function hold in the given property of the object in such a way that every call
// to store.forEachTiddler will actually be a call to forReallyEachTiddler, i.e. iterate over the
// tiddlers the main staire and of the included TiddlyWikis
//
// @param object
// @param property the name of the property of the object containing the function to be patched.
// @return the patched function
//
abego.TiddlyWikiIncluder.useForReallyEachTiddler = useForReallyEachTiddler;


// Add a listener function to the TiddlyWikiIncluder.
//
// @param listener function(urls)
//							url: [] of Strings, containing the urls of the TiddlyWiki just included
//									(see url@abego.TiddlyWikiIncluder.include)
//						called whenever one or more TiddlyWiki store are successfully included.
//
abego.TiddlyWikiIncluder.addListener = function(listener) {
	listeners.push(listener);
};

// -------------------------------------------------------------------------------
// TiddlyWikiIncluder initialization code

abego.TiddlyWikiIncluder.addListener(refreshTiddlyWiki);

//----------------------------------------------------------------------------
// Options Support

if (config.options.chkUseInclude === undefined) config.options.chkUseInclude = true;

config.shadowTiddlers.AdvancedOptions += "\n<<option chkUseInclude>> Include ~TiddlyWikis (IncludeList | IncludeState | [[help|http://tiddlywiki.abego-software.de/#%5B%5BIncludePlugin%20Documentation%5D%5D]])\n^^(Reload this ~TiddlyWiki to make changes become effective)^^";
config.shadowTiddlers.IncludeState = "<<includeState>>";

//================================================================================
// Default Progress Handling for abego.TiddlyWikiIncluder

var showAnimated = function(e, showing, duration) {
	if (!anim || !abego.ShowAnimation) {
		e.style.display = showing ? "block" : "none";
		return;
	}
	
	anim.startAnimating(new abego.ShowAnimation(e,showing,duration));
};

abego.TiddlyWikiIncluder.getDefaultProgressFunction = function() {

	setStylesheet(
		".includeProgressState{\n"+
		"background-color:#FFCC00;\n"+
		"position:absolute;\n"+
		"right:0.2em;\n"+
		"top:0.2em;\n"+
		"width:7em;\n"+
		"padding-left:0.2em;\n"+
		"padding-right:0.2em\n"+
		"}\n",
		"abegoInclude");

	var createStateElem = function() {
		var e = document.createElement("div");
		e.className = "includeProgressState";
		e.style.display = "none";
		document.body.appendChild(e);
		return e;
	};
	
	var stateElem = createStateElem();


	var showState = function(message) {
		removeChildren(stateElem);
		createTiddlyText(stateElem,message);
		showAnimated(stateElem,true,0);
	};

	var hideState = function() {
		// hide the state the next idle time 
		invokeLater(function() {
			showAnimated(stateElem,false,ANI_DURATION_HIDE_STATE);
		},100,ANIMATION_PRIORITY);
	};
	
	var myProgressFunction = function(message, sender, state, url, params) {
		
		if (state == "Done" || state == "Failed") {
			hideState();
			return;
		}
		
		if (sender == "abego.loadTiddlyWikiStore") {
			idleCount = 0;
			if (state == "Processing")
				showState("Including...");
		} else {
			showState(message);
		}
	};
	return myProgressFunction;
};

abego.TiddlyWikiIncluder.setProgressFunction(abego.TiddlyWikiIncluder.getDefaultProgressFunction());


//================================================================================
// The "include" macro
//
// Syntax: <<include {url}* [delay: {milliSeconds}] [hide: true] >>
//

config.macros.include = {};
config.macros.include.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
    params = paramString.parseParams("url",null,true,false,true); // allowEval, cascadeDefaults, names allowed
	var delay = parseInt(getParam(params,"delay","0"));
	var urls = params[0]["url"];
	var hide = getFlag(params, "hide", false);
	if (!hide)
		createTiddlyText(createTiddlyElement(place,"code"),wikifier.source.substring(wikifier.matchStart, wikifier.nextMatch));
	for (var i = 0; urls && i < urls.length; i++)
		abego.TiddlyWikiIncluder.include(urls[i],delay);
};


//================================================================================
// The "includeState" macro
//
// Syntax: <<includeState>>

config.macros.includeState = {};
config.macros.includeState.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
	var getFullState = function () {
		var s = "";
		var includes = abego.TiddlyWikiIncluder.getIncludes();
		if (!includes.length)
			return "{{noIncludes{\nNo includes or 'include' is disabled (see AdvancedOptions)\n}}}\n";
			
		s += "|!Address|!State|\n";
		for (var i = 0; i < includes.length; i++) {
			var inc = includes[i];
			s += "|{{{"+inc+"}}}|";
			var t = abego.TiddlyWikiIncluder.getState(inc);
			s += t ? "{{{"+t+"}}}" : "included";
			s += "|\n"
		}
		s += "|includeState|k\n";
		return s;
	};
	
	var updateState = function(){
		removeChildren(div);
		wikify(getFullState(),div);
		if (abego.TiddlyWikiIncluder.hasPendingIncludes())
			invokeLater(updateState,500,UPDATE_STATE_PRIORITY);
	};

	var div = createTiddlyElement(place,"div");
	
	invokeLater(updateState,0,UPDATE_STATE_PRIORITY);
};

//================================================================================
// Tiddler extension/modification

var orig_Tiddler_isReadOnly = Tiddler.prototype.isReadOnly;

// Includes tiddlers are readonly.
Tiddler.prototype.isReadOnly = function() {
	return orig_Tiddler_isReadOnly.apply(this,arguments) || this.isIncluded();
}

Tiddler.prototype.isIncluded = function() {
	return this.includeURL != undefined;
};

Tiddler.prototype.getIncludeURL = function() {
	return this.includeURL;
};


//================================================================================
// TiddlyWiki modifications

// In some TiddlyWiki functions the "forEachTiddler" should work on all tiddlers, also those from 
// included store. (E.g. TiddlyWiki.prototype.getTags)
//
// But not for all (e.g. TiddlyWiki.prototype.getTiddlers is used for saving, but only the "own" tiddlers should be saved)
//
// Therefore explicitly list the functions that should be "wrapped" to use the "forReallyEachTiddler".
//
var tiddlyWikiFunctionsUsingForReallyEachTiddler = {
	getMissingLinks: 1, getOrphans: 1,getTags:1, reverseLookup: 1, updateTiddlers: 1};
	
for (var n in tiddlyWikiFunctionsUsingForReallyEachTiddler)
	useForReallyEachTiddler(TiddlyWiki.prototype,n);


//================================================================================
// Make IntelliTagger "Include-aware"

var patchIntelliTagger = function() {
	if (abego.IntelliTagger)
		useForReallyEachTiddler(abego.IntelliTagger,"assistTagging");
};

//================================================================================
// Perform plugin startup tasks

attachToStore();
invokeLater(includeFromIncludeList,100);
invokeLater(patchIntelliTagger,100);

})();

//}}}
!About the ~IncludePlugin
Include other ~TiddlyWikis in your (main) TiddlyWiki, link to included tiddlers, view them in your (main) TiddlyWiki, without opening another TiddlyWiki. Even „search“ looks for included tiddlers. 

A great way to share tiddlers, to speed up "save changes" and to keep your ~TiddlyWikis small.
!Smaller ~TiddlyWikis
Other than „imported“ tiddlers, included tiddlers are not copied into your main ~TiddlyWiki. This keeps your individual ~TiddlyWikis small. 

Since your TiddlyWikis will become smaller (if you reorganize your TiddlyWikis using the IncludePlugin) also "save changes" becomes faster. You may even consider switching on "AutoSave" or "SaveBackups" again.

See also: [[Including even smaller TiddlyWiki Files]]

!Sharing ~TiddlyWikis
You may include one ~TiddlyWiki in several other ~TiddlyWikis. Changes you make to this shared ~TiddlyWiki are automatically reflected the next time you open the other ~TiddlyWikis, without any extra „import“ step or so.

''Examples''
* you may want to have a single „~TiddlyWikiHelp“ ~TiddlyWiki that you include in all your ~TiddlyWikis. So you can quickly find help information without looking into other files, and without blowing up your ~TiddlyWikis.
* You "archive" your old journal tiddlers into an extra TiddlyWiki (e.g. one per month) and just include the archived journals in you "current month diary/blog". This way you still have access to the old information (e.g. to reference historic information) but you avoid your diary/blog will get to large.
* ...

See also:
* [[How to use the IncludePlugin]]
* [[How Tiddlers are found]]
* [[IncludePlugin Options]]
* [[The "include" Macro]]
* [[The "includeState" Macro]]
* [[Programming with the IncludePlugin]]
* [[Troubleshooting the IncludePlugin]]
Using the AdvancedOptions page you have an easy way to configure the IncludePlugin options. 

You will find a section like this:
{{optionsBlock{
<<option chkUseInclude>> Include ~TiddlyWikis (IncludeList | IncludeState | [[help|http://tiddlywiki.abego-software.de/#%5B%5BIncludePlugin%20Documentation%5D%5D]])
^^(Reload this ~TiddlyWiki to make changes become effective)^^
}}}
* By default the IncludePlugin is enabled. If you uncheck the checkbox external TiddlyWikis are not included.
* The IncludeList is the preferred place for your {{{<<include ...>>}}} lines.
* The IncludeState page gives you can an overview what TiddlyWikis are included etc.
* The help directs you to the online documentation of the Include Plugin.
* [[How Tiddlers are found]]
* [[How to use the IncludePlugin]]
* [[IncludePlugin Documentation]]
* [[IncludePlugin Options]]
* [[The "include" Macro]]
* [[The "includeState" Macro]]
* IncludePlugin
<html>
<iframe src="http://ia300033.us.archive.org/3/items/tiddlywikitutorial/tiddlywiki.swf" width=950 height=720">
</iframe>
</html>
{{{
var myArray = [];
myArray[0] = 'January';
myArray[1] = 'February';
myArray[2] = 'March';
document.write('0>'+myArray[0]+'<BR>');                  // Will output: 0>January
document.write('1>'+myArray[1]+'<BR>');                  // Will output: 1>February
document.write('2>'+myArray[2]+'<BR>');                  // Will output: 2>March
}}}
<script>
var myArray = [];
myArray[0] = 'January';
myArray[1] = 'February';
myArray[2] = 'March';
document.write('0>'+myArray[0]+'<BR>');                  // Will output: 0>January
document.write('1>'+myArray[1]+'<BR>');                  // Will output: 1>February
document.write('2>'+myArray[2]+'<BR>');                  // Will output: 2>March
</script>
<script show>
 return "link to current user: [["+config.options.txtUserName+"]]";
</script>
<script label="click here" title="clicking this link will show an 'alert' box" show>
 if (!window.story) window.story=window;
 alert("Hello World!\nlinktext='"+place.firstChild.data+"'\ntiddler='"+story.findContainingTiddler(place).id.substr(7)+"'");
</script>
/***
|Name|InlineJavascriptPlugin|
|Source|http://www.TiddlyTools.com/#InlineJavascriptPlugin|
|Version|1.6.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <<br>>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|Insert Javascript executable code directly into your tiddler content.|

''Call directly into TW core utility routines, define new functions, calculate values, add dynamically-generated TiddlyWiki-formatted output'' into tiddler content, or perform any other programmatic actions each time the tiddler is rendered.
!!!!!Usage
<<<
When installed, this plugin adds new wiki syntax for surrounding tiddler content with {{{<script>}}} and {{{</script>}}} markers, so that it can be treated as embedded javascript and executed each time the tiddler is rendered.

''Deferred execution from an 'onClick' link''
By including a {{{label="..."}}} parameter in the initial {{{<script>}}} marker, the plugin will create a link to an 'onclick' script that will only be executed when that specific link is clicked, rather than running the script each time the tiddler is rendered. You may also include a {{{title="..."}}} parameter to specify the 'tooltip' text that will appear whenever the mouse is moved over the onClick link text

''External script source files:''
You can also load javascript from an external source URL, by including a src="..." parameter in the initial {{{<script>}}} marker (e.g., {{{<script src="demo.js"></script>}}}). This is particularly useful when incorporating third-party javascript libraries for use in custom extensions and plugins. The 'foreign' javascript code remains isolated in a separate file that can be easily replaced whenever an updated library file becomes available.

''Display script source in tiddler output''
By including the keyword parameter "show", in the initial {{{<script>}}} marker, the plugin will include the script source code in the output that it displays in the tiddler.

''Defining javascript functions and libraries:''
Although the external javascript file is loaded while the tiddler content is being rendered, any functions it defines will not be available for use until //after// the rendering has been completed. Thus, you cannot load a library and //immediately// use it's functions within the same tiddler. However, once that tiddler has been loaded, the library functions can be freely used in any tiddler (even the one in which it was initially loaded).

To ensure that your javascript functions are always available when needed, you should load the libraries from a tiddler that will be rendered as soon as your TiddlyWiki document is opened. For example, you could put your {{{<script src="..."></script>}}} syntax into a tiddler called LoadScripts, and then add {{{<<tiddler LoadScripts>>}}} in your MainMenu tiddler.

Since the MainMenu is always rendered immediately upon opening your document, the library will always be loaded before any other tiddlers that rely upon the functions it defines. Loading an external javascript library does not produce any direct output in the tiddler, so these definitions should have no impact on the appearance of your MainMenu.

''Creating dynamic tiddler content''
An important difference between this implementation of embedded scripting and conventional embedded javascript techniques for web pages is the method used to produce output that is dynamically inserted into the document:
* In a typical web document, you use the document.write() function to output text sequences (often containing HTML tags) that are then rendered when the entire document is first loaded into the browser window.
* However, in a ~TiddlyWiki document, tiddlers (and other DOM elements) are created, deleted, and rendered "on-the-fly", so writing directly to the global 'document' object does not produce the results you want (i.e., replacing the embedded script within the tiddler content), and completely replaces the entire ~TiddlyWiki document in your browser window.
* To allow these scripts to work unmodified, the plugin automatically converts all occurences of document.write() so that the output is inserted into the tiddler content instead of replacing the entire ~TiddlyWiki document.

If your script does not use document.write() to create dynamically embedded content within a tiddler, your javascript can, as an alternative, explicitly return a text value that the plugin can then pass through the wikify() rendering engine to insert into the tiddler display. For example, using {{{return "thistext"}}} will produce the same output as {{{document.write("thistext")}}}.

//Note: your script code is automatically 'wrapped' inside a function, {{{_out()}}}, so that any return value you provide can be correctly handled by the plugin and inserted into the tiddler. To avoid unpredictable results (and possibly fatal execution errors), this function should never be redefined or called from ''within'' your script code.//

''Accessing the ~TiddlyWiki DOM''
The plugin provides one pre-defined variable, 'place', that is passed in to your javascript code so that it can have direct access to the containing DOM element into which the tiddler output is currently being rendered.

Access to this DOM element allows you to create scripts that can:
* vary their actions based upon the specific location in which they are embedded
* access 'tiddler-relative' information (use findContainingTiddler(place))
* perform direct DOM manipulations (when returning wikified text is not enough)
<<<
!!!!!Examples
<<<
an "alert" message box:
><script show>
 alert('InlineJavascriptPlugin: this is a demonstration message');
</script>
dynamic output:
><script show>
 return (new Date()).toString();
</script>
wikified dynamic output:
><script show>
 return "link to current user: [["+config.options.txtUserName+"]]";
</script>
dynamic output using 'place' to get size information for current tiddler:
><script show>
 if (!window.story) window.story=window;
 var title=story.findContainingTiddler(place).id.substr(7);
 return title+" is using "+store.getTiddlerText(title).length+" bytes";
</script>
creating an 'onclick' button/link that runs a script:
><script label="click here" title="clicking this link will show an 'alert' box" show>
 if (!window.story) window.story=window;
 alert("Hello World!\nlinktext='"+place.firstChild.data+"'\ntiddler='"+story.findContainingTiddler(place).id.substr(7)+"'");
</script>
loading a script from a source url:
>http://www.TiddlyTools.com/demo.js contains:
>>{{{function demo() { alert('this output is from demo(), defined in demo.js') } }}}
>>{{{alert('InlineJavascriptPlugin: demo.js has been loaded'); }}}
><script src="demo.js" show>
 return "loading demo.js..."
</script>
><script label="click to execute demo() function" show>
 demo()
</script>
<<<
!!!!!Installation
<<<
import (or copy/paste) the following tiddlers into your document:
''InlineJavascriptPlugin'' (tagged with <<tag systemConfig>>)
<<<
!!!!!Revision History
<<<
''2007.02.19 [1.6.0]'' added support for title="..." to specify mouseover tooltip when using an onclick (label="...") script
''2006.10.16 [1.5.2]'' add newline before closing '}' in 'function out_' wrapper. Fixes error caused when last line of script is a comment.
''2006.06.01 [1.5.1]'' when calling wikify() on script return value, pass hightlightRegExp and tiddler params so macros that rely on these values can render properly
''2006.04.19 [1.5.0]'' added 'show' parameter to force display of javascript source code in tiddler output
''2006.01.05 [1.4.0]'' added support 'onclick' scripts. When label="..." param is present, a button/link is created using the indicated label text, and the script is only executed when the button/link is clicked. 'place' value is set to match the clicked button/link element.
''2005.12.13 [1.3.1]'' when catching eval error in IE, e.description contains the error text, instead of e.toString(). Fixed error reporting so IE shows the correct response text. Based on a suggestion by UdoBorkowski
''2005.11.09 [1.3.0]'' for 'inline' scripts (i.e., not scripts loaded with src="..."), automatically replace calls to 'document.write()' with 'place.innerHTML+=' so script output is directed into tiddler content. Based on a suggestion by BradleyMeck
''2005.11.08 [1.2.0]'' handle loading of javascript from an external URL via src="..." syntax
''2005.11.08 [1.1.0]'' pass 'place' param into scripts to provide direct DOM access 
''2005.11.08 [1.0.0]'' initial release
<<<
!!!!!Credits
<<<
This feature was developed by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]]
<<<
!!!!!Code
***/
//{{{
version.extensions.inlineJavascript= {major: 1, minor: 6, revision: 0, date: new Date(2007,2,19)};

config.formatters.push( {
 name: "inlineJavascript",
 match: "\\<script",
 lookahead: "\\<script(?: src=\\\"((?:.|\\n)*?)\\\")?(?: label=\\\"((?:.|\\n)*?)\\\")?(?: title=\\\"((?:.|\\n)*?)\\\")?( show)?\\>((?:.|\\n)*?)\\</script\\>",

 handler: function(w) {
 var lookaheadRegExp = new RegExp(this.lookahead,"mg");
 lookaheadRegExp.lastIndex = w.matchStart;
 var lookaheadMatch = lookaheadRegExp.exec(w.source)
 if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
 if (lookaheadMatch[1]) { // load a script library
 // make script tag, set src, add to body to execute, then remove for cleanup
 var script = document.createElement("script"); script.src = lookaheadMatch[1];
 document.body.appendChild(script); document.body.removeChild(script);
 }
 if (lookaheadMatch[5]) { // there is script code
 if (lookaheadMatch[4]) // show inline script code in tiddler output
 wikify("{{{\n"+lookaheadMatch[0]+"\n}}}\n",w.output);
 if (lookaheadMatch[2]) { // create a link to an 'onclick' script
 // add a link, define click handler, save code in link (pass 'place'), set link attributes
 var link=createTiddlyElement(w.output,"a",null,"tiddlyLinkExisting",lookaheadMatch[2]);
 link.onclick=function(){try{return(eval(this.code))}catch(e){alert(e.description?e.description:e.toString())}}
 link.code="function _out(place){"+lookaheadMatch[5]+"\n};_out(this);"
 link.setAttribute("title",lookaheadMatch[3]?lookaheadMatch[3]:"");
 link.setAttribute("href","javascript:;");
 link.style.cursor="pointer";
 }
 else { // run inline script code
 var code="function _out(place){"+lookaheadMatch[5]+"\n};_out(w.output);"
 code=code.replace(/document.write\(/gi,'place.innerHTML+=(');
 try { var out = eval(code); } catch(e) { out = e.description?e.description:e.toString(); }
 if (out && out.length) wikify(out,w.output,w.highlightRegExp,w.tiddler);
 }
 }
 w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
 }
 }
} )
//}}}
|!Sensor|!Qty/Well|!Strapped to|
|<html><input type="text" name="surv1Technique" size="30"></html>| <html><input type="text" name="surv1QTyWell" size="10"></html> |<html><input type="text" name="surv1StrappedTo" size="10"></html>|
/***
|''Name:''|IntelliTaggerPlugin|
|''Version:''|1.0.2 (2007-07-25)|
|''Type:''|plugin|
|''Source:''|http://tiddlywiki.abego-software.de/#IntelliTaggerPlugin|
|''Author:''|Udo Borkowski (ub [at] abego-software [dot] de)|
|''Documentation:''|[[IntelliTaggerPlugin Documentation]]|
|''~SourceCode:''|[[IntelliTaggerPlugin SourceCode]]|
|''Licence:''|[[BSD open source license (abego Software)]]|
|''~CoreVersion:''|2.0.8|
|''Browser:''|Firefox 1.5.0.2 or better|
***/
/***
!Version History
* 1.0.2 (2007-07-25): 
** Feature: "Return" key may be used to accept first tag suggestion (beside "Alt-1")
** Bugfix: Keyboard shortcuts (Alt+3 etc.) shifted
* 1.0.1 (2007-05-18): Improvement: Speedup when using TiddlyWikis with many tags
* 1.0.0 (2006-04-26): Initial release

***/
// /%
if(!version.extensions.IntelliTaggerPlugin){if(!window.abego){window.abego={};}if(!abego.internal){abego.internal={};}abego.alertAndThrow=function(s){alert(s);throw s;};if(version.major<2){abego.alertAndThrow("Use TiddlyWiki 2.0.8 or better to run the IntelliTagger Plugin.");}version.extensions.IntelliTaggerPlugin={major:1,minor:0,revision:2,date:new Date(2007,6,25),type:"plugin",source:"http://tiddlywiki.abego-software.de/#IntelliTaggerPlugin",documentation:"[[IntelliTaggerPlugin Documentation]]",sourcecode:"[[IntelliTaggerPlugin SourceCode]]",author:"Udo Borkowski (ub [at] abego-software [dot] de)",licence:"[[BSD open source license (abego Software)]]",tiddlywiki:"Version 2.0.8 or better",browser:"Firefox 1.5.0.2 or better"};abego.createEllipsis=function(_2){var e=createTiddlyElement(_2,"span");e.innerHTML="&hellip;";};abego.isPopupOpen=function(_4){return _4&&_4.parentNode==document.body;};abego.openAsPopup=function(_5){if(_5.parentNode!=document.body){document.body.appendChild(_5);}};abego.closePopup=function(_6){if(abego.isPopupOpen(_6)){document.body.removeChild(_6);}};abego.getWindowRect=function(){return {left:findScrollX(),top:findScrollY(),height:findWindowHeight(),width:findWindowWidth()};};abego.moveElement=function(_7,_8,_9){_7.style.left=_8+"px";_7.style.top=_9+"px";};abego.centerOnWindow=function(_a){if(_a.style.position!="absolute"){throw "abego.centerOnWindow: element must have absolute position";}var _b=abego.getWindowRect();abego.moveElement(_a,_b.left+(_b.width-_a.offsetWidth)/2,_b.top+(_b.height-_a.offsetHeight)/2);};abego.isDescendantOrSelf=function(_c,e){while(e){if(_c==e){return true;}e=e.parentNode;}return false;};abego.toSet=function(_e){var _f={};for(var i=0;i<_e.length;i++){_f[_e[i]]=true;}return _f;};abego.filterStrings=function(_11,_12,_13){var _14=[];for(var i=0;i<_11.length&&(_13===undefined||_14.length<_13);i++){var s=_11[i];if(s.match(_12)){_14.push(s);}}return _14;};abego.arraysAreEqual=function(a,b){if(!a){return !b;}if(!b){return false;}var n=a.length;if(n!=b.length){return false;}for(var i=0;i<n;i++){if(a[i]!=b[i]){return false;}}return true;};abego.moveBelowAndClip=function(_1b,_1c){if(!_1c){return;}var _1d=findPosX(_1c);var _1e=findPosY(_1c);var _1f=_1c.offsetHeight;var _20=_1d;var _21=_1e+_1f;var _22=findWindowWidth();if(_22<_1b.offsetWidth){_1b.style.width=(_22-100)+"px";}var _23=_1b.offsetWidth;if(_20+_23>_22){_20=_22-_23-30;}if(_20<0){_20=0;}_1b.style.left=_20+"px";_1b.style.top=_21+"px";_1b.style.display="block";};abego.compareStrings=function(a,b){return (a==b)?0:(a<b)?-1:1;};abego.sortIgnoreCase=function(arr){var _27=[];var n=arr.length;for(var i=0;i<n;i++){var s=arr[i];_27.push([s.toString().toLowerCase(),s]);}_27.sort(function(a,b){return (a[0]==b[0])?0:(a[0]<b[0])?-1:1;});for(i=0;i<n;i++){arr[i]=_27[i][1];}};abego.getTiddlerField=function(_2d,_2e,_2f){var _30=document.getElementById(_2d.idPrefix+_2e);var e=null;if(_30!=null){var _32=_30.getElementsByTagName("*");for(var t=0;t<_32.length;t++){var c=_32[t];if(c.tagName.toLowerCase()=="input"||c.tagName.toLowerCase()=="textarea"){if(!e){e=c;}if(c.getAttribute("edit")==_2f){e=c;}}}}return e;};abego.setRange=function(_35,_36,end){if(_35.setSelectionRange){_35.setSelectionRange(_36,end);var max=0+_35.scrollHeight;var len=_35.textLength;var top=max*_36/len,bot=max*end/len;_35.scrollTop=Math.min(top,(bot+top-_35.clientHeight)/2);}else{if(_35.createTextRange!=undefined){var _3b=_35.createTextRange();_3b.collapse();_3b.moveEnd("character",end);_3b.moveStart("character",_36);_3b.select();}else{_35.select();}}};abego.internal.TagManager=function(){var _3c=null;var _3d=function(){if(_3c){return;}_3c={};store.forEachTiddler(function(_3e,_3f){for(var i=0;i<_3f.tags.length;i++){var tag=_3f.tags[i];var _42=_3c[tag];if(!_42){_42=_3c[tag]={count:0,tiddlers:{}};}_42.tiddlers[_3f.title]=true;_42.count+=1;}});};var _43=TiddlyWiki.prototype.saveTiddler;TiddlyWiki.prototype.saveTiddler=function(_44,_45,_46,_47,_48,_49){var _4a=this.fetchTiddler(_44);var _4b=_4a?_4a.tags:[];var _4c=(typeof _49=="string")?_49.readBracketedList():_49;_43.apply(this,arguments);if(!abego.arraysAreEqual(_4b,_4c)){abego.internal.getTagManager().reset();}};var _4d=TiddlyWiki.prototype.removeTiddler;TiddlyWiki.prototype.removeTiddler=function(_4e){var _4f=this.fetchTiddler(_4e);var _50=_4f&&_4f.tags.length>0;_4d.apply(this,arguments);if(_50){abego.internal.getTagManager().reset();}};this.reset=function(){_3c=null;};this.getTiddlersWithTag=function(tag){_3d();var _52=_3c[tag];return _52?_52.tiddlers:null;};this.getAllTags=function(_53){_3d();var _54=[];for(var i in _3c){_54.push(i);}for(i=0;_53&&i<_53.length;i++){_54.pushUnique(_53[i],true);}abego.sortIgnoreCase(_54);return _54;};this.getTagInfos=function(){_3d();var _56=[];for(var _57 in _3c){_56.push([_57,_3c[_57]]);}return _56;};var _58=function(a,b){var a1=a[1];var b1=b[1];var d=b[1].count-a[1].count;return d!=0?d:abego.compareStrings(a[0].toLowerCase(),b[0].toLowerCase());};this.getSortedTagInfos=function(){_3d();var _5e=this.getTagInfos();_5e.sort(_58);return _5e;};this.getPartnerRankedTags=function(_5f){var _60={};for(var i=0;i<_5f.length;i++){var _62=this.getTiddlersWithTag(_5f[i]);for(var _63 in _62){var _64=store.getTiddler(_63);if(!(_64 instanceof Tiddler)){continue;}for(var j=0;j<_64.tags.length;j++){var tag=_64.tags[j];var c=_60[tag];_60[tag]=c?c+1:1;}}}var _68=abego.toSet(_5f);var _69=[];for(var n in _60){if(!_68[n]){_69.push(n);}}_69.sort(function(a,b){var d=_60[b]-_60[a];return d!=0?d:abego.compareStrings(a.toLowerCase(),b.toLowerCase());});return _69;};};abego.internal.getTagManager=function(){if(!abego.internal.gTagManager){abego.internal.gTagManager=new abego.internal.TagManager();}return abego.internal.gTagManager;};(function(){var _6e=2;var _6f=1;var _70=30;var _71;var _72;var _73;var _74;var _75;var _76;if(!abego.IntelliTagger){abego.IntelliTagger={};}var _77=function(){return _72;};var _78=function(tag){return _75[tag];};var _7a=function(s){var i=s.lastIndexOf(" ");return (i>=0)?s.substr(0,i):"";};var _7d=function(_7e){var s=_7e.value;var len=s.length;return (len>0&&s[len-1]!=" ");};var _81=function(_82){var s=_82.value;var len=s.length;if(len>0&&s[len-1]!=" "){_82.value+=" ";}};var _85=function(tag,_87,_88){if(_7d(_87)){_87.value=_7a(_87.value);}story.setTiddlerTag(_88.title,tag,0);_81(_87);abego.IntelliTagger.assistTagging(_87,_88);};var _89=function(n){if(_76&&_76.length>n){return _76[n];}return (_74&&_74.length>n)?_74[n]:null;};var _8b=function(n,_8d,_8e){var _8f=_89(n);if(_8f){_85(_8f,_8d,_8e);}};var _90=function(_91){var pos=_91.value.lastIndexOf(" ");var _93=(pos>=0)?_91.value.substr(++pos,_91.value.length):_91.value;return new RegExp(_93.escapeRegExp(),"i");};var _94=function(_95,_96){var _97=0;for(var i=0;i<_95.length;i++){if(_96[_95[i]]){_97++;}}return _97;};var _99=function(_9a,_9b,_9c){var _9d=1;var c=_9a[_9b];for(var i=_9b+1;i<_9a.length;i++){if(_9a[i][1].count==c){if(_9a[i][0].match(_9c)){_9d++;}}else{break;}}return _9d;};var _a0=function(_a1,_a2){var _a3=abego.internal.getTagManager().getSortedTagInfos();var _a4=[];var _a5=0;for(var i=0;i<_a3.length;i++){var c=_a3[i][1].count;if(c!=_a5){if(_a2&&(_a4.length+_99(_a3,i,_a1)>_a2)){break;}_a5=c;}if(c==1){break;}var s=_a3[i][0];if(s.match(_a1)){_a4.push(s);}}return _a4;};var _a9=function(_aa,_ab){return abego.filterStrings(abego.internal.getTagManager().getAllTags(_ab),_aa);};var _ac=function(){if(!_71){return;}var _ad=store.getTiddlerText("IntelliTaggerMainTemplate");if(!_ad){_ad="<b>Tiddler IntelliTaggerMainTemplate not found</b>";}_71.innerHTML=_ad;applyHtmlMacros(_71,null);refreshElements(_71,null);};var _ae=function(e){if(!e){var e=window.event;}var tag=this.getAttribute("tag");if(_73){_73.call(this,tag,e);}return false;};var _b2=function(_b3){createTiddlyElement(_b3,"span",null,"tagSeparator"," | ");};var _b4=function(_b5,_b6,_b7,_b8,_b9){if(!_b6){return;}var _ba=_b8?abego.toSet(_b8):{};var n=_b6.length;var c=0;for(var i=0;i<n;i++){var tag=_b6[i];if(_ba[tag]){continue;}if(c>0){_b2(_b5);}if(_b9&&c>=_b9){abego.createEllipsis(_b5);break;}c++;var _bf="";var _c0=_b5;if(_b7<10){_c0=createTiddlyElement(_b5,"span",null,"numberedSuggestion");_b7++;var key=_b7<10?""+(_b7):"0";createTiddlyElement(_c0,"span",null,"suggestionNumber",key+") ");var _c2=_b7==1?"Return or ":"";_bf=" (Shortcut: %1Alt-%0)".format([key,_c2]);}var _c3=config.views.wikified.tag.tooltip.format([tag]);var _c4=(_78(tag)?"Remove tag '%0'%1":"Add tag '%0'%1").format([tag,_bf]);var _c5="%0; Shift-Click: %1".format([_c4,_c3]);var btn=createTiddlyButton(_c0,tag,_c5,_ae,_78(tag)?"currentTag":null);btn.setAttribute("tag",tag);}};var _c7=function(){if(_71){window.scrollTo(0,ensureVisible(_71));}if(_77()){window.scrollTo(0,ensureVisible(_77()));}};var _c8=function(e){if(!e){var e=window.event;}if(!_71){return;}var _cb=resolveTarget(e);if(_cb==_77()){return;}if(abego.isDescendantOrSelf(_71,_cb)){return;}abego.IntelliTagger.close();};addEvent(document,"click",_c8);var _cc=Story.prototype.gatherSaveFields;Story.prototype.gatherSaveFields=function(e,_ce){_cc.apply(this,arguments);var _cf=_ce.tags;if(_cf){_ce.tags=_cf.trim();}};var _d0=function(_d1){story.focusTiddler(_d1,"tags");var _d2=abego.getTiddlerField(story,_d1,"tags");if(_d2){var len=_d2.value.length;abego.setRange(_d2,len,len);window.scrollTo(0,ensureVisible(_d2));}};var _d4=config.macros.edit.handler;config.macros.edit.handler=function(_d5,_d6,_d7,_d8,_d9,_da){_d4.apply(this,arguments);var _db=_d7[0];if((_da instanceof Tiddler)&&_db=="tags"){var _dc=_d5.lastChild;_dc.onfocus=function(e){abego.IntelliTagger.assistTagging(_dc,_da);setTimeout(function(){_d0(_da.title);},100);};_dc.onkeyup=function(e){if(!e){var e=window.event;}if(e.altKey&&!e.ctrlKey&&!e.metaKey&&(e.keyCode>=48&&e.keyCode<=57)){_8b(e.keyCode==48?9:e.keyCode-49,_dc,_da);}else{if(e.ctrlKey&&e.keyCode==32){_8b(0,_dc,_da);}}if(!e.ctrlKey&&(e.keyCode==13||e.keyCode==10)){_8b(0,_dc,_da);}setTimeout(function(){abego.IntelliTagger.assistTagging(_dc,_da);},100);return false;};_81(_dc);}};var _e0=function(e){if(!e){var e=window.event;}var _e3=resolveTarget(e);var _e4=_e3.getAttribute("tiddler");if(_e4){story.displayTiddler(_e3,_e4,"IntelliTaggerEditTagsTemplate",false);_d0(_e4);}return false;};var _e5=config.macros.tags.handler;config.macros.tags.handler=function(_e6,_e7,_e8,_e9,_ea,_eb){_e5.apply(this,arguments);abego.IntelliTagger.createEditTagsButton(_eb,createTiddlyElement(_e6.lastChild,"li"));};var _ec=function(){if(_71&&_72&&!abego.isDescendantOrSelf(document,_72)){abego.IntelliTagger.close();}};setInterval(_ec,100);abego.IntelliTagger.displayTagSuggestions=function(_ed,_ee,_ef,_f0,_f1){_74=_ed;_75=abego.toSet(_ee);_76=_ef;_72=_f0;_73=_f1;if(!_71){_71=createTiddlyElement(document.body,"div",null,"intelliTaggerSuggestions");_71.style.position="absolute";}_ac();abego.openAsPopup(_71);if(_77()){var w=_77().offsetWidth;if(_71.offsetWidth<w){_71.style.width=(w-2*(_6e+_6f))+"px";}abego.moveBelowAndClip(_71,_77());}else{abego.centerOnWindow(_71);}_c7();};abego.IntelliTagger.assistTagging=function(_f3,_f4){var _f5=_90(_f3);var s=_f3.value;if(_7d(_f3)){s=_7a(s);}var _f7=s.readBracketedList();var _f8=_f7.length>0?abego.filterStrings(abego.internal.getTagManager().getPartnerRankedTags(_f7),_f5,_70):_a0(_f5,_70);abego.IntelliTagger.displayTagSuggestions(_a9(_f5,_f7),_f7,_f8,_f3,function(tag,e){if(e.shiftKey){onClickTag.call(this,e);}else{_85(tag,_f3,_f4);}});};abego.IntelliTagger.close=function(){abego.closePopup(_71);_71=null;return false;};abego.IntelliTagger.createEditTagsButton=function(_fb,_fc,_fd,_fe,_ff,id,_101){if(!_fd){_fd="[edit]";}if(!_fe){_fe="Edit the tags";}if(!_ff){_ff="editTags";}var _102=createTiddlyButton(_fc,_fd,_fe,_e0,_ff,id,_101);_102.setAttribute("tiddler",(_fb instanceof Tiddler)?_fb.title:String(_fb));return _102;};abego.IntelliTagger.getSuggestionTagsMaxCount=function(){return 100;};config.macros.intelliTagger={label:"intelliTagger",handler:function(_103,_104,_105,_106,_107,_108){var _109=_107.parseParams("list",null,true);var _10a=_109[0]["action"];for(var i=0;_10a&&i<_10a.length;i++){var _10c=_10a[i];var _10d=config.macros.intelliTagger.subhandlers[_10c];if(!_10d){abego.alertAndThrow("Unsupported action '%0'".format([_10c]));}_10d(_103,_104,_105,_106,_107,_108);}},subhandlers:{showTags:function(_10e,_10f,_110,_111,_112,_113){_b4(_10e,_74,_76?_76.length:0,_76,abego.IntelliTagger.getSuggestionTagsMaxCount());},showFavorites:function(_114,_115,_116,_117,_118,_119){_b4(_114,_76,0);},closeButton:function(_11a,_11b,_11c,_11d,_11e,_11f){var _120=createTiddlyButton(_11a,"close","Close the suggestions",abego.IntelliTagger.close);},version:function(_121){var t="IntelliTagger %0.%1.%2".format([version.extensions.IntelliTaggerPlugin.major,version.extensions.IntelliTaggerPlugin.minor,version.extensions.IntelliTaggerPlugin.revision]);var e=createTiddlyElement(_121,"a");e.setAttribute("href","http://tiddlywiki.abego-software.de/#IntelliTaggerPlugin");e.innerHTML="<font color=\"black\" face=\"Arial, Helvetica, sans-serif\">"+t+"<font>";},copyright:function(_124){var e=createTiddlyElement(_124,"a");e.setAttribute("href","http://tiddlywiki.abego-software.de");e.innerHTML="<font color=\"black\" face=\"Arial, Helvetica, sans-serif\">&copy; 2006-2007 <b><font color=\"red\">abego</font></b> Software<font>";}}};})();config.shadowTiddlers["IntelliTaggerStyleSheet"]="/***\n"+"!~IntelliTagger Stylesheet\n"+"***/\n"+"/*{{{*/\n"+".intelliTaggerSuggestions {\n"+"\tposition: absolute;\n"+"\twidth: 600px;\n"+"\n"+"\tpadding: 2px;\n"+"\tlist-style: none;\n"+"\tmargin: 0;\n"+"\n"+"\tbackground: #eeeeee;\n"+"\tborder: 1px solid DarkGray;\n"+"}\n"+"\n"+".intelliTaggerSuggestions .currentTag {\n"+"\tfont-weight: bold;\n"+"}\n"+"\n"+".intelliTaggerSuggestions .suggestionNumber {\n"+"\tcolor: #808080;\n"+"}\n"+"\n"+".intelliTaggerSuggestions .numberedSuggestion{\n"+"\twhite-space: nowrap;\n"+"}\n"+"\n"+".intelliTaggerSuggestions .intelliTaggerFooter {\n"+"\tmargin-top: 4px;\n"+"\tborder-top-width: thin;\n"+"\tborder-top-style: solid;\n"+"\tborder-top-color: #999999;\n"+"}\n"+".intelliTaggerSuggestions .favorites {\n"+"\tborder-bottom-width: thin;\n"+"\tborder-bottom-style: solid;\n"+"\tborder-bottom-color: #999999;\n"+"\tpadding-bottom: 2px;\n"+"}\n"+"\n"+".intelliTaggerSuggestions .normalTags {\n"+"\tpadding-top: 2px;\n"+"}\n"+"\n"+".intelliTaggerSuggestions .intelliTaggerFooter .button {\n"+"\tfont-size: 10px;\n"+"\n"+"\tpadding-left: 0.3em;\n"+"\tpadding-right: 0.3em;\n"+"}\n"+"\n"+"/*}}}*/\n";config.shadowTiddlers["IntelliTaggerMainTemplate"]="<!--\n"+"{{{\n"+"-->\n"+"<div class=\"favorites\" macro=\"intelliTagger action: showFavorites\"></div>\n"+"<div class=\"normalTags\" macro=\"intelliTagger action: showTags\"></div>\n"+"<!-- The Footer (with the Navigation) ============================================ -->\n"+"<table class=\"intelliTaggerFooter\" border=\"0\" width=\"100%\" cellspacing=\"0\" cellpadding=\"0\"><tbody>\n"+" <tr>\n"+"\t<td align=\"left\">\n"+"\t\t<span macro=\"intelliTagger action: closeButton\"></span>\n"+"\t</td>\n"+"\t<td align=\"right\">\n"+"\t\t<span macro=\"intelliTagger action: version\"></span>, <span macro=\"intelliTagger action: copyright \"></span>\n"+"\t</td>\n"+" </tr>\n"+"</tbody></table>\n"+"<!--\n"+"}}}\n"+"-->\n";config.shadowTiddlers["IntelliTaggerEditTagsTemplate"]="<!--\n"+"{{{\n"+"-->\n"+"<div class='toolbar' macro='toolbar +saveTiddler -cancelTiddler'></div>\n"+"<div class='title' macro='view title'></div>\n"+"<div class='tagged' macro='tags'></div>\n"+"<div class='viewer' macro='view text wikified'></div>\n"+"<div class='toolbar' macro='toolbar +saveTiddler -cancelTiddler'></div>\n"+"<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser'></span></div>\n"+"<!--\n"+"}}}\n"+"-->\n";config.shadowTiddlers["BSD open source license (abego Software)"]="See [[Licence|http://tiddlywiki.abego-software.de/#%5B%5BBSD%20open%20source%20license%5D%5D]].";config.shadowTiddlers["IntelliTaggerPlugin Documentation"]="[[Documentation on abego Software website|http://tiddlywiki.abego-software.de/doc/IntelliTagger.pdf]].";config.shadowTiddlers["IntelliTaggerPlugin SourceCode"]="[[Plugin source code on abego Software website|http://tiddlywiki.abego-software.de/archive/IntelliTaggerPlugin/Plugin-IntelliTagger-src.1.0.2.js]]\n";(function(){var _126=restart;restart=function(){setStylesheet(store.getTiddlerText("IntelliTaggerStyleSheet"),"IntelliTaggerStyleSheet");_126.apply(this,arguments);};})();}
// %/
{{{
<script>
var people =
  { "programmers": [
    { "firstName": "Brett", "lastName":"McLaughlin", "email": "brett@newInstance.com" },
    { "firstName": "Jason", "lastName":"Hunter", "email": "jason@servlets.com" },
    { "firstName": "Elliotte", "lastName":"Harold", "email": "elharo@macfaq.com" }
   ],
  "authors": [
    { "firstName": "Isaac", "lastName": "Asimov", "genre": "science fiction" },
    { "firstName": "Tad", "lastName": "Williams", "genre": "fantasy" },
    { "firstName": "Frank", "lastName": "Peretti", "genre": "christian fiction" }
   ],
  "musicians": [
    { "firstName": "Eric", "lastName": "Clapton", "instrument": "guitar" },
    { "firstName": "Sergei", "lastName": "Rachmaninoff", "instrument": "piano" }
   ]
  }
// Accessing the data:
document.write(people.programmers[0].lastName + '<br>');
// Value is "fantasy
document.write(people.authors[1].genre + '<br>');
// Value is "Elliotte"
document.write(people.programmers[2].firstName + '<br>');

// modifying data
document.write(people.musicians[1].lastName + '<br>');
people.musicians[1].lastName = "Wagner";
people.musicians[1].firstName = "Richard";

document.write(people.musicians[1].firstName + ' ' + people.musicians[1].lastName + '<br>');

// Undefined. This refers to the fourth entry, and there isn't one
document.write(people.musicians[3].lastName + '<br>');	

</script>
}}}



<script>
var people =
  { "programmers": [
    { "firstName": "Brett", "lastName":"McLaughlin", "email": "brett@newInstance.com" },
    { "firstName": "Jason", "lastName":"Hunter", "email": "jason@servlets.com" },
    { "firstName": "Elliotte", "lastName":"Harold", "email": "elharo@macfaq.com" }
   ],
  "authors": [
    { "firstName": "Isaac", "lastName": "Asimov", "genre": "science fiction" },
    { "firstName": "Tad", "lastName": "Williams", "genre": "fantasy" },
    { "firstName": "Frank", "lastName": "Peretti", "genre": "christian fiction" }
   ],
  "musicians": [
    { "firstName": "Eric", "lastName": "Clapton", "instrument": "guitar" },
    { "firstName": "Sergei", "lastName": "Rachmaninoff", "instrument": "piano" }
   ]
  }
// Accessing the data:
document.write(people.programmers[0].lastName + '<br>');
// Value is "fantasy
document.write(people.authors[1].genre + '<br>');
// Value is "Elliotte"
document.write(people.programmers[2].firstName + '<br>');

// modifying data
document.write(people.musicians[1].lastName + '<br>');
people.musicians[1].lastName = "Wagner";
people.musicians[1].firstName = "Richard";

document.write(people.musicians[1].firstName + ' ' + people.musicians[1].lastName + '<br>');

// Undefined. This refers to the fourth entry, and there isn't one
document.write(people.musicians[3].lastName + '<br>');	

</script>
{{{
JSON Example
In the following example, we define a Person object, instantiate it, set its properties, serialize it, store it, retrieve it, and deserialize back into an object.

function Person()
{
    this.Name;
    this.BirthDate;
}

// instantiate a Person
var person = new Person();
person.Name = "Joe Blow";
person.BirthDate = new Date("July 1, 1975 08:30:00");

// serialize the Person object
var strPerson = person.toJSONString();
/*

strPerson =
{"name":"Joe Blow","BirthDate":"1975-07-01T08:30:00"}
*/

// store the serialized Person
Application.userStore.value("mykey") = strPerson;

// retrieve the serialized Person
var s = Application.userStore.value("mykey");

// deserialize from string back into object
var o = s.parseJSON();

Pretty simple! 
}}}



<script>
/*
    json.js
    2007-12-02

    Public Domain

    No warranty expressed or implied. Use at your own risk.

    This file has been superceded by http://www.JSON.org/json2.js

    See http://www.JSON.org/js.html

    This file adds these methods to JavaScript:

        array.toJSONString(whitelist)
        boolean.toJSONString()
        date.toJSONString()
        number.toJSONString()
        object.toJSONString(whitelist)
        string.toJSONString()
            These methods produce a JSON text from a JavaScript value.
            It must not contain any cyclical references. Illegal values
            will be excluded.

            The default conversion for dates is to an ISO string. You can
            add a toJSONString method to any date object to get a different
            representation.

            The object and array methods can take an optional whitelist
            argument. A whitelist is an array of strings. If it is provided,
            keys in objects not found in the whitelist are excluded.

        string.parseJSON(filter)
            This method parses a JSON text to produce an object or
            array. It can throw a SyntaxError exception.

            The optional filter parameter is a function which can filter and
            transform the results. It receives each of the keys and values, and
            its return value is used instead of the original value. If it
            returns what it received, then structure is not modified. If it
            returns undefined then the member is deleted.

            Example:

            // Parse the text. If a key contains the string 'date' then
            // convert the value to a date.

            myData = text.parseJSON(function (key, value) {
                return key.indexOf('date') >= 0 ? new Date(value) : value;
            });

    It is expected that these methods will formally become part of the
    JavaScript Programming Language in the Fourth Edition of the
    ECMAScript standard in 2008.

    This file will break programs with improper for..in loops. See
    http://yuiblog.com/blog/2006/09/26/for-in-intrigue/

    This is a reference implementation. You are free to copy, modify, or
    redistribute.

    Use your own copy. It is extremely unwise to load untrusted third party
    code into your pages.
*/

/*jslint evil: true */

/*members "\b", "\t", "\n", "\f", "\r", "\"", "\\", apply, charCodeAt,
    floor, getUTCDate, getUTCFullYear, getUTCHours, getUTCMinutes,
    getUTCMonth, getUTCSeconds, hasOwnProperty, join, length, parseJSON,
    prototype, push, replace, test, toJSONString, toString
*/

// Augment the basic prototypes if they have not already been augmented.

if (!Object.prototype.toJSONString) {

    Array.prototype.toJSONString = function (w) {
        var a = [],     // The array holding the partial texts.
            i,          // Loop counter.
            l = this.length,
            v;          // The value to be stringified.

// For each value in this array...

        for (i = 0; i < l; i += 1) {
            v = this[i];
            switch (typeof v) {
            case 'object':

// Serialize a JavaScript object value. Treat objects thats lack the
// toJSONString method as null. Due to a specification error in ECMAScript,
// typeof null is 'object', so watch out for that case.

                if (v && typeof v.toJSONString === 'function') {
                    a.push(v.toJSONString(w));
                } else {
                    a.push('null');
                }
                break;

            case 'string':
            case 'number':
            case 'boolean':
                a.push(v.toJSONString());
                break;
            default:
                a.push('null');
            }
        }

// Join all of the member texts together and wrap them in brackets.

        return '[' + a.join(',') + ']';
    };


    Boolean.prototype.toJSONString = function () {
        return String(this);
    };


    Date.prototype.toJSONString = function () {

// Eventually, this method will be based on the date.toISOString method.

        function f(n) {

// Format integers to have at least two digits.

            return n < 10 ? '0' + n : n;
        }

        return '"' + this.getUTCFullYear()   + '-' +
                   f(this.getUTCMonth() + 1) + '-' +
                   f(this.getUTCDate())      + 'T' +
                   f(this.getUTCHours())     + ':' +
                   f(this.getUTCMinutes())   + ':' +
                   f(this.getUTCSeconds())   + 'Z"';
    };


    Number.prototype.toJSONString = function () {

// JSON numbers must be finite. Encode non-finite numbers as null.

        return isFinite(this) ? String(this) : 'null';
    };


    Object.prototype.toJSONString = function (w) {
        var a = [],     // The array holding the partial texts.
            k,          // The current key.
            i,          // The loop counter.
            v;          // The current value.

// If a whitelist (array of keys) is provided, use it assemble the components
// of the object.

        if (w) {
            for (i = 0; i < w.length; i += 1) {
                k = w[i];
                if (typeof k === 'string') {
                    v = this[k];
                    switch (typeof v) {
                    case 'object':

// Serialize a JavaScript object value. Ignore objects that lack the
// toJSONString method. Due to a specification error in ECMAScript,
// typeof null is 'object', so watch out for that case.

                        if (v) {
                            if (typeof v.toJSONString === 'function') {
                                a.push(k.toJSONString() + ':' +
                                       v.toJSONString(w));
                            }
                        } else {
                            a.push(k.toJSONString() + ':null');
                        }
                        break;

                    case 'string':
                    case 'number':
                    case 'boolean':
                        a.push(k.toJSONString() + ':' + v.toJSONString());

// Values without a JSON representation are ignored.

                    }
                }
            }
        } else {

// Iterate through all of the keys in the object, ignoring the proto chain
// and keys that are not strings.

            for (k in this) {
                if (typeof k === 'string' &&
                        Object.prototype.hasOwnProperty.apply(this, [k])) {
                    v = this[k];
                    switch (typeof v) {
                    case 'object':

// Serialize a JavaScript object value. Ignore objects that lack the
// toJSONString method. Due to a specification error in ECMAScript,
// typeof null is 'object', so watch out for that case.

                        if (v) {
                            if (typeof v.toJSONString === 'function') {
                                a.push(k.toJSONString() + ':' +
                                       v.toJSONString());
                            }
                        } else {
                            a.push(k.toJSONString() + ':null');
                        }
                        break;

                    case 'string':
                    case 'number':
                    case 'boolean':
                        a.push(k.toJSONString() + ':' + v.toJSONString());

// Values without a JSON representation are ignored.

                    }
                }
            }
        }

// Join all of the member texts together and wrap them in braces.

        return '{' + a.join(',') + '}';
    };


    (function (s) {

// Augment String.prototype. We do this in an immediate anonymous function to
// avoid defining global variables.

// m is a table of character substitutions.

        var m = {
            '\b': '\\b',
            '\t': '\\t',
            '\n': '\\n',
            '\f': '\\f',
            '\r': '\\r',
            '"' : '\\"',
            '\\': '\\\\'
        };


        s.parseJSON = function (filter) {
            var j;

            function walk(k, v) {
                var i, n;
                if (v && typeof v === 'object') {
                    for (i in v) {
                        if (Object.prototype.hasOwnProperty.apply(v, [i])) {
                            n = walk(i, v[i]);
                            if (n !== undefined) {
                                v[i] = n;
                            }
                        }
                    }
                }
                return filter(k, v);
            }


// Parsing happens in three stages. In the first stage, we run the text against
// a regular expression which looks for non-JSON characters. We are especially
// concerned with '()' and 'new' because they can cause invocation, and '='
// because it can cause mutation. But just to be safe, we will reject all
// unexpected characters.

// We split the first stage into 4 regexp operations in order to work around
// crippling inefficiencies in IE's and Safari's regexp engines. First we
// replace all backslash pairs with '@' (a non-JSON character). Second, we
// replace all simple value tokens with ']' characters. Third, we delete all
// open brackets that follow a colon or comma or that begin the text. Finally,
// we look to see that the remaining characters are only whitespace or ']' or
// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.

            if (/^[\],:{}\s]*$/.test(this.replace(/\\./g, '@').
                    replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(:?[eE][+\-]?\d+)?/g, ']').
                    replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {

// In the second stage we use the eval function to compile the text into a
// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
// in JavaScript: it can begin a block or an object literal. We wrap the text
// in parens to eliminate the ambiguity.

                j = eval('(' + this + ')');

// In the optional third stage, we recursively walk the new structure, passing
// each name/value pair to a filter function for possible transformation.

                return typeof filter === 'function' ? walk('', j) : j;
            }

// If the text is not JSON parseable, then a SyntaxError is thrown.

            throw new SyntaxError('parseJSON');
        };


        s.toJSONString = function () {

// If the string contains no control characters, no quote characters, and no
// backslash characters, then we can simply slap some quotes around it.
// Otherwise we must also replace the offending characters with safe
// sequences.

            if (/["\\\x00-\x1f]/.test(this)) {
                return '"' + this.replace(/[\x00-\x1f\\"]/g, function (a) {
                    var c = m[a];
                    if (c) {
                        return c;
                    }
                    c = a.charCodeAt();
                    return '\\u00' + Math.floor(c / 16).toString(16) +
                                               (c % 16).toString(16);
                }) + '"';
            }
            return '"' + this + '"';
        };
    })(String.prototype);
}
</script>


<script>
function Person()
{
    this.Name;
    this.BirthDate;
}

// instantiate a Person
var person = new Person();
person.Name = "Joe Blow";
person.BirthDate = new Date("July 1, 1975 08:30:00");

// serialize the Person object
var strPerson = person.toJSONString();

/*
strPerson = {"name":"Joe Blow","BirthDate":"1975-07-01T08:30:00"}
*/

// store the serialized Person
Application.userStore.value("mykey") = strPerson;

// retrieve the serialized Person
var s = Application.userStore.value("mykey");

// deserialize from string back into object
var o = s.parseJSON();

</script>
/%
|Name|JavascriptShell|
|Source|http://www.TiddlyTools.com/#JavascriptShell|
|Version|0.0.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <<br>>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|script|
|Requires|InlineJavascriptPlugin|
|Overrides||
|Description|TidIDE: enter and invoke javascript in a command line|
%//%

Derived from http://www.squarefree.com/shell/?ignoreReferrerFrom=shell1.4

%/<html><div class="shell"><div id="output"></div><input type=text
 onkeydown="jsshell.inputKeydown(event)"
 id="input" class="input" wrap="off" autocomplete="off"
 title="TAB=auto-complete property names, Ctrl+Up/Down=history"
 style="width:100%;height:1.2em;margin-top:.2em;border:1px solid;color:#000;background:#fff;"><span style="float:right">height: <input type="text" name="height" value="20em" size="2" style="width:3em;padding:0;margin:0;" onchange="document.getElementById('output').style.height=this.value"> <input type="button" onclick="jsshell.go('clear()')"value="clear"></span><!--
 --><div>enter a javascript expression or shell function:
 ans, load(URL), scope(obj), <!--
 --><a accesskey="M" href="javascript:jsshell.go('scope(Math); mathHelp();');">Math</a>, <!--
 --><a accesskey="P" href="javascript:jsshell.go('props(ans)')">props(obj)</a>, <!--
 --><a accesskey="B" href="javascript:jsshell.go('blink(ans)')">blink(node)</a>, <!--
 --><a href="javascript:jsshell.go('wikify(ans)')">wikify(text)</a>, <!--
 --><a href="javascript:jsshell.go('print(ans)')">print(text)</a></div></div></html><script>

var shellstyles="";
shellstyles+=".shell #output { height:20em;width:100%;white-space:normal;overflow:auto; }";
shellstyles+=".shell #output { border:1px solid #999;background:#000 !important; }";
shellstyles+=".shell #output .input { color:#fff !important; }"; // white
shellstyles+=".shell #output .error { color:#f00 !important; }"; // red
shellstyles+=".shell #output .normalOutput { color:#0c0 !important; }"; // green
shellstyles+=".shell #output .propList { color:#0c0 !important; }"; // green
shellstyles+=".shell #output .print { color:#ccc !important; }"; // gray
shellstyles+=".shell #output .tabcomplete { color:#ff0 !important; }"; // yellow
shellstyles+=".shell #output .message { color:#0ff !important; }"; // cyan
setStylesheet(shellstyles,"JavascriptShellStyles");

window.jsshell = {}; // Put our functions in the global namespace.

window.jsshell.refocus = function()
{
 jsshell._in.blur(); // Needed for Mozilla to scroll correctly.
 jsshell._in.focus();
}

window.jsshell.initTarget = function()
{
 window.print = jsshell.shellCommands.print;
}

// Unless the user is selected something, refocus the textbox.
// (requested by caillon, brendan, asa)
window.jsshell.keepFocusInTextbox = function(e) 
{
 var g = e.srcElement ? e.srcElement : e.target; // IE vs. standard
 
 while (!g.tagName)
 g = g.parentNode;
 var t = g.tagName.toUpperCase();
 if (t=="A" || t=="INPUT")
 return;
 
 if (window.getSelection) {
 // Mozilla
 if (String(window.getSelection()))
 return;
 }
 else if (document.getSelection) {
 // Opera? Netscape 4?
 if (document.getSelection())
 return;
 }
 else {
 // IE
 if ( document.selection.createRange().text )
 return;
 }
 
 jsshell.refocus();
}

//function inputKeydown(e) {
window.jsshell.inputKeydown = function(e) {
 // Use onkeydown because IE doesn't support onkeypress for arrow keys

 //alert(e.keyCode + " ^ " + e.keycode);

 if (e.shiftKey && e.keyCode == 13) { // shift-enter
 // don't do anything; allow the shift-enter to insert a line break as normal
 } else if (e.keyCode == 13) { // enter
 // execute the input on enter
 try { jsshell.go(); } catch(er) { alert(er); };
 setTimeout(function() { jsshell._in.value = ""; }, 0); // can't preventDefault on input, so clear it later
 } else if (e.keyCode == 38) { // up
 // go up in history if at top or ctrl-up
 if (e.ctrlKey || jsshell.caretInFirstLine(jsshell._in))
 jsshell.hist(true);
 } else if (e.keyCode == 40) { // down
 // go down in history if at end or ctrl-down
 if (e.ctrlKey || jsshell.caretInLastLine(jsshell._in))
 jsshell.hist(false);
 } else if (e.keyCode == 9) { // tab
 jsshell.tabcomplete();
 setTimeout(function() { jsshell.refocus(); }, 0); // refocus because tab was hit
 } else { }

 setTimeout(jsshell.recalculateInputHeight, 0);
 
 //return true;
};

window.jsshell.caretInFirstLine = function(textbox)
{
 // IE doesn't support selectionStart/selectionEnd
 if (textbox.selectionStart == undefined)
 return true;

 var firstLineBreak = textbox.value.indexOf("\n");

 return ((firstLineBreak == -1) || (textbox.selectionStart <= firstLineBreak));
}

window.jsshell.caretInLastLine = function(textbox)
{
 // IE doesn't support selectionStart/selectionEnd
 if (textbox.selectionEnd == undefined)
 return true;

 var lastLineBreak = textbox.value.lastIndexOf("\n");
 
 return (textbox.selectionEnd > lastLineBreak);
}

window.jsshell.recalculateInputHeight = function()
{
 var rows = jsshell._in.value.split(/\n/).length
 + 1 // prevent scrollbar flickering in Mozilla
 + (window.opera ? 1 : 0); // leave room for scrollbar in Opera

 if (jsshell._in.rows != rows) // without this check, it is impossible to select text in Opera 7.60 or Opera 8.0.
 jsshell._in.rows = rows;
}

window.jsshell.println = function(s, type)
{
 if((s=String(s)))
 {
 var newdiv = document.createElement("div");
 newdiv.appendChild(document.createTextNode(s));
 newdiv.className = type;
 jsshell._out.appendChild(newdiv);
 jsshell._out.scrollTop=jsshell._out.scrollHeight-jsshell._out.clientHeight; // ELS: scroll output into view
 return newdiv;
 }
}

window.jsshell.printWithRunin = function(h, s, type)
{
 var div = jsshell.println(s, type);
 var head = document.createElement("strong");
 head.appendChild(document.createTextNode(h + ": "));
 div.insertBefore(head, div.firstChild);
}

window.jsshell.shellCommands = 
{
load : function load(url)
{
 var s = document.createElement("script");
 s.type = "text/javascript";
 s.src = url;
 document.getElementsByTagName("head")[0].appendChild(s);
 jsshell.println("Loading " + url + "...", "message");
},

clear : function clear()
{
 jsshell._out.innerHTML = "";
},

wikify : function wikify(text)
{
 window.wikify(text, jsshell._out);
},

print : function print(s) { jsshell.println(s, "print"); },

// the normal function, "print", shouldn't return a value
// (suggested by brendan; later noticed it was a problem when showing others)
pr : function pr(s) 
{ 
 jsshell.shellCommands.print(s); // need to specify shellCommands so it doesn't try window.print()!
 return s;
},

props : function props(e, onePerLine)
{
 if (e === null) {
 jsshell.println("props called with null argument", "error");
 return;
 }

 if (e === undefined) {
 jsshell.println("props called with undefined argument", "error");
 return;
 }

 var ns = ["Methods", "Fields", "Unreachables"];
 var as = [[], [], []]; // array of (empty) arrays of arrays!
 var p, j, i; // loop variables, several used multiple times

 var protoLevels = 0;

 for (p = e; p; p = p.__proto__)
 {
 for (i=0; i<ns.length; ++i)
 as[i][protoLevels] = [];
 ++protoLevels;
 }

 for(var a in e)
 {
 // Shortcoming: doesn't check that VALUES are the same in object and prototype.

 var protoLevel = -1;
 try
 {
 for (p = e; p && (a in p); p = p.__proto__)
 ++protoLevel;
 }
 catch(er) { protoLevel = 0; } // "in" operator throws when param to props() is a string

 var type = 1;
 try
 {
 if ((typeof e[a]) == "function")
 type = 0;
 }
 catch (er) { type = 2; }

 as[type][protoLevel].push(a);
 }

 function times(s, n) { return n ? s + times(s, n-1) : ""; }

 for (j=0; j<protoLevels; ++j)
 for (i=0;i<ns.length;++i)
 if (as[i][j].length) 
 jsshell.printWithRunin(
 ns[i] + times(" of prototype", j), 
 (onePerLine ? "\n\n" : "") + as[i][j].sort().join(onePerLine ? "\n" : ", ") + (onePerLine ? "\n\n" : ""), 
 "propList"
 );
},

blink : function blink(node)
{
 if (!node) throw("blink: argument is null or undefined.");
 if (node.nodeType == null) throw("blink: argument must be a node.");
 if (node.nodeType == 3) throw("blink: argument must not be a text node");
 if (node.documentElement) throw("blink: argument must not be the document object");

 function setOutline(o) { 
 return function() {
 if (node.style.outline != node.style.bogusProperty) {
 // browser supports outline (Firefox 1.1 and newer, CSS3, Opera 8).
 node.style.outline = o;
 }
 else if (node.style.MozOutline != node.style.bogusProperty) {
 // browser supports MozOutline (Firefox 1.0.x and older)
 node.style.MozOutline = o;
 }
 else {
 // browser only supports border (IE). border is a fallback because it moves things around.
 node.style.border = o;
 }
 }
 } 
 
 function focusIt(a) {
 return function() {
 a.focus(); 
 }
 }

 if (node.ownerDocument) {
 var windowToFocusNow = (node.ownerDocument.defaultView || node.ownerDocument.parentWindow); // Moz vs. IE
 if (windowToFocusNow)
 setTimeout(focusIt(windowToFocusNow.top), 0);
 }

 for(var i=1;i<7;++i)
 setTimeout(setOutline((i%2)?'3px solid red':'none'), i*100);

 setTimeout(focusIt(window), 800);
 setTimeout(focusIt(jsshell._in), 810);
},

scope : function scope(sc)
{
 if (!sc) sc = {};
 jsshell._scope = sc;
 jsshell.println("Scope is now " + sc + ". If a variable is not found in this scope, window will also be searched. New variables will still go on window.", "message");
},

mathHelp : function mathHelp()
{
 jsshell.printWithRunin("Math constants", "E, LN2, LN10, LOG2E, LOG10E, PI, SQRT1_2, SQRT2", "propList");
 jsshell.printWithRunin("Math methods", "abs, acos, asin, atan, atan2, ceil, cos, exp, floor, log, max, min, pow, random, round, sin, sqrt, tan", "propList");
},

ans : undefined
};


window.jsshell.hist = function(up)
{
 // histList[0] = first command entered, [1] = second, etc.
 // type something, press up --> thing typed is now in "limbo"
 // (last item in histList) and should be reachable by pressing 
 // down again.

 var L = jsshell.histList.length;

 if (L == 1)
 return;

 if (up)
 {
 if (jsshell.histPos == L-1)
 {
 // Save this entry in case the user hits the down key.
 jsshell.histList[jsshell.histPos] = jsshell._in.value;
 }

 if (jsshell.histPos > 0)
 {
 jsshell.histPos--;
 // Use a timeout to prevent up from moving cursor within new text
 // Set to nothing first for the same reason
 setTimeout(
 function() {
 jsshell._in.value = ''; 
 jsshell._in.value = jsshell.histList[jsshell.histPos];
 var caretPos = jsshell._in.value.length;
 if (jsshell._in.setSelectionRange) 
 jsshell._in.setSelectionRange(caretPos, caretPos);
 },
 0
 );
 }
 } 
 else // down
 {
 if (jsshell.histPos < L-1)
 {
 jsshell.histPos++;
 jsshell._in.value = jsshell.histList[jsshell.histPos];
 }
 else if (jsshell.histPos == L-1)
 {
 // Already on the current entry: clear but save
 if (jsshell._in.value)
 {
 jsshell.histList[jsshell.histPos] = jsshell._in.value;
 ++jsshell.histPos;
 jsshell._in.value = "";
 }
 }
 }
}

window.jsshell.tabcomplete = function()
{
 /*
 * Working backwards from s[from], find the spot
 * where this expression starts. It will scan
 * until it hits a mismatched ( or a space,
 * but it skips over quoted strings.
 * If stopAtDot is true, stop at a '.'
 */
 function findbeginning(s, from, stopAtDot)
 {
 /*
 * Complicated function.
 *
 * Return true if s[i] == q BUT ONLY IF
 * s[i-1] is not a backslash.
 */
 function equalButNotEscaped(s,i,q)
 {
 if(s.charAt(i) != q) // not equal go no further
 return false;

 if(i==0) // beginning of string
 return true;

 if(s.charAt(i-1) == '\\') // escaped?
 return false;

 return true;
 }

 var nparens = 0;
 var i;
 for(i=from; i>=0; i--)
 {
 if(s.charAt(i) == ' ')
 break;

 if(stopAtDot && s.charAt(i) == '.')
 break;
 
 if(s.charAt(i) == ')')
 nparens++;
 else if(s.charAt(i) == '(')
 nparens--;

 if(nparens < 0)
 break;

 // skip quoted strings
 if(s.charAt(i) == '\'' || s.charAt(i) == '\"')
 {
 //dump("skipping quoted chars: ");
 var quot = s.charAt(i);
 i--;
 while(i >= 0 && !equalButNotEscaped(s,i,quot)) {
 //dump(s.charAt(i));
 i--;
 }
 //dump("\n");
 }
 }
 return i;
 }

 // XXX should be used more consistently (instead of using selectionStart/selectionEnd throughout code)
 // XXX doesn't work in IE, even though it contains IE-specific code
 function getcaretpos(inp)
 {
 if(inp.selectionEnd != null)
 return inp.selectionEnd;
 
 if(inp.createTextRange)
 {
 var docrange = document.selection.createRange();
 var inprange = inp.createTextRange();
 if (inprange.setEndPoint)
 {
 inprange.setEndPoint('EndToStart', docrange);
 return inprange.text.length;
 }
 }

 return inp.value.length; // sucks, punt
 }

 function setselectionto(inp,pos)
 {
 if(inp.selectionStart) {
 inp.selectionStart = inp.selectionEnd = pos;
 }
 else if(inp.createTextRange) {
 var docrange = document.selection.createRange();
 var inprange = inp.createTextRange();
 inprange.move('character',pos);
 inprange.select();
 }
 else { // err...
 /*
 inp.select();
 if(document.getSelection())
 document.getSelection() = "";
 */
 }
 }
 // get position of cursor within the input box
 var caret = getcaretpos(jsshell._in);

 if(caret) {
 //dump("----\n");
 var dotpos, spacepos, complete, obj;
 //dump("caret pos: " + caret + "\n");
 // see if there's a dot before here
 dotpos = findbeginning(jsshell._in.value, caret-1, true);
 //dump("dot pos: " + dotpos + "\n");
 if(dotpos == -1 || jsshell._in.value.charAt(dotpos) != '.') {
 dotpos = caret;
//dump("changed dot pos: " + dotpos + "\n");
 }

 // look backwards for a non-variable-name character
 spacepos = findbeginning(jsshell._in.value, dotpos-1, false);
 //dump("space pos: " + spacepos + "\n");
 // get the object we're trying to complete on
 if(spacepos == dotpos || spacepos+1 == dotpos || dotpos == caret)
 {
 // try completing function args
 if(jsshell._in.value.charAt(dotpos) == '(' ||
 (jsshell._in.value.charAt(spacepos) == '(' && (spacepos+1) == dotpos))
 {
 var fn,fname;
 var from = (jsshell._in.value.charAt(dotpos) == '(') ? dotpos : spacepos;
 spacepos = findbeginning(jsshell._in.value, from-1, false);

 fname = jsshell._in.value.substr(spacepos+1,from-(spacepos+1));
 //dump("fname: " + fname + "\n");
 try {
 with(window)
 with(jsshell._scope)
 with(jsshell.shellCommands)
 fn = eval(fname);
 }
 catch(er) {
 //dump('fn is not a valid object\n');
 return;
 }
 if(fn == undefined) {
 //dump('fn is undefined');
 return;
 }
 if(fn instanceof Function)
 {
 // Print function definition, including argument names, but not function body
 if(!fn.toString().match(/function .+?\(\) +\{\n +\[native code\]\n\}/))
 jsshell.println(fn.toString().match(/function .+?\(.*?\)/), "tabcomplete");
 }

 return;
 }
 else
 obj = window;
 }
 else
 {
 var objname = jsshell._in.value.substr(spacepos+1,dotpos-(spacepos+1));
 //dump("objname: |" + objname + "|\n");
 try {
 with(jsshell._scope)
 with(window)
 obj = eval(objname);
 }
 catch(er) {
 jsshell.printError(er); 
 return;
 }
 if(obj == undefined) {
 // sometimes this is tabcomplete's fault, so don't print it :(
 // e.g. completing from "print(document.getElements"
 // jsshell.println("Can't complete from null or undefined expression " + objname, "error");
 return;
 }
 }
 //dump("obj: " + obj + "\n");
 // get the thing we're trying to complete
 if(dotpos == caret)
 {
 if(spacepos+1 == dotpos || spacepos == dotpos)
 {
 // nothing to complete
 //dump("nothing to complete\n");
 return;
 }

 complete = jsshell._in.value.substr(spacepos+1,dotpos-(spacepos+1));
 }
 else {
 complete = jsshell._in.value.substr(dotpos+1,caret-(dotpos+1));
 }
 //dump("complete: " + complete + "\n");
 // ok, now look at all the props/methods of this obj
 // and find ones starting with 'complete'
 var matches = [];
 var bestmatch = null;
 for(var a in obj)
 {
 //a = a.toString();
 //XXX: making it lowercase could help some cases,
 // but screws up my general logic.
 if(a.substr(0,complete.length) == complete) {
 matches.push(a);
 ////dump("match: " + a + "\n");
 // if no best match, this is the best match
 if(bestmatch == null)
 {
 bestmatch = a;
 }
 else {
 // the best match is the longest common string
 function min(a,b){ return ((a<b)?a:b); }
 var i;
 for(i=0; i< min(bestmatch.length, a.length); i++)
 {
 if(bestmatch.charAt(i) != a.charAt(i))
 break;
 }
 bestmatch = bestmatch.substr(0,i);
 ////dump("bestmatch len: " + i + "\n");
 }
 ////dump("bestmatch: " + bestmatch + "\n");
 }
 }
 bestmatch = (bestmatch || "");
 ////dump("matches: " + matches + "\n");
 var objAndComplete = (objname || obj) + "." + bestmatch;
 //dump("matches.length: " + matches.length + ", jsshell.tooManyMatches: " + jsshell.tooManyMatches + ", objAndComplete: " + objAndComplete + "\n");
 if(matches.length > 1 && (jsshell.tooManyMatches == objAndComplete || matches.length <= 10)) {

 jsshell.printWithRunin("Matches: ", matches.join(', '), "tabcomplete");
 jsshell.tooManyMatches = null;
 }
 else if(matches.length > 10)
 {
 jsshell.println(matches.length + " matches. Press tab again to see them all", "tabcomplete");
 jsshell.tooManyMatches = objAndComplete;
 }
 else {
 jsshell.tooManyMatches = null;
 }
 if(bestmatch != "")
 {
 var sstart;
 if(dotpos == caret) {
 sstart = spacepos+1;
 }
 else {
 sstart = dotpos+1;
 }
 jsshell._in.value = jsshell._in.value.substr(0, sstart)
 + bestmatch
 + jsshell._in.value.substr(caret);
 setselectionto(jsshell._in,caret + (bestmatch.length - complete.length));
 }
 }
}

window.jsshell.printQuestion = function(q)
{
 jsshell.println(q, "input");
}

window.jsshell.printAnswer = function(a)
{
 if (a !== undefined) {
 jsshell.println(a, "normalOutput");
 jsshell.shellCommands.ans = a;
 }
}

window.jsshell.printError = function(er)
{ 
 var lineNumberString;

 lastError = er; // for debugging the shell
 if (er.name)
 {
 // lineNumberString should not be "", to avoid a very wacky bug in IE 6.
 lineNumberString = (er.lineNumber != undefined) ? (" on line " + er.lineNumber + ": ") : ": ";
 jsshell.println(er.name + lineNumberString + er.message, "error"); // Because IE doesn't have error.toString.
 }
 else
 jsshell.println(er, "error"); // Because security errors in Moz /only/ have toString.
}

window.jsshell.go = function(s)
{
 jsshell._in.value = jsshell.question = s ? s : jsshell._in.value;

 if (jsshell.question == "")
 return;

 jsshell.histList[jsshell.histList.length-1] = jsshell.question;
 jsshell.histList[jsshell.histList.length] = "";
 jsshell.histPos = jsshell.histList.length - 1;
 
 // Unfortunately, this has to happen *before* the JavaScript is run, so that 
 // print() output will go in the right place.
 jsshell._in.value='';
 jsshell.recalculateInputHeight();
 jsshell.printQuestion(jsshell.question);

 if (window.closed) {
 jsshell.printError("Target window has been closed.");
 return;
 }
 
 try { ("jsshell" in window) }
 catch(er) {
 jsshell.printError("The JavaScript Shell cannot access variables in the target window. The most likely reason is that the target window now has a different page loaded and that page has a different hostname than the original page.");
 return;
 }

 if (!("jsshell" in window))
 initTarget(); // silent

 // Evaluate Shell.question using _win's eval (this is why eval isn't in the |with|, IIRC).
// window.location.href = "javascript:try{ jsshell.printAnswer(eval('with(jsshell._scope) with(jsshell.shellCommands) {' + jsshell.question + String.fromCharCode(10) + '}')); } catch(er) { jsshell.printError(er); }; setTimeout(jsshell.refocus, 0); void 0";
 try { 
 jsshell.printAnswer(eval(
 'with(jsshell._scope) with(jsshell.shellCommands) {' 
 + jsshell.question + String.fromCharCode(10) + 
 '}')); 
 } catch(er) { 
 jsshell.printError(er); 
 }; 
 setTimeout(jsshell.refocus, 0);
}

window.jsshell.histList = [""]; 
window.jsshell.histPos = 0; 
window.jsshell._scope = {}; 
window.jsshell.question;
window.jsshell._in;
window.jsshell._out;
window.jsshell.tooManyMatches = null;
window.jsshell.lastError = null;

jsshell._in = document.getElementById("input");
jsshell._out = document.getElementById("output");

jsshell.initTarget();

jsshell.recalculateInputHeight();
jsshell.refocus();

</script>
Ref.: http://rickyspears.com/blog/?p=100

Since I’ve been using TiddlyWiki as my primary task manager, I move text around A LOT. Selecting, cutting, and pasting text is still much better than shuffling paper, however. Except as noted, the keyboard shortcuts below work in textarea fields of any web page and not just for TiddlyWiki. Note also that these may not always work the same way in all browsers on all platforms. I’m currently using Firefox on Windows primarily.

You may remember that one of the reasons I started using TiddlyWiki was because I wanted to be able to reorganize my list items quickly. At first I did this by selecting each item with the mouse and then cutting it using keyboard shortcuts, re-positioning the cursor with the mouse, and then pasting it with a keyboard shortcut. If you do this very much, I think you will find the following very useful. The challenge is to get them deeply ingrained in your workflow. I would suggest trying to avoid the mouse or trackpad for a week and use these as much as possible for all your text navigating, selecting, and editing. You will find the trial well worth the effort.
Cut, Copy, and Paste:
CTRL-X - Cut the selected text to the clipboard
CTRL-C - Copy the selected text to the clipboard
CTRL-V - Paste the clipboard to the current cursor position

Undo and Redo:
CTRL-Z - Undo the last editing command
CTRL-Y - Redo the last undo command

Navigating Text:
HOME: Move cursor to the beginning of the current line
END: Move the cursor to the end of the current line
CTRL-HOME: Move the cursor the very beginning of the current text field.
CTRL-END: Move the cursor to the very end of the last line of the current text field.
PAGE UP: Moves the cursor up the same number of lines as is displayed in the textarea.
PAGE DOWN: Moves the cursor down the same number of lines as is displayed in the textarea.
UP ARROW: Move the cursor up one line to the current horizontal cursor position. If the current horizontal position doesn’t exist, the cursor will move to the end of the line.
DOWN ARROW: Move the cursor down one line to the current horizontal cursor position. If the current horizontal position doesn’t exist, the cursor will move to the end of the line.
LEFT ARROW: Moves the cursor one character to the left.
RIGHT ARROW: Moves the cursor one character to the right.
CTRL RIGHT ARROW: Moves the cursor one word to the right, placing the cursor before the first letter of the next word.
CTRL LEFT ARROW: Moves the cursor one word to the left, placing the cursor before the first letter of the previous word.

Selecting Text:
SHIFT-HOME: Selects all text from the cursor to the beginning of the current line
SHIFT-END: Selects all text from the cursor to the end of the current line
SHIFT-CTRL-HOME: Selects all text from the cursor the very beginning of the current text field.
SHIFT-CTRL-END: Selects all text from the cursor to the very end of the last line of the current text field.
SHIFT-PAGE UP: Selects all text from the cursor up the same number of lines as is displayed in the textarea.
SHIFT-PAGE DOWN: Selects all text from the cursor down the same number of lines as is displayed in the textarea.
SHIFT-UP ARROW: Selects all text from the cursor up one line to the current horizontal cursor position. If the current horizontal position doesn’t exist on that line, the cursor will selects all text from the end of the line.
SHIFT-DOWN ARROW: Selects all text from the cursor down one line to the current horizontal cursor position. If the current horizontal position doesn’t exist on that line, the cursor will Selects all text to the end of the line.
SHIFT-LEFT ARROW: Selects one character to the left of the cursor.
SHIFT-RIGHT ARROW: Selects one character to the right of the cursor.
SHIFT-CTRL RIGHT ARROW: Selects all characters from the cursor to the first letter of the next word.
SHIFT-CTRL LEFT ARROW: Selects all characters from the cursor to the first letter of the previous word.

TiddlyWiki Specific:
CTRL-ENTER: Closes and accepts changes to the current tiddler being edited.
ESCAPE: Closes and discards changes to the current tiddler being edited.

If you have other useful keyboard shortcuts for manipulating text (either in TiddlyWiki or any other textarea field) that I’ve missed here, please post a comment to let me know.
<code>
config.macros.LaunchApplication.handler = function (place,macroName,params,wikifier,paramString,tiddler) {
    // 0=ButtonText, 1=toolTip, 2=AppToLaunch, 3...AppParameters
    
    if (params[0] &amp;&amp; params[1] &amp;&amp; params[2]) {
        var theButton = createTiddlyButton(place, getParam(params,&quot;buttonText&quot;,params[0]), getParam(params,&quot;toolTip&quot;,params[1]), onClickLaunchApplication);
        theButton.setAttribute(&quot;appToLaunch&quot;, getParam(params,&quot;appToLaunch&quot;,params[2]));
        params.splice(0,3);
        theButton.setAttribute(&quot;appParameters&quot;, params.join(&quot; &quot;));
        return;
    }
}

    function onClickLaunchApplication(e) {
	var theAppToLaunch = this.getAttribute(&quot;appToLaunch&quot;);
	var theAppParams = this.getAttribute(&quot;appParameters&quot;).readMacroParams();
	LaunchApplication(theAppToLaunch,theAppParams);
    }

</code>
{{{
<<LaunchApplication "Emacs" "Linux Emacs" "file:///C:\Apps\cygwin\bin\emacs.exe">>
}}}
<<LaunchApplication "Emacs" "Linux Emacs" "file:///C:\Apps\cygwin\bin\emacs.exe">>

{{{
<<LaunchApplication "LocalProgram" "Program relative to Tiddly html file" "localDir/bin/emacs">>
}}}
<<LaunchApplication "LocalProgram" "Program relative to Tiddly html file" "localDir/bin/emacs">>
					     
{{{
<<LaunchApplication "Open Notepad" "Text Editing" "file:///C:/WINNT/system32/notepad.exe">>
}}}
<<LaunchApplication "Open Notepad" "Text Editing" "file:///C:/WINX64/system32/notepad.exe">>

{{{
<<LaunchApplication "C Drive" "Folder" "file:///c:/">>
}}}
<<LaunchApplication "C Drive" "Folder" "file:///c:/">>		

<<LaunchApplication "Linux" "Linux Admin" "file:///C:/Documents%20and%20Settings/All%20Users.WINX64/Documents/LinuxAdmin-v3.html">>	
/***
|''Name:''|LaunchApplicationPlugin|
|''Author:''|Lyall Pearce|
|''Source:''|http://www.Remotely-Helpful.com/TiddlyWiki/LaunchApplication.html|
|''License:''|[[Creative Commons Attribution-Share Alike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|''Version:''|1.3.1|
|''~CoreVersion:''|2.2.4|
|''Requires:''| |
|''Overrides:''| |
|''Description:''|Launch an application from within TiddlyWiki using a button|
!!!!!Usage
<<<
{{{<<LaunchApplication "buttonLabel" "tooltip" "application" ["arguments" ...]>>}}}
* buttonLabel is anything you like
* tooltip is anything you like
* application is a path to the executable
* arguments is any command line arguments the application requires.
* You must supply relative path from the location of the TiddlyWiki OR a fully qualified path
* Forward slashes works fine for Windows

eg.

{{{
<<LaunchApplication "Emacs" "Linux Emacs" "file:///usr/bin/emacs">>
}}}
<<LaunchApplication "Emacs" "Linux Emacs" "file:///usr/bin/emacs">>

{{{
<<LaunchApplication "LocalProgram" "Program relative to Tiddly html file" "localDir/bin/emacs">>
}}}
<<LaunchApplication "LocalProgram" "Program relative to Tiddly html file" "localDir/bin/emacs">>
					     
{{{
<<LaunchApplication "Open Notepad" "Text Editing" "file:///e:/Windows/notepad.exe">>
}}}
<<LaunchApplication "Open Notepad" "Text Editing" "file:///e:/Windows/notepad.exe">>

{{{
<<LaunchApplication "C Drive" "Folder" "file:///c:/">>
}}}
<<LaunchApplication "C Drive" "Folder" "file:///c:/">>


!!!!!Revision History
* 1.1.0 - leveraged some tweaks from from Bradly Meck's version (http://bradleymeck.tiddlyspot.com/#LaunchApplicationPlugin) and the example text.
* 1.2.0 - Make launching work in Linux too and use displayMessage() to give diagnostics/status info.
* 1.3.0 - execute programs relative to TiddlyWiki html file plus fix to args for firefox.
* 1.3.1 - parameters to the macro are properly parsed, allowing dynamic paramters using {{{ {{javascript}} }}} notation.

<<<
***/
//{{{
version.extensions.LaunchApplication = {major: 1, minor: 3, revision: 1, date: new Date(2007,8,7)};
config.macros.LaunchApplication = {};

function LaunchApplication(appToLaunch,appParams) {
    if(! appToLaunch)
	return;
    var tiddlyBaseDir = self.location.pathname.substring(0,self.location.pathname.lastIndexOf("\\")+1);
    if(!tiddlyBaseDir || tiddlyBaseDir == "") {
	tiddlyBaseDir = self.location.pathname.substring(0,self.location.pathname.lastIndexOf("/")+1);
    }
    // if Returns with a leading slash, we don't want that.
    if(tiddlyBaseDir.substring(0,1) == "/") {
	tiddlyBaseDir = tiddlyBaseDir.substring(1);
    }
    if(appToLaunch.indexOf("file:///") == 0) // windows would have C:\ as the resulting file
    {
	tiddlyBaseDir = "";
	appToLaunch = appToLaunch.substring(8);
    }

    if (config.browser.isIE) {
	// want where the tiddly is actually located, excluding tiddly html file

	var theShell = new ActiveXObject("WScript.Shell");
	if(theShell) {
            // the app name may have a directory component, need that too
	    // as we want to start with current working dir as the location
	    // of the app.
	    var appDir = appToLaunch.substring(0, appToLaunch.lastIndexOf("\\"));
	    if(! appDir || appDir == "") {
		appDir = appToLaunch.substring(0, appToLaunch.lastIndexOf("/"));
	    }
	    appParams = appParams.length > 0 ? " \""+appParams.join("\" \"")+"\"" : "";
	    try {
		theShell.CurrentDirectory = decodeURI(tiddlyBaseDir + appDir);
		var commandString = ('"' +decodeURI(tiddlyBaseDir+appToLaunch) + '" ' + appParams);
		pluginInfo.log.push(commandString);
	        theShell.run(commandString);
	    } catch (e) {
		displayMessage("LaunchApplication cannot locate/execute file '"+tiddlyBaseDir+appToLaunch+"'");
		return;
	    }
	} else {
	    displayMessage("LaunchApplication failed to create ActiveX component WScript.Shell");
	}
    } else { // Not IE
	// want where the tiddly is actually located, excluding tiddly html file
	netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
        var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
        var launchString;
	try { // try linux/unix format
            launchString = decodeURI(tiddlyBaseDir+appToLaunch);
	    file.initWithPath(launchString);
	} catch (e) {
	    try { // leading slash on tiddlyBaseDir
                launchString = decodeURI("/"+tiddlyBaseDir+appToLaunch);
		file.initWithPath(launchString);
	    } catch (e) {
		try { // try windows format
		    launchString = decodeURI(appToLaunch).replace(/\//g,"\\");
		    file.initWithPath(launchString);
		} catch (e) {
		    try { // try windows format
			launchString = decodeURI(tiddlyBaseDir+appToLaunch).replace(/\//g,"\\");
			file.initWithPath(launchString);
		    } catch (e) {
			displayMessage("LaunchApplication cannot locate file '"+launchString+"' : "+e);
			return;
		    } // try windows mode
		} // try windows mode
	    }; // try with leading slash in tiddlyBaseDir
	}; // try linux/unix mode
	try {
	    if (file.isFile() && file.isExecutable()) {
		displayMessage("LaunchApplication executing '"+launchString+"' "+appParams.join(" "));
		var process = Components.classes['@mozilla.org/process/util;1'].createInstance(Components.interfaces.nsIProcess);
		process.init(file);
		process.run(false, appParams, appParams.length);
	    }
	    else
	    {
		displayMessage("LaunchApplication launching '"+launchString+"' "+appParams.join(" "));
		file.launch(); // No args available with this option
	    }
	} catch (e) {
	    displayMessage("LaunchApplication cannot execute/launch file '"+launchString+"'");
	}
    }
};

config.macros.LaunchApplication.handler = function (place,macroName,params,wikifier,paramString,tiddler) {
    // 0=ButtonText, 1=toolTip, 2=AppToLaunch, 3...AppParameters
    
    if (params[0] && params[1] && params[2]) {
        var theButton = createTiddlyButton(place, getParam(params,"buttonText",params[0]), getParam(params,"toolTip",params[1]), onClickLaunchApplication);
        theButton.setAttribute("appToLaunch", getParam(params,"appToLaunch",params[2]));
        params.splice(0,3);
        theButton.setAttribute("appParameters", params.join(" "));
        return;
    }
}

    function onClickLaunchApplication(e) {
	var theAppToLaunch = this.getAttribute("appToLaunch");
	var theAppParams = this.getAttribute("appParameters").readMacroParams();
	LaunchApplication(theAppToLaunch,theAppParams);
    }

//}}}
/***
| Name|LessBackupsPlugin|
| Description|Intelligently limit the number of backup files you create|
| Version|3.0 ($Rev: 2320 $)|
| Date|$Date: 2007-06-18 22:37:46 +1000 (Mon, 18 Jun 2007) $|
| Source|http://mptw.tiddlyspot.com/#LessBackupsPlugin|
| Author|Simon Baird|
| Email|simon.baird@gmail.com|
| License|http://mptw.tiddlyspot.com/#TheBSDLicense|
!!!Description
You end up with just backup one per year, per month, per weekday, per hour, minute, and second.  So total number won't exceed about 200 or so. Can be reduced by commenting out the seconds/minutes/hours line from modes array

!!!Notes
Works in IE and Firefox only.  Algorithm by Daniel Baird. IE code by by Saq Imtiaz.
!!!Code
***/
//{{{
window.getSpecialBackupPath = function(backupPath) {

	var MINS  = 60 * 1000;
	var HOURS = 60 * MINS;
	var DAYS  = 24 * HOURS;

	// comment out the ones you don't want
	var modes = [
		["YYYY",  365*DAYS], // one per year for ever
		["MMM",   31*DAYS],  // one per month
		["ddd",   7*DAYS],   // one per weekday
		//["d0DD",  1*DAYS],   // one per day of month
		["h0hh",  24*HOURS], // one per hour
		["m0mm",  1*HOURS],  // one per minute
		["s0ss",  1*MINS],   // one per second
		["latest",0]         // always keep last version. (leave this).
	];

	var now = new Date();

	for (var i=0;i<modes.length;i++) {

		// the filename we will try
		var specialBackupPath = backupPath.replace(/(\.)([0-9]+\.[0-9]+)(\.html)$/,
						'$1'+now.formatString(modes[i][0]).toLowerCase()+'$3')

		// open the file

		try {
			if (config.browser.isIE) {
				var fsobject = new ActiveXObject("Scripting.FileSystemObject")
				var fileExists  = fsobject.FileExists(specialBackupPath);
				if (fileExists) {
					var fileObject = fsobject.GetFile(specialBackupPath);
					var modDate = new Date(fileObject.DateLastModified).valueOf();
				}
			}
			else {
				netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
				var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
				file.initWithPath(specialBackupPath);
				var fileExists = file.exists();
				if (fileExists) {
					var modDate = file.lastModifiedTime;
				}
			}
		}
		catch(e) {
			// give up
			return backupPath;
		}

		// expiry is used to tell if it's an 'old' one. Eg, if the month is June and there is a
		// June file on disk that's more than an month old then it must be stale so overwrite
		// note that "latest" should be always because the expiration period is zero (see above)
		var expiry = new Date(modDate + modes[i][1]);
		if (!fileExists || now > expiry)
			return specialBackupPath;
	}
}

// hijack the core function
window.getBackupPath_orig = window.getBackupPath;
window.getBackupPath = function(localPath) {
	return getSpecialBackupPath(getBackupPath_orig(localPath));
}

//}}}
http://tw.lewcid.org/#%5B%5BExtensions%20Overview%5D%5D
http://project.dahukanna.net/tiddlywiki/twextensions.htm
<<forEachTiddler 
 where 
 'tiddler.tags.contains(["script"])'
>>

See also [[ForEachTiddlerExamples]].
{{{
<<forEachTiddler 
 where 
 'tiddler.tags.containsAny(["TaskToDo","TaskOpen","TaskDone"])'
>>
}}}
//''Result:''//
<<forEachTiddler 
 where 
 'tiddler.tags.containsAny(["TaskToDo","TaskOpen","TaskDone"])'
>>

See also [[ForEachTiddlerExamples]].
{{{
<<forEachTiddler
 where
 'tiddler.tags && tiddler.tags.length'
 sortBy 
 'getSortedTagsText(tiddler)+"###"+tiddler.title'
 script
 'function getSortedTagsText(tiddler) {var tags = tiddler.tags; if (!tags) return ""; tags.sort(); var result = ""; for (var i = 0; i < tags.length;i++) {result += tags[i]+ " ";} return result;} function getGroupTitle(tiddler, context) {if (!context.lastGroup || context.lastGroup != getSortedTagsText(tiddler)) { context.lastGroup = getSortedTagsText(tiddler); return "* {{{"+(context.lastGroup?context.lastGroup:"no tags")+"}}}\n";} else return "";} '
 write
 'getGroupTitle(tiddler, context)+"** [[" + tiddler.title+"]]\n"'
>>
}}}
<<forEachTiddler
 where
 'tiddler.tags && tiddler.tags.length'
 sortBy 
 'getSortedTagsText(tiddler)+"###"+tiddler.title'
 script
 'function getSortedTagsText(tiddler) {var tags = tiddler.tags; if (!tags) return ""; tags.sort(); var result = ""; for (var i = 0; i < tags.length;i++) {result += tags[i]+ " ";} return result;} function getGroupTitle(tiddler, context) {if (!context.lastGroup || context.lastGroup != getSortedTagsText(tiddler)) { context.lastGroup = getSortedTagsText(tiddler); return "* {{{"+(context.lastGroup?context.lastGroup:"no tags")+"}}}\n";} else return "";} '
 write
 'getGroupTitle(tiddler, context)+"** [[" + tiddler.title+"]]\n"'
>>
//(Tiddlers without tags are not included)//
{{{
<<forEachTiddler 
 where
 'tiddler.tags.length == 0'
>>
}}}
//''Result:''//
<<forEachTiddler 
 where
 'tiddler.tags.length == 0'
>>
See also [[ForEachTiddlerExamples]].
{{{
<<forEachTiddler
 where ! 'tiddler.tags.contains("Plugin")'
 sortBy 
 'tiddler.text.length'
 descending
 write
 '"* [["+tiddler.title+"]] ("+tiddler.text.length+")\n"'
>>
}}}
//''Result:''//
<<forEachTiddler
 sortBy 
 'tiddler.text.length'
 descending
 write
 '"* [["+tiddler.title+"]] ("+tiddler.text.length+")\n"'
>>
/***
|Name|ListboxPlugin|
|Source|http://www.TiddlyTools.com/#ListboxPlugin|
|Documentation|http://www.TiddlyTools.com/#ListboxPluginInfo|
|Version|0.8.1|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|set tiddler fields by selecting enumerated values from a listbox or droplist|
The {{{<<select>>}}} macro allows you to set tiddler field values by selecting pre-configured enumerated values from a listbox/droplist control.  
!!!!!Documentation
>see [[ListboxPluginInfo]]
!!!!!Revision History
<<<
2007.08.31 [0.8.2] corrected handling for "@tiddlername" syntax for non-default 'target' tiddler.
2007.08.06 [0.8.1] added support for "@here" keyword syntax and cleaned up handling for identifying 'target' tiddler.  Also added 'onclick' handler for "other:" item, so that prompt dialog is presented even if "other" was already selected (and hence, no "onchange" event)
2007.07.29 [0.8.0] added getWikifiedData() and support for "*" prefix on TiddlerName.  Causes tiddler content to be wikified before processing it as a listbox definition.  Allows you to use macros or inline scripts to *generate* dynamic list definitions from current document content.  Based on a request from EdgarWhipple.
2007.07.26 [0.7.3] in onChange(), corrected call to config.macros.select.setFieldValue() instead of config.macros.setFieldValue().  Thanks to EdgarWhipple for the bug report!
2007.07.24 [0.7.2] in setFieldValue(), 'touch' target tiddler AFTER setting value to avoid early refresh event that steps on listbox attributes, causing a fatal error (in IE only).  Thanks go to Ken Girard for the bug report!  Also, in render(), fixed problem where selecting "edit list..." would set the value of the field to the name of the tiddler containing the list.  Also removed unneeded deferred (setTimeout) handling for invoking setFieldValue()
2007.06.28 [0.7.1] in render(), retrieve current val from tiddler editor control (when editing) or use stored field (when viewing).
2007.05.29 [0.7.0] split render() logic from handler(), added notification-based refresh() for lists that use +TiddlerName definition so changes in underlying tiddler definition are automatically sync'ed up in any currently displayed lists
2007.05.15 [0.6.1] code/documentation cleanup
2007.05.14 [0.6.0] lots more options
2007.05.12 [0.5.0] started
<<<
!!!!!Code
***/
//{{{
version.extensions.select= {major: 0, minor: 8, revision: 2, date: new Date(2007,8,31)};

config.macros.select = {
	tooltip: "select a value for %0@%1",
	blankTooltip: "set %0@%1=[null] (delete field value)",
	valueTooltip: "set %0@%1=%2",
	otherLabel: "other",
	otherTooltip: "set %0@%1=[???] (enter custom value)",
	otherPrompt: "enter a value for '%0'",
	editLabel: "edit list...",
	editTooltip: "edit '%0' list definition (%1)",
	changeMsg: "setting %0@%1=%2",
	verbose: false,
	hereKeyword: "here",
	defaultTarget: "SiteFields",
	handler:
	function(place,macroName,params,wikifier,paramString,tiddler) {

		// get containing tiddler (or use default "SiteFields" catch-all tiddler)
		var here=story.findContainingTiddler(place);
		var targetID=here?here.getAttribute("tiddler"):this.defaultTarget;
		// get field name
		var field=params.shift();
		var pos=field.indexOf("@"); // if non-default target ("field@tiddler" syntax)
		if(pos!=-1) { // split field into field and tiddlername.
			if (field.substr(pos+1)!=this.hereKeyword) // "here" == use default target
				targetID=field.substr(pos+1); // switch to different target tiddler
			field=field.substr(0,pos);
		}

		// if no field name, do nothing
		if(!field || !field.length) return;

		var p=params.shift();
		var rows="0"; if (p.substr(0,5)=="rows:") { rows=p.substr(5); p=params.shift(); } // optional list height in lines
		var width="auto"; if (p.substr(0,6)=="width:") { width=p.substr(6); p=params.shift(); } // optional CSS width
		var autosave=(p.toLowerCase()=="autosave"); if (autosave) p=params.shift(); // optional autosave
		var allowBlank=(p.toLowerCase()=="allowblank"); if (allowBlank) p=params.shift(); // add optional empty item
		var allowOther=(p.toLowerCase()=="allowother"); if (allowOther) p=params.shift(); // add optional "other: ____" item

		if (tiddler && !story.isDirty(tiddler.title)) autosave=true; // if tiddler is in VIEW mode, force autosave

		if (p.substr(0,1)=="+"||p.substr(0,1)=="*") { // get list from HR-separated tiddler (* means wikify source first)
			var listsrc=p.substr(1);
			var listtxt=store.getTiddlerText(listsrc);
			var wikifyData=p.substr(0,1)=="*"; if (wikifyData) listtxt=this.getWikifiedData(listtxt);
			var separator="\n";
			if (listtxt && listtxt.indexOf("\n----\n")!=-1) separator="\n----\n";
			var list=[];
			if (listtxt && listtxt.length) var list=listtxt.split(separator);
			var allowEdit=(params[0] && params[0].toLowerCase()=="allowedit"); // add optional "edit list..." item
			if (allowEdit) p=params.shift();
		}
		else { // get list from macro params: "value value value ..." or "label=value label=value label=value ..."
			var list=[];
			while (p) {
				var parts=p.split("=");
				var label=parts[0]; var v=parts[1]?parts[1]:parts[0];
				list.push(label+"="+v);
				p=params.shift();
			}
		}
		// register notification handler for ALL tiddler changes (to sync lists)
		store.addNotification(null,this.refresh);
		// render the control
		this.render(createTiddlyElement(place,"span"), null, targetID, field, list, listsrc, wikifyData, rows, width, autosave, allowBlank, allowOther, allowEdit);
	},
	getWikifiedData: // wikify tiddler content, then extract text WITH newlines and HRs included
	function(txt) {
		var e=createTiddlyElement(document.body,"div"); wikify(txt,e);
		var breaks=e.getElementsByTagName("br");
		for (var b=0; b<breaks.length; b++) breaks[b].parentNode.insertBefore(document.createTextNode("\n"),breaks[b]);
		var lines=e.getElementsByTagName("hr");
		for (var l=0; l<lines.length; l++) lines[l].parentNode.insertBefore(document.createTextNode("----\n"),lines[l]);
		var items=e.getElementsByTagName("li");
		for (var i=0; i<items.length; i++) items[i].parentNode.insertBefore(document.createTextNode("\n"),items[i]);
		var txt=getPlainText(e); removeNode(e); return txt;
	},
	refresh:
	function (title) {
		var lists=document.getElementsByTagName("select");
		for (i=0; i<lists.length; i++) {
			if (lists[i].getAttribute("listsrc")==title) {
				var here=lists[i];
				var place=here.parentNode;
				var targetID=here.getAttribute("tiddler");
				var field=here.getAttribute("edit");
				var listsrc=here.getAttribute("listsrc");
				var rows=here.getAttribute("rows");
				var width=here.getAttribute("width");
				var autosave=here.getAttribute("autosave")=="true";
				var allowBlank=here.getAttribute("allowBlank")=="true";
				var allowOther=here.getAttribute("allowOther")=="true";
				var allowEdit=here.getAttribute("allowEdit")=="true";
				var wikifyData=here.getAttribute("wikifyData")=="true";
				// get the list
				var listtxt=store.getTiddlerText(listsrc,""); if (wikifyData) listtxt=config.macros.select.getWikifiedData(listtxt);
				var separator="\n"; if (listtxt && listtxt.indexOf("\n----\n")!=-1) separator="\n----\n";
				var list=[]; if (listtxt && listtxt.length) var list=listtxt.split(separator);
				// re-render control
				config.macros.select.render(place, here, targetID, field, list, listsrc, wikifyData, rows, width, autosave, allowBlank, allowOther, allowEdit);
			}
		}
	},
	render:
	function (place, here, targetID, field, list, listsrc, wikifyData, rows, width, autosave, allowBlank, allowOther, allowEdit) {
		// use selected value from existing listbox (except for "edit list..." item)
		if (here && here.selectedIndex!=-1 && here.options[here.selectedIndex].text!=config.macros.select.editLabel)
			{ var val=here.value; if (val && !val.length) val=undefined; }
		// if listbox doesn't yet exist, or 'edit list' item was selected, use value from existing field, if available...
		if (!val) var val=store.getValue(targetID,field);
		var count=0; var options="";
		// add default 'undefined' item
		if (val==undefined || allowBlank) {
			var title=this.blankTooltip.format([field,targetID]);
			options+='<option value="" title="'+title+'"></option>';
			count++;
		}
		// add enumerated items
		var isOther=(val!=undefined);
		for (opt=0; opt<list.length; opt++) {
			var lines=list[opt].split("\n"); var parts=lines[0].split("=");
			var label=parts[0];
			var v=parts[1]?parts[1]:parts[0];
			var title=lines[1]?lines[1]:this.valueTooltip.format([field,targetID,v]);
			options+='<option value="'+v+'" '+(val==v?'selected':'')+' title="'+title+'">'+label+'</option>';
			if (val==v) isOther=false; // found matching value in list
			count++;
		}
		// add other... item
		if (isOther||allowOther) {
			var label="other"+(isOther?(": "+val):"...");
			var v=isOther?val:"";
			var title=this.otherTooltip.format([field,targetID]);
			options+='<option value="'+v+'" '+(isOther?'selected':'')+' title="'+title+'">'+label+'</option>';
			count++;
		}
		// add edit list... item
		if (listsrc && (!store.tiddlerExists(listsrc) || allowEdit)) {
			var title=this.editTooltip.format([field,listsrc]);
			options+='<option value="'+listsrc+'" title="'+title+'">'+this.editLabel+'</option>';
			count++;
		}
		// construct full HTML
		var html='<select ';
		html+=(val!=undefined?'value="'+val+'" ':'')+'" edit="'+field+'" ';
		html+='onclick="return config.macros.select.onClick(this,event)" ';
		html+='onchange="return config.macros.select.onChange(this,event)" ';
		html+='ondblclick="return false" ';
		html+='autosave="'+autosave+'" allowBlank="'+allowBlank+'" ';
		html+='allowOther="'+allowOther+'" allowEdit="'+allowEdit+'" ';
		html+='rows="'+rows+'" size="'+(rows!=0?rows:count)+'" ';
		html+='tiddler="'+targetID+'" '+'" listsrc="'+listsrc+'" wikifyData="'+wikifyData+'" ';
		html+='title="'+this.tooltip.format([field,targetID])+'" style="width:'+width+'">'+options+'</select>';
		// pass to browser for rendering
		place.innerHTML=html;
	},
	onClick:
	function(here,event) {
		var label=config.macros.select.otherLabel;
		if (here.getAttribute("allowother")=="true" && here.options[here.selectedIndex].text.substr(0,label.length)==label)
			here.onchange.apply(here,arguments);
	},
	onChange:
	function(here,event) {
		if (here.options[here.selectedIndex].text==config.macros.select.editLabel) {
			story.displayTiddler(story.findContainingTiddler(here),here.value,DEFAULT_EDIT_TEMPLATE);
			return false;
		}
		var label=config.macros.select.otherLabel;
		if (here.getAttribute("allowother")=="true" && here.options[here.selectedIndex].text.substr(0,label.length)==label) {
			var newval=prompt(config.macros.select.otherPrompt.format([here.getAttribute("edit")]),here.value);
			if (!newval) {// user cancelled
				var v=store.getValue(here.getAttribute("tiddler"),here.getAttribute("edit"));
				{ here.value=v; if (v==undefined) here.selectedIndex=0; return false; }
			};
			here.options[here.selectedIndex].value=newval;
			here.options[here.selectedIndex].text=config.macros.select.otherLabel+": "+newval;
			here.value=newval;
		}
		if (here.getAttribute("autosave")=="true") config.macros.select.setFieldValue(here);
		return false;
	},
	setFieldValue: function(here) {
		var tid=here.getAttribute("tiddler"); if (!tid || !tid.length) return; // no target tiddler specified, do nothing
		var field=here.getAttribute("edit");
		// if tiddler doesn't exist, create it...
		if (!store.tiddlerExists(tid)) store.saveTiddler(tid,tid,"",config.options.txtUserName,new Date(),[]);
		// set the field value in the target tiddler
		store.setValue(tid,field,here.value.length?here.value:null); // if value is blank, delete field
		// touch target tiddler so that modified and modifier are updated
		var t=store.getTiddler(tid);
		store.saveTiddler(tid,tid,t.body,config.options.txtUserName,new Date(),t.tags,t.fields);
		if (config.macros.select.verbose) // tell user what happened
			{ clearMessage(); displayMessage(config.macros.select.changeMsg.format([field,tid,here.value])); }
	}
}
//}}}
|Name|ListboxPlugin|
|Source|http://www.TiddlyTools.com/#ListboxPlugin|
|Documentation|http://www.TiddlyTools.com/#ListboxPluginInfo|
|Version|0.8.1|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|documentation|
|Requires||
|Overrides||
|Description|documentation for ListboxPlugin|
The {{{<<select>>}}} macro allows you to set tiddler field values by selecting pre-configured enumerated values from a listbox/droplist control.  
!!!!!Usage
<<<
The macro may be used within the ViewTemplate or EditTemplate to add a listbox/droplist to every tiddler, or embedded directly in specific tiddler content to create interfaces for custom-built TW "applications" that use tiddler fields to store application-specific values.

Syntax for use in ViewTemplate/EditTemplate:
{{{
<div class="editor" macro="select fieldname@tiddlername rows:nn width:xxx autoSave allowBlank allowOther
	value value value ..."></div>
<div class="editor" macro="select fieldname@tiddlername rows:nn width:xxx autoSave allowBlank allowOther
	label=value label=value label=value ..."></div>
<div class="editor" macro="select fieldname@tiddlername rows:nn width:xxx autoSave allowBlank allowOther
	+TiddlerName allowEdit"></div>
}}}

Syntax for direct embedding in tiddler content:
{{{
<<select fieldname@tiddlername rows:nn width:xxx allowBlank allowOther
	value value value ...>>
<<select fieldname@tiddlername rows:nn width:xxx allowBlank allowOther
	label=value label=value label=value ...>>
<<select fieldname@tiddlername rows:nn width:xxx allowBlank allowOther
	+TiddlerName allowEdit>>
}}}

//where://
''fieldname@tiddlername''
>specifies the tiddler field associated with the list display.  The "@tiddlername" portion is optional and, when omitted, the current tiddler is assumed (note: you may also use the special keyword, "@here", to designate the current tiddler)
''rows:nn''
>specifies the number of lines to display in the list.  If rows=1, a 'droplist' is displayed. If rows>1 a fixed-height listbox is used.  By default (or if rows=0 is used), the listbox is displayed with enough lines to show all items without scrolling (i.e., "fit to contents - vertically")
''width:xxx''
>specifies the width of the list, using a CSS dimension value (px, em, in, cm, or %).  The default is auto (i.e., "fit to contents - horizontally").
''autoSave''
>when used in EditTemplate, this keyword forces selection changes to be applied immediately rather than waiting for the "done" command to be invoked.  Note: because the standard ViewTemplate toolbar does not have a "done" command to signal the end of the editing activity, ''autoSave'' is always enabled when working with a selection list that is being displayed in 'view mode'.
''allowBlank''
>when the value of a tiddler field is "undefined", a 'blank' item is added at the beginning of the list to represent the undefined field value.  When a field value is subsequently selected, the blank item is removed from the list.   Use the ''allowBlank'' keyword to always include the blank item in the list.  Selecting the blank item sets the field value back to "undefined" (i.e., deletes the field).
''allowOther''
>when the value of a tiddler field does not match any of the values in the list, a special 'other' item is added at the end of the list so that the unrecognized field value can be shown.  If another field value is subsequently selected, the 'other' item is removed from the list.  Use the ''allowOther'' keyword to always include the 'other item in the list.  When this item is selected, you will be prompted to enter a custom value to assign to the field.
''value value value ...'' //(inline list definition)//
//or// ''label=value label=value label=value ...'' //(inline list definition)//
//or// ''+TiddlerName'' (//or// ''*TiddlerName'') //(tiddler-based list definition)//
>specifies list item values or label/value pairs.  You can also use the ''+TiddlerName'' or ''*TiddlerName'' syntax to define the values or label/value pairs using a tiddler containing an "HR-separated" list, where each list item is one or two lines of text, separated from the next item by a horizontal rule: """----""".  The first line of each item contains the value or label=value that will appear in the list.  The second, optional line allows you to specify a custom tooltip for that list item.  If you use "*" preceding the TiddlerName, the contents of the tiddler will be processed by the TiddlyWiki parser before being processed as a list definition.  This allows you to use macros to dynamically generate list definitions based on the current document contents (such as available tag names).  The default tooltip for a list item is: "{{{set fieldname@tiddlername=itemvalue}}}".  Note: if all list entries are single-line (i.e., you are not defining ANY custom tooltips), you can omit the horizontal rule between entries... each line of text will be treated as a separate list entry.
''allowEdit'' //(for use with +TiddlerName param only)//
>adds optional "edit list..." item to the end of the list, to enable quick editing of a tiddler-based list definition.  Note: if the ''+TiddlerName'' parameter refers to a tiddler that does not yet exist, the "edit list..." item is automatically added to the list, even if ''allowEdit'' was not specified.  This allows you to place an 'empty' tiddler-based list into your content (e.g., """<<select fieldname =NewTiddlerName>>"""), and then create and define the tiddler-based list later on.
<<<
!!!!!Examples
<<<
''inline list definition:''
{{{<<select thing rows:1 eenie meenie miney moe>>}}}
<<select thing rows:1 eenie meenie miney moe>>
{{{<<select size rows:1 xsmall=30 small=32 medium=34 large=36 xlarge=38>>}}}
<<select size rows:1 xsmall=30 small=32 medium=34 large=36 xlarge=38>>
{{{<<select size allowOther xsmall=30 small=32 medium=34 large=36 xlarge=38>>}}}
<<select size allowOther xsmall=30 small=32 medium=34 large=36 xlarge=38>>

''tiddler-based list definition:''
{{{<<select color rows:1 +ListboxSample>>}}}
<<select color rows:1 +ListboxSample>>
{{{<<select color allowBlank allowOther +ListboxSample allowEdit>>}}}
<<select color allowBlank allowOther +ListboxSample allowEdit>>
{{{<<select demo@ListboxDemoTarget +ListboxNewSample>>}}}
<<select demo@ListboxDemoTarget +ListboxNewSample>>
<<<
/***
|''Name:''|LoadRemoteFileThroughProxy (previous LoadRemoteFileHijack)|
|''Description:''|When the TiddlyWiki file is located on the web (view over http) the content of [[SiteProxy]] tiddler is added in front of the file url. If [[SiteProxy]] does not exist "/proxy/" is added. |
|''Version:''|1.1.0|
|''Date:''|mar 17, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#LoadRemoteFileHijack|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0|
***/
//{{{
version.extensions.LoadRemoteFileThroughProxy = {
 major: 1, minor: 1, revision: 0, 
 date: new Date("mar 17, 2007"), 
 source: "http://tiddlywiki.bidix.info/#LoadRemoteFileThroughProxy"};

if (!window.bidix) window.bidix = {}; // bidix namespace
if (!bidix.core) bidix.core = {};

bidix.core.loadRemoteFile = loadRemoteFile;
loadRemoteFile = function(url,callback,params)
{
 if ((document.location.toString().substr(0,4) == "http") && (url.substr(0,4) == "http")){ 
  url = store.getTiddlerText("SiteProxy", "/proxy/") + url;
 }
 return bidix.core.loadRemoteFile(url,callback,params);
}
//}}}
Name: Blue
Background: #fff
Foreground: #000
PrimaryPale: #cdf
PrimaryLight: #57c
PrimaryMid: #114
PrimaryDark: #012
SecondaryPale: #ffc
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #841
TertiaryPale: #eee
TertiaryLight: #ccc
TertiaryMid: #999
TertiaryDark: #666
Error: #f88
Name: Green
Background: #fff
Foreground: #000
PrimaryPale: #9b9
PrimaryLight: #385
PrimaryMid: #031
PrimaryDark: #020
SecondaryPale: #ffc
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #841
TertiaryPale: #eee
TertiaryLight: #ccc
TertiaryMid: #999
TertiaryDark: #666
Error: #f88
Name: Red
Background: #fff
Foreground: #000
PrimaryPale: #fdd
PrimaryLight: #c55
PrimaryMid: #711
PrimaryDark: #500
SecondaryPale: #ffc
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #841
TertiaryPale: #eee
TertiaryLight: #ccc
TertiaryMid: #999
TertiaryDark: #666
Error: #f88
Name: Smoke
Background: #fff
Foreground: #000
PrimaryPale: #aaa
PrimaryLight: #777
PrimaryMid: #111
PrimaryDark: #000
SecondaryPale: #ffc
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #841
TertiaryPale: #eee
TertiaryLight: #ccc
TertiaryMid: #999
TertiaryDark: #666
Error: #f88
Name: Teal
Background: #fff
Foreground: #000
PrimaryPale: #B5D1DF
PrimaryLight: #618FA9
PrimaryMid: #1a3844
PrimaryDark: #000
SecondaryPale: #ffc
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #841
TertiaryPale: #f8f8f8
TertiaryLight: #bbb
TertiaryMid: #999
TertiaryDark: #888
Error: #f88
<code>
config.macros.allTags.handler = function(place,macroName,params)
{
	var tags = store.getTags(params[0]);
	var ul = createTiddlyElement(place,"ul");
	if(tags.length == 0)
		createTiddlyElement(ul,"li",null,"listTitle",this.noTags);
	for(var t=0; t<tags.length; t++) {
		var title = tags[t][0];
		var info = getTiddlyLinkInfo(title);
		var li =createTiddlyElement(ul,"li");
		var btn = createTiddlyButton(li,title + " (" + tags[t][1] + ")",this.tooltip.format([title]),onClickTag,info.classes);
		btn.setAttribute("tag",title);
		btn.setAttribute("refresh","link");
		btn.setAttribute("tiddlyLink",title);
	}
};
</code>
[[Welcome]] GettingStarted [[Configuration]] [[Tag Cloud]] JavascriptShell [[tidIDE]]

|!Format|!Markup|!Example|
|Bold|{{{''Bold''}}} (2 single quotes)|''Bold''|
|Italic|{{{//Italic//}}}|//Italic//|
|Bold Italic|{{{''//Bold Italic//''}}}|''//Bold Italic//''|
|Underlined|{{{__Underline__}}}(2 underscores)|__Underlined__|
|Strikethough|{{{--Strikethrough--}}}<br />{{{--}}} replaced {{{==}}} for Stikethrough in TiddlyWiki 2.1|--Strikethrough--|
|Superscript|{{{Text^^Superscript^^}}}|Text^^Superscript^^|
|Subscript|{{{Text~~Subscript~~}}}|Text~~Subscript~~|
|Monospaced text|<html><code>{{{Monospaced}}}</code></html>|{{{Monospaced}}}|
|Monospaced multiline block|Put <html><code>{{{</code></html> and <html><code>}}}</code></html> on their own lines|<html><pre>{{{<br/>Monospaced<br/>Multi-line<br/>Block<br/>}}}</pre></html>|
|Highlight|{{{@@Highlight@@}}}|@@Highlight@@|
|Color|{{{@@color(green):green text@@}}}|@@color(green):green text@@ |
|~|{{{@@bgcolor(green):text@@}}}|@@bgcolor(green):text@@ |
|~|{{{@@bgcolor(#3399ff):text@@}}}|@@bgcolor(#3399ff):text@@|
|~|{{{@@bgcolor(#39f):text@@}}}|@@bgcolor(#39f):text@@|
|CSS Extended Highlights|{{{@@some css;Highlight@@}}}<br />For backwards compatibility, the following highlight syntax is also accepted:<br />{{{@@bgcolor(#ff0000):color(#ffffff):red coloured@@}}}|@@background-color:#ff0000;color:#ffffff;red coloured@@<br /><<slider AtEg ./atEg 'Extended example ...'>>|
|Custom CSS Class|<html><code>{{wrappingClass{Text that is now accentuated}}}</code></html><br />By default, the text is placed in a <span>. To use a <div> instead, insert a line break before the text (after the single {)<br />In the CSS:<br />{{{.wrappingClass {color: red;} }}}|Add .wrappingClass to StyleSheet|
|Any HTML|{{{<html><span>any</span><br />}}}<br />{{{<b>valid</b> <em>xhtml</em></html>}}}|<html><span>any</span><br /><b>valid</b> <em>xhtml</em></html>|

http://en.wikibooks.org/wiki/TiddlyWiki/Writing
[[call test macro]] [[call myToday macro]]
http://checkettsweb.com/tw/beta.html

''Plugins''
{{{
	AllowEditing			
	ApplyHtmlMacroFix		
	EditMacroWithDefault		
	InlineEditCommand		
	InlineSaveMacro			
	MetaTemplates			
	NewTiddlerAutoNumberExtension	
	Select Macro			
	ShowQuotes			
	TheNewMetaView			
	TiddlyWiki.prototype.getTiddlersWithField			
	Upload Plugin			
	quickAddMacro			
}}}
/%
|Name|MiniBrowser|
|Source|http://www.TiddlyTools.com/#MiniBrowser|
|Version|0.0.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <<br>>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|script|
|Requires|InlineJavascriptPlugin, MiniBrowserList|
|Overrides||
|Description|use an 'inline frame' to display another site inside a tiddler with navigation buttons and a dropdown list of favorite URLs.|

Usage:
<<tiddler MiniBrowser with: id>>

where:
	id - (optional) specifies an ID to assign to the DOM element for the embedded IFRAME.  If you want to have **more than one** MiniBrowser displayed at a time, you MUST provide an ID, so that each MiniBrowser can be uniquely identified within the DOM structure.

Note: MiniBrowserList can be *empty*, but must already exist for you to ADD a favorite to the list.  If you don't copy the sample list from TiddlyTools, be sure to create this tiddler in your own document if you intend to use the MiniBrowser's "favorites" droplist.

%/
<html><form target="browser_$1" style="margin:0;padding:0"
	onsubmit="this.action=this.url.value; this.form.done.disabled=false" style="margin:0;padding:0"><nobr><!--
--><input type="button" value="<" title="back" style="font-size:8pt;width:3%"
	onclick="try{window.frames['browser_$1'].history.go(-1)}catch(e){window.history.go(-1)}" ><!--
--><input type="button" value=">" title="forward" style="font-size:8pt;width:3%"
	onclick="try{window.frames['browser_$1'].history.go(+1)}catch(e){window.history.go(+1)}"><!--
--><input type="button" value="+" title="refresh"style="font-size:8pt;width:3%"
	onclick="window.frames['browser_$1'].location.reload()"><!--
--><input type="button" value="x" title="stop"style="font-size:8pt;width:3%"
	onclick="window.stop()"><!--
--><select name="bookmarks" id="browser_bookmarks_$1" size="1" style="font-size:8pt;width:21%"
	onchange="var f=document.getElementById('browser_$1'); if (!this.value.length) return window.miniBrowserResetSize(); else window.miniBrowserSetSize(this.form); this.form.url.value=this.value; this.form.action=this.value; this.form.submit(); this.form.done.disabled=false">
<option value="">bookmarks...</option>
</select><!--
--><input type="button" value="add" title="add this URL to the MiniBrowser bookmarks" style="font-size:8pt;width:5%"
	onclick="window.miniBrowserAddBookmark(this.form.url);"><!--
--><input type="button" value="del" title="remove this URL from the MiniBrowser bookmarks" style="font-size:8pt;width:5%"
	onclick="window.miniBrowserDeleteBookmark(this.form.bookmarks);"><!--
--><input type="button" value="edit" title="edit the MiniBrowser bookmarks list definition" style="font-size:8pt;width:5%"
	onclick="story.displayTiddler(null,'MiniBrowserList',2)"><!--
--><input type="text" name="url" size="60" value="" style="font-size:8pt;width:35%"
	onfocus="this.select();" onkeyup="var k=event.keyCode; if (k==13|k==10) this.form.go.click();"><!--
--><input type="button" name="go" value="go" title="view this URL" style="font-size:8pt;width:4%"
	onclick="if(!this.form.url.value.length) return; window.miniBrowserSetSize(this.form); this.form.action=this.form.url.value; this.form.submit(); this.form.done.disabled=false"><!--
--><input type="button" value="open" title="open this URL in a separate window" style="font-size:8pt;width:6%"
	onclick="if(this.form.url.value.length) window.open(this.form.url.value)"><!--
--><input type="button" value="done" name="done" title="stop viewing this URL" disabled style="font-size:8pt;width:6%"
	onclick="this.form.url.value=''; this.form.bookmarks.selectedIndex=0; window.miniBrowserResetSize(); this.disabled=true;">
<iframe name="browser_$1" id="browser_$1" style="width:100%;height:1em;display:none;background:#fff;border:1px solid"></iframe><div id="browser_resize_$1" style="text-align:center;marginTop:2px;display:none;font-size:8pt"><!--
--> size: <input type="text" name="w" size="3" value="100%" style="font-size:8pt;"
	onfocus="this.select()"><!--
-->x<input type="text" name="h" size="3" value="400" style="font-size:8pt;"
	onfocus="this.select()"><!--
--> <input type="button" value="set" style="font-size:8pt;"
	onclick="var w=this.form.w.value.trim(); if (!w||!w.length) w='100%'; var h=this.form.h.value.trim(); if (!h||!h.length) h='400'; if (!w.replace(/[0-9]*/,'').length) w+='px'; if (!h.replace(/[0-9]*/,'').length) h+='px'; var f=document.getElementById('browser_$1'); f.style.width=w; f.style.height=h;"><!--
--><input type="button" value="reset" style="font-size:8pt;"
	onclick="var w='100%'; var h='400'; var f=document.getElementById('browser_$1'); f.style.width=w; f.style.height=h+'px'; this.form.w.value=w; this.form.h.value=h;"><!--
--><input type="button" value="fit" title="resize to fit containing window" style="font-size:8pt;"
	onclick="window.miniBrowserFitSize(this)"><!--
--></div></nobr></form></html><script>

	// load bookmarks droplist from HR-separated "MiniBrowserList" tiddler contents
	var here=document.getElementById("browser_bookmarks_$1");
	while (here.length) here.options[0]=null; // remove current list items
	here.options[here.length]=new Option("bookmarks...","",true,true);
	var list=store.getTiddlerText("MiniBrowserList");
	if (list && list.trim().length) {
		var parts=list.split("\n----\n");
		for (var p=0; p<parts.length; p++) {
			var lines=parts[p].split("\n");
			var label=lines.shift(); // 1st line=display text
			var value=lines.shift(); // 2nd line=item value
			var indent=value&&value.length?"\xa0\xa0":"";
			here.options[here.length]=new Option(indent+label,value,false,false);
		}
	}

window.miniBrowserSetSize = function(form) {
	var f=document.getElementById('browser_$1');
	var w=form.w.value.trim(); if (!w||!w.length) w='100%'; if (!w.replace(/[0-9]*/,'').length) w+='px'; 
	var h=form.h.value.trim(); if (!h||!h.length) h='400'; if (!h.replace(/[0-9]*/,'').length) h+='px';
	f.style.width=w; f.style.height=h; f.style.display="block";
	document.getElementById('browser_resize_$1').style.display="block";
	return false;
}

window.miniBrowserResetSize = function() {
	var f=document.getElementById('browser_$1');
	if (f.src.length) f.src="";
	f.style.width='100%'; f.style.height='1em'; f.style.display="none";
	document.getElementById('browser_resize_$1').style.display="none";
	return false;
}
window.miniBrowserFitSize = function(place) {
	var trim=88; 	// fudge factor for controls + padding + borders.  ADJUST TO FIT LAYOUT
	var t=story.findContainingTiddler(place);
	if (!t) { t=place; while (t && t.className!='floatingPanel') t=t.parentNode; } if (!t) return;
	var w="100%"; // horizontal stretching via CSS works, but vertical stretching doesn't... so:
	var h=(t.offsetHeight-trim); // workaround: get containing panel/tiddler height and subtract "trim" height
	place.form.w.value=w; place.form.h.value=h; // update width/height input fields
	var f=document.getElementById('browser_$1');
	f.style.width=w; f.style.height=h+"px";
}

window.miniBrowserAddBookmark = function(place) {
	var v=place.value; if (!v.length) return;
	var d=prompt("Please enter a description for\n"+place.value); if (!d || !d.length) return;
	var t = store.getTiddler("MiniBrowserList"); t.set(null,"%0\n%1\n----\n%2".format([d,v,t.text]));
	var here=story.findContainingTiddler(place);
	if (here) story.refreshTiddler(here.getAttribute("tiddler"),1,true);
	story.refreshTiddler("MiniBrowserList",1,true);
	story.refreshTiddler("MiniBrowser",1,true);
	store.setDirty(true);
}

window.miniBrowserDeleteBookmark = function(place) {
	var v=place.value; if (!v.length) return;
	var d=place.options[place.selectedIndex].text; if (!d.length) return;
	var t = store.getTiddler("MiniBrowserList");
	if (!confirm("Are you sure you want to remove this MiniBrowser bookmark?\n\n"+d+"\n"+v)) return;
	var pat='%0\n%1\n----\n'.format([d.replace(/\xa0/g,''),v]); var re=new RegExp(pat,"i");
	t.set(null,t.text.replace(re,""));
	var here=story.findContainingTiddler(place);
	if (here) story.refreshTiddler(here.getAttribute("tiddler"),1,true);
	story.refreshTiddler("MiniBrowserList",1,true);
	story.refreshTiddler("MiniBrowser",1,true);
	store.setDirty(true);
}
</script><<tiddler HideTiddlerTags>>
google news
http://news.google.com/
----
yahoo
http://yahoo.com
----
microsoft
http://microsoft.com
----
Plugins, MPTW home site
http://mptw2.tiddlyspot.com
http://monkeygtd.tiddlyspot.com/demo3.html
[[MonkeyPirateTiddlyWiki|http://mptw.tiddlyspot.com]] is a distribution of [[TiddlyWiki|http://www.tiddlywiki.com/]] created by Simon Baird. See [[the web site|http://mptw.tiddlyspot.com/]] for more information.
!!Upgrading ~MonkeyPirateTiddlyWiki
This "empty" ~MonkeyPirateTiddlyWiki file comes pre-installed with the core ~MonkeyPirateTiddlyWiki plugins. You can upgrade these core plugins to the latest version by doing the following:
* Click ImportTiddlers
* Click "Choose..." and select "~MptwUpgradeURL"
* Click "open"
* Click the checkbox in the first column heading to select all tiddlers
* Click "More actions..." and select "Import these tiddlers"
* Click "OK" to confirm you want to overwrite the tiddlers
* Save and reload
<!--{{{-->
<!--- http://mptw.tiddlyspot.com/#MptwEditTemplate ($Rev: 2720 $) --->
<div class="toolbar" macro="toolbar +saveTiddler saveCloseTiddler copyTiddler closeOthers -cancelTiddler cancelCloseTiddler deleteTiddler"></div>
<div class="title" macro="view title"></div>
<div class="editLabel">Title</div><div class="editor" macro="edit title"></div>
<div macro='annotations'></div>
<div macro="showWhenExists EditPanelTemplate">[[EditPanelTemplate]]</div>
<div class="editLabel">Content</div><div class="editor" macro="edit text"></div>
<div class="editLabel">Tags</div><div class="editor" macro="edit tags"></div>
<div class="editorFooter"><span macro="message views.editor.tagPrompt"></span><span macro="tagChooser"></span></div>
<!--}}}-->
/***
| Name|MptwLayoutPlugin|
| Description|A package containing templates and css for the MonkeyPirateTiddlyWiki layout|
| Version|3.0 ($Rev: 2721 $)|
| Source|http://mptw.tiddlyspot.com/#MptwLayoutPlugin|
| Author|Simon Baird <simon.baird@gmail.com>|
| License|http://mptw.tiddlyspot.com/#TheBSDLicense|
!Notes
Presumes you have TagglyTaggingPlugin installed. To enable this you should have a PageTemplate containing {{{[[MptwPageTemplate]]}}} and similar for ViewTemplate and EditTemplate.
***/
//{{{
// used in MptwViewTemplate
config.mptwDateFormat = 'DD/MM/YY';
config.mptwJournalFormat = 'Journal DD/MM/YY';
//config.mptwDateFormat = 'MM/0DD/YY';
//config.mptwJournalFormat = 'Journal MM/0DD/YY';

config.shadowTiddlers.GettingStarted += "\n\nSee also MonkeyPirateTiddlyWiki.";

merge(config.annotations,{
	MptwEditTemplate: "Contains the default MPTW EditTemplate. If you want to customise this rename it to EditTemplate",
	MptwViewTemplate: "Contains the default MPTW ViewTemplate. If you want to customise this rename it to ViewTemplate",
	MptwPageTemplate: "Contains the default MPTW PageTemplate. If you want to customise this rename it to PageTemplate",
	MptwStyleSheet:   "Contains the default MPTW ~StyleSheet. Designed to be included in StyleSheet tiddler using the double square bracketted notation like this: {{{[[MptwStyleSheet]]}}}"
});

//}}}

//{{{
merge(config.shadowTiddlers,{

'MptwEditTemplate':[
 "<!--{{{-->",
 "<!--- http://mptw.tiddlyspot.com/#MptwEditTemplate ($Rev: 2720 $) --->",
 "<div class=\"toolbar\" macro=\"toolbar +saveTiddler saveCloseTiddler closeOthers -cancelTiddler cancelCloseTiddler deleteTiddler\"></div>",
 "<div class=\"title\" macro=\"view title\"></div>",
 "<div class=\"editLabel\">Title</div><div class=\"editor\" macro=\"edit title\"></div>",
 "<div macro='annotations'></div>",
 "<div macro=\"showWhenExists EditPanelTemplate\">[[EditPanelTemplate]]</div>",
 "<div class=\"editLabel\">Content</div><div class=\"editor\" macro=\"edit text\"></div>",
 "<div class=\"editLabel\">Tags</div><div class=\"editor\" macro=\"edit tags\"></div>",
 "<div class=\"editorFooter\"><span macro=\"message views.editor.tagPrompt\"></span><span macro=\"tagChooser\"></span></div>",
 "<!--}}}-->"
].join("\n"),

'MptwPageTemplate':[
 "<!--{{{-->",
 "<!-- http://mptw.tiddlyspot.com/#MptwPageTemplate ($Rev: 1829 $) -->",
 "<div class='header' macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryMid]]'>",
 "	<div class='headerShadow'>",
 "		<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;",
 "		<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>",
 "	</div>",
 "	<div class='headerForeground'>",
 "		<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;",
 "		<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>",
 "	</div>",
 "</div>",
 "<!-- horizontal MainMenu -->",
 "<div id='topMenu' refresh='content' tiddler='MainMenu'></div>",
 "<!-- original MainMenu menu -->",
 "<!-- <div id='mainMenu' refresh='content' tiddler='MainMenu'></div> -->",
 "<div id='sidebar'>",
 "	<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>",
 "	<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>",
 "</div>",
 "<div id='displayArea'>",
 "	<div id='messageArea'></div>",
 "	<div id='tiddlerDisplay'></div>",
 "</div>",
 "<!--}}}-->"
].join("\n"),

'MptwStyleSheet':[
 "/*{{{*/",
 "/* http://mptw.tiddlyspot.com/#MptwStyleSheet ($Rev: 2720 $) */",
 "",
 "/* a contrasting background so I can see where one tiddler ends and the other begins */",
 "body {",
 "	background: [[ColorPalette::TertiaryLight]];",
 "}",
 "",
 "/* sexy colours and font for the header */",
 ".headerForeground {",
 "	color: [[ColorPalette::PrimaryPale]];",
 "}",
 ".headerShadow, .headerShadow a {",
 "	color: [[ColorPalette::PrimaryMid]];",
 "}",
 "",
 "/* separate the top menu parts */",
 ".headerForeground, .headerShadow {",
 "	padding: 1em 1em 0;",
 "}",
 "",
 ".headerForeground, .headerShadow {",
 "	font-family: 'Trebuchet MS' sans-serif;",
 "	font-weight:bold;",
 "}",
 ".headerForeground .siteSubtitle {",
 "	color: [[ColorPalette::PrimaryLight]];",
 "}",
 ".headerShadow .siteSubtitle {",
 "	color: [[ColorPalette::PrimaryMid]];",
 "}",
 "",
 "/* make shadow go and down right instead of up and left */",
 ".headerShadow {",
 "	left: 1px;",
 "	top: 1px;",
 "}",
 "",
 "/* prefer monospace for editing */",
 ".editor textarea, .editor input {",
 "	font-family: 'Consolas' monospace;",
 "	background-color:[[ColorPalette::TertiaryPale]];",
 "}",
 "",
 "",
 "/* sexy tiddler titles */",
 ".title {",
 "	font-size: 250%;",
 "	color: [[ColorPalette::PrimaryLight]];",
 "	font-family: 'Trebuchet MS' sans-serif;",
 "}",
 "",
 "/* more subtle tiddler subtitle */",
 ".subtitle {",
 "	padding:0px;",
 "	margin:0px;",
 "	padding-left:0.5em;",
 "	font-size: 90%;",
 "	color: [[ColorPalette::TertiaryMid]];",
 "}",
 ".subtitle .tiddlyLink {",
 "	color: [[ColorPalette::TertiaryMid]];",
 "}",
 "",
 "/* a little bit of extra whitespace */",
 ".viewer {",
 "	padding-bottom:3px;",
 "}",
 "",
 "/* don't want any background color for headings */",
 "h1,h2,h3,h4,h5,h6 {",
 "	background: [[ColorPalette::Background]];",
 "	color: [[ColorPalette::Foreground]];",
 "}",
 "",
 "/* give tiddlers 3d style border and explicit background */",
 ".tiddler {",
 "	background: [[ColorPalette::Background]];",
 "	border-right: 2px [[ColorPalette::TertiaryMid]] solid;",
 "	border-bottom: 2px [[ColorPalette::TertiaryMid]] solid;",
 "	margin-bottom: 1em;",
 "	padding:1em 2em 2em 1.5em;",
 "}",
 "",
 "/* make options slider look nicer */",
 "#sidebarOptions .sliderPanel {",
 "	border:solid 1px [[ColorPalette::PrimaryLight]];",
 "}",
 "",
 "/* the borders look wrong with the body background */",
 "#sidebar .button {",
 "	border-style: none;",
 "}",
 "",
 "/* this means you can put line breaks in SidebarOptions for readability */",
 "#sidebarOptions br {",
 "	display:none;",
 "}",
 "/* undo the above in OptionsPanel */",
 "#sidebarOptions .sliderPanel br {",
 "	display:inline;",
 "}",
 "",
 "/* horizontal main menu stuff */",
 "#displayArea {",
 "	margin: 1em 15.7em 0em 1em; /* use the freed up space */",
 "}",
 "#topMenu br {",
 "	display: none;",
 "}",
 "#topMenu {",
 "	background: [[ColorPalette::PrimaryMid]];",
 "	color:[[ColorPalette::PrimaryPale]];",
 "}",
 "#topMenu {",
 "	padding:2px;",
 "}",
 "#topMenu .button, #topMenu .tiddlyLink, #topMenu a {",
 "	margin-left: 0.5em;",
 "	margin-right: 0.5em;",
 "	padding-left: 3px;",
 "	padding-right: 3px;",
 "	color: [[ColorPalette::PrimaryPale]];",
 "	font-size: 115%;",
 "}",
 "#topMenu .button:hover, #topMenu .tiddlyLink:hover {",
 "	background: [[ColorPalette::PrimaryDark]];",
 "}",
 "",
 "/* make 2.2 act like 2.1 with the invisible buttons */",
 ".toolbar {",
 "	visibility:hidden;",
 "}",
 ".selected .toolbar {",
 "	visibility:visible;",
 "}",
 "",
 "/* experimental. this is a little borked in IE7 with the button ",
 " * borders but worth it I think for the extra screen realestate */",
 ".toolbar { float:right; }",
 "",
 "/* Tagger Plugin users uncomment this.  from sb56637 */",
 "/*",
 ".popup li a {",
 "   display:inline;",
 "}",
 "*/",
 "",
 "/* make it print a little cleaner */",
 "@media print {",
 "	#topMenu {",
 "		display: none ! important;",
 "	}",
 "	/* not sure if we need all the importants */",
 "	.tiddler {",
 "		border-style: none ! important;",
 "		margin:0px ! important;",
 "		padding:0px ! important;",
 "		padding-bottom:2em ! important;",
 "	}",
 "	.tagglyTagging .button, .tagglyTagging .hidebutton {",
 "		display: none ! important;",
 "	}",
 "	.headerShadow {",
 "		visibility: hidden ! important;",
 "	}",
 "	.tagglyTagged .quickopentag, .tagged .quickopentag {",
 "		border-style: none ! important;",
 "	}",
 "	.quickopentag a.button, .miniTag {",
 "		display: none ! important;",
 "	}",
 "}",
 "/*}}}*/"
].join("\n"),

'MptwViewTemplate':[
 "<!--{{{-->",
 "<!--- http://mptw.tiddlyspot.com/#MptwViewTemplate ($Rev: 2247 $) --->",
 "",
 "<div class='toolbar'>",
 "	<span macro=\"showWhenTagged systemConfig\">",
 "		<span macro=\"toggleTag systemConfigDisable . '[[disable|systemConfigDisable]]'\"></span>",
 "	</span>",
 "	<span macro=\"showWhenTagged palette\">",
 "		<span macro=\"setPalette\"></span>",
 "	</span>",
 "	<span style=\"padding:1em;\"></span>",
 "	<span macro='toolbar closeTiddler closeOthers +editTiddler deleteTiddler > fields syncing permalink references jump'></span> <span macro='newHere label:\"new here\"'></span>",
 "	<span macro='newJournalHere {{config.mptwJournalFormat?config.mptwJournalFormat:\"MM/0DD/YY\"}}'></span>",
 "</div>",
 "",
 "<div class=\"tagglyTagged\" macro=\"tags\"></div>",
 "",
 "<div class='titleContainer'>",
 "	<span class='title' macro='view title'></span>",
 "	<span macro=\"miniTag\"></span>",
 "</div>",
 "",
 "<div class='subtitle'>",
 "	<span macro='view modifier link'></span>,",
 "	<span macro='view modified date {{config.mptwDateFormat?config.mptwDateFormat:\"MM/0DD/YY\"}}'></span>",
 "	(<span macro='message views.wikified.createdPrompt'></span>",
 "	<span macro='view created date {{config.mptwDateFormat?config.mptwDateFormat:\"MM/0DD/YY\"}}'></span>)",
 "</div>",
 "",
 "<div macro=\"showWhenExists ViewPanelTemplate\">[[ViewPanelTemplate]]</div>",
 "",
 "<div macro=\"hideWhen tiddler.tags.containsAny(['css','html','pre','systemConfig']) && !tiddler.text.match('{{'+'{')\">",
 "	<div class='viewer' macro='view text wikified'></div>",
 "</div>",
 "<div macro=\"showWhen tiddler.tags.containsAny(['css','html','pre','systemConfig']) && !tiddler.text.match('{{'+'{')\">",
 "	<div class='viewer'><pre macro='view text'></pre></div>",
 "</div>",
 "",
 "<div macro=\"showWhenExists ViewDashboardTemplate\">[[ViewDashboardTemplate]]</div>",
 "",
 "<div class=\"tagglyTagging\" macro=\"tagglyTagging\"></div>",
 "",
 "<!--}}}-->"
].join("\n")

});
//}}}
/*{{{*/
/* http://mptw.tiddlyspot.com/#MptwStyleSheet ($Rev: 2720 $) */

/* a contrasting background so I can see where one tiddler ends and the other begins */
body {
	background: [[ColorPalette::TertiaryLight]];
}

/* sexy colours and font for the header */
.headerForeground {
	color: [[ColorPalette::PrimaryPale]];
}
.headerShadow, .headerShadow a {
	color: [[ColorPalette::PrimaryMid]];
}

/* separate the top menu parts */
.headerForeground, .headerShadow {
	padding: 1em 1em 0;
}

.headerForeground, .headerShadow {
	font-family: 'Trebuchet MS' sans-serif;
	font-weight:bold;
}
.headerForeground .siteSubtitle {
	color: [[ColorPalette::PrimaryLight]];
}
.headerShadow .siteSubtitle {
	color: [[ColorPalette::PrimaryMid]];
}

/* make shadow go and down right instead of up and left */
.headerShadow {
	left: 1px;
	top: 1px;
}

/* prefer monospace for editing */
.editor textarea, .editor input {
	font-family: 'Consolas' monospace;
	background-color:[[ColorPalette::TertiaryPale]];
}


/* sexy tiddler titles */
.title {
	font-size: 200%;
	color: [[ColorPalette::PrimaryLight]];
	font-family: 'Trebuchet MS' sans-serif;
}

/* more subtle tiddler subtitle */
.subtitle {
	padding:0px;
	margin:0px;
	padding-left:0.5em;
	font-size: 90%;
	color: [[ColorPalette::TertiaryMid]];
}
.subtitle .tiddlyLink {
	color: [[ColorPalette::TertiaryMid]];
}

/* a little bit of extra whitespace */
.viewer {
	padding-bottom:3px;
}

/* don't want any background color for headings */
h1,h2,h3,h4,h5,h6 {
	background: [[ColorPalette::Background]];
	color: [[ColorPalette::Foreground]];
}

/* give tiddlers 3d style border and explicit background */
.tiddler {
	background: [[ColorPalette::Background]];
	border-right: 2px [[ColorPalette::TertiaryMid]] solid;
	border-bottom: 2px [[ColorPalette::TertiaryMid]] solid;
	margin-bottom: 1em;
	padding:1em 2em 2em 1.5em;
}

/* make options slider look nicer */
#sidebarOptions .sliderPanel {
	border:solid 1px [[ColorPalette::PrimaryLight]];
}

/* the borders look wrong with the body background */
#sidebar .button {
	border-style: none;
}

/* this means you can put line breaks in SidebarOptions for readability */
#sidebarOptions br {
	display:none;
}
/* undo the above in OptionsPanel */
#sidebarOptions .sliderPanel br {
	display:inline;
}

/* horizontal main menu stuff */
#displayArea {
	margin: 1em 15.7em 0em 1em; /* use the freed up space */
}
#topMenu br {
	display: none;
}
#topMenu {
	background: [[ColorPalette::PrimaryMid]];
	color:[[ColorPalette::PrimaryPale]];
}
#topMenu {
	padding:2px;
}
#topMenu .button, #topMenu .tiddlyLink, #topMenu a {
	margin-left: 0.5em;
	margin-right: 0.5em;
	padding-left: 3px;
	padding-right: 3px;
	color: [[ColorPalette::PrimaryPale]];
	font-size: 115%;
}
#topMenu .button:hover, #topMenu .tiddlyLink:hover {
	background: [[ColorPalette::PrimaryDark]];
}

/* make 2.2 act like 2.1 with the invisible buttons */
.toolbar {
	visibility:hidden;
}
.selected .toolbar {
	visibility:visible;
}

/* experimental. this is a little borked in IE7 with the button 
 * borders but worth it I think for the extra screen realestate */
.toolbar { float:right; }

/* Tagger Plugin users uncomment this.  from sb56637 */
/*
.popup li a {
   display:inline;
}
*/

/* make it print a little cleaner */
@media print {
	#topMenu {
		display: none ! important;
	}
	/* not sure if we need all the importants */
	.tiddler {
		border-style: none ! important;
		margin:0px ! important;
		padding:0px ! important;
		padding-bottom:2em ! important;
	}
	.tagglyTagging .button, .tagglyTagging .hidebutton {
		display: none ! important;
	}
	.headerShadow {
		visibility: hidden ! important;
	}
	.tagglyTagged .quickopentag, .tagged .quickopentag {
		border-style: none ! important;
	}
	.quickopentag a.button, .miniTag {
		display: none ! important;
	}
}
/*}}}*/
For upgrading directly from tiddlyspot. See [[ImportTiddlers]].
URL: /proxy/mptw.tiddlyspot.com/upgrade.html
For upgrading. See [[ImportTiddlers]].
URL: http://mptw.tiddlyspot.com/upgrade.html
<!--{{{-->
<!--- http://mptw.tiddlyspot.com/#MptwViewTemplate ($Rev: 2247 $) --->

<div class='toolbar'>
	<span macro="showWhenTagged systemConfig">
		<span macro="toggleTag systemConfigDisable . '[[disable|systemConfigDisable]]'"></span>
	</span>
	<span macro="showWhenTagged palette">
		<span macro="setPalette"></span>
	</span>
	<span style="padding:1em;"></span>
	<span macro='toolbar closeTiddler closeOthers +editTiddler copyTiddler deleteTiddler > fields syncing permalink references jump'></span> <span macro='newHere label:"new here" '></span>
<span macro='newJournalHere {{config.mptwJournalFormat?config.mptwJournalFormat:"MM/0DD/YY"}}'></span>
<span macro ='newDocument label:print nofile print here'></span>
</div>
<br></br>
<div class="tagglyTagged" macro="tags"></div>

<div class='titleContainer'>
	<span class='title' macro='view title'></span>
	<span macro="miniTag"></span>
</div>

<div class='subtitle'>
	<span macro='view modifier link'></span>,
	<span macro='view modified date {{config.mptwDateFormat?config.mptwDateFormat:"MM/0DD/YY"}}'></span>
	(<span macro='message views.wikified.createdPrompt'></span>
	<span macro='view created date {{config.mptwDateFormat?config.mptwDateFormat:"MM/0DD/YY"}}'></span>)
</div>

<div macro="showWhenExists ViewPanelTemplate">[[ViewPanelTemplate]]</div>

<div macro="hideWhen tiddler.tags.containsAny(['css','html','pre','systemConfig']) && !tiddler.text.match('{{'+'{')">
	<div class='viewer' macro='view text wikified'></div>
</div>
<div macro="showWhen tiddler.tags.containsAny(['css','html','pre','systemConfig']) && !tiddler.text.match('{{'+'{')">
	<div class='viewer'><pre macro='view text'></pre></div>
</div>

<div macro="showWhenExists ViewDashboardTemplate">[[ViewDashboardTemplate]]</div>
<div macro="showWhenExists ReferencesViewTemplate">[[ReferencesViewTemplate]]</div>

<div class="tagglyTagging" macro="tagglyTagging"></div>

<!--}}}-->
{{{
var myFirstJSON = { "firstName" : "John",
                    "lastName"  : "Doe",
                    "age"       : 23 };

document.write(myFirstJSON["firstName"]);  // Outputs John
document.write(myFirstJSON["lastName"]);   // Outputs Doe
document.write(myFirstJSON["age"]);        // Outputs 23
}}}
Output:

<script>
var myFirstJSON = { "firstName" : "John",
                    "lastName"  : "Doe",
                    "age"       : 23 };

document.write(myFirstJSON["firstName"]);  // Outputs John
document.write(myFirstJSON["lastName"]);   // Outputs Doe
document.write(myFirstJSON["age"]);        // Outputs 23
</script>

Idea: http://www.hunlock.com/blogs/Mastering_JSON_%28_JavaScript_Object_Notation_%29
/***
|Name|MyHelloWorldMacro|
|Version|1.0.3|
|Requires|~TW2.x|


!Code
***/
//{{{

// this part is not actually required but useful to other people using your plugin
version.extensions.HelloWorldMacro = { major: 1, minor: 0, revision: 3, date: new Date(2006,3,3),
 source: "http://simonbaird.com/mptw/#HelloWorldMacro"
};

config.macros.MyhelloWorld = {
	label: "MyhelloWorld",
	prompt: "This will send a message" 
};
config.macros.MyhelloWorld.handler = function (place,macroName,params,wikifier,paramString,tiddler) {
	var who = params.length > 0 ? params[0] : "world";

	wikify("Hello //" + who + "// from the '" + macroName + "' macro in tiddler [[" + tiddler.title + "]].", place);
wikify("<html><input name=userName type=text/></html>",place);
}

// a one liner...
config.macros.Myshout = { 
	handler: function(place,name,params) { 
		wikify("//''@@font-size:5em;color:#696;"+ params[0] + "!@@''//", place); 
	} 
};


//}}}

/***

!Another example
{{{<<Myshout Yeah>>}}}


<<Myshout Yeah>>

<<MyhelloWorld>>


***/
http://www.giffmex.org/emptynotestw.html
/***
''NestedSlidersPlugin for TiddlyWiki version 1.2.x and 2.0''
^^author: Eric Shulman
source: http://www.TiddlyTools.com/#NestedSlidersPlugin
license: [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]^^

Quickly make any tiddler content into an expandable 'slider' panel, without needing to create a separate tiddler to contain the slider content.  Optional syntax allows ''default to open'', ''custom button label/tooltip'' and ''automatic blockquote formatting.''

You can also 'nest' these sliders as deep as you like (see complex nesting example below), so that expandable 'tree-like' hierarchical displays can be created.  This is most useful when converting existing in-line text content to create in-line annotations, footnotes, context-sensitive help, or other subordinate information displays.

For more details, please click on a section headline below:
++++!!!!![Configuration]>
Debugging messages for 'lazy sliders' deferred rendering:
<<option chkDebugLazySliderDefer>> show debugging alert when deferring slider rendering
<<option chkDebugLazySliderRender>> show debugging alert when deferred slider is actually rendered
===
++++!!!!![Usage]>
When installed, this plugin adds new wiki syntax for embedding 'slider' panels directly into tiddler content.  Use {{{+++}}} and {{{===}}} to delimit the slider content.  Additional optional syntax elements let you specify
*default to open
*cookiename
*heading level
*floater (with optional CSS width value)
*mouse auto rollover
*custom label/tooltip/accesskey
*automatic blockquote
*deferred rendering
The complete syntax, using all options, is:
//{{{
++++(cookiename)!!!!!^width^*[label=key|tooltip]>...
content goes here
===
//}}}
where:
* {{{+++}}} (or {{{++++}}}) and {{{===}}}^^
marks the start and end of the slider definition, respectively.  When the extra {{{+}}} is used, the slider will be open when initially displayed.^^
* {{{(cookiename)}}}^^
saves the slider opened/closed state, and restores this state whenever the slider is re-rendered.^^
* {{{!}}} through {{{!!!!!}}}^^
displays the slider label using a formatted headline (Hn) style instead of a button/link style^^
* {{{^width^}}} (or just {{{^}}})^^
makes the slider 'float' on top of other content rather than shifting that content downward.  'width' must be a valid CSS value (e.g., "30em", "180px", "50%", etc.).  If omitted, the default width is "auto" (i.e., fit to content)^^
* {{{*}}}^^
automatically opens/closes slider on "rollover" as well as when clicked^^
* {{{[label=key|tooltip]}}}^^
uses custom label/tooltip/accesskey.  {{{=key}}} and {{{|tooltip}}} are optional.  'key' is must be a ''single letter only''.  Default labels/tootips are: ">" (more) and "<" (less), with no default access key assignment.^^
* {{{">"}}} //(without the quotes)//^^
automatically adds blockquote formatting to slider content^^
* {{{"..."}}} //(without the quotes)//^^
defers rendering of closed sliders until the first time they are opened.  //Note: deferred rendering may produce unexpected results in some cases.  Use with care.//^^

//Note: to make slider definitions easier to read and recognize when editing a tiddler, newlines immediately following the {{{+++}}} 'start slider' or preceding the {{{===}}} 'end slider' sequence are automatically supressed so that excess whitespace is eliminated from the output.//
===
++++!!!!![Examples]>
simple in-line slider: 
{{{
+++
   content
===
}}}
+++
   content
===
----
use a custom label and tooltip: 
{{{
+++[label|tooltip]
   content
===
}}}
+++[label|tooltip]
   content
===
----
content automatically blockquoted: 
{{{
+++>
   content
===
}}}
+++>
   content
===
----
all options combined //(default open, cookie, heading, sized floater, rollover, label/tooltip/key, blockquoted, deferred)//
{{{
++++(testcookie)!!!^30em^*[label=Z|click or press Alt-Z to open]>...
   content
===
}}}
++++(testcookie)!!!^30em^*[label=Z|click or press Alt-Z to open]>...
   content
===
----
complex nesting example:
{{{
+++^[get info...=I|click for information or press Alt-I]
   put some general information here, plus a floating slider with more specific info:
   +++^10em^[view details...|click for details]
      put some detail here, which could include a rollover with a +++^25em^*[glossary definition]explaining technical terms===
   ===
===
}}}
+++^[get info...=I|click for information or press Alt-I]
   put some general information here, plus a floating slider with more specific info:
   +++^10em^[view details...|click for details]
      put some detail here, which could include a rollover with a +++^25em^*[glossary definition]explaining technical terms===
   ===
===
----
nested floaters
>menu: <<tiddler NestedSlidersExample>>
(see [[NestedSlidersExample]] for definition)
----
===
!!!!!Installation
<<<
import (or copy/paste) the following tiddlers into your document:
''NestedSlidersPlugin'' (tagged with <<tag systemConfig>>)
<<<
!!!!!Revision History
<<<
''2006.05.11 - 1.9.0'' added optional '^width^' syntax for floating sliders and '=key' syntax for setting an access key on a slider label
''2006.05.09 - 1.8.0'' in onClickNestedSlider(), when showing panel, set focus to first child input/textarea/select element
''2006.04.24 - 1.7.8'' in adjustSliderPos(), if floating panel is contained inside another floating panel, subtract offset of containing panel to find correct position
''2006.02.16 - 1.7.7'' corrected deferred rendering to account for use-case where show/hide state is tracked in a cookie
''2006.02.15 - 1.7.6'' in adjustSliderPos(), ensure that floating panel is positioned completely within the browser window (i.e., does not go beyond the right edge of the browser window)
''2006.02.04 - 1.7.5'' add 'var' to unintended global variable declarations to avoid FireFox 1.5.0.1 crash bug when assigning to globals
''2006.01.18 - 1.7.4'' only define adjustSliderPos() function if it has not already been provided by another plugin.  This lets other plugins 'hijack' the function even when they are loaded first.
''2006.01.16 - 1.7.3'' added adjustSliderPos(place,btn,panel,panelClass) function to permit specialized logic for placement of floating panels.  While it provides improved placement for many uses of floating panels, it exhibits a relative offset positioning error when used within *nested* floating panels.  Short-term workaround is to only adjust the position for 'top-level' floaters.
''2006.01.16 - 1.7.2'' added button property to slider panel elements so that slider panel can tell which button it belongs to.  Also, re-activated and corrected animation handling so that nested sliders aren't clipped by hijacking Slider.prototype.stop so that "overflow:hidden" can be reset to "overflow:visible" after animation ends
''2006.01.14 - 1.7.1'' added optional "^" syntax for floating panels.  Defines new CSS class, ".floatingPanel", as an alternative for standard in-line ".sliderPanel" styles.
''2006.01.14 - 1.7.0'' added optional "*" syntax for rollover handling to show/hide slider without requiring a click (Based on a suggestion by tw4efl)
''2006.01.03 - 1.6.2'' When using optional "!" heading style, instead of creating a clickable "Hn" element, create an "A" element inside the "Hn" element.  (allows click-through in SlideShowPlugin, which captures nearly all click events, except for hyperlinks)
''2005.12.15 - 1.6.1'' added optional "..." syntax to invoke deferred ('lazy') rendering for initially hidden sliders
removed checkbox option for 'global' application of lazy sliders
''2005.11.25 - 1.6.0'' added optional handling for 'lazy sliders' (deferred rendering for initially hidden sliders)
''2005.11.21 - 1.5.1'' revised regular expressions: if present, a single newline //preceding// and/or //following// a slider definition will be suppressed so start/end syntax can be place on separate lines in the tiddler 'source' for improved readability.  Similarly, any whitespace (newlines, tabs, spaces, etc.) trailing the 'start slider' syntax or preceding the 'end slider' syntax is also suppressed.
''2005.11.20 - 1.5.0'' added (cookiename) syntax for optional tracking and restoring of slider open/close state
''2005.11.11 - 1.4.0'' added !!!!! syntax to render slider label as a header (Hn) style instead of a button/link style
''2005.11.07 - 1.3.0'' removed alternative syntax {{{(((}}} and {{{)))}}} (so they can be used by other
formatting extensions) and simplified/improved regular expressions to trim multiple excess newlines
''2005.11.05 - 1.2.1'' changed name to NestedSlidersPlugin
more documentation
''2005.11.04 - 1.2.0'' added alternative character-mode syntax {{{(((}}} and {{{)))}}}
tweaked "eat newlines" logic for line-mode {{{+++}}} and {{{===}}} syntax
''2005.11.03 - 1.1.1'' fixed toggling of default tooltips ("more..." and "less...") when a non-default button label is used
code cleanup, added documentation
''2005.11.03 - 1.1.0'' changed delimiter syntax from {{{(((}}} and {{{)))}}} to {{{+++}}} and {{{===}}}
changed name to EasySlidersPlugin
''2005.11.03 - 1.0.0'' initial public release
<<<
!!!!!Credits
<<<
This feature was implemented by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]] with initial research and suggestions from RodneyGomes, GeoffSlocock, and PaulPetterson.
<<<
!!!!!Code
***/
//{{{
version.extensions.nestedSliders = {major: 1, minor: 9, revision: 0, date: new Date(2006,5,11)};
//}}}

//{{{
// options for deferred rendering of sliders that are not initially displayed
if (config.options.chkDebugLazySliderDefer==undefined) config.options.chkDebugLazySliderDefer=false;
if (config.options.chkDebugLazySliderRender==undefined) config.options.chkDebugLazySliderRender=false;

// default styles for 'floating' class
setStylesheet(".floatingPanel { position:absolute; z-index:10; padding:0.5em; margin:0em; \
	background-color:#eee; color:#000; border:1px solid #000; text-align:left; }","floatingPanelStylesheet");
//}}}

//{{{
config.formatters.push( {
	name: "nestedSliders",
	match: "\\n?\\+{3}",
	terminator: "\\s*\\={3}\\n?",
	lookahead: "\\n?\\+{3}(\\+)?(\\([^\\)]*\\))?(\\!*)?(\\^(?:[^\\^\\*\\[\\>]*\\^)?)?(\\*)?(\\[[^\\]]*\\])?(\\>)?(\\.\\.\\.)?\\s*",
	handler: function(w)
		{
			var lookaheadRegExp = new RegExp(this.lookahead,"mg");
			lookaheadRegExp.lastIndex = w.matchStart;
			var lookaheadMatch = lookaheadRegExp.exec(w.source)
			if(lookaheadMatch && lookaheadMatch.index == w.matchStart)
			{
				// location for rendering button and panel
				var place=w.output;

				// default to closed, no cookie, no accesskey
				var show="none"; var title=">"; var tooltip="show"; var cookie=""; var key="";

				// extra "+", default to open
				if (lookaheadMatch[1])
					{ show="block"; title="<"; tooltip="hide"; }

				// cookie, use saved open/closed state
				if (lookaheadMatch[2]) {
					cookie=lookaheadMatch[2].trim().slice(1,-1);
					cookie="chkSlider"+cookie;
					if (config.options[cookie]==undefined)
						{ config.options[cookie] = (show=="block") }
					if (config.options[cookie])
						{ show="block"; title="<"; tooltip="hide"; }
					else
						{ show="none"; title=">"; tooltip="show"; }
				}

				// parse custom label/tooltip/accesskey: [label=X|tooltip]
				if (lookaheadMatch[6]) {
					title = lookaheadMatch[6].trim().slice(1,-1);
					var pos=title.indexOf("|");
					if (pos!=-1) { tooltip = title.substr(pos+1,title.length); title=title.substr(0,pos); }
					if (title.substr(title.length-2,1)=="=") { key=title.substr(title.length-1,1); title=title.slice(0,-2); }
					if (pos==-1) tooltip += " "+title; // default tooltip: "show/hide <title>"
				}

				// create the button
				if (lookaheadMatch[3]) { // use "Hn" header format instead of button/link
					var lvl=(lookaheadMatch[3].length>6)?6:lookaheadMatch[3].length;
					var btn = createTiddlyElement(createTiddlyElement(place,"h"+lvl,null,null,null),"a",null,null,title);
					btn.onclick=onClickNestedSlider;
					btn.setAttribute("href","javascript:;");
					btn.setAttribute("title",tooltip);
				}
				else
					var btn = createTiddlyButton(place,title,tooltip,onClickNestedSlider);
				btn.sliderCookie = cookie; // save the cookiename (if any) in the button object
				btn.keyparam=key; // save the access key letter ("" if none)
				if (key.length) {
					btn.setAttribute("accessKey",key); // init access key
					btn.onfocus=function(){this.setAttribute("accessKey",this.keyparam);}; // **reclaim** access key on focus
				}

				// "non-click" MouseOver open/close slider
				if (lookaheadMatch[5]) btn.onmouseover=onClickNestedSlider;

				// create slider panel
				var panelClass=lookaheadMatch[4]?"floatingPanel":"sliderPanel";
				var panel=createTiddlyElement(place,"div",null,panelClass,null);
				panel.style.display = show;
				if (lookaheadMatch[4] && lookaheadMatch[4].length>2) panel.style.width=lookaheadMatch[4].slice(1,-1); // custom width
				panel.button = btn; // so the slider panel know which button it belongs to
				btn.sliderPanel=panel;

				// render slider (or defer until shown) 
				w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
				if ((show=="block")||!lookaheadMatch[8]) {
					// render now if panel is supposed to be shown or NOT deferred rendering
					w.subWikify(lookaheadMatch[7]?createTiddlyElement(panel,"blockquote"):panel,this.terminator);
					// align slider/floater position with button
					adjustSliderPos(place,btn,panel,panelClass);
				}
				else {
					var src = w.source.substr(w.nextMatch);
					var endpos=findMatchingDelimiter(src,"+++","===");
					panel.setAttribute("raw",src.substr(0,endpos));
					panel.setAttribute("blockquote",lookaheadMatch[7]?"true":"false");
					panel.setAttribute("rendered","false");
					w.nextMatch += endpos+3;
					if (w.source.substr(w.nextMatch,1)=="\n") w.nextMatch++;
					if (config.options.chkDebugLazySliderDefer) alert("deferred '"+title+"':\n\n"+panel.getAttribute("raw"));
				}
			}
		}
	}
)

// TBD: ignore 'quoted' delimiters (e.g., "{{{+++foo===}}}" isn't really a slider)
function findMatchingDelimiter(src,starttext,endtext) {
	var startpos = 0;
	var endpos = src.indexOf(endtext);
	// check for nested delimiters
	while (src.substring(startpos,endpos-1).indexOf(starttext)!=-1) {
		// count number of nested 'starts'
		var startcount=0;
		var temp = src.substring(startpos,endpos-1);
		var pos=temp.indexOf(starttext);
		while (pos!=-1)  { startcount++; pos=temp.indexOf(starttext,pos+starttext.length); }
		// set up to check for additional 'starts' after adjusting endpos
		startpos=endpos+endtext.length;
		// find endpos for corresponding number of matching 'ends'
		while (startcount && endpos!=-1) {
			endpos = src.indexOf(endtext,endpos+endtext.length);
			startcount--;
		}
	}
	return (endpos==-1)?src.length:endpos;
}
//}}}

//{{{
window.onClickNestedSlider=function(e)
{
	if (!e) var e = window.event;
	var theTarget = resolveTarget(e);
	var theLabel = theTarget.firstChild.data;
	var theSlider = theTarget.sliderPanel
	var isOpen = theSlider.style.display!="none";
	// if using default button labels, toggle labels
	if (theLabel==">") theTarget.firstChild.data = "<";
	else if (theLabel=="<") theTarget.firstChild.data = ">";
	// if using default tooltips, toggle tooltips
	if (theTarget.getAttribute("title")=="show")
		theTarget.setAttribute("title","hide");
	else if (theTarget.getAttribute("title")=="hide")
		theTarget.setAttribute("title","show");
	if (theTarget.getAttribute("title")=="show "+theLabel)
		theTarget.setAttribute("title","hide "+theLabel);
	else if (theTarget.getAttribute("title")=="hide "+theLabel)
		theTarget.setAttribute("title","show "+theLabel);
	// deferred rendering (if needed)
	if (theSlider.getAttribute("rendered")=="false") {
		if (config.options.chkDebugLazySliderRender)
			alert("rendering '"+theLabel+"':\n\n"+theSlider.getAttribute("raw"));
		var place=theSlider;
		if (theSlider.getAttribute("blockquote")=="true")
			place=createTiddlyElement(place,"blockquote");
		wikify(theSlider.getAttribute("raw"),place);
		theSlider.setAttribute("rendered","true");
	}
	// show/hide the slider
	if(config.options.chkAnimate)
		anim.startAnimating(new Slider(theSlider,!isOpen,e.shiftKey || e.altKey,"none"));
	else
		theSlider.style.display = isOpen ? "none" : "block";
	// if showing panel, set focus to first 'focus-able' element in panel
	if (theSlider.style.display!="none") {
		var ctrls=theSlider.getElementsByTagName("*");
		for (var c=0; c<ctrls.length; c++) {
			var t=ctrls[c].tagName.toLowerCase();
			if (t=="input" || t=="textarea" || t=="select")
				{ ctrls[c].focus(); break; }
		}
	}
	if (this.sliderCookie && this.sliderCookie.length)
		{ config.options[this.sliderCookie]=!isOpen; saveOptionCookie(this.sliderCookie); }
	// align slider/floater position with target button
	adjustSliderPos(theSlider.parentNode,theTarget,theSlider,theSlider.className);
	return false;
}

// hijack animation handler 'stop' handler so overflow is visible after animation has completed
Slider.prototype.coreStop = Slider.prototype.stop;
Slider.prototype.stop = function() { this.coreStop(); this.element.style.overflow = "visible"; }

// adjust panel position based on button position
if (window.adjustSliderPos==undefined) window.adjustSliderPos=function(place,btn,panel,panelClass) {
	if (panelClass=="floatingPanel") {
		var left=0;
		var top=btn.offsetHeight; 
		if (place.style.position!="relative") {
			var left=findPosX(btn);
			var top=findPosY(btn)+btn.offsetHeight;
			var p=place; while (p && p.className!='floatingPanel') p=p.parentNode;
			if (p) { left-=findPosX(p); top-=findPosY(p); }
		}
		if (left+panel.offsetWidth > getWindowWidth()) left=getWindowWidth()-panel.offsetWidth-10;
		panel.style.left=left+"px"; panel.style.top=top+"px";
	}
}

function getWindowWidth() {
	if(document.width!=undefined)
		return document.width; // moz (FF)
	if(document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) )
		return document.documentElement.clientWidth; // IE6
	if(document.body && ( document.body.clientWidth || document.body.clientHeight ) )
		return document.body.clientWidth; // IE4
	if(window.innerWidth!=undefined)
		return window.innerWidth; // IE - general
	return 0; // unknown
}
//}}}
{{new{''<<newTiddler label:'New dropdown record' title:'dropdown record' text:{{"<<formTiddler DropdownTemplate\>\>"}} tag: dropdown >>''}}}
<<newTiddler label:'New Table' title:'New Table' text:{{"<<formTiddler addRowsTemplate\>\>"}} tag: testing >>
<<formTiddler addRowsTemplate>>
{{niceTable{
|!Title/link|[[TW Help|http://twhelp.tiddlyspot.com]]|
|!Creator|Morris Gray|
|!Subject matter|Tutorial|
|!Description/notes|A beginners to intermedate level help file|
|!Screenshot|[img[http://www.giffmex.org/twinactionimgs/twhelp.png]]|
}}}
<<newTiddler label:"new task" title:NewTask tag:task text:"Type some text and then press DONE to view the task controls" >><data>{}</data>
<<newTiddler label:"new task 2" title:NewTask2 tag:task2 text:"Type some text and then press DONE to view the task controls" >><data>{}</data>
<<tiddler showLink>>
<code>
<select size=1 name='sys_opts' style='width:100%;font-size:%fontsize%;' \
 onchange='this.form.config_view.value=this.value'> \
 <option value=\"\">config.options.*</option> </select> \

<select size=1 name='sys_macros' style='width:25%;font-size:%fontsize%;' \
 onchange='this.form.sysview.style.display=\"block\"; this.form.%id%_sysview.value=this.value'> \
 <option value=\"\">macros...</option> </select>\

 <select size=1 name='sys_commands' style='width:25%;font-size:%fontsize%;' \
 onchange='this.form.sysview.style.display=\"block\"; this.form.%id%_sysview.value=this.value'> \
 <option value=\"\">toolbars...</option>  </select> \
</code>
http://www.cs.utexas.edu/~joeraii/pytw/.htaccess
<<forEachTiddler
 where
 'tiddler.tags.contains("comboBox")'
 sortBy
 'tiddler.created'
 writeTtTaskLine
 'MasterTaskList'
>>
<<tiddler MiniBrowser with: 22>>
</select><span macro="dropdownSelect Frequency freq2"></span></td>
<code>
	params = paramString.parseParams("anon",null,true,false,false);
	var theList = createTiddlyElement(place,"ul");
	var title = getParam(params,"anon","");
	if(title && store.tiddlerExists(title))
		tiddler = store.getTiddler(title);
	var sep = getParam(params,"sep"," ");
	var lingo = config.views.wikified.tag;
	var prompt = tiddler.tags.length == 0 ? lingo.labelNoTags : lingo.labelTags;
</code>
<part Hobbies>test</part>

[[Hobbies|AboutMe/Hobbies]]
<<newTiddler label:'New code' title:'New Code' text:{{"<<formTiddler myCodeTemplate\>\>"}} tag: myCode>>
<<newTiddler label:"New dropdown Bookmarks 2" title:'New dropdown Bookmarks 2' tag:dropdownBookmarks2 text:"Type some text and then press DONE to view the task controls" >>
<data>{}</data>
/%
|Author|Alfonso Reyes|
|Type|script|
|Requires|InlineJavascriptPlugin|
|Overrides|None|
|Description|adds new item|

Usage: <<tiddler NewCheckboxGroup>>

%/<script label="new checkbox group">

 var tags = "[[checkboxGroup]]";

 var title = prompt("Please enter name for this item", "");
 if( (title == null) || (title == "") ){
 return;
 }//if

cmds = "<<formTiddler checkboxGroupTemplate>><data>{}</data><<myToday>>";
store.saveTiddler(title, title, cmds, config.options.txtUserName, new Date(), tags);
story.displayTiddler(null,title,DEFAULT_VIEW_TEMPLATE);
// add the tiddler title to the key field
//DataTiddler.setData(title,"StatusDefinitions","")
// refresh to reflect the added tiddler title to the key field
story.refreshTiddler(title,null,true);

</script>
/***
|Name|NewDocumentPlugin|
|Source|http://www.TiddlyTools.com/#NewDocumentPlugin|
|Version|1.7.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <<br>>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|Quickly create new TiddlyWiki documents from your existing document, with just one click|

Use the {{{<<newDocument>>}}} macro to place a "new document" link into your sidebar/mainmenu/any tiddler (wherever you like).  Select this command to automatically create a "new.html" document containing a specific set of tagged tiddlers.  Optional parameters let you specify an alternate path/filename for the new file, or different tags to match.  You can also indicate "ask" for either parameter, which will  trigger a prompt for input when the command is selected.

!!!!!Usage
<<<
{{{<<newDocument label:text prompt:text filename tag tag tag...>>}}}
{{{<<newDocument label:text prompt:text filename all>>}}}
{{{<<newDocument label:text prompt:text filename snap ID>>}}}
{{{<<newDocument label:text prompt:text filename snap here>>}}}
{{{<<newDocument label:text prompt:text nofile print ID>>}}}
{{{<<newDocument label:text prompt:text nofile print here>>}}}
 where:
* ''label:text'' defines //optional// alternative link text (replaces default "new document" display)
* ''prompt:text'' defines //optional// alternative tooltip text for 'mouseover' prompting (replaces default hard-coded tooltip text)
* ''filename'' is any local path-and-filename.  If no parameters are provided, the default is to create the file "new.html" in the current directory.  If a filename is provided without a path (i.e., there is no "/" in the input), then the current directory is also assumed.  Otherwise, this parameter is expected to contain the complete path and filename needed to write the file to your local hard disk.  If ''ask'' is used in place of the filename parameter then, when the command link is selected, a message box will be automatically displayed so you can select/enter the path and filename.
* ''tag tag tag...'' is a list of one or more space-separated tags (use quotes or {{{[[]]}}} around tags that contain spaces).  The new document will include all tiddlers that match at least one of the tags in the list.  The default is to include tiddlers tagged with <<tag includeNew>>.    The special value ''all'' may be used to match every tiddler (even those without tags).   If ''ask'' is used in place of the tags then, when the command link is selected, a message box will be automatically displayed so you can enter the desired tags at that time.
* When you use the keyword ''snap'' in place of the tags, you can generate a file containing the //rendered//  CSS-and-HTML that is currently being displayed in browser.  By default, the snapshop uses the 'contentWrapper' DOM element ID to automatically include all the TiddlyWiki elements, such as the sidebars and header, in addition to the center 'story' column containing the tiddler content.
* When you use the keyword ''print'' in place of the tags, a snapshot is generated, but the contents are not written to a file.  Instead, they are displayed in a separate browser tab/window, and the print dialog for that tab/window is automatically invoked.
* You can limit the snapshot to capture only a portion of the rendered TiddlyWiki elements by specifiying an optional alternate DOM element ID, such as "displayArea" (the entire center 'story' column) or even just a single tiddler (e.g., "tidderMyTiddlerTitle", assuming that "MyTiddlerTitle" is currently displayed).  Only the portions of the document that are contained //within// the specified DOM element will be transcribed to the resulting snapshot file.  If ''ask'' is used in place of a DOM element ID, you will be prompted to enter the ID (default is "contentWrapper") when the snapshot is being taken.  This allows you to easily enter the ID of any currently displayed tiddler to make quick snapshots of specific tiddlers.  If ''here'' is used in place of a DOM element ID, the current tiddler id is used.

Note: as of version 1.4.0 of this plugin, support for selecting tiddlers by using tag *expressions* has been replaced with simpler, more efficient "containsAny()" logic.  To create new ~TiddlyWiki documents that contain only those tiddlers selected with advanced AND/OR/NOT Boolean expressions, you can use the filtering features provided by the ExportTiddlersPlugin (see www.TiddlyTools.com/#ExportTiddlersPlugin).
<<<
!!!!!Examples:
<<<
{{{<<newDocument>>}}}
equivalent to {{{<<newDocument new.htm includeNew systemTiddlers>>}}}
creates default "new.html" containing tiddlers tagged with either<<tag includeNew>>or<<tag systemTiddlers>>
try it: <<newDocument>>

{{{<<newDocument empty.html systemTiddlers>>}}}
creates "empty.html" containing only tiddlers tagged with<<tag systemTiddlers>>
//(reproduces old-style (pre 2.0.2) empty file)//
try it: <<newDocument empty.html systemTiddlers>>

{{{<<newDocument "label:create Import/Export starter" ask importexport>>}}}
save importexport tiddlers to a new file, prompts for path/file
try it: <<newDocument "label:create Import/Export starter" ask importexport>>

{{{<<newDocument ask ask>>}}}
prompts for path/file, prompts for tags to match
try it: <<newDocument ask ask>>

{{{<<newDocument ask all>>}}}
save all current TiddlyWiki contents to a new file, prompts for path/file
try it: <<newDocument ask all>>

{{{<<newDocument ask snap>>}}}
generates snapshot of currently displayed document, prompts for path/file
try it: <<newDocument ask snap>>

{{{<<newDocument ask snap here>>}}}
generates snapshot of this tiddler ONLY, prompts for path/file
try it: <<newDocument ask snap here>>

{{{<<newDocument ask print here>>}}}
prints a snapshot of this tiddler ONLY
try it: <<newDocument nofile print here>>

<<<
!!!!!Installation
<<<
Import (or copy/paste) the following tiddlers into your document:
''NewDocumentPlugin'' (tagged with <<tag systemConfig>>)
<<<
!!!!!Revision History
<<<
''2007.03.30 [1.7.0]'' added support for "print" param as alternative for "snap".  When "print" is used, the filename is ignored and ouput is directed to another browser tab/window, where the print dialog is then automatically triggered.
''2007.03.30 [1.6.1]'' added support for "here" keyword for current tiddler elementID and "prompt:text" param for specifying tooltip text
''2007.02.12 [1.6.0]'' in onClickNewDocument(), reset HTML source 'markup'
''2006.10.23 [1.5.1]'' in onClickNewDocument(), get saved parameter value for snapID instead of using default "contentWrapper" (oops!)
''2006.10.18 [1.5.0]'' new optional param for 'snap'... specify alternative DOM element ID (default is still "contentWrapper").  Based on a suggestion from Xavier Verges.
''2006.08.03 [1.4.3]'' in promptForFilename(), for IE (WinXP only), added handling for UserAccounts.CommonDialog
''2006.07.29 [1.4.2]'' in onClickNewDocument(), okmsg display is now linked to newly created file
''2006.07.24 [1.4.1]'' in promptForFilename(), check for nsIFilePicker.returnCancel to allow nsIFilePicker.returnOK **OR** nsIFilePicker.returnReplace to be processed.
''2006.05.23 [1.4.0]'' due to very poor performance, support for tag *expressions* has been removed, in favor of a simpler "containsAny()" scan for tags.
''2006.04.09 [1.3.6]'' in onClickNewDocument, added call to convertUnicodeToUTF8() to better handle international characters.
''2006.03.15 [1.3.5]'' added nsIFilePicker() handler for selecting filename in moz-based browsers.  IE and other non-moz browsers still use simple prompt() dialog
''2006.03.15 [1.3.0]'' added "label:text" param for custom link text.  added special "all" filter parameter for "save as..." handling (writes all tiddlers to output file)
''2006.03.09 [1.2.0]'' added special "snap" filter parameter to generate and write "snapshot" files containing static HTML+CSS for currently rendered document.
''2006.02.24 [1.1.2]'' Fix incompatiblity with TW 2.0.5 by removing custom definition of getLocalPath() (which is now part of TW core)
''2006.02.03 [1.1.1]'' concatentate 'extra' params so that tag expressions don't have to be quoted.   moved all text to 'formatted' string definitions for easier translation.
''2006.02.03 [1.1.0]'' added support for tag EXPRESSIONS.  plus improved documentation and code cleanup
''2006.02.03 [1.0.0]'' Created.
<<<
!!!!!Credits
<<<
This feature was developed by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]]
<<<
!!!!!Code
***/
//{{{
version.extensions.newDocument = {major: 1, minor: 7, revision: 0, date: new Date(2007,3,30)};

config.macros.newDocument = {
	newlabel: "new document",
	newprompt: "Create a new TiddlyWiki 'starter' document",
	newdefault: "new.html",
	allparam: "all",
	saveaslabel: "save as...",
	saveasprompt: "Save current TiddlyWiki to a different file",
	printparam: "print",
	snapparam: "snap",
	snaplabel: "create a snapshot",
	snapprompt: "Create a 'snapshot' of the current TiddlyWiki display",
	snapdefault: "snapshot.html",
	snapID: "contentWrapper",
	snapIDprompt: "Please enter a DOM element ID for the desired content",
	snapIDerrmsg: "Unrecognized document element ID: '%0'",
	askparam: "ask",
	hereparam: "here",
	labelparam: "label:",
	promptparam: "prompt:",
	fileprompt: "Please enter a filename",
	filter: "includeNew",
	filterprompt: "Match one or more tags:\n(space-separated, use [[...]] around tags containing spaces)",
	filtererrmsg: "Error in tag filter '%0'",
	snapmsg: "Document snapshot written to %1",
	okmsg: "%0 tiddlers written to %1",
	failmsg: "An error occurred while creating %0"
};

config.macros.newDocument.handler = function(place,macroName,params) {

	var path=getLocalPath(document.location.href);
	var slashpos=path.lastIndexOf("/"); if (slashpos==-1) slashpos=path.lastIndexOf("\\"); 
	if (slashpos!=-1) path = path.substr(0,slashpos+1); // remove filename from path, leave the trailing slash

	if (params[0] && params[0].substr(0,config.macros.newDocument.labelparam.length)==config.macros.newDocument.labelparam)
		var label=params.shift().substr(config.macros.newDocument.labelparam.length)
	if (params[0] && params[0].substr(0,config.macros.newDocument.promptparam.length)==config.macros.newDocument.promptparam)
		var prompt=params.shift().substr(config.macros.newDocument.promptparam.length)
	var filename=params.shift(); if (!filename) filename=config.macros.newDocument.newdefault;
	if (params[0]==config.macros.newDocument.snapparam || params[0]==config.macros.newDocument.printparam) {
		var printmode=(params[0]==config.macros.newDocument.printparam);
		params.shift();
		if (!label) var label=config.macros.newDocument.snaplabel;
		if (!prompt) var prompt=config.macros.newDocument.snapprompt;
		var defaultfile=config.macros.newDocument.snapdefault;
		var snapID=config.macros.newDocument.snapID;// default to "contentWrapper"
		if (params[0]) var snapID=params.shift(); // alternate DOM element for snapshot
	}
	if (params[0]==config.macros.newDocument.allparam) {
		if (!label) var label=config.macros.newDocument.saveaslabel;
		if (!prompt) var prompt=config.macros.newDocument.saveasprompt;
		var defaultfile=getLocalPath(document.location.href);
		var slashpos=defaultfile.lastIndexOf("/"); if (slashpos==-1) slashpos=defaultfile.lastIndexOf("\\");
		if (slashpos!=-1) defaultfile=defaultfile.substr(slashpos+1); // get filename only
	}
	if (!prompt) var prompt=config.macros.newDocument.newprompt;
	if (!label) var label=config.macros.newDocument.newlabel;
	if (!defaultfile) var defaultfile=config.macros.newDocument.newdefault;

	var btn=createTiddlyButton(place,label,prompt,onClickNewDocument);
	btn.path=path;
	btn.file=filename;
	btn.defaultfile=defaultfile;
	btn.snapID=snapID; // NULL unless snapshot is being taken
	btn.printmode=printmode;
	btn.filter=params.length?params:[config.macros.newDocument.filter]; 
}

// IE needs explicit global scoping for functions called by browser events
window.onClickNewDocument=function(e)
{
	if (!e) var e = window.event; var btn=resolveTarget(e);

	// assemble document content, write file, report result
	var okmsg=config.macros.newDocument.okmsg;
	var failmsg=config.macros.newDocument.failmsg;
	var count=0;
	var out="";
	if (btn.snapID) { // HTML+CSS snapshot
		var snapID=btn.snapID;
		if (btn.snapID==config.macros.newDocument.askparam)
			snapID=prompt(config.macros.newDocument.snapIDprompt,config.macros.newDocument.snapID);
		if (btn.snapID==config.macros.newDocument.hereparam)
			{ var here=story.findContainingTiddler(btn); if (here) snapID=here.id; }
		if (!document.getElementById(snapID)) { // if specified element does not exist
			if (snapID) // ID=null if prompt was cancelled by user
				displayMessage(config.macros.newDocument.snapIDerrmsg.format([snapID]));
			e.cancelBubble = true; if (e.stopPropagation) e.stopPropagation(); return(false);
		}
		var styles=document.getElementsByTagName("style");
		out+="<html>\n<head>\n<style>\n";
		for(var i=0; i < styles.length; i++)
			out +="/* stylesheet from tiddler:"+styles[i].getAttribute("id")+" */\n"+styles[i].innerHTML+"\n\n";
		out+="</style>\n</head>\n<body>\n\n"+document.getElementById(snapID).innerHTML+"\n\n</body>\n</html>";
		okmsg=config.macros.newDocument.snapmsg;
	} else { // TW starter document
		// get the TiddlyWiki core code source
		var sourcefile=getLocalPath(document.location.href);
		var source=loadFile(sourcefile);
		if(source==null) { alert(config.messages.cantSaveError); return null; }
		// reset existing HTML source markup
		source=updateMarkupBlock(source,"PRE-HEAD");
		source=updateMarkupBlock(source,"POST-HEAD");
		source=updateMarkupBlock(source,"PRE-BODY");
		source=updateMarkupBlock(source,"POST-BODY");
		// find store area
		var posOpeningDiv=source.indexOf(startSaveArea);
		var posClosingDiv=source.lastIndexOf(endSaveArea);
		if((posOpeningDiv==-1)||(posClosingDiv==-1)) { alert(config.messages.invalidFileError.format([sourcefile])); return; }
		// get the matching tiddler divs
		var match=btn.filter;
		if (match[0]==config.macros.newDocument.askparam) { // ask user for tags
			var newfilt=prompt(config.macros.newDocument.filterprompt,config.macros.newDocument.filter);
			if (!newfilt) return;  // cancelled by user
			match=newfilt.readMacroParams();
		}
		var storeAreaDivs=[];
		var tiddlers=store.getTiddlers('title');
		for (var i=0; i<tiddlers.length; i++)
			if (match[0]==config.macros.newDocument.allparam || (tiddlers[i].tags && tiddlers[i].tags.containsAny(match)) )
				storeAreaDivs.push(tiddlers[i].saveToDiv());
		out+=source.substr(0,posOpeningDiv+startSaveArea.length);
		out+=convertUnicodeToUTF8(storeAreaDivs.join("\n"))+"\n\t\t";
		out+=source.substr(posClosingDiv);
		count=storeAreaDivs.length;
	}
	if (btn.printmode) {
		var win=window.open("","_blank","");
		win.document.open();
		win.document.writeln(out);
		win.document.close();
		win.focus(); // bring to front
		win.print(); // trigger print dialog
	} else {
		// get output path/filename
		var filename=btn.file;
		if (filename==config.macros.newDocument.askparam)
			filename=promptForFilename(config.macros.newDocument.fileprompt,btn.path,btn.defaultfile);
		if (!filename) return; // cancelled by user
		// if specified file does not include a path, assemble fully qualified path and filename
		var slashpos=filename.lastIndexOf("/"); if (slashpos==-1) slashpos=filename.lastIndexOf("\\");
		if (slashpos==-1) filename=btn.path+filename;
		var ok=saveFile(filename,out);
		var msg=ok?okmsg.format([count,filename]):failmsg.format([filename]);
		var link=ok?"file:///"+filename.replace(regexpBackSlash,'/'):""; // change local path to link text
		clearMessage(); displayMessage(msg,link);
	}
	e.cancelBubble = true; if (e.stopPropagation) e.stopPropagation(); return(false);
}
//}}}

//{{{
function promptForFilename(msg,path,file)
{
	if(window.Components) { // moz
		try {
			netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
			var nsIFilePicker = window.Components.interfaces.nsIFilePicker;
			var picker = Components.classes['@mozilla.org/filepicker;1'].createInstance(nsIFilePicker);
			picker.init(window, msg, nsIFilePicker.modeSave);
			var thispath = Components.classes['@mozilla.org/file/local;1'].createInstance(Components.interfaces.nsILocalFile);
			thispath.initWithPath(path);
			picker.displayDirectory=thispath;
			picker.defaultExtension='html';
			picker.defaultString=file;
			picker.appendFilters(nsIFilePicker.filterAll|nsIFilePicker.filterText|nsIFilePicker.filterHTML);
			if (picker.show()!=nsIFilePicker.returnCancel) var result=picker.file.persistentDescriptor;
		}
		catch(e) { alert('error during local file access: '+e.toString()) }
	}
	else { // IE
		try { // XP only
			var s = new ActiveXObject('UserAccounts.CommonDialog');
			s.Filter='All files|*.*|Text files|*.txt|HTML files|*.htm;*.html|';
			s.FilterIndex=3; // default to HTML files;
			s.InitialDir=path;
			s.FileName=file;
			if (s.showOpen()) var result=s.FileName;
		}
		catch(e) { var result=prompt(msg,path+file); } // fallback for non-XP IE
	}
	return result;
}
//}}}
/***
| Name:|NewHerePlugin|
| Description:|Creates the new here and new journal macros|
| Version:|3.0 ($Rev: 1845 $)|
| Date:|$Date: 2007-03-16 15:19:22 +1000 (Fri, 16 Mar 2007) $|
| Source:|http://mptw.tiddlyspot.com/#NewHerePlugin|
| Author:|Simon Baird <simon.baird@gmail.com>|
| License|http://mptw.tiddlyspot.com/#TheBSDLicense|
***/
//{{{
merge(config.macros, {
	newHere: {
		handler: function(place,macroName,params,wikifier,paramString,tiddler) {
			wikify("<<newTiddler "+paramString+" tag:[["+tiddler.title+"]]>>",place,null,tiddler);
		}
	},
	newJournalHere: {
		handler: function(place,macroName,params,wikifier,paramString,tiddler) {
			wikify("<<newJournal "+paramString+" tag:[["+tiddler.title+"]]>>",place,null,tiddler);
		}
	}
});

//}}}
/***
| Name:|NewMeansNewPlugin|
| Description:|If 'New Tiddler' already exists then create 'New Tiddler (1)' and so on|
| Version:|1.0 ($Rev: 2263 $)|
| Date:|$Date: 2007-06-13 04:22:32 +1000 (Wed, 13 Jun 2007) $|
| Source:|http://mptw.tiddlyspot.com/empty.html#NewMeansNewPlugin|
| Author:|Simon Baird <simon.baird@gmail.com>|
| License|http://mptw.tiddlyspot.com/#TheBSDLicense|
***/
//{{{

String.prototype.getNextFreeName = function() {
       var numberRegExp = / \(([0-9]+)\)$/;
       var match = numberRegExp.exec(this);
       if (match) {
               var num = parseInt(match[1]) + 1;
               return this.replace(numberRegExp," ("+num+")");
       }
       else {
               return this + " (1)";
       }
}

config.macros.newTiddler.getName = function(newName) {
       while (store.getTiddler(newName))
               newName = newName.getNextFreeName();
       return newName;
}


config.macros.newTiddler.onClickNewTiddler = function()
{
	var title = this.getAttribute("newTitle");
	if(this.getAttribute("isJournal") == "true") {
		var now = new Date();
		title = now.formatString(title.trim());
	}

	title = config.macros.newTiddler.getName(title); // <--- only changed bit

	var params = this.getAttribute("params");
	var tags = params ? params.split("|") : [];
	var focus = this.getAttribute("newFocus");
	var template = this.getAttribute("newTemplate");
	var customFields = this.getAttribute("customFields");
	story.displayTiddler(null,title,template,false,null,null);
	var tiddlerElem = document.getElementById(story.idPrefix + title);
	if(customFields)
		story.addCustomFields(tiddlerElem,customFields);
	var text = this.getAttribute("newText");
	if(typeof text == "string")
		story.getTiddlerField(title,"text").value = text.format([title]);
	for(var t=0;t<tags.length;t++)
		story.setTiddlerTag(title,tags[t],+1);
	story.focusTiddler(title,focus);
	return false;
};

//}}}
<<newTiddler title:'New Table' text:{{store.getTiddlerText('BlankTable')}}>>
/%
|Name|NewWell|
|Author|Alfonso Reyes|
|Type|script|
|Requires|InlineJavascriptPlugin|
|Overrides|None|
|Description|adds new Data Gathering item|

Usage: <<tiddler NewTextSelection>>

%/<script label="new Text Selection">

 var tags = "[[TextSelection]]";

 var title = prompt("Please enter name for this item", "");
 if( (title == null) || (title == "") ){
 return;
 }//if

store.saveTiddler(title, title, "<<formTiddler TextSelectionTemplate>><data>{}</data>", config.options.txtUserName, new Date(), tags);
story.displayTiddler(null,title,DEFAULT_VIEW_TEMPLATE);
// add the tiddler title to the key field
//DataTiddler.setData(title,"Data",title)
// refresh to reflect the added tiddler title to the key field
//story.refreshTiddler(title,null,true);

</script>
<<newTiddler label:"New dropdown Bookmarks 2" title:New dropdown Bookmarks 2 tag:NewdropdownBookmarks2 text:"Type some text and then press DONE to view the task controls" >><data>{}</data>
/%
|Author|Alfonso Reyes|
|Type|script|
|Requires|InlineJavascriptPlugin|
|Overrides|None|
|Description|adds new item|

Usage: <<tiddler NewdropdownTagged>>

%/<script label="new dropdownTagged">

 var tags = "[[dropdownTagged]]";

 var title = prompt("Please enter name for this item", "");
 if( (title == null) || (title == "") ){
 return;
 }//if

store.saveTiddler(title, title, "<<formTiddler dropdownTaggedTemplate>><data>{}</data>", config.options.txtUserName, new Date(), tags);
story.displayTiddler(null,title,DEFAULT_VIEW_TEMPLATE);
// add the tiddler title to the key field
//DataTiddler.setData(title,"txtBox",title)
// refresh to reflect the added tiddler title to the key field
story.refreshTiddler(title,null,true);

</script>
/%
|Name|NextTiddler|
|Source|http://www.TiddlyTools.com/#NextTiddler|
|Version|0.0.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <<br>>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|script|
|Requires|InlineJavascriptPlugin|
|Overrides||
|Description|insert a link that, when clicked, closes the current tiddler and opens another one in its place|

usage: <<tiddler NextTiddler with: NewTiddlerTitle linktext>>


%/<script label="$2">
 var tiddler=story.findContainingTiddler(place);
 story.displayTiddler(tiddler,"$1");
 story.closeTiddler(tiddler.id.substr(7)); // close self
 return false;
</script>
http://www.giffmex.org/experiments/NoteStorm.html
<<forEachTiddler
     where 'tiddler != context.inTiddler && 
            tiddler.tags.contains(context.inTiddler.title)'
>>
''=SETF(GetRef(User.ODBCConnection),User.Row_5)''

Apply the string value in user.row_5 to User.ODBCConnection. A direct string assignment of what resides in User.Row_5 will not work to update the database.
Source: http://msdn2.microsoft.com/en-us/library/bb299886.aspx

An object literal defines the members of an object and their values. The list of object members and values is enclosed in curly braces ({}) and each member is delimited by a comma. Within each member, the name and value are delimited by a colon (:). The following example creates an object and initializes it with three members named Address, City, and PostalCode with respective values "123 Anywhere St.", "Springfield", and "99999."
{{{
var mailingAddress = { 
     "Address"    :   "123 Anywhere St.", 
     "City"       :   "Springfield", 
     "PostalCode" :   99999
};
alert("The package will be shipped to postal code " +
 mailingAddress.PostalCode);
}}}

<script>
var mailingAddress = { 
     "Address"    :   "123 Anywhere St.", 
     "City"       :   "Springfield", 
     "PostalCode" :   99999
};
alert("The package will be shipped to postal code " +
 mailingAddress.PostalCode);
</script>
{{{
var data = {name: 'Violet', occupation: 'character', age: 25 };
Object.toJSON(data);
//-> '{"name": "Violet", "occupation": "character", "age": 25}'
}}}
<script>
var data = {name: 'Violet', occupation: 'character', age: 25 };
Object.toJSON(data);
//-> '{"name": "Violet", "occupation": "character", "age": 25}'
</script>
<script label="click here" title="clicking this link will show an 'alert' box" show>
 if (!window.story) window.story=window;
 alert("Hello World!\nlinktext='"+place.firstChild.data+"'\ntiddler='"+story.findContainingTiddler(place).id.substr(7)+"'");
</script>
[[MptwPageTemplate]]
/***
|<html><a name="Top"/></html>''Name:''|PartTiddlerPlugin|
|''Version:''|1.0.9 (2007-07-14)|
|''Source:''|http://tiddlywiki.abego-software.de/#PartTiddlerPlugin|
|''Author:''|UdoBorkowski (ub [at] abego-software [dot] de)|
|''Licence:''|[[BSD open source license]]|
|''CoreVersion:''|2.1.3|
|''Browser:''|Firefox 1.0.4+; InternetExplorer 6.0|
!Table of Content<html><a name="TOC"/></html>
* <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Description',null, event)">Description, Syntax</a></html>
* <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Applications',null, event)">Applications</a></html>
** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('LongTiddler',null, event)">Refering to Paragraphs of a Longer Tiddler</a></html>
** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Citation',null, event)">Citation Index</a></html>
** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('TableCells',null, event)">Creating "multi-line" Table Cells</a></html>
** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Tabs',null, event)">Creating Tabs</a></html>
** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Sliders',null, event)">Using Sliders</a></html>
* <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Revisions',null, event)">Revision History</a></html>
* <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Code',null, event)">Code</a></html>
!Description<html><a name="Description"/></html>
With the {{{<part aPartName> ... </part>}}} feature you can structure your tiddler text into separate (named) parts. 
Each part can be referenced as a "normal" tiddler, using the "//tiddlerName//''/''//partName//" syntax (e.g. "About/Features").  E.g. you may create links to the parts (e.g. {{{[[Quotes/BAX95]]}}} or {{{[[Hobbies|AboutMe/Hobbies]]}}}), use it in {{{<<tiddler...>>}}} or {{{<<tabs...>>}}} macros etc.


''Syntax:'' 
|>|''<part'' //partName// [''hidden''] ''>'' //any tiddler content// ''</part>''|
|//partName//|The name of the part. You may reference a part tiddler with the combined tiddler name "//nameOfContainerTidder//''/''//partName//. <<br>>If you use a partName containing spaces you need to quote it (e.g. {{{"Major Overview"}}} or {{{[[Shortcut List]]}}}).|
|''hidden''|When defined the content of the part is not displayed in the container tiddler. But when the part is explicitly referenced (e.g. in a {{{<<tiddler...>>}}} macro or in a link) the part's content is displayed.|
|<html><i>any&nbsp;tiddler&nbsp;content</i></html>|<html>The content of the part.<br>A part can have any content that a "normal" tiddler may have, e.g. you may use all the formattings and macros defined.</html>|
|>|~~Syntax formatting: Keywords in ''bold'', optional parts in [...]. 'or' means that exactly one of the two alternatives must exist.~~|
<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>

!Applications<html><a name="Applications"/></html>
!!Refering to Paragraphs of a Longer Tiddler<html><a name="LongTiddler"/></html>
Assume you have written a long description in a tiddler and now you want to refer to the content of a certain paragraph in that tiddler (e.g. some definition.) Just wrap the text with a ''part'' block, give it a nice name, create a "pretty link" (like {{{[[Discussion Groups|Introduction/DiscussionGroups]]}}}) and you are done.

Notice this complements the approach to first writing a lot of small tiddlers and combine these tiddlers to one larger tiddler in a second step (e.g. using the {{{<<tiddler...>>}}} macro). Using the ''part'' feature you can first write a "classic" (longer) text that can be read "from top to bottom" and later "reuse" parts of this text for some more "non-linear" reading.

<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>

!!Citation Index<html><a name="Citation"/></html>
Create a tiddler "Citations" that contains your "citations". 
Wrap every citation with a part and a proper name. 

''Example''
{{{
<part BAX98>Baxter, Ira D. et al: //Clone Detection Using Abstract Syntax Trees.// 
in //Proc. ICSM//, 1998.</part>

<part BEL02>Bellon, Stefan: //Vergleich von Techniken zur Erkennung duplizierten Quellcodes.// 
Thesis, Uni Stuttgart, 2002.</part>

<part DUC99>Ducasse, Stéfane et al: //A Language Independent Approach for Detecting Duplicated Code.// 
in //Proc. ICSM//, 1999.</part>
}}}

You may now "cite" them just by using a pretty link like {{{[[Citations/BAX98]]}}} or even more pretty, like this {{{[[BAX98|Citations/BAX98]]}}}.

<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>

!!Creating "multi-line" Table Cells<html><a name="TableCells"/></html>
You may have noticed that it is hard to create table cells with "multi-line" content. E.g. if you want to create a bullet list inside a table cell you cannot just write the bullet list
{{{
* Item 1
* Item 2
* Item 3
}}}
into a table cell (i.e. between the | ... | bars) because every bullet item must start in a new line but all cells of a table row must be in one line.

Using the ''part'' feature this problem can be solved. Just create a hidden part that contains the cells content and use a {{{<<tiddler >>}}} macro to include its content in the table's cell.

''Example''
{{{
|!Subject|!Items|
|subject1|<<tiddler ./Cell1>>|
|subject2|<<tiddler ./Cell2>>|

<part Cell1 hidden>
* Item 1
* Item 2
* Item 3
</part>
...
}}}

Notice that inside the {{{<<tiddler ...>>}}} macro you may refer to the "current tiddler" using the ".".

BTW: The same approach can be used to create bullet lists with items that contain more than one line.

<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>

!!Creating Tabs<html><a name="Tabs"/></html>
The build-in {{{<<tabs ...>>}}} macro requires that you defined an additional tiddler for every tab it displays. When you want to have "nested" tabs you need to define a tiddler for the "main tab" and one for every tab it contains. I.e. the definition of a set of tabs that is visually displayed at one place is distributed across multiple tiddlers.

With the ''part'' feature you can put the complete definition in one tiddler, making it easier to keep an overview and maintain the tab sets.

''Example''
The standard tabs at the sidebar are defined by the following eight tiddlers:
* SideBarTabs
* TabAll
* TabMore
* TabMoreMissing
* TabMoreOrphans
* TabMoreShadowed
* TabTags
* TabTimeline

Instead of these eight tiddlers one could define the following SideBarTabs tiddler that uses the ''part'' feature:
{{{
<<tabs txtMainTab 
    Timeline Timeline SideBarTabs/Timeline 
    All 'All tiddlers' SideBarTabs/All 
    Tags 'All tags' SideBarTabs/Tags 
    More 'More lists' SideBarTabs/More>>
<part Timeline hidden><<timeline>></part>
<part All hidden><<list all>></part>
<part Tags hidden><<allTags>></part>
<part More hidden><<tabs txtMoreTab 
    Missing 'Missing tiddlers' SideBarTabs/Missing 
    Orphans 'Orphaned tiddlers' SideBarTabs/Orphans 
    Shadowed 'Shadowed tiddlers' SideBarTabs/Shadowed>></part>
<part Missing hidden><<list missing>></part>
<part Orphans hidden><<list orphans>></part>
<part Shadowed hidden><<list shadowed>></part>
}}}

Notice that you can easily "overwrite" individual parts in separate tiddlers that have the full name of the part.

E.g. if you don't like the classic timeline tab but only want to see the 100 most recent tiddlers you could create a tiddler "~SideBarTabs/Timeline" with the following content:
{{{
<<forEachTiddler 
		sortBy 'tiddler.modified' descending 
		write '(index < 100) ? "* [["+tiddler.title+"]]\n":""'>>
}}}
<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>

!!Using Sliders<html><a name="Sliders"/></html>
Very similar to the build-in {{{<<tabs ...>>}}} macro (see above) the {{{<<slider ...>>}}} macro requires that you defined an additional tiddler that holds the content "to be slid". You can avoid creating this extra tiddler by using the ''part'' feature

''Example''
In a tiddler "About" we may use the slider to show some details that are documented in the tiddler's "Details" part.
{{{
...
<<slider chkAboutDetails About/Details details "Click here to see more details">>
<part Details hidden>
To give you a better overview ...
</part>
...
}}}

Notice that putting the content of the slider into the slider's tiddler also has an extra benefit: When you decide you need to edit the content of the slider you can just doubleclick the content, the tiddler opens for editing and you can directly start editing the content (in the part section). In the "old" approach you would doubleclick the tiddler, see that the slider is using tiddler X, have to look for the tiddler X and can finally open it for editing. So using the ''part'' approach results in a much short workflow.

<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>

!Revision history<html><a name="Revisions"/></html>
* v1.0.9 (2007-07-14)
** Bugfix: Error when using the SideBarTabs example and switching between "More" and "Shadow". Thanks to cmari for reporting the issue.
* v1.0.8 (2007-06-16)
** Speeding up display of tiddlers containing multiple pard definitions. Thanks to Paco Rivière for reporting the issue.
** Support "./partName" syntax inside <<tabs ...>> macro
* v1.0.7 (2007-03-07)
** Bugfix: <<tiddler "./partName">> does not always render correctly after a refresh (e.g. like it happens when using the "Include" plugin). Thanks to Morris Gray for reporting the bug.
* v1.0.6 (2006-11-07)
** Bugfix: cannot edit tiddler when UploadPlugin by Bidix is installed. Thanks to José Luis González Castro for reporting the bug.
* v1.0.5 (2006-03-02)
** Bugfix: Example with multi-line table cells does not work in IE6. Thanks to Paulo Soares for reporting the bug.
* v1.0.4 (2006-02-28)
** Bugfix: Shadow tiddlers cannot be edited (in TW 2.0.6). Thanks to Torsten Vanek for reporting the bug.
* v1.0.3 (2006-02-26)
** Adapt code to newly introduced Tiddler.prototype.isReadOnly() function (in TW 2.0.6). Thanks to Paulo Soares for reporting the problem.
* v1.0.2 (2006-02-05)
** Also allow other macros than the "tiddler" macro use the "." in the part reference (to refer to "this" tiddler)
* v1.0.1 (2006-01-27)
** Added Table of Content for plugin documentation. Thanks to RichCarrillo for suggesting.
** Bugfix: newReminder plugin does not work when PartTiddler is installed. Thanks to PauloSoares for reporting.
* v1.0.0 (2006-01-25)
** initial version
<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>

!Code<html><a name="Code"/></html>
<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
***/
//{{{
//============================================================================
//                           PartTiddlerPlugin

// Ensure that the PartTiddler Plugin is only installed once.
//
if (!version.extensions.PartTiddlerPlugin) {



version.extensions.PartTiddlerPlugin = {
    major: 1, minor: 0, revision: 9,
    date: new Date(2007, 6, 14), 
    type: 'plugin',
    source: "http://tiddlywiki.abego-software.de/#PartTiddlerPlugin"
};

if (!window.abego) window.abego = {};
if (version.major < 2) alertAndThrow("PartTiddlerPlugin requires TiddlyWiki 2.0 or newer.");

//============================================================================
// Common Helpers

// Looks for the next newline, starting at the index-th char of text. 
//
// If there are only whitespaces between index and the newline 
// the index behind the newline is returned, 
// otherwise (or when no newline is found) index is returned.
//
var skipEmptyEndOfLine = function(text, index) {
	var re = /(\n|[^\s])/g;
	re.lastIndex = index;
	var result = re.exec(text);
	return (result && text.charAt(result.index) == '\n') 
			? result.index+1
			: index;
}


//============================================================================
// Constants

var partEndOrStartTagRE = /(<\/part>)|(<part(?:\s+)((?:[^>])+)>)/mg;
var partEndTagREString = "<\\/part>";
var partEndTagString = "</part>";

//============================================================================
// Plugin Specific Helpers

// Parse the parameters inside a <part ...> tag and return the result.
//
// @return [may be null] {partName: ..., isHidden: ...}
//
var parseStartTagParams = function(paramText) {
	var params = paramText.readMacroParams();
	if (params.length == 0 || params[0].length == 0) return null;
	
	var name = params[0];
	var paramsIndex = 1;
	var hidden = false;
	if (paramsIndex < params.length) {
		hidden = params[paramsIndex] == "hidden";
		paramsIndex++;
	}
	
	return {
		partName: name, 
		isHidden: hidden
	};
}

// Returns the match to the next (end or start) part tag in the text, 
// starting the search at startIndex.
// 
// When no such tag is found null is returned, otherwise a "Match" is returned:
// [0]: full match
// [1]: matched "end" tag (or null when no end tag match)
// [2]: matched "start" tag (or null when no start tag match)
// [3]: content of start tag (or null if no start tag match)
//
var findNextPartEndOrStartTagMatch = function(text, startIndex) {
	var re = new RegExp(partEndOrStartTagRE);
	re.lastIndex = startIndex;
	var match = re.exec(text);
	return match;
}

//============================================================================
// Formatter

// Process the <part ...> ... </part> starting at (w.source, w.matchStart) for formatting.
//
// @return true if a complete part section (including the end tag) could be processed, false otherwise.
//
var handlePartSection = function(w) {
	var tagMatch = findNextPartEndOrStartTagMatch(w.source, w.matchStart);
	if (!tagMatch) return false;
	if (tagMatch.index != w.matchStart || !tagMatch[2]) return false;

	// Parse the start tag parameters
	var arguments = parseStartTagParams(tagMatch[3]);
	if (!arguments) return false;
	
	// Continue processing
	var startTagEndIndex = skipEmptyEndOfLine(w.source, tagMatch.index + tagMatch[0].length);
	var endMatch = findNextPartEndOrStartTagMatch(w.source, startTagEndIndex);
	if (endMatch && endMatch[1]) {
		if (!arguments.isHidden) {
			w.nextMatch = startTagEndIndex;
			w.subWikify(w.output,partEndTagREString);
		}
		w.nextMatch = skipEmptyEndOfLine(w.source, endMatch.index + endMatch[0].length);
		
		return true;
	}
	return false;
}

config.formatters.push( {
    name: "part",
    match: "<part\\s+[^>]+>",
	
	handler: function(w) {
		if (!handlePartSection(w)) {
			w.outputText(w.output,w.matchStart,w.matchStart+w.matchLength);
		}
	}
} )

//============================================================================
// Extend "fetchTiddler" functionality to also recognize "part"s of tiddlers 
// as tiddlers.

var currentParent = null; // used for the "." parent (e.g. in the "tiddler" macro)

// Return the match to the first <part ...> tag of the text that has the
// requrest partName.
//
// @return [may be null]
//
var findPartStartTagByName = function(text, partName) {
	var i = 0;
	
	while (true) {
		var tagMatch = findNextPartEndOrStartTagMatch(text, i);
		if (!tagMatch) return null;

		if (tagMatch[2]) {
			// Is start tag
	
			// Check the name
			var arguments = parseStartTagParams(tagMatch[3]);
			if (arguments && arguments.partName == partName) {
				return tagMatch;
			}
		}
		i = tagMatch.index+tagMatch[0].length;
	}
}

// Return the part "partName" of the given parentTiddler as a "readOnly" Tiddler 
// object, using fullName as the Tiddler's title. 
//
// All remaining properties of the new Tiddler (tags etc.) are inherited from 
// the parentTiddler.
// 
// @return [may be null]
//
var getPart = function(parentTiddler, partName, fullName) {
	var text = parentTiddler.text;
	var startTag = findPartStartTagByName(text, partName);
	if (!startTag) return null;
	
	var endIndexOfStartTag = skipEmptyEndOfLine(text, startTag.index+startTag[0].length);
	var indexOfEndTag = text.indexOf(partEndTagString, endIndexOfStartTag);

	if (indexOfEndTag >= 0) {
		var partTiddlerText = text.substring(endIndexOfStartTag,indexOfEndTag);
		var partTiddler = new Tiddler();
		partTiddler.set(
						fullName,
						partTiddlerText,
						parentTiddler.modifier,
						parentTiddler.modified,
						parentTiddler.tags,
						parentTiddler.created);
		partTiddler.abegoIsPartTiddler = true;
		return partTiddler;
	}
	
	return null;
}

// Hijack the store.fetchTiddler to recognize the "part" addresses.
//
var hijackFetchTiddler = function() {
	var oldFetchTiddler = store.fetchTiddler ;
	store.fetchTiddler = function(title) {
		var result = oldFetchTiddler.apply(this, arguments);
		if (!result && title) {
			var i = title.lastIndexOf('/');
			if (i > 0) {
				var parentName = title.substring(0, i);
				var partName = title.substring(i+1);
				var parent = (parentName == ".") 
						? store.resolveTiddler(currentParent)
						: oldFetchTiddler.apply(this, [parentName]);
				if (parent) {
					return getPart(parent, partName, parent.title+"/"+partName);
				}
			}
		}
		return result;	
	};
};

// for debugging the plugin is not loaded through the systemConfig mechanism but via a script tag. 
// At that point in the "store" is not yet defined. In that case hijackFetchTiddler through the restart function.
// Otherwise hijack now.
if (!store) {
	var oldRestartFunc = restart;
	window.restart = function() {
		hijackFetchTiddler();
		oldRestartFunc.apply(this,arguments);
	};
} else
	hijackFetchTiddler();




// The user must not edit a readOnly/partTiddler
//

config.commands.editTiddler.oldIsReadOnlyFunction = Tiddler.prototype.isReadOnly;

Tiddler.prototype.isReadOnly = function() {
	// Tiddler.isReadOnly was introduced with TW 2.0.6.
	// For older version we explicitly check the global readOnly flag
	if (config.commands.editTiddler.oldIsReadOnlyFunction) {
		if (config.commands.editTiddler.oldIsReadOnlyFunction.apply(this, arguments)) return true;
	} else {
		if (readOnly) return true;
	}

	return this.abegoIsPartTiddler;
}

config.commands.editTiddler.handler = function(event,src,title)
{
	var t = store.getTiddler(title);
	// Edit the tiddler if it either is not a tiddler (but a shadowTiddler)
	// or the tiddler is not readOnly
	if(!t || !t.abegoIsPartTiddler)
		{
		clearMessage();
		story.displayTiddler(null,title,DEFAULT_EDIT_TEMPLATE);
		story.focusTiddler(title,"text");
		return false;
		}
}

// To allow the "./partName" syntax in macros we need to hijack 
// the invokeMacro to define the "currentParent" while it is running.
// 
var oldInvokeMacro = window.invokeMacro;
function myInvokeMacro(place,macro,params,wikifier,tiddler) {
	var oldCurrentParent = currentParent;
	if (tiddler) currentParent = tiddler;
	try {
		oldInvokeMacro.apply(this, arguments);
	} finally {
		currentParent = oldCurrentParent;
	}
}
window.invokeMacro = myInvokeMacro;

// To correctly support the "./partName" syntax while refreshing we need to hijack 
// the config.refreshers.tiddlers to define the "currentParent" while it is running.
// 
(function() {
	var oldTiddlerRefresher= config.refreshers.tiddler;
	config.refreshers.tiddler = function(e,changeList) {
		var oldCurrentParent = currentParent;
		try {
			currentParent = e.getAttribute("tiddler");
			return oldTiddlerRefresher.apply(this,arguments);
		} finally {
			currentParent = oldCurrentParent;
		}
	};
})();

// Support "./partName" syntax inside <<tabs ...>> macro
(function() {
	var extendRelativeNames = function(e, title) {
		var nodes = e.getElementsByTagName("a");
		for(var i=0; i<nodes.length; i++) {
			var node = nodes[i];
			var s = node.getAttribute("content");
			if (s && s.indexOf("./") == 0)
				node.setAttribute("content",title+s.substr(1));
		}
	};
	var oldHandler = config.macros.tabs.handler;
	config.macros.tabs.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
		var result = oldHandler.apply(this,arguments);
		if (tiddler)
			extendRelativeNames(place, tiddler.title);
		return result;
	};
})();

// Scroll the anchor anchorName in the viewer of the given tiddler visible.
// When no tiddler is defined use the tiddler of the target given event is used.
window.scrollAnchorVisible = function(anchorName, tiddler, evt) {
	var tiddlerElem = null;
	if (tiddler) {
		tiddlerElem = document.getElementById(story.idPrefix + tiddler);
	}
	if (!tiddlerElem && evt) {
		var target = resolveTarget(evt);
		tiddlerElem = story.findContainingTiddler(target);
	}
	if (!tiddlerElem) return;

	var children = tiddlerElem.getElementsByTagName("a");
	for (var i = 0; i < children.length; i++) {
		var child = children[i];
		var name = child.getAttribute("name");
		if (name == anchorName) {
			var y = findPosY(child);
			window.scrollTo(0,y);
			return;
		}
	}
}

} // of "install only once"
//}}}

/***
<html><sub><a href="javascript:;" onclick="scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>

!Licence and Copyright
Copyright (c) abego Software ~GmbH, 2006 ([[www.abego-software.de|http://www.abego-software.de]])

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.

Neither the name of abego Software nor the names of its contributors may be
used to endorse or promote products derived from this software without specific
prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

<html><sub><a href="javascript:;" onclick="scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
***/
{{{
var say = function(what) {
   what('say function');
}

var hello = function (who) {
   alert('Hello '+who);      // outputs "Hello say function"
}

say(hello);
}}}
<script>
var say = function(what) {
   what('say function');
}

var hello = function (who) {
   alert('Hello '+who);      // outputs "Hello say function"
}

say(hello);
</script>
http://bradleymeck.tiddlyspot.com/#OpenToday
http://yann.perrin.googlepages.com/twkd.html
''If you want this documentation available offline, you will need to copy this tiddler to your TW.''
!Description:
Using the popup macro you can create popups with any wiki text. The wiki text can be written in the macro call, can be generated using a different macro, or included from a tiddler.

!Usage:
*the button label is the first parameter
*the text to put in the popup is the second parameter
**embed macro output like forEachTiddler or tiddlerList
***start macro calls with {{{<<}}} like normal, but end with {{{$))}}}
**define popup content inline, or embed from a tidder using the core tiddler macro {{{<<tiddler$))}}}
*you can nest popups up to one level
**nested popups have an id of 'nestedpopup' for easier styling.
**specify unique id's for nested popups by passing the id as a third parameter.

----
!Example's

''Put a forEachTiddler macro generated list in a popup:''
{{{<<popup forEachTiddlerDemo [[<<forEachTiddler where 'tiddler.tags.contains("systemConfig")']]$))}}}
<<popup forEachTiddlerDemo [[<<forEachTiddler
where
'tiddler.tags.contains("systemConfig")'$))]]>>

''Use the core {{{<<tiddler>>}}} macro to put the contents of a tiddler into a popup:''
MainMenu popup:
{{{<<popup MainMenu [[<<tiddler MainMenu$))]]>>}}}
<<popup MainMenu [[<<tiddler MainMenu$))]]>>

''Or create a custom menu in a tiddler using various macro's and normal tiddlylinks.''
{{{<<popup CustomMenu '<<tiddler CustomMenu$))'>>}}}
<<popup CustomMenu '<<tiddler CustomMenu$))'>>
this menu was created with a combination of forEachTiddler and normal tiddlyLinks!
Note that the 'Plugins' button opens a second nested popup.
Source tiddler: CustomMenu

''Or define your custom menu inline.''
{{{<<popup 'Inline Custom Menu' [[Custom Menu
*MainMenu
----
<<forEachTiddler
 where
 'tiddler.tags.contains("systemConfig")']]$))]] 
>>}}}
<<popup 'Inline Custom Menu' [[Custom Menu
*MainMenu
----
<<forEachTiddler where 'tiddler.tags.contains("systemConfig")'$))]] 
>>

''Note: you can pass a third parameter and it will be set as the id of any nested popups''
By default, nested popups have an id of 'nestedpopup' to facilitate styling.

----
!Current Issues:
*better support for custom classes for popups and nestedpopups
----
!Code
PopupMacro
/%
|Name|PopupTiddlersByAuthor|
|Source|http://www.TiddlyTools.com/#PopupTiddlersByAuthor|
|Version|0.0.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|html|
|Requires||
|Overrides||
|Description|create a popup list of tiddlers modified by a given author|

usage: create a tiddler with title==authorname, containing "<<tiddler PopupTiddlersByAuthor>>"

%/<html><a href="javascript:;" onclick="
var here=story.findContainingTiddler(this); 
if (!here) return; 
var who=here.getAttribute('tiddler'); 
var p=Popup.create(this); if (!p) return; 
createTiddlyText(p,'modified by '+who); createTiddlyElement(p,'hr'); var tids=store.getTiddlers('modified'); 
for (i=tids.length-1;i>=0;i--) if (tids[i].modifier==who) { createTiddlyLink(p,tids[i].title,false).innerHTML=tids[i].modified.formatString('YY0MM0DD 0hh:0mm')+' '+tids[i].title; createTiddlyElement(p,'br'); 
} 
Popup.show(p,false); 
event.cancelBubble = true; 
if (event.stopPropagation) event.stopPropagation(); 
return(false);
">submissions:</a></html>
http://elj.tiddlyspot.com/

Features:
* main page with multiple divisions on left
* sidebar simplified with multiple sections
http://www.math.ist.utl.pt/~psoares/addons.html#SlideShowExample
<script show>
var myArray = [];
    myArray[0] = 0;
    myArray[1] = 1;
    myArray[2] = 2;
    myArray[3] = 3;
    for (i=0; i < myArray.length; i++) {
       document.write(myArray[i]);
    }
</script>
High
Medium
Low
Unknown
/***
| Name|QuickOpenTagPlugin|
| Description|Changes tag links to make it easier to open tags as tiddlers|
| Version|3.0.1 ($Rev: 2342 $)|
| Date|$Date: 2007-07-05 10:57:49 +1000 (Thu, 05 Jul 2007) $|
| Source|http://mptw.tiddlyspot.com/#QuickOpenTagPlugin|
| Author|Simon Baird <simon.baird@gmail.com>|
| License|http://mptw.tiddlyspot.com/#TheBSDLicense|
***/
//{{{
config.quickOpenTag = {

	dropdownChar: (document.all ? "\u25bc" : "\u25be"), // the little one doesn't work in IE?

	createTagButton: function(place,tag,excludeTiddler) {
		// little hack so we can to <<tag PrettyTagName|RealTagName>>
		var splitTag = tag.split("|");
		var pretty = tag;
		if (splitTag.length == 2) {
			tag = splitTag[1];
			pretty = splitTag[0];
		}
		
		var sp = createTiddlyElement(place,"span",null,"quickopentag");
		createTiddlyText(createTiddlyLink(sp,tag,false),pretty);
		
		var theTag = createTiddlyButton(sp,config.quickOpenTag.dropdownChar,
                        config.views.wikified.tag.tooltip.format([tag]),onClickTag);
		theTag.setAttribute("tag",tag);
		if (excludeTiddler)
			theTag.setAttribute("tiddler",excludeTiddler);
    		return(theTag);
	},

	miniTagHandler: function(place,macroName,params,wikifier,paramString,tiddler) {
		var tagged = store.getTaggedTiddlers(tiddler.title);
		if (tagged.length > 0) {
			var theTag = createTiddlyButton(place,config.quickOpenTag.dropdownChar,
                        	config.views.wikified.tag.tooltip.format([tiddler.title]),onClickTag);
			theTag.setAttribute("tag",tiddler.title);
			theTag.className = "miniTag";
		}
	},

	allTagsHandler: function(place,macroName,params) {
		var tags = store.getTags(params[0]);
		var filter = params[1]; // new feature
		var ul = createTiddlyElement(place,"ul");
		if(tags.length == 0)
			createTiddlyElement(ul,"li",null,"listTitle",this.noTags);
		for(var t=0; t<tags.length; t++) {
			var title = tags[t][0];
			if (!filter || (title.match(new RegExp('^'+filter)))) {
				var info = getTiddlyLinkInfo(title);
				var theListItem =createTiddlyElement(ul,"li");
				var theLink = createTiddlyLink(theListItem,tags[t][0],true);
				var theCount = " (" + tags[t][1] + ")";
				theLink.appendChild(document.createTextNode(theCount));
				var theDropDownBtn = createTiddlyButton(theListItem," " +
					config.quickOpenTag.dropdownChar,this.tooltip.format([tags[t][0]]),onClickTag);
				theDropDownBtn.setAttribute("tag",tags[t][0]);
			}
		}
	},

	// todo fix these up a bit
	styles: [
"/*{{{*/",
"/* created by QuickOpenTagPlugin */",
".tagglyTagged .quickopentag, .tagged .quickopentag ",
"	{ margin-right:1.2em; border:1px solid #eee; padding:2px; padding-right:0px; padding-left:1px; }",
".quickopentag .tiddlyLink { padding:2px; padding-left:3px; }",
".quickopentag a.button { padding:1px; padding-left:2px; padding-right:2px;}",
"/* extra specificity to make it work right */",
"#displayArea .viewer .quickopentag a.button, ",
"#displayArea .viewer .quickopentag a.tiddyLink, ",
"#mainMenu .quickopentag a.tiddyLink, ",
"#mainMenu .quickopentag a.tiddyLink ",
"	{ border:0px solid black; }",
"#displayArea .viewer .quickopentag a.button, ",
"#mainMenu .quickopentag a.button ",
"	{ margin-left:0px; padding-left:2px; }",
"#displayArea .viewer .quickopentag a.tiddlyLink, ",
"#mainMenu .quickopentag a.tiddlyLink ",
"	{ margin-right:0px; padding-right:0px; padding-left:0px; margin-left:0px; }",
"a.miniTag {font-size:150%;} ",
"#mainMenu .quickopentag a.button ",
"	/* looks better in right justified main menus */",
"	{ margin-left:0px; padding-left:2px; margin-right:0px; padding-right:0px; }", 
"#topMenu .quickopentag { padding:0px; margin:0px; border:0px; }",
"#topMenu .quickopentag .tiddlyLink { padding-right:1px; margin-right:0px; }",
"#topMenu .quickopentag .button { padding-left:1px; margin-left:0px; border:0px; }",
"/*}}}*/",
		""].join("\n"),

	init: function() {
		// we fully replace these builtins. can't hijack them easily
		window.createTagButton = this.createTagButton;
		config.macros.allTags.handler = this.allTagsHandler;
		config.macros.miniTag = { handler: this.miniTagHandler };
		config.shadowTiddlers["QuickOpenTagStyles"] = this.styles;
		store.addNotification("QuickOpenTagStyles",refreshStyles);
	}
}

config.quickOpenTag.init();

//}}}
http://reasoningwell.tiddlyspot.com/
[[Citations/BAX98]] 

[[Citations/DUC99]] 

/***
''Name:'' ReferencesPlugin
''Author:'' Garrett Lisi
''Description:'' Places a comma separated list of referring notes at the bottom of each note -- replacing the "references" command bar button.
''Installation:'' Copy this note, change the [[StyleSheet]] to set the references class style, and add a line in the [[ViewTemplate]].

''Code:''
***/
/*{{{*/
config.macros.references = {};
config.macros.references.handler = function(place,macroName,params,wikifier,paramString,tiddler)
{
	var references = store.getReferringTiddlers(tiddler.title);
	if(references.length>0)
		{
//		createTiddlyText(place,"\xAB ");	
		createTiddlyLink(place,references[0].title,true);
		}
	for(var r=1; r<references.length; r++)
		if(references[r].title != tiddler.title)
			{
			createTiddlyText(place,", ");
			createTiddlyLink(place,references[r].title,true);
			}
}
/*}}}*/
.references {
	font-size: 1em;
	text-align: center;
	color: #666;
	margin-top: .75em;
	padding: .25em;
	border: 1px solid #eee;
	background-color: #eee;}
.selected .references {
	background-color: #eee;
	border: 1px solid #ccc;}
.references .tiddlyLinkExisting {font-weight: normal;}
<div class='references' macro="references"></div>
/***
| Name:|RenameTagsPlugin|
| Description:|Allows you to easily rename or delete tags across multiple tiddlers|
| Version:|3.0 ($Rev: 1845 $)|
| Date:|$Date: 2007-03-16 15:19:22 +1000 (Fri, 16 Mar 2007) $|
| Source:|http://mptw.tiddlyspot.com/#RenameTagsPlugin|
| Author:|Simon Baird <simon.baird@gmail.com>|
| License|http://mptw.tiddlyspot.com/#TheBSDLicense|
Rename a tag and you will be prompted to rename it in all its tagged tiddlers.
***/
//{{{
config.renameTags = {

	prompts: {
		rename: "Rename the tag '%0' to '%1' in %2 tidder%3?",
		remove: "Remove the tag '%0' from %1 tidder%2?"
	},

	removeTag: function(tag,tiddlers) {
		store.suspendNotifications();
		for (var i=0;i<tiddlers.length;i++) {
			store.setTiddlerTag(tiddlers[i].title,false,tag);
		}
		store.resumeNotifications();
		store.notifyAll();
	},

	renameTag: function(oldTag,newTag,tiddlers) {
		store.suspendNotifications();
		for (var i=0;i<tiddlers.length;i++) {
			store.setTiddlerTag(tiddlers[i].title,false,oldTag); // remove old
			store.setTiddlerTag(tiddlers[i].title,true,newTag);  // add new
		}
		store.resumeNotifications();
		store.notifyAll();
	},

	storeMethods: {

		saveTiddler_orig_renameTags: TiddlyWiki.prototype.saveTiddler,

		saveTiddler: function(title,newTitle,newBody,modifier,modified,tags,fields) {
			if (title != newTitle) {
				var tagged = this.getTaggedTiddlers(title);
				if (tagged.length > 0) {
					// then we are renaming a tag
					if (confirm(config.renameTags.prompts.rename.format([title,newTitle,tagged.length,tagged.length>1?"s":""])))
						config.renameTags.renameTag(title,newTitle,tagged);

					if (!this.tiddlerExists(title) && newBody == "")
						// dont create unwanted tiddler
						return null;
				}
			}
			return this.saveTiddler_orig_renameTags(title,newTitle,newBody,modifier,modified,tags,fields);
		},

		removeTiddler_orig_renameTags: TiddlyWiki.prototype.removeTiddler,

		removeTiddler: function(title) {
			var tagged = this.getTaggedTiddlers(title);
			if (tagged.length > 0)
				if (confirm(config.renameTags.prompts.remove.format([title,tagged.length,tagged.length>1?"s":""])))
					config.renameTags.removeTag(title,tagged);
			return this.removeTiddler_orig_renameTags(title);
		}

	},

	init: function() {
		merge(TiddlyWiki.prototype,this.storeMethods);
	}
}

config.renameTags.init();

//}}}
/%
|Name|ReplaceTiddlerTitle|
|Source|http://www.TiddlyTools.com/#ReplaceTiddlerTitle|
|Version|1.0.1|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|script|
|Requires|InlineJavascriptPlugin|
|Overrides||
|Description|replace tiddler's title text with other content - may include wiki syntax|

Usage:
	<<tiddler ReplaceTiddlerTitle with: "new title text">>

%/<script>
	// get the tiddler element
	var here=story.findContainingTiddler(place);
	if (!here || here.getAttribute("tiddler")=="ReplaceTiddlerTitle") return; // don't change the title on the script itself!
	var nodes=here.getElementsByTagName("*");
	for (var i=0; i<nodes.length; i++)
		if (hasClass(nodes[i],"title")) { removeChildren(nodes[i]); wikify("$1",nodes[i]); break; }
</script>
<<showData Invoice1>>
|<<siteMap scripts 3 sliders>>|<<siteMap webLinks 2 popups >>|<<siteMap editing 2 popups >>|
|<<siteMap scriptEvent 2 popups>>|<<siteMap application 2 popups >>|<<siteMap table 2 popups >>|
|<<siteMap scriptExamples 2 popups>>|<<siteMap plugin 2 popups >>|<<siteMap forms 2 popups >>|
|<<siteMap scriptMine 2 popups>>|<<siteMap pluginDevelopment 2 popups >>|<<siteMap template 2 popups >>|
|<<siteMap scriptJSON 2 popups>>|<<siteMap pluginExample 2 popups >>|<<siteMap stylesheet 2 popups >>|
|<<siteMap scriptJSON 2 popups>>|<<siteMap pluginNice 2 popups >>|<<siteMap stylesheet 2 popups >>|
|<<siteMap scriptNot-working 2 popups>>|<<siteMap pluginRepo 2 popups >>|<<siteMap server-side 2 popups >>|
<code>
// STYLESHEETS
while (f.sys_styles.options.length > 1) { f.sys_styles.options[1]=null; } // clear list
var c=1;
var styles=document.getElementsByTagName("style");
for(var i=0; i < styles.length; i++) {
	var id=styles[i].getAttribute("id"); if (!id) id="(default)";
	var txt=id;
	var val="/* stylesheet:"+txt+" */\n"+styles[i].innerHTML;
	f.sys_styles.options[c++]=new Option(txt,val,false,false);
}
</code>
Type some text and then press DONE to view the task controls
Type some text and then press DONE to view the task controls
/***
| Name|SaveCloseTiddlerPlugin|
| Description|Provides two extra toolbar commands, saveCloseTiddler and cancelCloseTiddler|
| Version|3.0 ($Rev: 2134 $)|
| Date|$Date: 2007-04-30 16:11:12 +1000 (Mon, 30 Apr 2007) $|
| Source|http://mptw.tiddlyspot.com/#SaveCloseTiddlerPlugin|
| Author|Simon Baird <simon.baird@gmail.com>|
| License|http://mptw.tiddlyspot.com/#TheBSDLicense|
To use these you must add them to the tool bar in your EditTemplate
***/
//{{{
merge(config.commands,{

	saveCloseTiddler: {
		text: 'done/close',
		tooltip: 'Save changes to this tiddler and close it',
		handler: function(e,src,title) {
			config.commands.saveTiddler.handler(e,src,title);
			config.commands.closeTiddler.handler(e,src,title);
			return false;
		}
	},

	cancelCloseTiddler: {
		text: 'cancel/close',
		tooltip: 'Undo changes to this tiddler and close it',
		handler: function(e,src,title) {
			config.commands.cancelTiddler.handler(e,src,title);
			config.commands.closeTiddler.handler(e,src,title);
			return false;
		}
	}

});

//}}}
/%
|Name|SaveTiddlerToFile|
|Source|http://www.TiddlyTools.com/#SaveTiddlerToFile|
|Version|1.0.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <<br>>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|script|
|Requires|InlineJavascriptPlugin|
|Overrides||
|Description|save tiddler SOURCE text to a local file|

Usage:

<<tiddler SaveTiddlerToFile with: 'label' 'tooltip'>>

%/<script label="$1" title="$2">

function promptForFilename(msg,path,file,defext)
{
	if(window.Components) { // moz
		try {
			netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
			var nsIFilePicker = window.Components.interfaces.nsIFilePicker;
			var picker = Components.classes['@mozilla.org/filepicker;1'].createInstance(nsIFilePicker);
			picker.init(window, msg, nsIFilePicker.modeSave);
			picker.displayDirectory=null;
			picker.defaultExtension=defext;
			picker.defaultString=file;
			picker.appendFilters(nsIFilePicker.filterAll|nsIFilePicker.filterText|nsIFilePicker.filterHTML);
			if (picker.show()!=nsIFilePicker.returnCancel) var result=picker.file.persistentDescriptor;
		}
		catch(e) { var result=prompt(msg,path+file); }
	}
	else { // IE
		try { // XP only
			var s = new ActiveXObject('UserAccounts.CommonDialog');
			s.Filter='All files|*.*|Text files|*.txt|HTML files|*.htm;*.html|';
			s.FilterIndex=1; // default to ALL files;
			s.InitialDir=path;
			s.FileName=file;
			if (s.showOpen()) var result=s.FileName;
		}
		catch(e) { var result=prompt(msg,path+file); } // fallback for non-XP IE
	}
	return result;
}
	var okmsg="Tiddler source written to %0";
	var failmsg="An error occurred while creating %0";
	var here=story.findContainingTiddler(place); if (!here) return;
	var title=here.getAttribute('tiddler');
	var tid=store.getTiddler(title);
	var path=getLocalPath(document.location.href);
	var slashpos=path.lastIndexOf("/"); if (slashpos==-1) slashpos=path.lastIndexOf("\\"); 
	if (slashpos!=-1) path = path.substr(0,slashpos+1); // remove filename from path, leave the trailing slash
	var filename=promptForFilename("select an output filename for this tiddler",path,title,"");
	if (!filename || !filename.length) return;
//
	var ok = saveFile(filename,tid.text);
	var msg=ok?okmsg:failmsg;
	var link=ok?"file:///"+filename.replace(regexpBackSlash,'/'):""; // change local path to link text
	clearMessage();
	displayMessage(msg.format([filename]),link);
</script><script>
	place.lastChild.style.fontWeight="normal";
	if ("$1"=="$"+"1") place.lastChild.innerHTML="save this tiddler to a file";
	if ("$2"=="$"+"2") place.lastChild.title="save this tiddler's SOURCE text to a local file";
</script>
<script>
sayHello = function(name) {
//alert('text')
  var text = 'Hello ' + name;
  var sayAlert = function() { alert(text); }
  sayAlert();
}
</script>

<html><input type="button" name="clickThis" value="sayHello('Bob')" onclick="try{sayHello('Bob')} catch(e) {sayHello('Bob')}"></html>
Work
Play
/%

Usage:
	<<tiddler ReplaceTiddlerTitle with: "new title text">>

%/<script>
	var tid="$1";
var s = "$1";
var out = "";
	if (tid=='$'+'1') { // use current tiddler
		var here=story.findContainingTiddler(place); if (!here) return;
		var tid=here.getAttribute('tiddler');
	}
out = "<<chkSlider" + s + " " + s + " " + s + ">>";
notes = "$2";
lbl = "$1"+"...>";

wikify("slider " + "chkSlider"+ "_" + "$1" + "F " + "$1" + "F  " +  lbl + " " + "[[" +notes +"]]"+ ">>" ,place);

//return (s);
</script>

[[test ScriptArg]]
<script>
	var here=story.findContainingTiddler(place);
	var title='$1'!='$'+'1'?'$1':here?here.getAttribute('tiddler'):'';
	var tid=store.getTiddler(title); if (!tid) return;
wikify("$1",place);
</script>

call ScriptArgSimple
/***
| Name|SelectPalettePlugin|
| Description|Lets you easily change colour palette|
| Version|3.0 ($Rev: 1845 $)|
| Date|$Date: 2007-03-16 15:19:22 +1000 (Fri, 16 Mar 2007) $|
| Source|http://mptw.tiddlyspot.com/#SelectPalettePlugin|
| Author|Simon Baird <simon.baird@gmail.com>|
| License|http://mptw.tiddlyspot.com/#TheBSDLicense|
/***
!!Usage:
{{{<<<selectPalette>>}}}
<<selectPalette>>

!!WARNING
Will overwrite your ColorPalette tiddler.
***/

//{{{

merge(config.macros,{

	setPalette: {

		handler: function(place,macroName,params,wikifier,paramString,tiddler) {
			var paletteName = params[0] ? params[0] : tiddler.title;
			createTiddlyButton(place,"apply","Apply this palette",function(e) {
				config.macros.selectPalette.updatePalette(tiddler.title);
				return false;
			});
		}
	},

	selectPalette: {

		handler: function(place,macroName,params,wikifier,paramString,tiddler) {
			createTiddlyDropDown(place,this.onPaletteChange,this.getPalettes());
		},

		getPalettes: function() {
			var result = [
				{caption:"-palette-", name:""},
				{caption:"(Default)", name:"(default)"}
			];
			var tagged = store.getTaggedTiddlers("palette","title");
			for(var t=0; t<tagged.length; t++) {
				var caption = tagged[t].title;
				var sliceTitle = store.getTiddlerSlice(caption,"Name");
				if (sliceTitle)
					caption = sliceTitle;
				result.push({caption:sliceTitle, name:tagged[t].title});
			}
			return result;
		},

		onPaletteChange: function(e) {
			config.macros.selectPalette.updatePalette(this.value);
			return true;
		},

		updatePalette: function(title) {
			if (title != "") {
				store.deleteTiddler("ColorPalette");
				if (title != "(default)")
					store.saveTiddler("ColorPalette","ColorPalette",store.getTiddlerText(title),
								config.options.txtUserName,undefined,"");
				this.refreshPalette();
				if(config.options.chkAutoSave)
					saveChanges(true);
			}
		},

		refreshPalette: function() {
			config.macros.refreshDisplay.onClick();
		}
	}
});

config.shadowTiddlers.OptionsPanel = "<<selectPalette>>\n\n" + config.shadowTiddlers.OptionsPanel;

//}}}
http://www.tiddlywiki.org/wiki/Server-side_implementation
<script>
setFocus=function()
{
document.getElementById("age").focus();
}
</script>

<html>
<head>
</head>

<body onload="setFocus()">
<form>
Name: <input type="text" id="fname" size="30"><br />
Age: <input type="text" id="age" size="30"> 
</form>
</body>

</html>
/%
|Name|SetDefaultTiddlers|
|Source|http://www.TiddlyTools.com/#SetDefaultTiddlers|
|Version|1.0.3|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <<br>>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|script|
|Requires|InlineJavascriptPlugin|
|Overrides||
|Description|set contents of DefaultTiddlers list to match currently displayed tiddlers|

Usage: <<tiddler SetDefaultTiddlers>>

%/<script label="set default tiddlers">
 // get list of current open tiddlers
 var tids=[];
 story.forEachTiddler(function(title,element){tids.push("[["+title+"]]")}); // always put titles in brackets
// if (!confirm("DefaultTiddlers will be set to:\n\n%0\n\nIs it OK to proceed?".format([tids.join(" ")]))) // return;
 tids=tids.join("\n"); // separate tiddler links by newlines for easier reading
 var title="DefaultTiddlers";
 var t=store.getTiddler(title);
 store.saveTiddler(title,title,tids,config.options.txtUserName,new Date(),t?t.tags:"",t?t.fields:null);
 story.refreshTiddler(title,null,true);
 displayMessage(title+" has been "+(t?"updated":"created"));
 // alfonso reyes added this on August
setTimeout ( "saveChanges()", 1500 );
</script>
<script>
var name = "VariableExample"
document.write(name+"\n")
document.write("<b>"+name+"</b>")
</script>
/%
|Name|ShowAllByTags|
|Source|http://www.TiddlyTools.com/#ShowAllByTags|
|Version|0.0.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <<br>>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|script|
|Requires|InlineJavascriptPlugin|
|Overrides||
|Description|for each tag, show a numbered list of all tiddlers with that tag|
%/<script>
	var tags = store.getTags();
	if(tags.length == 0) return "no tags in document";
	var out="";
	for(var t=0; t<tags.length; t++) {
		out+="*[["+tags[t][0]+"]] ("+tags[t][1]+")"+"\n";
		var tids=store.getTaggedTiddlers(tags[t][0]);
		for (i=0; i<tids.length; i++) out+="##[["+tids[i].title+"]]\n";
	}
	return out;
</script>
/%
|Name|ShowSimilarTiddlers|
|Source|http://www.TiddlyTools.com/#ShowSimilarTiddlers|
|Version|1.2.0|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|script|
|Requires|InlineJavascriptPlugin|
|Overrides||
|Description|list tiddlers, by number of shared tags|

Usage:  <<tiddler ShowSimilarTiddlers with: TiddlerName limit>>

where:
'TiddlerName' (optional) indicates the title of the tiddler whose tags are to be matched (default=current tiddler)
'limit' (optional) only reports tiddlers with at least the indicated number of tags in common (default=1)

%/<script>
	var out=[]; var similar={}; var rank=[];
	var here=story.findContainingTiddler(place);
	var title='$1'!='$'+'1'?'$1':here?here.getAttribute('tiddler'):'';
	var limit='$2'!='$'+'2'?'$2':1;
	var tid=store.getTiddler(title); if (!tid) return;
	var tids=store.reverseLookup('tags','excludeLists'); // get all tiddlers (including from IncludePlugin)
	for (var i=0; i<tids.length; i++) { var t=tids[i];
		if (t.title==tid.title) continue;
		var tags=[]; for (var j=0; j<t.tags.length; j++)
			if (tid.tags.contains(t.tags[j])) tags.push(t.tags[j]);
		if (tags.length >= limit) {
			similar[tids[i].title]=tags;
			if (!rank[tags.length]) rank[tags.length]=new Array();
			rank[tags.length].push(tids[i].title);
		}
	}
	for (var r=rank.length-1; r>=0; r--) { if (!rank[r]) continue;
		out.push('*%0 shared tags:'.format([r,rank[r].length]));
		for (var t=0; t<rank[r].length; t++)
			out.push('##[[%0]] ~~("""%1""")~~'.format([rank[r][t],similar[rank[r][t]].join(', ')]));
	}
	return out.join('\n');
</script>
/%
|Name|ShowTabsForTags|
|Source|http://www.TiddlyTools.com/#ShowTabsForTags|
|Version|1.0.1|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|script|
|Requires||
|Overrides||
|Description|generate a tabbed display for tiddlers with a specified set of tags|

Usage:
	<<tiddler ShowTabsForTags with: "tag tag ...">>
where:
	"tag tag ..." is a space-separated list of tag values, ALL of which
	must be present on the tiddlers that are to be displayed.

%/{{left wrap{<script>
	var tags="$1".readBracketedList();
	if ("$1"=="$"+"1") { // no tags specified... ASK for tags...
		var response=prompt("enter tag(s) to match:","package");  
		if (!response) return "no tags specified"; // cancelled by user
		var tags=response.readBracketedList(); 
	}
	// get matching tiddlers in date order (newest first) and add params to tabs macro output
	var out="";
	var tids=store.getTaggedTiddlers(tags[0],'modified').reverse();
	for (var t=0; t<tids.length; t++)
		if (tids[t].tags.containsAll(tags)) out+='[[%0 ]] "view %0" [[%0]]'.format([tids[t].title]); 
	if (out.length) return "<<tabs tabTabsForTags "+out+">>"; // if any tiddlers matched, show tabs
	// else, show message with tag popups
	return "There are no tiddlers tagged with <<tag "+tags.join(">> and <<tag ")+">>";
</script>}}}
/%
|Name|ShowTiddlerInfo|
|Source|http://www.TiddlyTools.com/#ShowTiddlerInfo|
|Version|0.0.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <<br>>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|script|
|Requires|InlineJavascriptPlugin|
|Overrides||
|Description|display information and source excerpt for a specific tiddler|

Usage:

<<tiddler ShowTiddlerInfo with: TiddlerName ClipMarker>>

where 'TiddlerName' is any existing tiddler and 'ClipMarker' (optional) is a unique text string for delimiting the end of the clip. Embed the clip marker in a tiddler (using a TW comment so it doesn't appear in that tiddler when displayed). The script will display the tiddler source content up to the marker

%/<script>
 var tid="$1"; if ("$1"=="$"+"1") return; // must specify tiddlername... otherwise do nothing.
 var marker="$2"; if ("$2"=="$"+"2") marker="TiddlerInfoClipMarker"; // default end-of-clip marker
 marker="/%"+marker+"%/"; // marker is enclosed in TW comment
 var clipsize=500; // default # of chars to display from beginning of each tiddler
 var tiddler=store.getTiddler(tid); if (!tiddler) return "";
 var title=tiddler.title;
 var author=tiddler.modifier
 var size=tiddler.text.length;
 var mod=tiddler.modified.formatString("DDD, MMM DDth YYYY 0hh:0mm");
 var pos=tiddler.text.indexOf(marker); if (pos!=-1) clipsize=pos;
 var clip=tiddler.text.substr(0,clipsize);
 var edit='onclick="story.displayTiddler(null,\''+title+'\',2);return false;">'+(readOnly?'view':'edit')+' source';
 var out="";
 out+='@@display:block;';
 out+='{{groupbox{@@display:block;overflow:hidden;width:auto;';
 out+='{{floatright{[[goto tiddler|'+title+']] | '+'<html><b><a href="javascript:;" '+edit+'</a></b></html>}}}';
 out+='[['+title+']] ('+size+' bytes)\n';
 out+='^^modified on '+mod+' by '+author+'^^\n';
 out+='//{{fine{'+clip.length+' character source excerpt:}}}//\n----\n{{{\n'+clip+'\n}}}\n';
 out+='@@}}}';
 out+='@@';
 return out;
</script>
<<tiddler ShowTiddlerInfo with: ShowTiddlerInfo>>
/%
|Name|ShowTiddlerStatistics|
|Source|http://www.TiddlyTools.com/#ShowTiddlerStatistics|
|Version|0.0.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <<br>>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|script|
|Requires|InlineJavascriptPlugin|
|Overrides||
|Description|display document summary / tiddler stats (newest, oldest, largest, smallest, etc.)|
%/<script>
 var tiddlers=store.getTiddlers("modified","excludeLists");
 var last=tiddlers[tiddlers.length-1];
 var total=0;
 for (var i=0; i<tiddlers.length; i++) {
 total+=tiddlers[i].text.length;
 if (!oldest || tiddlers[i].created<oldest)
 { var oldest=tiddlers[i].created; var oldtid=tiddlers[i]; }
 if (!newest || tiddlers[i].created>newest)
 { var newest=tiddlers[i].created; var newtid=tiddlers[i]; }
 if (!smallest || tiddlers[i].text.length<smallest)
 { var smallest=tiddlers[i].text.length; var smalltid=tiddlers[i]; }
 if (!largest || tiddlers[i].text.length>largest)
 { var largest=tiddlers[i].text.length; var largetid=tiddlers[i]; }
 }
 var out="";
 out+="There are "+tiddlers.length+" tiddlers";
 out+=" {{fine{("+total+" bytes)}}}\n";
 out+="last change: [["+last.title+"]]";
 out+=" {{fine{(updated "+last.modified.formatString("MMM DDth YYYY, 0hh:0mm")+")}}}\n";
 out+="newest: [["+newtid.title+"]]";
 out+=" {{fine{(created "+newtid.created.formatString("MMM DDth YYYY, 0hh:0mm")+")}}}\n";
 out+="oldest: [["+oldtid.title+"]]";
 out+=" {{fine{(created "+oldtid.created.formatString("MMM DDth YYYY, 0hh:0mm")+")}}}\n";
 out+="smallest: [["+smalltid.title+"]]";
 out+=" {{fine{("+smalltid.text.length+" bytes)}}}\n"
 out+="largest: [["+largetid.title+"]]";
 out+=" {{fine{("+largetid.text.length+" bytes)}}}"
 return(out);
</script>
<<search>><<closeAll>><<permaview>><<newTiddler>><<newJournal "DD MMM YYYY">><<tiddler SetDefaultTiddlers>><<saveChanges>><<tiddler TspotSidebar>><<slider chkSliderOptionsPanel OptionsPanel "options »" "Change TiddlyWiki advanced options">>
http://sidebarpluginvault.tiddlyspot.com/
|<<siteMap scripts 2 openSliders>><<siteMap Completions 2 openSliders>>|<<siteMap webLinks 2 openSliders >><<siteMap editing 2 openSliders>>|<<siteMap template 2 openSliders >><<siteMap table 2 openSliders >><<siteMap palette 2 openSliders >><<siteMap forms 2 openSliders >><<siteMap stylesheet 2 openSliders >>|
|noBorder threeCol|k
/***
| Name:|SiteMapMacro|
| Author:|Simon Baird|
| Location:|http://simonbaird.com/mptw/#SiteMapMacro|
| Version:|1.0.3, 15-Mar-06|

!!Examples
See SiteMap and SliderSiteMap for example usage.

!!Parameters
* Name of tiddler to start at
* Max depth (a number) 
* Format (eg, nested, see formats below)
* Don't show root flag (anything other than null turns it on)
* Tags - a string containing a bracketed list of tags that we are interested in

!!History
* 1.0.3 (15-Mar-06)
** added tag filtering
* 1.0.2 (15-Mar-06)
** Added json format and dontshowroot option
* 1.0.1 (9-Mar-06)
** Added selectable formats and fixed nested slider format
* 1.0.0 (8-Mar-06)
** first release

***/
//{{{

version.extensions.SiteMapMacro = {
	major: 1,
	minor: 0,
	revision: 3,
	date: new Date(2006,3,15),
	source: "http://simonbaird.com/mptw/#SiteMapMacro"
};

config.macros.siteMap = {

	formats: {
		bullets: {
			formatString: "%0[[%1]]\n%2",
			indentString: "*"
		},

		// put this in your StyleSheet to make it look good.
		// .sliderPanel { margin-left: 2em; }

		sliders: {
			formatString: "[[%1]]+++\n%2===\n\n",
			formatStringLeaf: "[[%1]]\n"
		},

		openSliders: {
			formatString: "[[%1]]++++\n%2===\n\n",
			formatStringLeaf: "[[%1]]\n"
		},

		popups: {
			formatString: "[[%1]]+++^\n%2===\n\n",
			formatStringLeaf: "[[%1]]\n"
		},

		// these don't work too well
		openPopups: {
			formatString: "[[%1]]++++^\n%2===\n\n",
			formatStringLeaf: "[[%1]]\n"
		},
		
		// this is a little nuts but it works
		json: {
			formatString: '\n%0{"%1":[%2\n%0]}',
			formatStringLeaf: '\n%0"%1"',
			indentString: "  ",
			separatorString: ","
		}


	},

	defaultFormat: "bullets",

	treeTraverse: function(title,depth,maxdepth,format,dontshowroot,tags,excludetags) {

		var tiddler = store.getTiddler(title);
		var tagging = store.getTaggedTiddlers(title);

		if (dontshowroot)
			depth = 0;

		var indent = "";
		if (this.formats[format].indentString)
			for (var j=0;j<depth;j++)
				indent += this.formats[format].indentString;

		var childOutput = "";
		if (!maxdepth || depth < parseInt(maxdepth)) 
			for (var i=0;i<tagging.length;i++)
				if (tagging[i].title != title) {
					if (this.formats[format].separatorString && i != 0)
						childOutput += this.formats[format].separatorString;
					childOutput += this.treeTraverse(tagging[i].title,depth+1,maxdepth,format,null,tags,excludetags);
				}

		if (childOutput == "" && (
				(tags && tags != "" && !tiddler.tags.containsAll(tags.readBracketedList())) ||
				(excludetags && excludetags != "" && tiddler.tags.containsAny(excludetags.readBracketedList()))
				)
			) {
			// so prune it cos it doesn't have the right tags and neither do any of it's children
			return "";
		}

		if (dontshowroot)
			return childOutput;

		if (this.formats[format].formatStringLeaf && childOutput == "") {
			// required for nestedSliders
			return this.formats[format].formatStringLeaf.format([indent,title,childOutput]);
		}

		return this.formats[format].formatString.format([indent,title,childOutput]);
	},

	handler: function (place,macroName,params,wikifier,paramString,tiddler) {
		wikify(this.treeTraverse(
			params[0] && params[0] != '.' ? params[0] : tiddler.title, 1, 
			params[1] && params[1] != '.' ? params[1] : null, // maxdepth
			params[2] && params[2] != '.' ? params[2] : this.defaultFormat, // format
			params[3] && params[3] != '.' ? params[3] : null, // dontshowroot
			params[4] && params[4] != '.' ? params[4] : null, // tags
			params[5] && params[5] != '.' ? params[5] : null // excludetags
			),place);
	}

}

//}}}
TiddlyWiki tips
TW202
/***
|Name|SliderMacro|
|Version|1.0.3|
|Requires|~TW2.x|


!Code
***/
//{{{

// this part is not actually required but useful to other people using your plugin
version.extensions.SliderFolderMacro = { major: 1, minor: 0, revision: 3, date: new Date(2006,3,3),
 source: "http://simonbaird.com/mptw/#HelloWorldMacro"
};

config.macros.SliderFolder = {
	label: "SliderFolder",
	prompt: "This will send a message" 
};
config.macros.SliderFolder.handler = function (place,macroName,params,wikifier,paramString,tiddler) {
	var who = params.length > 0 ? params[0] : "world";
	var tg = params.length > 0 ? params[0] : "world";
	var note = params[1] != null ?  params[1] : "please, add a comment"; 
	note = "[["+note+"]]";
	var folder = tg + "F";
	var lbl = tg + "...>";
	var opn = "[[o|"+tg+"]]";

	//wikify("Hello //" + who + "// from the '" + macroName + "' macro in tiddler [[" + tiddler.title + "]].", place);
	wikify("<<slider chkSlider" + folder + " " + folder + " " + lbl + " " + note + ">>" + opn,place);

}

// a one liner...
config.macros.MySlider = { 
	handler: function(place,name,params) { 
		wikify("//''@@font-size:5em;color:#696;"+ params[0] + "!@@''//", place); 
	} 
};


//}}}

/***

!Another example
{{{<<MySlider Yeah>>}}}


<<MySlider Yeah>>

<<SliderFolder>>


***/
&infin;
&empty;
&int;
&asymp;
&equiv;
&otimes;
&harr;
&copy;
&para;
&times;
&Ntilde;&ntilde;
&aacute; &eacute; &iacute; &oacute; &uacute;
&oslash;	&Oslash;	
{{{
&#8869;  	&perp;  	perpendicular
}}}
&#8869;  	&perp;  	perpendicular
{{{
&#8629;  	&crarr;  	carriage return arrow
}}}
&#8629;  	&crarr;  	carriage return arrow
!Printing with script
<script>
var print = function() {
s = arguments[0].substr(0,3);
document.write(s+"=");
   document.write(arguments[0]+'<BR>'); 
   }
print("\x30");
document.write("\x30"); // 0
document.write("\x40"); // @
print("\x40");
document.write("\x41"); // A
document.write("\x45"); // E
document.write("\x50"); // P
document.write("\x55"); // 
document.write("\x60");
document.write("\x61");
document.write("\x62");
document.write("\x65");
document.write("\x66");
document.write("\x76");

document.write("\x85");
document.write("\x86");
document.write("\x99");
document.write("\xA0");
document.write("\xA1");
document.write("\xA2");
document.write("\xA3");
document.write("\xA4");
document.write("\xA5");
document.write("\xA6");
document.write("\xA7");
document.write("\xA8");
document.write("\xA9");
document.write("\xAB");
document.write("\xAC");
//document.write("<br> \\xAD=","\xAD","<br>");
print("\xAD");
document.write("\xAD");
document.write("\xAE");
document.write("\xD8");
document.write("\xD7");
document.write("\xB0");
document.write("\xB1");
document.write("\xB2");
document.write("\xBB");
document.write("\xAB");
document.write("\xAC");
document.write("\xC0");
document.write("\xC1");
document.write("\xC2");
document.write("\xC3");
/*
s = "";
    for (i=0; i < 9; i++) {
s = "xA"+i
       document.write("\\"+s);
    }
*/

document.write("\xBB");
document.write("\xAB");
document.write("\xAC");

</script>
{{{
This is AnotherLink, this is a copyright symbol &copy; and this site is called <<tiddler SiteTitle>>
<nowiki>This is AnotherLink, this is a copyright symbol &copy; and this site is called <<tiddler SiteTitle>></nowiki>
"""This is AnotherLink, this is a copyright symbol &copy; and this site is called <<tiddler SiteTitle>>"""
}}}
This is AnotherLink, this is a copyright symbol &copy; and this site is called <<tiddler SiteTitle>>
<nowiki>This is AnotherLink, this is a copyright symbol &copy; and this site is called <<tiddler SiteTitle>></nowiki>
"""This is AnotherLink, this is a copyright symbol &copy; and this site is called <<tiddler SiteTitle>>"""
Pending
InProgress
OnHold
Complete
http://gimcrackd.com/
.makeMeRed {
color:red;
}

.stretch img { 
	width:100%; 
}


.consoleClass{

	color: #fff; background: #000;
	font-size:.75em; 
	font-family:arial,helvetica; 
	margin:0; padding:0;
/*	font-family: 'Courier New';	*/
/*	font-weight:bold; */



}

.wrappingClass{
        color: #666; background: #abc;
}



[[MptwStyleSheet]]
[[StyleSheetSyntaxHighlighter]]
[[ReferencesStyleSheet]]
/***
StyleSheet for ~SyntaxHighlighter
***/

/*{{{*/
.dp-highlighter
{
	font-family: "Consolas", "Courier New", Courier, mono, serif;
	font-size: 12px;
	background-color: #E7E5DC;
	width: 99%;
	overflow: auto;
	margin: 18px 0 18px 0 !important;
	padding-top: 1px; /* adds a little border on top when controls are hidden */
}

/* clear styles */
.dp-highlighter ol,
.dp-highlighter ol li,
.dp-highlighter ol li span 
{
	margin: 0;
	padding: 0;
	border: none;
}

.dp-highlighter a,
.dp-highlighter a:hover
{
	background: none;
	border: none;
	padding: 0;
	margin: 0;
}

.dp-highlighter .bar
{
	padding-left: 45px;
}

.dp-highlighter.collapsed .bar,
.dp-highlighter.nogutter .bar
{
	padding-left: 0px;
}

.dp-highlighter ol
{
	list-style: decimal; /* for ie */
	background-color: #fff;
	margin: 0px 0px 1px 45px !important; /* 1px bottom margin seems to fix occasional Firefox scrolling */
	padding: 0px;
	color: #5C5C5C;
}

.dp-highlighter.nogutter ol,
.dp-highlighter.nogutter ol li
{
	list-style: none !important;
	margin-left: 0px !important;
}

.dp-highlighter ol li,
.dp-highlighter .columns div
{
	list-style: decimal-leading-zero; /* better look for others, override cascade from OL */
	list-style-position: outside !important;
	border-left: 3px solid #6CE26C;
	background-color: #F8F8F8;
	color: #5C5C5C;
	padding: 0 3px 0 10px !important;
	margin: 0 !important;
	line-height: 14px;
}

.dp-highlighter.nogutter ol li,
.dp-highlighter.nogutter .columns div
{
	border: 0;
}

.dp-highlighter .columns
{
	background-color: #F8F8F8;
	color: gray;
	overflow: hidden;
	width: 100%;
}

.dp-highlighter .columns div
{
	padding-bottom: 5px;
}

.dp-highlighter ol li.alt
{
	background-color: #FFF;
	color: inherit;
}

.dp-highlighter ol li span
{
	color: black;
	background-color: inherit;
}

/* Adjust some properties when collapsed */

.dp-highlighter.collapsed ol
{
	margin: 0px;
}

.dp-highlighter.collapsed ol li
{
	display: none;
}

/* Additional modifications when in print-view */

.dp-highlighter.printing
{
	border: none;
}

.dp-highlighter.printing .tools
{
	display: none !important;
}

.dp-highlighter.printing li
{
	display: list-item !important;
}

/* Styles for the tools */

.dp-highlighter .tools
{
	padding: 3px 8px 3px 10px;
	font: 9px Verdana, Geneva, Arial, Helvetica, sans-serif;
	color: silver;
	background-color: #f8f8f8;
	padding-bottom: 10px;
	border-left: 3px solid #6CE26C;
}

.dp-highlighter.nogutter .tools
{
	border-left: 0;
}

.dp-highlighter.collapsed .tools
{
	border-bottom: 0;
}

.dp-highlighter .tools a
{
	font-size: 9px;
	color: #a0a0a0;
	background-color: inherit;
	text-decoration: none;
	margin-right: 10px;
}

.dp-highlighter .tools a:hover
{
	color: red;
	background-color: inherit;
	text-decoration: underline;
}

/* About dialog styles */

.dp-about { background-color: #fff; color: #333; margin: 0px; padding: 0px; }
.dp-about table { width: 100%; height: 100%; font-size: 11px; font-family: Tahoma, Verdana, Arial, sans-serif !important; }
.dp-about td { padding: 10px; vertical-align: top; }
.dp-about .copy { border-bottom: 1px solid #ACA899; height: 95%; }
.dp-about .title { color: red; background-color: inherit; font-weight: bold; }
.dp-about .para { margin: 0 0 4px 0; }
.dp-about .footer { background-color: #ECEADB; color: #333; border-top: 1px solid #fff; text-align: right; }
.dp-about .close { font-size: 11px; font-family: Tahoma, Verdana, Arial, sans-serif !important; background-color: #ECEADB; color: #333; width: 60px; height: 22px; }

/* Language specific styles */

.dp-highlighter .comment, .dp-highlighter .comments { color: #008200; background-color: inherit; }
.dp-highlighter .string { color: blue; background-color: inherit; }
.dp-highlighter .keyword { color: #069; font-weight: bold; background-color: inherit; }
.dp-highlighter .preprocessor { color: gray; background-color: inherit; }

/*}}}*/
<script>
var a = 'Hello world!';
document.write(a.substring(0,4));
</script>
// make it so you can by default see edit controls via http
config.options.chkHttpReadOnly = false;
window.readOnly = false; // make sure of it (for tw 2.2)
window.showBackstage = true; // show backstage too
/*{{{*/

/* flag dev version */
body {border-top:solid 3px #c44; }

#sidebar {display:none;}

.flaggedMandatory { background-color:#c99;}
.txtOptionInput { border:1px solid #ddd; border-top:1px solid #999; margin:4px;}
a.tiddlyLink { padding:0.1em 0.2em; }
a.tiddlyLink:hover { background-color:#ccd; color:#000; }

#mainMenu { width:15em; }
#displayArea { margin:1em 1em 1em 15em; }
#tiddlerDisplay { margin:0 5em 2em 5em; }
	
#controlsContainer { background-color:#ddd; border-top:solid 1px #fff;  border-bottom:solid 1px #aaa; }
#controlsContainer a.button { padding:0.4em 1em; border:solid 0 #000; color:#333; font-size:1em; line-height:2em; border-right:solid 1px #ccc;}
#controlsContainer a.button:hover { background-color:#ccc; color:#000; }
#controlsContainer div.sliderPanel { background-color:#333; border-top:solid 1px #aaa;}
#controlsContainer  .txtOptionInput { margin: 0; font-size:0.9em; padding:2px; border-right:solid 1px #ccc;}

#controlsContainer div.txtMainTab {  }
#controlsContainer div.txtMainTab div.tabset { background-color:#ccd; color:#ccc; float:left; padding:0; height:200px; width:150px; border-right:solid 1px #aaa; }
#controlsContainer div.txtMainTab div.tabset a.tab { display:block; padding:0.5em 1em; text-align:right; background-color:#ccd; border-bottom:solid 1px #aaa; margin:0;}
#controlsContainer div.txtMainTab div.tabset a.tabSelected {background-color:#bbc; border-top:solid 0px #aaa; color:#fff; }
#controlsContainer div.txtMainTab div.tabset a.tab:hover {background-color:#bbc; }
 
#controlsContainer div.tabContents {float:left; height:200px; width:350px; background-color: transparent; overflow:auto; border:solid 0px #aaa; border-right:solid 1px #aaa; padding:0;}

#controlsContainer div.sliderPanel div.txtMainTab ul { list-style:none; margin:0; padding:0.5em 0; }
#controlsContainer div.sliderPanel div.txtMainTab ul li { padding:0 20px;}
#controlsContainer div.sliderPanel div.txtMainTab ul li a { font-weight:normal; line-height:1.3em; margin:0.2em 0; }
#controlsContainer div.sliderPanel div.txtMainTab ul li.listTitle { border-top:solid 1px #bbc; padding:0.5em 0 0.2em 20px; font-size:1.5em; color:#bbc; }
#controlsContainer div.sliderPanel div.txtMainTab ul li.listLink { margin:0; }
#controlsContainer div.sliderPanel div.txtMainTab ul:first-child li.listTitle { border: solid 0 #ccc;  }

#popup { border:solid 1px [[ColorPalette::Subtle]]; border-bottom:solid 1px [[ColorPalette::LessSubtle]]; border-right:solid 1px [[ColorPalette::LessSubtle]]; background-color:[[ColorPalette::Background]]; padding:1px 0 0 0;}
#popup li a { background-color:[[ColorPalette::SubtleSuperLight]]; color:[[ColorPalette::MuchLessSubtle]]; text-align:left;}
#popup li a:hover { background-color:[[ColorPalette::SubtleLight]]; color:[[ColorPalette::MuchLessSubtle]];}
#popup li.listBreak div {border-bottom:solid 1px [[ColorPalette::Background]]; border-top:solid 1px [[ColorPalette::SubtleLight]]; margin:0;}

#controlsContainer div.topOptions {float:left; background-color:#bbc; width:400px; }

div.tiddler div.viewer { padding:1em 0 3em 0; border-bottom:solid 1px #ccc;}
h1,h2,h3,h4 { border-style:none; }
div.tiddler div.viewer > img {width:100%;}


div.tiddler div.task { border:solid 1px #aaa; background-color:#f2f2f2; position:relative; overflow:auto; clear:both; zoom:1;}
div.tiddler div.task div.taskBody { float:left; display:block; padding:1em 1em 1em 1em;}
div.tiddler div.task div.viewer { border-style:none; }
div.tiddler div.task div.taskControls {float:right; border-left:solid 1px #aaa; width:21em;  background-color:#ccd; padding:0; white-space:nowrap; }
div.tiddler div.task div.taskControls div.toolbar a { display:block; padding:0.5em 1em; text-align:right; background-color:#ccd; border-style:none; font-size:1.2em; color:#fff; text-align:left; border-bottom:solid 1px #aaa; margin:0;}
div.tiddler div.task div.taskControls div.toolbar a:hover {background-color:#bbc; }
div.tiddler div.task div.taskControls div.metacontrols { padding:1em; }
div.tiddler div.task div.taskControls div.metacontrols select {width: 150px; border:solid 1px #aaa; font-size:0.9em; padding:0.2em;}
div.tiddler div.task div.taskControls div.metacontrols table {border-style:none; margin:0;}
div.tiddler div.task div.taskControls div.metacontrols table tr {border-style:none;}
div.tiddler div.task div.taskControls div.metacontrols table td {border-style:none;}

#createTeamTaskUserForm { background-color:#f0f0f0; padding:1em; border:solid 1px #ccc;}
#createTeamTaskUserForm label { margin-bottom:10px; display:block; clear:left; font-size:0.9em;}
#createTeamTaskUserForm label input {float:left; border:1px solid #ddd; border-top:1px solid #999; padding:2px 4px; font-size:1em; width:30em;}


/*}}}*/
http://twmath.tiddlyspot.com/
http://deferentialgeometry.org/
<<allTags excludeLists>>
<<tabs txtMoreTab "Tags" "All Tags" TabAllTags "Miss" "Missing tiddlers" TabMoreMissing "Orph" "Orphaned tiddlers" TabMoreOrphans "Shad" "Shadowed tiddlers" TabMoreShadowed>>
<<allTags excludeLists [a-z]>>
Example 1
|!one|!two|!three|
|>| r1r2c1c2 |r1c3|
|>|~|r2c3|


Example 2
|!one|!two|!three|
|r1c1| r1r2c2 |r1c3|
|r2c1|~|r2c3|

Example 3
|!one|!two|!three|
|r1c1|r1c2| r1r2c3 |
|r2c1|r2c2|~|

Example 4
|!one|!two|!three|!four|
| r1r2c1 |>| r1c2c3 | a |
|~|b|c|d|
|e|~|~| f|

Example 5
|!one|!two|!three|!four|
| r1r2c1 |>| r1c2c3 |a|
|~|b|c|d|
|e|~|f|~|

|>|>|>|>| !June 2007 Statistics |
|&nbsp;| Page Loads | Unique Visitors | First Time Visitors | Returning Visitors |
|Total | 5,340| 4,639| 3,372| 1,267|
|Average | 178| 155| 112| 42|
~~open:  [[all|Tasks - All]] | [[pending|Tasks - Pending]] | [[completed|Tasks - Completed]] | [[work|Tasks - Work]]~~
<<tabs txtFavourite
Pending Pending "Tasks - Pending"
Completed Completed "Tasks - Completed"
Work Work "Tasks - Work"
>>
<<tagCloud systemConfig>>
/***
|Name|TaggedTemplateTweak|
|Source|http://www.TiddlyTools.com/#TaggedTemplateTweak|
|Version|1.1.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides|Story.prototype.chooseTemplateForTiddler()|
|Description|use alternative ViewTemplate/EditTemplate for tiddler's tagged with specific tag values|
The core function, "story.chooseTemplateForTiddler(title,template)" is essentially a "pass-thru" that returns the same template it was given, and is provided by the core so that plugins can customize the template selection logic to select alternative templates, based on whatever programmatic criteria is appropriate.  This tweak extends story.chooseTemplateForTiddler() so that ''whenever a tiddler is marked with a specific tag value, it can be viewed and/or edited using alternatives to the standard tiddler templates.'' 
!!!!!Usage
<<<
Each alternative template is associated with a specific tiddler tag value by using that tag value as a prefix added to the standard TiddlyWiki template titles, [[ViewTemplate]] and [[EditTemplate]].

For example, any tiddlers that are tagged with ''<<tag media>>'' will look for alternative templates named [[mediaViewTemplate]] and [[mediaEditTemplate]].  Additionally, in order to find templates that have proper WikiWord tiddler titles (e.g., [[MediaViewTemplate]] and [[MediaEditTemplate]]), the plugin will also attempt to use a capitalized form of the tag value (e.g., ''Media'') as a prefix.  //This capitalization is for comparison purposes only and will not alter the actual tag values that are stored in the tiddler.//

If no matching alternative template can be found by using //any// of the tiddler's tags (either "as-is" or capitalized), the tiddler defaults to using the appropriate standard [[ViewTemplate]] or [[EditTemplate]] definition.

''To add your own custom templates:''
>First, decide upon a suitable tag keyword to uniquely identify your custom templates and create custom view and/or edit templates using that keyword as a prefix (e.g., "KeywordViewTemplate" and "KeywordEditTemplate").  Then, simply create a tiddler and tag it with your chosen keyword... that's it!  As long as the tiddler is tagged with your keyword, it will be displayed using the corresponding alternative templates.  If you remove the tag or rename/delete the alternative templates, the tiddler will revert to using the standard viewing and editing templates.
<<<
!!!!!Examples
<<<
|Sample tiddler| tag | view template | edit template |
|[[MediaSample - QuickTime]]| <<tag media>> | [[MediaViewTemplate]] | [[MediaEditTemplate]] |
|[[MediaSample - Windows]]| <<tag media>> | [[MediaViewTemplate]] | [[MediaEditTemplate]] |
|[[CDSample]]| <<tag CD>> | [[CDViewTemplate]] | [[CDEditTemplate]] |
|<<newTiddler label:"create new task..." title:SampleTask tag:task text:"Type some text and then press DONE to view the task controls">> | <<tag task>> | [[TaskViewTemplate]] | [[EditTemplate]] |

//(note: if these samples are not present in your document, please visit// http://www.TiddlyTools.com/ //to view these sample tiddlers on-line)//
<<<
!!!!!Revision History
<<<
2007.06.23 [1.1.0] re-written to use automatic 'tag prefix' search instead of hard coded check for each tag.  Allows new custom tags to be used without requiring code changes to this plugin.
2007.06.11 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.taggedTemplate= {major: 1, minor: 1, revision: 0, date: new Date(2007,6,18)};
Story.prototype.taggedTemplate_chooseTemplateForTiddler = Story.prototype.chooseTemplateForTiddler
Story.prototype.chooseTemplateForTiddler = function(title,template)
{
	// get default template from core
	var template=this.taggedTemplate_chooseTemplateForTiddler.apply(this,arguments);

	// if the tiddler to be rendered doesn't exist yet, just return core result
	var tiddler=store.getTiddler(title); if (!tiddler) return template;

	// look for template whose prefix matches a tag on this tiddler
	for (t=0; t<tiddler.tags.length; t++) {
		var tag=tiddler.tags[t];
		if (store.tiddlerExists(tag+template)) { template=tag+template; break; }
		// try capitalized tag (to match WikiWord template titles)
		var cap=tag.substr(0,1).toUpperCase()+tag.substr(1);
		if (store.tiddlerExists(cap+template)) { template=cap+template; break; }
	}

	return template;
}
//}}}
/***
| Name|TagglyTaggingPlugin|
| Description|tagglyTagging macro is a replacement for the builtin tagging macro in your ViewTemplate|
| Version|3.1 ($Rev: 2351 $)|
| Date|$Date: 2007-07-12 10:18:02 +1000 (Thu, 12 Jul 2007) $|
| Source|http://mptw.tiddlyspot.com/#TagglyTaggingPlugin|
| Author|Simon Baird <simon.baird@gmail.com>|
| License|http://mptw.tiddlyspot.com/#TheBSDLicense|
!Notes
See http://mptw.tiddlyspot.com/#TagglyTagging
***/
//{{{
config.taggly = {

	// for translations
	lingo: {
		labels: {
			asc:        "\u2191", // down arrow
			desc:       "\u2193", // up arrow
			title:      "title",
			modified:   "modified",
			created:    "created",
			show:       "+",
			hide:       "-",
			normal:     "normal",
			group:      "group",
			commas:     "commas",
			sitemap:    "sitemap",
			numCols:    "cols\u00b1", // plus minus sign
			label:      "Tagged as '%0':",
			excerpts:   "excerpts",
			contents:   "contents",
			sliders:    "sliders",
			noexcerpts: "title only"
		},

		tooltips: {
			title:    "Click to sort by title",
			modified: "Click to sort by modified date",
			created:  "Click to sort by created date",
			show:     "Click to show tagging list",
			hide:     "Click to hide tagging list",
			normal:   "Click to show a normal ungrouped list",
			group:    "Click to show list grouped by tag",
			sitemap:  "Click to show a sitemap style list",
			commas:   "Click to show a comma separated list",
			numCols:  "Click to change number of columns",
			excerpts: "Click to show excerpts",
			contents: "Click to show entire tiddler contents",
			sliders:  "Click to show tiddler contents in sliders",
			noexcerpts: "Click to show entire title only"
		}
	},

	config: {
		showTaggingCounts: true,
		listOpts: {
			// the first one will be the default
			sortBy:     ["title","modified","created"],
			sortOrder:  ["asc","desc"],
			hideState:  ["show","hide"],
			listMode:   ["normal","group","sitemap","commas"],
			numCols:    ["1","2","3","4","5","6"],
			excerpts:   ["noexcerpts","excerpts","contents","sliders"]
		},
		valuePrefix: "taggly.",
		excludeTags: ["excludeLists","excludeTagging"],
		excerptSize: 50,
		excerptMarker: "/%"+"%/"
	},

	getTagglyOpt: function(title,opt) {
		var val = store.getValue(title,this.config.valuePrefix+opt);
		return val ? val : this.config.listOpts[opt][0];
	},

	setTagglyOpt: function(title,opt,value) {
		if (!store.tiddlerExists(title))
			// create it silently
			store.saveTiddler(title,title,config.views.editor.defaultText.format([title]),config.options.txtUserName,new Date(),null);
		// if value is default then remove it to save space
		return store.setValue(title,
			this.config.valuePrefix+opt,
			value == this.config.listOpts[opt][0] ? null : value);
	},

	getNextValue: function(title,opt) {
		var current = this.getTagglyOpt(title,opt);
		var pos = this.config.listOpts[opt].indexOf(current);
		// a little usability enhancement. actually it doesn't work right for grouped or sitemap
		var limit = (opt == "numCols" ? store.getTaggedTiddlers(title).length : this.config.listOpts[opt].length);
		var newPos = (pos + 1) % limit;
		return this.config.listOpts[opt][newPos];
	},

	toggleTagglyOpt: function(title,opt) {
		var newVal = this.getNextValue(title,opt);
		this.setTagglyOpt(title,opt,newVal);
	}, 

	createListControl: function(place,title,type) {
		var lingo = config.taggly.lingo;
		var label;
		var tooltip;
		var onclick;

		if ((type == "title" || type == "modified" || type == "created")) {
			// "special" controls. a little tricky. derived from sortOrder and sortBy
			label = lingo.labels[type];
			tooltip = lingo.tooltips[type];

			if (this.getTagglyOpt(title,"sortBy") == type) {
				label += lingo.labels[this.getTagglyOpt(title,"sortOrder")];
				onclick = function() {
					config.taggly.toggleTagglyOpt(title,"sortOrder");
					return false;
				}
			}
			else {
				onclick = function() {
					config.taggly.setTagglyOpt(title,"sortBy",type);
					config.taggly.setTagglyOpt(title,"sortOrder",config.taggly.config.listOpts.sortOrder[0]);
					return false;
				}
			}
		}
		else {
			// "regular" controls, nice and simple
			label = lingo.labels[type == "numCols" ? type : this.getNextValue(title,type)];
			tooltip = lingo.tooltips[type == "numCols" ? type : this.getNextValue(title,type)];
			onclick = function() {
				config.taggly.toggleTagglyOpt(title,type);
				return false;
			}
		}

		// hide button because commas don't have columns
		if (!(this.getTagglyOpt(title,"listMode") == "commas" && type == "numCols"))
			createTiddlyButton(place,label,tooltip,onclick,type == "hideState" ? "hidebutton" : "button");
	},

	makeColumns: function(orig,numCols) {
		var listSize = orig.length;
		var colSize = listSize/numCols;
		var remainder = listSize % numCols;

		var upperColsize = colSize;
		var lowerColsize = colSize;

		if (colSize != Math.floor(colSize)) {
			// it's not an exact fit so..
			upperColsize = Math.floor(colSize) + 1;
			lowerColsize = Math.floor(colSize);
		}

		var output = [];
		var c = 0;
		for (var j=0;j<numCols;j++) {
			var singleCol = [];
			var thisSize = j < remainder ? upperColsize : lowerColsize;
			for (var i=0;i<thisSize;i++) 
				singleCol.push(orig[c++]);
			output.push(singleCol);
		}

		return output;
	},

	drawTable: function(place,columns,theClass) {
		var newTable = createTiddlyElement(place,"table",null,theClass);
		var newTbody = createTiddlyElement(newTable,"tbody");
		var newTr = createTiddlyElement(newTbody,"tr");
		for (var j=0;j<columns.length;j++) {
			var colOutput = "";
			for (var i=0;i<columns[j].length;i++) 
				colOutput += columns[j][i];
			var newTd = createTiddlyElement(newTr,"td",null,"tagglyTagging"); // todo should not need this class
			wikify(colOutput,newTd);
		}
		return newTable;
	},

	createTagglyList: function(place,title) {
		switch(this.getTagglyOpt(title,"listMode")) {
			case "group":  return this.createTagglyListGrouped(place,title); break;
			case "normal": return this.createTagglyListNormal(place,title,false); break;
			case "commas": return this.createTagglyListNormal(place,title,true); break;
			case "sitemap":return this.createTagglyListSiteMap(place,title); break;
		}
	},

	getTaggingCount: function(title) {
		// thanks to Doug Edmunds
		if (this.config.showTaggingCounts) {
			var tagCount = store.getTaggedTiddlers(title).length;
			if (tagCount > 0)
				return " ("+tagCount+")";
		}
		return "";
	},

	getExcerpt: function(inTiddlerTitle,title,indent) {
    if (!indent)
			indent = 1;
		if (this.getTagglyOpt(inTiddlerTitle,"excerpts") == "excerpts") {
			var t = store.getTiddler(title);
			if (t) {
				var text = t.text.replace(/\n/," ");
				var marker = text.indexOf(this.config.excerptMarker);
				if (marker != -1) {
					return " {{excerpt{<nowiki>" + text.substr(0,marker) + "</nowiki>}}}";
				}
				else if (text.length < this.config.excerptSize) {
					return " {{excerpt{<nowiki>" + t.text + "</nowiki>}}}";
				}
				else {
					return " {{excerpt{<nowiki>" + t.text.substr(0,this.config.excerptSize) + "..." + "</nowiki>}}}";
				}
			}
		}
		else if (this.getTagglyOpt(inTiddlerTitle,"excerpts") == "contents") {
			var t = store.getTiddler(title);
			if (t) {
				return "\n{{contents indent"+indent+"{\n" + t.text + "\n}}}";
			}
		}
		else if (this.getTagglyOpt(inTiddlerTitle,"excerpts") == "sliders") {
			var t = store.getTiddler(title);
			if (t) {
				return "<slider slide>\n{{contents{\n" + t.text + "\n}}}\n</slider>";
			}
		}
		return "";
	},

	notHidden: function(t,inTiddler) {
		if (typeof t == "string") 
			t = store.getTiddler(t);
		return (!t || !t.tags.containsAny(this.config.excludeTags) ||
				(inTiddler && this.config.excludeTags.contains(inTiddler)));
	},

	// this is for normal and commas mode
	createTagglyListNormal: function(place,title,useCommas) {

		var list = store.getTaggedTiddlers(title,this.getTagglyOpt(title,"sortBy"));

		if (this.getTagglyOpt(title,"sortOrder") == "desc")
			list = list.reverse();

		var output = [];
		var first = true;
		for (var i=0;i<list.length;i++) {
			if (this.notHidden(list[i],title)) {
				var countString = this.getTaggingCount(list[i].title);
				var excerpt = this.getExcerpt(title,list[i].title);
				if (useCommas)
					output.push((first ? "" : ", ") + "[[" + list[i].title + "]]" + countString + excerpt);
				else
					output.push("*[[" + list[i].title + "]]" + countString + excerpt + "\n");

				first = false;
			}
		}

		return this.drawTable(place,
			this.makeColumns(output,useCommas ? 1 : parseInt(this.getTagglyOpt(title,"numCols"))),
			useCommas ? "commas" : "normal");
	},

	// this is for the "grouped" mode
	createTagglyListGrouped: function(place,title) {
		var sortBy = this.getTagglyOpt(title,"sortBy");
		var sortOrder = this.getTagglyOpt(title,"sortOrder");

		var list = store.getTaggedTiddlers(title,sortBy);

		if (sortOrder == "desc")
			list = list.reverse();

		var leftOvers = []
		for (var i=0;i<list.length;i++)
			leftOvers.push(list[i].title);

		var allTagsHolder = {};
		for (var i=0;i<list.length;i++) {
			for (var j=0;j<list[i].tags.length;j++) {

				if (list[i].tags[j] != title) { // not this tiddler

					if (this.notHidden(list[i].tags[j],title)) {

						if (!allTagsHolder[list[i].tags[j]])
							allTagsHolder[list[i].tags[j]] = "";

						if (this.notHidden(list[i],title)) {
							allTagsHolder[list[i].tags[j]] += "**[["+list[i].title+"]]"
										+ this.getTaggingCount(list[i].title) + this.getExcerpt(title,list[i].title) + "\n";

							leftOvers.setItem(list[i].title,-1); // remove from leftovers. at the end it will contain the leftovers

						}
					}
				}
			}
		}

		var allTags = [];
		for (var t in allTagsHolder)
			allTags.push(t);

		var sortHelper = function(a,b) {
			if (a == b) return 0;
			if (a < b) return -1;
			return 1;
		};

		allTags.sort(function(a,b) {
			var tidA = store.getTiddler(a);
			var tidB = store.getTiddler(b);
			if (sortBy == "title") return sortHelper(a,b);
			else if (!tidA && !tidB) return 0;
			else if (!tidA) return -1;
			else if (!tidB) return +1;
			else return sortHelper(tidA[sortBy],tidB[sortBy]);
		});

		var leftOverOutput = "";
		for (var i=0;i<leftOvers.length;i++)
			if (this.notHidden(leftOvers[i],title))
				leftOverOutput += "*[["+leftOvers[i]+"]]" + this.getTaggingCount(leftOvers[i]) + this.getExcerpt(title,leftOvers[i]) + "\n";

		var output = [];

		if (sortOrder == "desc")
			allTags.reverse();
		else if (leftOverOutput != "")
			// leftovers first...
			output.push(leftOverOutput);

		for (var i=0;i<allTags.length;i++)
			if (allTagsHolder[allTags[i]] != "")
				output.push("*[["+allTags[i]+"]]" + this.getTaggingCount(allTags[i]) + this.getExcerpt(title,allTags[i]) + "\n" + allTagsHolder[allTags[i]]);

		if (sortOrder == "desc" && leftOverOutput != "")
			// leftovers last...
			output.push(leftOverOutput);

		return this.drawTable(place,
				this.makeColumns(output,parseInt(this.getTagglyOpt(title,"numCols"))),
				"grouped");

	},

	// used to build site map
	treeTraverse: function(title,depth,sortBy,sortOrder) {

		var list = store.getTaggedTiddlers(title,sortBy);
		if (sortOrder == "desc")
			list.reverse();

		var indent = "";
		for (var j=0;j<depth;j++)
			indent += "*"

		var childOutput = "";
		for (var i=0;i<list.length;i++)
			if (list[i].title != title)
				if (this.notHidden(list[i].title,this.config.inTiddler))
					childOutput += this.treeTraverse(list[i].title,depth+1,sortBy,sortOrder);

		if (depth == 0)
			return childOutput;
		else
			return indent + "[["+title+"]]" + this.getTaggingCount(title) + this.getExcerpt(this.config.inTiddler,title,depth) + "\n" + childOutput;
	},

	// this if for the site map mode
	createTagglyListSiteMap: function(place,title) {
		this.config.inTiddler = title; // nasty. should pass it in to traverse probably
		var output = this.treeTraverse(title,0,this.getTagglyOpt(title,"sortBy"),this.getTagglyOpt(title,"sortOrder"));
		return this.drawTable(place,
				this.makeColumns(output.split(/(?=^\*\[)/m),parseInt(this.getTagglyOpt(title,"numCols"))), // regexp magic
				"sitemap"
				);
	},

	macros: {
		tagglyTagging: {
			handler: function (place,macroName,params,wikifier,paramString,tiddler) {
				var refreshContainer = createTiddlyElement(place,"div");
				// do some refresh magic to make it keep the list fresh - thanks Saq
				refreshContainer.setAttribute("refresh","macro");
				refreshContainer.setAttribute("macroName",macroName);
        			refreshContainer.setAttribute("title",tiddler.title);
				this.refresh(refreshContainer);
			},

			refresh: function(place) {
				var title = place.getAttribute("title");
				removeChildren(place);
				if (store.getTaggedTiddlers(title).length > 0) {
					var lingo = config.taggly.lingo;
					config.taggly.createListControl(place,title,"hideState");
					if (config.taggly.getTagglyOpt(title,"hideState") == "show") {
						createTiddlyElement(place,"span",null,"tagglyLabel",lingo.labels.label.format([title]));
						config.taggly.createListControl(place,title,"title");
						config.taggly.createListControl(place,title,"modified");
						config.taggly.createListControl(place,title,"created");
						config.taggly.createListControl(place,title,"listMode");
						config.taggly.createListControl(place,title,"excerpts");
						config.taggly.createListControl(place,title,"numCols");
						config.taggly.createTagglyList(place,title);
					}
				}
			}
		}
	},

	// todo fix these up a bit
	styles: [
"/*{{{*/",
"/* created by TagglyTaggingPlugin */",
".tagglyTagging { padding-top:0.5em; }",
".tagglyTagging li.listTitle { display:none; }",
".tagglyTagging ul {",
"	margin-top:0px; padding-top:0.5em; padding-left:2em;",
"	margin-bottom:0px; padding-bottom:0px;",
"}",
".tagglyTagging { vertical-align: top; margin:0px; padding:0px; }",
".tagglyTagging table { margin:0px; padding:0px; }",
".tagglyTagging .button { visibility:hidden; margin-left:3px; margin-right:3px; }",
".tagglyTagging .button, .tagglyTagging .hidebutton {",
"	color:[[ColorPalette::TertiaryLight]]; font-size:90%;",
"	border:0px; padding-left:0.3em;padding-right:0.3em;",
"}",
".tagglyTagging .button:hover, .hidebutton:hover, ",
".tagglyTagging .button:active, .hidebutton:active  {",
"	border:0px; background:[[ColorPalette::TertiaryPale]]; color:[[ColorPalette::TertiaryDark]];",
"}",
".selected .tagglyTagging .button { visibility:visible; }",
".tagglyTagging .hidebutton { color:[[ColorPalette::Background]]; }",
".selected .tagglyTagging .hidebutton { color:[[ColorPalette::TertiaryLight]] }",
".tagglyLabel { color:[[ColorPalette::TertiaryMid]]; font-size:90%; }",
".tagglyTagging ul {padding-top:0px; padding-bottom:0.5em; margin-left:1em; }",
".tagglyTagging ul ul {list-style-type:disc; margin-left:-1em;}",
".tagglyTagging ul ul li {margin-left:0.5em; }",
".editLabel { font-size:90%; padding-top:0.5em; }",
".tagglyTagging .commas { padding-left:1.8em; }",
"/* not technically tagglytagging but will put them here anyway */",
".tagglyTagged li.listTitle { display:none; }",
".tagglyTagged li { display: inline; font-size:90%; }",
".tagglyTagged ul { margin:0px; padding:0px; }",
".excerpt { color:[[ColorPalette::TertiaryDark]]; }",
"div.tagglyTagging table,",
"div.tagglyTagging table tr,",
"td.tagglyTagging",
" {border-style:none!important; }",
".tagglyTagging .contents { border-bottom:2px solid [[ColorPalette::TertiaryPale]]; padding:0 1em 1em 0.5em;",
"  margin-bottom:0.5em; }",
".tagglyTagging .indent1  { margin-left:3em;  }",
".tagglyTagging .indent2  { margin-left:4em;  }",
".tagglyTagging .indent3  { margin-left:5em;  }",
".tagglyTagging .indent4  { margin-left:6em;  }",
".tagglyTagging .indent5  { margin-left:7em;  }",
".tagglyTagging .indent6  { margin-left:8em;  }",
".tagglyTagging .indent7  { margin-left:9em;  }",
".tagglyTagging .indent8  { margin-left:10em; }",
".tagglyTagging .indent9  { margin-left:11em; }",
".tagglyTagging .indent10 { margin-left:12em; }",
"/*}}}*/",
		""].join("\n"),

	init: function() {
		merge(config.macros,this.macros);
		config.shadowTiddlers["TagglyTaggingStyles"] = this.styles;
		store.addNotification("TagglyTaggingStyles",refreshStyles);
	}
};

config.taggly.init();

//}}}

/***
InlineSlidersPlugin
By Saq Imtiaz
http://tw.lewcid.org/sandbox/#InlineSlidersPlugin

// syntax adjusted to not clash with NestedSlidersPlugin

***/
//{{{
config.formatters.unshift( {
	name: "inlinesliders",
	// match: "\\+\\+\\+\\+|\\<slider",
	match: "\\<slider",
	// lookaheadRegExp: /(?:\+\+\+\+|<slider) (.*?)(?:>?)\n((?:.|\n)*?)\n(?:====|<\/slider>)/mg,
	lookaheadRegExp: /(?:<slider) (.*?)(?:>)\n((?:.|\n)*?)\n(?:<\/slider>)/mg,
	handler: function(w) {
		this.lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = this.lookaheadRegExp.exec(w.source)
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart ) {
			var btn = createTiddlyButton(w.output,lookaheadMatch[1] + " "+"\u00BB",lookaheadMatch[1],this.onClickSlider,"button sliderButton");
			var panel = createTiddlyElement(w.output,"div",null,"sliderPanel");
			panel.style.display = "none";
			wikify(lookaheadMatch[2],panel);
			w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
		}
   },
   onClickSlider : function(e) {
		if(!e) var e = window.event;
		var n = this.nextSibling;
		n.style.display = (n.style.display=="none") ? "block" : "none";
		return false;
	}
});

//}}}
<code>
	drawTable: function(place,columns,theClass) {
		var newTable = createTiddlyElement(place,&quot;table&quot;,null,theClass);
		var newTbody = createTiddlyElement(newTable,&quot;tbody&quot;);
		var newTr = createTiddlyElement(newTbody,&quot;tr&quot;);
		for (var j=0;j&lt;columns.length;j++) {
			var colOutput = &quot;&quot;;
			for (var i=0;i&lt;columns[j].length;i++) 
				colOutput += columns[j][i];
			var newTd = createTiddlyElement(newTr,&quot;td&quot;,null,&quot;tagglyTagging&quot;); // todo should not need this class
			wikify(colOutput,newTd);
		}
		return newTable;
	},
</code>
http://www.strm.us/TidlyWiki/Examples_TWGG/IJSTaskManager.html

http://www.strm.us/TidlyWiki/NewLayout.html

http://www.strm.us/TidlyWiki/TestWiki.htm
<div><span macro="tiddler 'New Task 2'"></span></div>
<!--{{{-->
<div class='task'>
	<div class='taskBody'>
		<div class='title' macro='view title'></div>
		<div class='viewer' macro='view text wikified'></div>
	</div>
	<div class='taskControls'>
		<div class='toolbar' macro='toolbar  +editTiddler closeTiddler closeOthers fields'></div>
		<div class='metacontrols' macro='tiddler TaskTiddlerControls2'></div>
	</div>
</div>
<!--}}}-->
|scope |<<ValueSwitcher dropdown ScopeDefinitions>> |
|priority |<<ValueSwitcher dropdown PriorityDefinitions>> |
|assigned to |<<ValueSwitcher dropdown UserDefinitions>> |
|status |<<ValueSwitcher dropdown StatusDefinitions>> |
<data>{"UserDefinitions":"AlfonsoReyes","StatusDefinitions":"Complete"}</data>
|check |<<ValueSwitcher2 checkbox AnyCheckbox>> |
|scope |<<ValueSwitcher2 dropdown ScopeDefinitions>> |
|priority |<<ValueSwitcher2 dropdown PriorityDefinitions>> |
|assigned to |<<ValueSwitcher2 dropdown UserDefinitions>> |
|status |<<ValueSwitcher2 dropdown StatusDefinitions>>|
|any text|<html><input type="text" name="textField"></html>|
<data>{"ScopeDefinitions":"Play","UserDefinitions":"AlfonsoReyes","StatusDefinitions":"Pending"}</data>
/***
|Name|TaskTimerPlugin|
|Source|http://www.TiddlyTools.com/#TaskTimerPlugin|
|Version|1.2.2|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|'timer' button automatically writes start/end/elapsed time into tiddler content|
Quickly generate 'timed task' logs that can be used for status reports, billing purposes, etc.  
!!!!!Usage
<<<
{{{<<taskTimer TiddlerName "output format" "prompt text" "default description">>}}}

displays a pushbutton that, when pressed, prompts for a 'target tiddler', and then displays the current time and elapsed time on the button, updated automatically each second.  Pressing the button again will stop the timer, prompt for a 'task description' and then write the description, starttime, endtime, and elapsed time into the target tiddler content.

''~TiddlerName'' //or// ''ask'' //or// ''here'' //or// ''today'' //or// ''"""today:YYYY0MM0DD"""''
>If you omit the ''~TiddlerName'' parameter or use the keyword, ''here'', the output is inserted into the current tiddler.  If you use the keyword, ''ask'', then you will be prompted for a ~TiddlerName each time you press the button to start the timer.  If you use the keyword, ''today'', then the current date is used as the ~TiddlerName.  You can specify any date format you like by appending it to the "today:" keyword.  By default, if the format is omitted from the paramter, the date format will match that used by {{{<<newJournal>>}}} macro or the {{{<<date>>}}} and {{{<<calendar>>}}} macros (if [[DatePlugin]] and/or [[CalendarPlugin]] are installed).
>
>If the target tiddler does not yet exist, it will be automatically created when a timer activity is recorded for the first time.  Note: When used in a non-tiddler area (such as MainMenu), you should either provide a specific ~TiddlerName value (e.g., {{{<<taskTimer MainMenu>>}}} or use the ''ask'' or '''today'' keywords.
''output format''
>The default output format is: {{{|%0|%1|%2|%3|}}} where %0, %1, %2, and %3 are automatically replaced with the description, starttime, stoptime and elapsed time values, respectively.  This format generates a single row using TiddlyWiki table format, allowing each subsequent timed task to add another row to an existing table of recorded activities.  If this table format is not appropriate for your needs, you can provide an alternative formatting string, using the %n substitution markers to place those values where you want
>
>(note: do not use either single-quotes or double-quotes within the format string, as this interferes with the plugin's button generating code.  I will eventually be re-writing things to fix this, but for now... don't use quotes in the format string - ELS)
>
>The task timer output is usually appended to the end of the target tiddler content.  However, you may choose to insert the output //anywhere// within the tiddler content simply by embedding an 'insertion point marker', consisting of the keyword "tasktimer", enclosed in TW style comments, like this: ''{{{/%}}}{{{tasktimer}}}{{{%/}}}''.  When the marker is present in the tiddler source, the timed task report output is placed immediately //before// that marker, instead of at the end of the tiddler.
<<<
!!!!!Configuration
<<<
To Be Developed:
using different markers for inserting multiple task timers in different places within a single tiddler
<<<
!!!!!Examples
<<<
{{{<<taskTimer>>}}}
<<taskTimer>>
|//Description//|//Started//|//Stopped//|//Elapsed//|
/%tasktimer%/
{{{<<taskTimer ask>>}}}
<<taskTimer ask>>
<<<
!!!!!Revision History
<<<
''2007.12.13 [1.2.2]'' in getDateFormat(), cleanup fallback logic 
''2007.06.28 [1.2.1]'' pass current tiddler.fields to saveTiddler(), so updates to existing tiddler won't lose custom fields
''2007.06.25 [1.2.0]'' added optional "default text" param for specifying the default description for new activity log entries
''2007.06.22 [1.1.0]'' added "today" and "today:MMDDYYYY" as special keywords.  Generates tiddlername from current date, and uses date format defined in CalendarPlugin, DatePlugin, or DatePluginConfig if any of those tiddlers is installed.  Also, don't stop timer until user completes entering of prompted inputs (e.g., after asking for a target tiddler and activity description)
''2007.05.22 [1.0.0]'' target tiddler created when stopping timer button (i.e., second button press) instead of when starting timer.  Default header content includes comment marker.  Target tiddler is tagged with "task".
''2007.04.04 [0.8.2]'' moved handling for 'here' param into toggle().  In toggle(), only render target tiddler if button is not in that tiddler... fixes problem where starting timer with target=here was re-rendering (and thus re-initializing) the timer button (immediately stopping the timer)
''2007.03.21 [0.8.1]'' handle case where target tiddler is deleted while timer is running.
''2007.03.21 [0.8.0]'' use UTC time functions to calculate elapsed time in hours, minutes, and seconds
''2007.03.20 [0.7.0]'' added lots of cool features, like automatically creating tiddlers, with prompting, etc.
''2007.03.14 [0.5.0]'' converted from inline script
<<<
!!!!!Code
***/
//{{{
version.extensions.taskTimer= {major: 1, minor:2, revision: 2, date: new Date(2007,12,13)};

config.macros.taskTimer = {
	label: "start timer",
	title: "press to start the task timer",
	format: "|%0|%1|%2|%3|\\n", // note: double-backslash-en
	defText: " ", // default description text
	todayKeyword: "today",
	todayFormat: "0MM/0DD/YYYY", // default format - superceded by CalendarPlugin, DatePlugin, or DatePluginConfig
	defHeader: "|//Description//|//Started//|//Stopped//|//Elapsed//|\n",
	defTarget: "ActivityReport",
	prompt: "Enter a short description for this activity.  Press [cancel] to continue timer.",
	askMsg: "Enter the title of a tiddler in which to record this activity.  Press [cancel] to continue timer.",
	createdMsg: "'%0' has been created",
	updatedMsg: "'%0' has been updated",
	marker: "/%"+"tasktimer"+"%/",
	tag: "task",
	handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		var target=params.shift(); // get optional target tiddler title
		if (!target) target="";
		var format=this.format; if (params[0]) format=params.shift(); // get optional output format
		var prompt=this.prompt; if (params[0]) prompt=params.shift(); // get optional prompt text
		var defText=this.defText; if (params[0]) defText=params.shift(); // get optional default text
		var onclick="config.macros.taskTimer.toggle(this,'"+target+"','"+format+"','"+prompt+"','"+defText+"')";
		createTiddlyElement(place,"span").innerHTML =
			'<input type="button" value="start timer" title="'+this.title+'" onclick="'+onclick+'">';
	},
	toggle: function(here,target,format,msg,defText) {
		if (!target || !target.length || target=="here") {
			var  tid=story.findContainingTiddler(here);
			target=tid?tid.getAttribute("tiddler"):"ask";
		}
		if (!here.running) { // not running... start timer...
			var now=new Date();
			here.startTime=now;
			here.title=(here.target?here.target:target)+" - "+now.formatString("started at 0hh:0mm:0ss");
			here.value=now.formatString("0hh:0mm:0ss - 00:00:00");
			here.id=(new Date()).convertToYYYYMMDDHHMMSSMMM()+Math.random().toString(); // unique ID
			here.ticker=setTimeout("config.macros.taskTimer.tick('"+here.id+"')",500);
			here.running=true;
		} else {
			if (target=="ask") {
				target=prompt(this.askMsg,here.target?here.target:this.defTarget);
				if (!target) return; // user cancelled input...  continue timer
			}
			var txt=prompt(msg,defText); // get description from user
			if (!txt) return; // user cancelled input...  continue timer
			if (target==this.todayKeyword || target.substr(0,this.todayKeyword.length+1)==this.todayKeyword+":")
				target=(new Date()).formatString(this.getDateFormat(target));
			here=document.getElementById(here.id); // RE-get button element after timer has stopped...
			clearTimeout(here.ticker);
			here.target=target;
			var before=this.defHeader;
			var after=this.marker+"\n";
			var tiddler=store.getTiddler(here.target);
			if (tiddler && tiddler.text.length) {
				var pos=tiddler.text.indexOf(this.marker);
				if (pos==-1) pos=tiddler.text.length; // no marker, append content to end
				var before=tiddler.text.substr(0,pos); // everything up to marker
				var after=tiddler.text.substr(pos); // marker+everything else
			}
			var start=here.startTime.formatString("0hh:0mm:0ss");
			var now=new Date();
			var stop=now.formatString("0hh:0mm:0ss");
			var diff=new Date(now-here.startTime);
			var s=diff.getUTCSeconds(); if (s<10) s="0"+s;
			var m=diff.getUTCMinutes();  if (m<10) m="0"+m;
			var h=diff.getUTCHours();  if (h<10) h="0"+h;
			var elapsed=h+":"+m+":"+s;
			var newtxt=before+format.format([txt,start,stop,elapsed])+after;
			var newtags=(tiddler?tiddler.tags:['task']); // include 'task' tag when creating new tiddlers
			store.saveTiddler(here.target,here.target,newtxt,config.options.txtUserName,new Date(),newtags,tiddler?tiddler.fields:null);
			if (!tiddler) displayMessage(this.createdMsg.format([here.target]));
			else displayMessage(this.updatedMsg.format([here.target]));
			here.running=false;
			here.value=this.label;
			here.title=this.title;
			var  tid=story.findContainingTiddler(here);
			if (!tid || tid.getAttribute("tiddler")!=target) // display target tiddler, but only when button is not IN the target tiddler
				{ story.displayTiddler(story.findContainingTiddler(here),here.target); story.refreshTiddler(here.target,1,true); }
		}
	},
	tick: function(id) {
		var here=document.getElementById(id); if (!here) return;
		var now=new Date();
		var diff=new Date(now-here.startTime);
		var s=diff.getUTCSeconds(); if (s<10) s="0"+s;
		var m=diff.getUTCMinutes();  if (m<10) m="0"+m;
		var h=diff.getUTCHours();  if (h<10) h="0"+h;
		var elapsed=h+":"+m+":"+s;
		here.value=now.formatString("0hh:0mm:0ss")+" - "+elapsed;
		here.ticker=setTimeout("config.macros.taskTimer.tick('"+id+"')",500);
	},
	getDateFormat: function(target) {
		var fmt=target.split(":"); fmt.shift(); fmt=fmt.join(":");
		if (!fmt || !fmt.length) { // if date format was not specified
			if (config.macros.date)  // if installed, use default from DatePlugin
				fmt=config.macros.date.linkformat;
			if (config.macros.calendar) { // if installed, use default from CalendarPlugin
				if (!config.macros.date) // hard-coded calendar fallback if no DatePlugin
					fmt=config.macros.calendar.tiddlerformat;
				else // journalDateFmt is set when calendar is rendered with DatePlugin
					fmt=config.macros.calendar.journalDateFmt;
			}
		}
		if (!fmt) { // if not specified and no DatePlugin/CalendarPlugin
			// get format from <<newJournal>> in SideBarOptions
			var text = store.getTiddlerText("SideBarOptions");
			var re=new RegExp("<<(?:newJournal)([^>]*)>>","mg"); var fm=re.exec(text);
			if (fm && fm[1]!=null) { var pa=fm[1].readMacroParams(); if (pa[0]) fmt = pa[0]; }
		}
		if (!fmt) var fmt=this.todayFormat; // no "newJournal"... final fallback.
		return fmt;
	}
}
//}}}
<div><span macro="tiddler 'New Task'"></span></div>
<!--{{{-->
<div class='task'>
	<div class='taskBody'>
		<div class='title' macro='view title'></div>
		<div class='viewer' macro='view text wikified'></div>
	</div>
	<div class='taskControls'>
		<div class='toolbar' macro='toolbar +editTiddler closeTiddler closeOthers'></div>
		<div class='metacontrols' macro='tiddler TaskTiddlerControls'></div>
	</div>
</div>
<html><input type="text" name="textBox"></html><data>{}</data>
<!--}}}-->
~~open:  [[all|Tasks - All]] | [[pending|Tasks - Pending]] | [[completed|Tasks - Completed]] | [[work|Tasks - Work]]~~

<<forEachTiddler
      where 'tiddler.tags.contains("Tasks") &&
      tiddler.tags.contains("Completed")'
      sortBy 'tiddler.title'
      write "'[X('+tiddler.title+':Completed)] [['+tiddler.title+'|'+tiddler.title+']]\n'">> 
~~open:  [[all|Tasks - All]] | [[pending|Tasks - Pending]] | [[completed|Tasks - Completed]] | [[work|Tasks - Work]]~~

<<forEachTiddler
      where 'tiddler.tags.contains("Tasks") &&
      ! tiddler.tags.contains("Completed")'
      sortBy 'tiddler.title'
      write "'[X('+tiddler.title+':Completed)] [['+tiddler.title+'|'+tiddler.title+']]\n'">>
~~open:  [[all|Tasks - All]] | [[pending|Tasks - Pending]] | [[completed|Tasks - Completed]] | [[work|Tasks - Work]]~~

<<forEachTiddler
      where 'tiddler.tags.contains("Tasks") &&
      tiddler.tags.contains("Work") &&
      ! tiddler.tags.contains("Completed")'
      sortBy 'tiddler.title'
      write "'[X('+tiddler.title+':Completed)] [['+tiddler.title+'|'+tiddler.title+']]\n'">>
Task, project tracker using field storage. Customized plugins.
http://www.hawksworx.com/playground/TeamTasks/
<script>
 var tiddlerName = story.findContainingTiddler(place).id.substr(7);
 var title = tiddlerName;
 var t=store.getTiddler(tiddlerName);
 var tag = "new";
document.write("<b>"+tiddlerName+"</b><br>");
document.write(t.tags+"<br>")
//{t.tags.push(tag)}
//document.write(t.tags)

 if (!t || !t.tags) return;
 if (t.tags.find(tag)==null)
    {t.tags.push(tag)}
// else
//   var ts = t.tags.splice(t.tags.find(tag),1);
//   {t.tags.splice(t.tags.find(tag),1)};
//   story.saveTiddler(title);
//   story.refreshTiddler(title,null,true);
document.write(t.tags)


</script>
<<tiddler ShowTiddlerInfo>>
http://docbox.flint.com:8081/TextBrook
http://docbox.flint.com:8081/TextBrook
<html>
<form name="txtComboForm2">
<input type="text" size="25" name="txtBox">
<input type="button" name="B1" value="..." onclick="popText('called from button')">
<input type="reset" name="B2" value="Reset">
</form>
</html>

<script>
popText = function(str)
{
//document.example.answer.value = "100"
//eval(document.example.calculator.value)
alert(str);
document.txtComboForm2.txtBox.value = str;
//a = popup(MainMenu, "MainMenu$");
// <<popup MainMenu [[<<tiddler MainMenu$))]]>>
}
</script>
<html>
<form name="txtComboForm">
<input type="text" size="25" name="txtBox">
<input type="button" name="B1" value="..." onclick="popText('called from button')">
<input type="reset" name="B2" value="Reset">
</form>
</html>

<script>
popText = function(str)
{
//document.example.answer.value = "100"
//eval(document.example.calculator.value)
alert(str);
document.txtComboForm.txtBox.value = str;
//a = popup(MainMenu, "MainMenu$");
// <<popup MainMenu [[<<tiddler MainMenu$))]]>>
}
</script>
Include the tiddlers of an external TiddlyWiki into the current TiddlyWiki.

''Syntax'' 
|>|{{{<<}}}''include'' [''url:''] //tiddlyWikiPath// [''delay:'' //delayDuration//] [''hide:'' //hideFlag//]{{{>>}}}|
|//tiddlyWikiPath//|The path to the TiddlyWiki to include.<<br>>This may be a relative path, an absolute local file path, or a "file:", "http:" or "https:" URL)|
|//delayDuration//|Integer. Defines the number of milliseconds (thousands of a second) to wait before actually including the TiddlyWiki. By default a TiddlyWiki is included immediately when the TiddlyWiki starts.|
|//hideFlag//|When "{{{true}}}" the "include" macro is not displayed in the tiddler.|
|>|~~Syntax formatting: Keywords in ''bold'', optional parts in [...]. 'or' means that exactly one of the two alternatives must exist.~~|

''Examples'' 
{{{
<<include "http://tiddlywiki.abego-software.de/index.html">>
<<include "C:\TiddlyWiki\shared\TiddlyWikiHelp.html">>
<<include "file://C:/Private/journals/2006-12.html" delay: 8000 >>
<<include "test/sample33.html">>
}}}

''Notes''
* For security reasons it may not be possible to include some TiddlyWikis. Especially you cannot access a TiddlyWiki on a different website when running your TiddlyWiki on your webserver (the so-called "Cross-Site Scripting" issue). Nevertheless you can access TiddlyWikis on various websites if you are running your TiddlyWiki locally. And you may refer to other Wikis on your own site.
* The macro may be placed in any tiddler, but it is recommended to put them into the "IncludeList" tiddler. The includes listed in the "IncludeList" are processed at TiddlyWiki startup. An include defined in a different tiddler are processed the first time the tiddler is displayed. The order the include macros are processed is used when [[looking for a tiddler|How Tiddlers are found]].
Displays the list of "included" TiddlyWikis, together with their "load state". I.e. you can see if the TiddlyWiki is already loaded (include), if there was an error (e.g. the TiddlyWiki to include was not found) etc.

''Syntax:'' 
|>|{{{<<}}}''includeState''{{{>>}}}|

The TiddlyWikis are listed in the order they are checked for tiddlers (see [[How Tiddlers are found]])

The (shadow) tiddler "IncludeState" contains this macro, i.e. you can view that tiddler to see the current include state.

See also: [[The "include" Macro]].
<!--{{{-->
<!--
|Name|TidIDEEditTemplate|
|Source|http://www.TiddlyTools.com/#TidIDEEditTemplate|
|Version||
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <<br>>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|template|
|Requires||
|Overrides||
|Description|alternative for EditTemplate, used with TidIDEStylesheet|
-->
<div class='toolbar' macro='toolbar -cancelTiddler'></div>
<div class='title' macro='view title'></div>
<div class='viewer' macro='tidIDE system +edit:here'></div>
<span macro='resizeEditor'></span><span macro='setUserName'></span>
<span 
<!--}}}-->
    * InlineJavascriptPlugin
    * TidIDEEditTemplate
    * TidIDEPanel
    * TidIDEPlugin
    * TidIDEStyleSheet
/%
Usage: <<tiddler TidIDEPanel with: ID>>

where 'ID' is any unique text, and is used to differentiate multiple instances of TidIDE that may be displayed simultaneously

%/<script>config.macros.tidIDE.versionMsg="";</script>/%
%/{{smallform left fine{<<tidIDE id:$1 +system +JavascriptShell CompareTiddlers ShowSlices TicketTracker edit>>}}}
/***
|Name|TidIDEPlugin|
|Source|http://www.TiddlyTools.com/#TidIDEPlugin|
|Version|1.6.1|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <<br>>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|TiddlyWiki Integrated Development Environment - tools for authors and plugin writers|

~TidIDE (//prounounced "Tie Dyed"//) - ''Tid''dlyWiki ''I''ntegrated ''D''evelopment ''E''nvironment - tools for ~TiddlyWiki authors and editors.  

Provides a full-featured tiddler editor with key-by-key ''LIVE PREVIEW'' of //formatted// tiddler content!!  Also includes diagnostic tools to help you debug your TiddlyWiki problems by letting you view current TiddlyWiki internal option values, messages, shadows, stylesheets, notify and macro functions or display the internal DOM (Document Object Model) tree structure for any specific part of the TiddlyWiki document.
!!!!!Configuration
<<<
Automatically freeze preview updates when a tiddler takes more than <<option txtTidIDEAutoFreeze>> milliseconds to render.
<<<
!!!!!Usage/Example
<<<
{{{<<tidIDE id:example "font:Courier New" size:8pt system +edit:GettingStarted>>}}}
<<tidIDE id:example "font:Courier New" size:8pt system +edit:GettingStarted>>
!!!!!parameters:
* ''id'' - assign a unique ID to this instance of TidIDE.  (default id=current tiddler title or "" if not in a tiddler)
* ''font'' - sets the CSS font-family used by textarea controls in editor and system information panels.  Note: if the font name includes a space (e.g., Courier New), then you must enclose the entire parameter in double-quotes: {{{"font:Courier New"}}}.
* ''size'' - sets the CSS font-size used by text input and droplist controls in editor and system information panels.
* ''system'' includes system information panel.
* ''edit'' includes tiddler editor/previewer.
**''edit:here'' automatically sets the editor to show the current tiddler contents (if in a tiddler)
**''edit:tiddlertitle'' automatically sets the editor to show the specified tiddler contents
* use ''{{{[[label|tiddlertitle]]}}}'' to include 'custom panels' (and corresponding labelled checkboxes to toggle their display)
* all parameters are optional.  The default panel is "edit:here".
* panel parameters preceded by a "+" are displayed by default.  If only one panel specified in the parameters, it is automatically displayed, even if the "+" is omitted.
!!!!!using the editor
The editor includes a droplist of all tiddlers in the document, sorted alpha-numerically by tiddler title.  Shadow tiddlers that have not been customized are added to the end of this list and marked with "(shadow)".  Next to the droplist are several buttons:
* ''view'' opens the tiddler in the normal ~TiddlyWiki display area
* ''add'' prompts for a new tiddler title and begins a new editing session
* ''remove'' deletes an existing tiddler (note: shadow tiddlers cannot be removed)
* ''save'' saves changes to the tiddler currently being edited
* ''save as'' saves changes using a new tiddler title
If a tiddlername was not specified in the macro, select a tiddler from the droplist (or press ''add'') to begin editing.  Once a tiddler has been loaded into the editor, you can change it's content, enter or select tags.

Normally, when you save changes to a tiddler, the created/modified dates and tiddler author are automatically updated.  However, it is sometimes useful to make small changes to a tiddler without automatically updating the date/author information.  Select the ''minor edits'' checkbox to prevent those values from being //automatically// changed.  In addition, this enables the date/author edit fields which allows you to //manually// 'back date' a tiddler or change the author to another name.  When the tiddler is saved, the date/author values shown in the edit fields will be used.
!!!!!using the previewer
The ''preview'' checkbox adds a display area that shows you what your tiddler changes will look like, //before// committing to those changes.

By default, this preview display is automatically rendered each time a key is typed into the tiddler content edit field.  As soon as changes are entered, they will be instantly visible within the preview display.  Unfortunately, the partial tiddler source definitions that occur //during// editing may somtimes cause rendering problems, and some exceptionally complex tiddlers make take an unusually long amount of time to completely render their content.   In such cases, key-by-key display updates are undesirable or impractical.

When ''preview'' is selected, you can also select ''freeze'' to suspend automatic key-by-key preview display updates.  The preview display will not be re-rendered again until you press the ''refresh'' button, or clear the 'freeze' checkbox, or switch to editing a different tiddler.  The editor automatically freezes the preview display whenever the //rendering time// exceeds a pre-determined time limit (see configuration section), specified in milliseconds.  Note: the ''actual elapsed time'' used to process and render any given tiddler is reported in the browser's status bar area whenever that tiddler is previewed.

The previewer also can display a ''DOM viewer'' and an ''HTML viewer'' that are also updated with each keystroke.  These text-based displays can be helpful while attempting to correct or enhance the formatting of tiddler content, especially when complex combinations of wiki-syntax produce unexpected or undesired results.
!!!!!system information and TW option settings
You can use the ''system information'' panel to view a variety of system internal data and functions, and view/modify ''all'' of ~TiddlyWiki's internal config.option.* settings.  NOTE: Non-default config.options are stored in cookies and are retrieved whenever the TW document is loaded into a browser; however, ''core TW functions and custom-defined plugins can explicitly ignore or reset any locally-stored cookie values and use their own, internally-defined values'' instead.  As a result, changes to these may be completely ignored, or may only have an effect during the current TW document "session" (i.e., until the TW document is reloaded), even though a persistent cookie value has been saved.
!!!!! ~DOMViewer macro
syntax: {{{<<DOMViewer rows:nn indent:xxxx inline path elementID|tiddlertitle>>}}}

Whenever TiddlyWiki renders a given tiddler, it creates a 'tree' of DOM (Document Object Model) elements that represent the information that is displayed by the browser.  You can use the ''DOMViewer'' macro to examine the internal DOM elements that are produced by TiddlyWiki's formatter (the 'wikifier'), or elements directly produced by embedded macros that create custom formatted output.  This can be particularly helpful when trying to fine tune the layout and appearance of your tiddler content.

DOMViewer creates a textarea control and reports the DOM tree for the current 'insertion point' where the DOMViewer macro is being placed.  ''inline'' flag uses TiddlyWiki rendering instead of textarea control. ''path'' shows the relative location of each child element in the DOM tree, using subscript notation, ''[elementID or tiddlertitle]'' displays DOM elements starting from the node with the specified ID.  If that ID is not found in the DOM tree, the macro attempts to open a tiddler with that title and then displays the "tiddler"+title DOM elements that were rendered.
<<<
!!!!!Installation
<<<
import (or copy/paste) the following tiddlers into your document:
''TidIDEPlugin'' (tagged with <<tag systemConfig>>)
^^documentation and javascript for macro handling^^
<<<
!!!!!Revision History
<<<
''2006.12.09 [1.6.1]'' in handler(), allow non-existing tiddler title when processing "edit:title" param
so that new tiddler (or journal) can be created directly from newTiddler, newJournal, or tidIDE macro (without pressing "new" button).  Also, set 'edit=text' attribute on text area field so that default content can be initialized from "text:xxx" parameter specified in newTiddler/newJournal macro.
''2006.11.28 [1.6.0]'' added font and size params to set CSS for form controls in editor and system info panels
|please see [[TidIDEPluginHistory]] for additional revision details|
''2006.04.15 [0.5.0]'' Initial ALPHA release. Converted from inline script.
<<<
!!!!!Credits
<<<
This feature was developed by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]].
<<<
!!!!!Code
***/
// // version info
//{{{
version.extensions.tidIDE = {major: 1, minor: 6, revision: 1, date: new Date(2006,12,9)};
//}}}

// //  macro definition
//{{{
config.macros.tidIDE = {
	versionMsg: "TidIDE v%0.%1.%2: ",
	datetimefmt: "0MM/0DD/YYYY 0hh:0mm",
	titleMsg: "Please enter a new tiddler title",
	isShadowMsg: "'%0' is a shadow tiddler and cannot be removed.",
	renderMsg: "rendering preview...",
	timeoutMsg: " (> %0ms)",
	freezeMsg: " - preview is frozen.  Press [refresh] to re-display.",
	evalMsg: "Warning!!\n\nThis action will process '%0' as a systemConfig (plugin) tiddler, and may produce unexpected results!\n\nAre you sure you want to proceed?",
	toolsDef: "<html><a href='javascript:config.macros.tidIDE.set(\"%0\",\"%1\");'>edit %1...</a></html>",
	editorLabel: "TiddlerEditor",
	systemLabel: "SystemInfo"
};
config.macros.tidIDE.handler= function(place,macroName,params) {
	var here=story.findContainingTiddler(place);
	var selectors="";
	var panels="";
	var showsys=false;
	var title="";
	var id=""; if (here) id=here.id.substr(7);
	var p=params.shift();
	if (!p) p="edit:here"; // default to editor if no params
	var openpanels=[];
	var panelcount=0;
	var fontsize="8pt";
	var fontface="Courier New,fixed";
	while (p) {
		var defOpen=(p.substr(0,1)=="+"); if (defOpen) p=p.substr(1);
		if (p.substr(0,3)=="id:")
			{ id=p.substr(3); }
		else if (p.substr(0,5)=="font:")
			{ fontface=p.substr(5); }
		else if (p.substr(0,5)=="size:")
			{ fontsize=p.substr(5); }
		else if (p.substr(0,4)=="edit") {
			panelcount++;
			defOpen=defOpen || (!params[0] && panelcount==1); // if only one panel to show, default to open
			var toolname=this.editorLabel;
			if (p.indexOf('|')!=-1) toolname=p.substr(0,p.indexOf('|'));
			selectors+=this.html.editorchk.replace(/%toolname%/mg,toolname);
			selectors=selectors.replace(/%showpanel%/mg,defOpen?"CHECKED":"");
			panels+=this.html.editorpanel;
			// editor panel setup...
			panels=panels.replace(/%showpanel%/mg,defOpen?"block":"none");
			panels=panels.replace(/%maxrows%/mg,config.options.txtMaxEditRows);
			panels=panels.replace(/%disabled%/mg,readOnly?"DISABLED":"");
			panels=panels.replace(/%readonlychk%/mg,readOnly?"CHECKED":"");
			panels=panels.replace(/%minoredits%/mg,config.options.chkForceMinorUpdate&&!readOnly?"":"DISABLED");
			panels=panels.replace(/%minorchk%/mg,config.options.chkForceMinorUpdate?"CHECKED":"");
			panels=panels.replace(/%fontsize%/mg,fontsize);
			panels=panels.replace(/%fontface%/mg,fontface);
			var tiddlers=store.getTiddlers("title"); var tiddlerlist=""; 
			for (var t=0; t<tiddlers.length; t++)
				tiddlerlist+='<option value="'+tiddlers[t].title+'">'+tiddlers[t].title+'</option>';
			for (var t in config.shadowTiddlers)
				if (!store.tiddlerExists(t)) tiddlerlist+="<option value='"+t+"'>"+t+" (shadow)</option>";
			panels=panels.replace(/%tiddlerlist%/mg,tiddlerlist);
			var tags = store.getTags(); var taglist="";
			for (var t=0; t<tags.length; t++)
				taglist+="<option value='"+tags[t][0]+"'>"+tags[t][0]+"</option>";
			panels=panels.replace(/%taglist%/mg,taglist);
			if (p.substr(0,5)=="edit:") { 
				title=p.substr(5); 
				if (here && title=="here") title=here.id.substr(7);
			}
		}
		else if (p=="system") {
			panelcount++;
			defOpen=defOpen || (!params[0] && panelcount==1); // if only one panel to show, default to open
			var toolname=this.systemLabel;
			showsys=defOpen;
			if (p.indexOf('|')!=-1) toolname=p.substr(0,p.indexOf('|'));
			selectors+=this.html.systemchk.replace(/%toolname%/mg,toolname);
			selectors=selectors.replace(/%showpanel%/mg,defOpen?"CHECKED":"");
			panels+=this.html.systempanel;
			panels=panels.replace(/%showpanel%/mg,defOpen?"block":"none");
			panels=panels.replace(/%fontsize%/mg,fontsize);
			panels=panels.replace(/%fontface%/mg,fontface);
		}
		else {
			panelcount++;
			defOpen=defOpen || (!params[0] && panelcount==1); // if only one panel to show, default to open
			var toolid=toolname=p;
			if (p.indexOf('|')!=-1)
				{ toolname=p.substr(0,p.indexOf('|')); toolid=p.substr(p.indexOf('|')+1); }
			selectors+=this.html.toolschk.replace(/%toolid%/mg,toolid).replace(/%toolname%/mg,toolname);
			selectors=selectors.replace(/%showpanel%/mg,defOpen?"CHECKED":"");
			panels+=this.html.toolspanel.replace(/%toolid%/mg,toolid);
			panels=panels.replace(/%showpanel%/mg,defOpen?"block":"none");
			if (defOpen) openpanels.push(toolid);
		}
		p=params.shift(); // next param
	}
	var html=this.html.framework;
	if (panelcount<2)
		html=html.replace(/%version%/mg,'').replace(/%selector%/mg,''); // omit header/selectors if just one panel to display
	else {
		html=html.replace(/%version%/mg,
			this.versionMsg.format([version.extensions.tidIDE.major,version.extensions.tidIDE.minor,version.extensions.tidIDE.revision]));
		html=html.replace(/%selector%/mg,selectors+"<hr style='margin:0;padding:0'>");
	}
	html=html.replace(/%panels%/mg,panels);
	html=html.replace(/%id%/mg,id);
	var newIDE=createTiddlyElement(place,"span");
	newIDE.innerHTML=html;
	if (title.length) this.set(id,title);  // pre-load tiddler editor (if needed)
	if (showsys) config.macros.tidIDE.getsys(id); // pre-load system information (if needed)
	if (openpanels.length) for (i=0;i<openpanels.length;i++) { config.macros.tidIDE.loadPanel(id,openpanels[i]); }
	// see [[TextAreaPlugin]] for extended ctrl-F/G (search/search again)and TAB handler definitions
	var elems=newIDE.getElementsByTagName("textarea");
	for (var i=0;i<elems.length;i++) { 
		if (window.addKeyDownHandlers!=undefined) window.addKeyDownHandlers(elems[i]);
	}
}
//}}}

// // CUSTOM PANEL FUNCTIONS 
//{{{
config.macros.tidIDE.loadPanel=function(id,toolid) {
	var place=document.getElementById(id+"_"+toolid+"_panel"); if (!place) return;
	var t=store.getTiddler(toolid);
	place.innerHTML=""; 
	if (t) wikify(t.text,place); else place.innerHTML=this.toolsDef.format([id,toolid]);
}
//}}}

// // EDITOR PANEL FUNCTIONS
//{{{
config.macros.tidIDE.set=function(id,title) {
	var place=document.getElementById(id+"_editorpanel"); if (!place) return;
	var f=document.getElementById(id+"_editorform");
	var p=document.getElementById(id+"_preview");
	if (f.dirty && !confirm(config.commands.cancelTiddler.warning.format([f.current]))) return;
	// reset to form defaults
	f.dirty=false;
	f.current="";
	f.created.value=f.created.defaultValue;
	f.modified.value=f.modified.defaultValue;
	f.author.value=f.author.defaultValue;
	f.content.value=f.content.defaultValue;
	f.tags.value=f.tags.defaultValue;
	f.size.value=f.size.defaultValue;
	f.freeze.checked=false;
	f.domview.value="";
	f.htmlview.value="";
	f.status.value="";
	p.innerHTML="";
	if (!title.length) return;
	f.current=title;
	// values for new/shadow tiddlers
	var cdate=new Date();
	var mdate=new Date();
	var modifier=config.options.txtUserName;
	var text=config.views.editor.defaultText.format([title]);
	var tags="";
	// adjust values for shadow tiddlers
	if (store.isShadowTiddler(title))
		{ modifier=config.views.wikified.shadowModifier; text=store.getTiddlerText(title) }
	// get values for specified tiddler (if it exists)
	var t=store.getTiddler(title);
	if (t)	{ var cdate=t.created; var mdate=t.modified; var modifier=t.modifier; var text=t.text; var tags=t.getTags(); }
	if (!t && !store.isShadowTiddler(title)) f.tiddlers.options[f.tiddlers.options.length]=new Option(title,title,false,true); // add item to list
	f.tiddlers.value=title; // select current title (just in case it wasn't already selected)
	f.created.value=cdate.formatString(this.datetimefmt);
	f.modified.value=mdate.formatString(this.datetimefmt);
	f.author.value=modifier;
	f.content.value=text;
	f.tags.value=tags;
	f.minoredits.checked=config.options.chkForceMinorUpdate&&!readOnly;
	f.size.value=f.content.value.length+" bytes";
	if (f.preview.checked) { p.style.display="block"; this.render(id); }
}

config.macros.tidIDE.add=function(id) {
	var place=document.getElementById(id+"_editorpanel"); if (!place) return;
	var f=document.getElementById(id+"_editorform");
	var p=document.getElementById(id+"_preview");
	if (f.dirty && !confirm(config.commands.cancelTiddler.warning.format([f.current]))) return;
	var title=prompt(this.titleMsg,config.macros.newTiddler.title);
	while (title && store.tiddlerExists(title) && !confirm(config.messages.overwriteWarning.format([title])))
		title=prompt(this.titleMsg,config.macros.newTiddler.title);
	if (!title || !title.trim().length) return; // cancelled by user
	f.dirty=false; // suppress unneeded confirmation message
	this.set(id,title);
}

config.macros.tidIDE.remove=function(id) {
	var place=document.getElementById(id+"_editorpanel"); if (!place) return;
	var f=document.getElementById(id+"_editorform");
	var p=document.getElementById(id+"_preview");
	if (!f.current.length) return;
	if (!store.tiddlerExists(f.current) && store.isShadowTiddler(f.current)) { alert(this.isShadowMsg.format([f.current])); return; }
	if (config.options.chkConfirmDelete && !confirm(config.commands.deleteTiddler.warning.format([f.current]))) return;
	if (store.tiddlerExists(f.current)) {
		story.closeTiddler(f.current);
		store.removeTiddler(f.current);
		store.setDirty(true);
		if(config.options.chkAutoSave) saveChanges();
	}
	f.tiddlers.options[f.tiddlers.selectedIndex]=null; // remove item from list
	f.dirty=false; // suppress unneeded confirmation message
	this.set(id,""); // clear form controls
}

config.macros.tidIDE.save=function(id,saveAs) {
	var place=document.getElementById(id+"_editorpanel"); if (!place) return;
	var f=document.getElementById(id+"_editorform");
	var title=f.current;
	if (!title || !title.trim().length || saveAs) { // get a new title
		title=prompt(this.titleMsg,config.macros.newTiddler.title);
		while (title && store.tiddlerExists(title) && !confirm(config.messages.overwriteWarning.format([title])))
			title=prompt(this.titleMsg,config.macros.newTiddler.title);
		if (!title || !title.trim().length) return; // cancelled by user
		f.tiddlers.options[f.tiddlers.options.length]=new Option(title,title,false,true); // add item to list
		f.current=title;
	}
	var author=config.options.txtUserName;
	var mdate=new Date();
	var content=f.content.value;
	var tags=f.tags.value;
	var tiddler=store.saveTiddler(title,title,content,author,mdate,tags);
	if (f.minoredits.checked) {
		var author=f.author.value;
		var mdate=new Date(f.modified.value);
		var cdate=new Date(f.created.value);
		tiddler.assign(null,null,author,mdate,null,cdate);
	}
	store.setDirty(true);
	if(config.options.chkAutoSave) saveChanges();
	story.refreshTiddler(title,null,true);
	f.dirty=false;
}
//}}}

// // EDITOR PANEL: PREVIEW FUNCTIONS
//{{{
if (config.options.txtTidIDEAutoFreeze==undefined)
	config.options.txtTidIDEAutoFreeze=250; // limit (in milliseconds) for auto-freezing preview display

config.macros.tidIDE.render=function(id) {
	var place=document.getElementById(id+"_editorpanel"); if (!place) return;
	var f=document.getElementById(id+"_editorform");
	var p=document.getElementById(id+"_preview");
	var d=document.getElementById(id+"_domview");
	var h=document.getElementById(id+"_htmlview");
	p.innerHTML="";
	f.status.value=this.renderMsg;
	var start=new Date();
	wikify(f.content.value.replace(regexpCarriageReturn,''),p);
	var end=new Date();
	this.renderDOM(id);
	this.renderHTML(id);
	f.status.value=f.current+": "+(end-start+1)+"ms";
	// automatically suspend preview updates for slow rendering tiddlers
	if (end-start+1>config.options.txtTidIDEAutoFreeze) {
		f.freeze.checked=true;
		f.status.value+=this.timeoutMsg.format([config.options.txtTidIDEAutoFreeze]);
	}
	if (f.freeze.checked) f.status.value+=this.freezeMsg;
}

config.macros.tidIDE.renderDOM=function(id) {
	var place=document.getElementById(id+"_editorpanel"); if (!place) return;
	var f=document.getElementById(id+"_editorform");
	var p=document.getElementById(id+"_preview");
	var d=document.getElementById(id+"_domview");
	var h=document.getElementById(id+"_htmlview");
	p.style.height=(f.dom.checked||f.html.checked)?"10em":"25em";
	if (f.dom.checked) d.value=this.getNodeTree(p,"|  ");
	d.style.display=f.dom.checked?"inline":"none";
	d.style.width=f.html.checked?"49.5%":"100%";
	h.style.width=f.dom.checked?"49.5%":"100%";
}

config.macros.tidIDE.renderHTML=function(id) {
	var place=document.getElementById(id+"_editorpanel"); if (!place) return;
	var f=document.getElementById(id+"_editorform");
	var p=document.getElementById(id+"_preview");
	var d=document.getElementById(id+"_domview");
	var h=document.getElementById(id+"_htmlview");
	p.style.height=(f.dom.checked||f.html.checked)?"10em":"25em";
	if (f.html.checked) h.value=this.formatHTML(p.innerHTML);
	h.style.display=f.html.checked?"inline":"none";
	d.style.width=f.html.checked?"49.5%":"100%";
	h.style.width=f.dom.checked?"49.5%":"100%";
}

config.macros.tidIDE.formatHTML=function(txt) {
	if (config.browser.isIE) return txt; // BYPASS - 4/24/2006 due to IE hang problem.  Will fix later...
	var out="";
	var indent="";
	var level=0;
	for (var i=0;i<txt.length;i++) {
		var c=txt.substr(i,1);
		if (c=="<") {
			if (txt.substr(i+1,1)=="/")  indent=indent.substr(0,indent.length-2);
			out+="\n"+indent;
			if (txt.substr(i+1,1)!="/" && txt.substr(i+1,3)!="br>" && txt.substr(i+1,2)!="p>" && txt.substr(i+1,3)!="hr>")  indent+="  ";
		}
		out+=c;
		if (c=="\n")
			out+=indent;
		if (c==">" && txt.substr(i+1,1)!="<")
			out+="\n"+indent;
	}
	return out;
}

config.macros.tidIDE.getNodeTree=function(theNode,theIndent,showPath,inline,thePrefix,thePath)
{
	if (!theNode) return "";
	if (!thePrefix) thePrefix="";
	if (!thePath) thePath="";
	var mquote='"'+(inline?"{{{":"");
	var endmquote=(inline?"}}}":"")+'"';
	// generate output for this node
	var out = thePrefix;
	if (showPath && thePath.length)
		out += (inline?"//":"")+thePath.substr(1)+":"+(inline?"//":"")+"\r\n"+thePrefix;
	if (theNode.className=="DOMViewer")
		return out+'[DOMViewer]\r\n'; // avoid self-referential recursion
	out += (inline?"''":"")+theNode.nodeName.toUpperCase()+(inline?"''":"");
	if (theNode.nodeName=="#text")
		out += ' '+mquote+theNode.nodeValue.replace(/\n/g,'\\n')+endmquote;
	if (theNode.className)
		out += ' class='+mquote+theNode.className+endmquote;
	if (theNode.type)
		out += ' type='+mquote+theNode.type+endmquote;
	if (theNode.id)
		out += ' id='+mquote+theNode.id+endmquote;
	if (theNode.name)
		out += " "+theNode.name+(theNode.value?"="+mquote+theNode.value+endmquote:"");
	if (theNode.href)
		out += ' href='+mquote+theNode.href+endmquote;
	if (theNode.src)
		out += ' src='+mquote+theNode.src+endmquote;
	if (theNode.attributes && theNode.getAttribute("tiddlyLink")!=undefined)
		out += ' tiddler='+mquote+theNode.getAttribute("tiddlyLink")+endmquote;
	out += "\r\n";
	// recursively generate output for child nodes
	thePath=thePath+"."+theNode.nodeName.toLowerCase();
	thePrefix=theIndent+thePrefix;
	for (var i=0;i<theNode.childNodes.length;i++)
	{
		var thisChild=theNode.childNodes.item(i);
		var theNum=(inline?"~~":"(")+(i+1)+(inline?"~~":")");
		out += this.getNodeTree(thisChild,theIndent,showPath,inline,thePrefix,thePath+theNum);
	}
	return out;
}
//}}}

// // DOMViewer macro
//{{{
version.extensions.DOMViewer = version.extensions.tidIDE;
config.macros.DOMViewer = { };
config.macros.DOMViewer.handler = function(place,macroName,params) {
	// set default params
	var inline=false;
	var theRows=15;
	var theIndent="|  ";
	var showPath=false;
	var theTarget=place;
	// unpack options parameters
	if (params[0]=='inline') { inline=true; theIndent=">"; params.shift(); } 
	if (params[0]&&(params[0].substr(0,7)=="indent:")) { theIndent=params[0].substr(7); params.shift(); } 
	if (params[0]&&(params[0].substr(0,5)=="rows:")) { theRows=params[0].substr(5); params.shift(); } 
	if (params[0]=='path') { showPath=true; params.shift(); } 
	if (params[0]) {
		theTarget=document.getElementById(params[0]);
		if (!theTarget)
			if (store.getTiddler(params[0])!=undefined) {
				theTarget=document.getElementById("tiddler"+params[0]);
				if (!theTarget && confirm("DOMViewer asks:\n\nIs it OK to open tiddler '"+params[0]+"' now?")) { 
					story.displayTiddler(null,params[0],1,null,null,false);
					theTarget=document.getElementById("tiddler"+params[0]);
				}
			}
		params.shift();
	}
	// generate and display DOM tree
	if (inline) {
		var out=config.macros.tidIDE.getNodeTree(theTarget,theIndent,showPath,inline);
		wikify(out,place);
	}
	else {
		var out=config.macros.tidIDE.getNodeTree(theTarget,theIndent,showPath,inline);
		var css=".DOMViewer{width:100%;font-size:8pt;color:inherit;background:transparent;border:0px;}";
		setStylesheet(css,"DOMViewerPlugin");
		var theTextArea=createTiddlyElement(place,"textarea",null,"DOMViewer",out);
		theTextArea.rows=theRows;
		theTextArea.cols=60;
		theTextArea.wrap="off";
		theTextArea.theTarget=theTarget;
		theTextArea.theIndent=theIndent;
		theTextArea.showPath=showPath;
	}
}
//}}}

// // SYSTEM PANEL FUNCTIONS
//{{{
config.macros.tidIDE.showObject=function(o) { // generate formatted output for displaying object references
	var t="";
	for (var p in o) {
		if (typeof o[p]=="function") {
			t+="- - - - - - - - - - "+p+" - - - - - - - - - -\n";
			t+=o[p].toString();
			t+="\n- - - - - - - - - - END: "+p+" - - - - - - - - - -\n";
		}
		else
			t+='['+typeof o[p]+'] '+p+": "+o[p]+"\n";
	}
	return t;
}

config.macros.tidIDE.getsys=function(id) {
	var place=document.getElementById(id+"_systempanel"); if (!place) return;
	var f=document.getElementById(id+"_systemform");
	f.sysview.value="";
	// OPTIONS
	while (f.sys_opts.options.length > 1) { f.sys_opts.options[1]=null; } // clear list
	f.config_view.value="";  // clear edit field
	var cookies = { };
	if (document.cookie != "") {
		var p = document.cookie.split("; ");
		for (var i=0; i < p.length; i++) {
			var pos=p[i].indexOf("=");
			if (pos==-1)
				cookies[p[i]]="";
			else
				cookies[p[i].substr(0,pos)]=unescape(p[i].slice(pos+1));
		}
	}
	var c=1;
	var opt=new Array(); for (var i in config.options) opt.push(i); opt.sort();
	for(var i=0; i<opt.length; i++) {
		if ((opt[i].substr(0,3)=="txt")||(opt[i].substr(0,3)=="chk")) {
			var txt = (opt[i].substr(0,3)=="chk"?("["+(config.options[opt[i]]?"x":"_")+"] "):"")+opt[i]+(cookies[opt[i]]?" (cookie)":"");
			var val = config.options[opt[i]];
			f.sys_opts.options[c++]=new Option(txt,val,false,false);
		}
	}
	// STYLESHEETS
	while (f.sys_styles.options.length > 1) { f.sys_styles.options[1]=null; } // clear list
	var c=1;
	var styles=document.getElementsByTagName("style");
	for(var i=0; i < styles.length; i++) {
		var id=styles[i].getAttribute("id"); if (!id) id="(default)";
		var txt=id;
		var val="/* stylesheet:"+txt+" */\n"+styles[i].innerHTML;
		f.sys_styles.options[c++]=new Option(txt,val,false,false);
	}
	// SHADOWS
	while (f.sys_shadows.options.length > 1) { f.sys_shadows.options[1]=null; } // clear list
	var c=1;
	for(var s in config.shadowTiddlers) f.sys_shadows.options[c++]=new Option(s,config.shadowTiddlers[s],false,false);
	// NOTIFICATIONS
	while (f.sys_notify.options.length > 1) { f.sys_notify.options[1]=null; } // clear list
	var c=1;
	for (var i=0; i<store.namedNotifications.length; i++) {
		var n = store.namedNotifications[i];
		var fn = n.notify.toString();
		fn = fn.substring(fn.indexOf("function ")+9,fn.indexOf("{")-1);
		var txt=(n.name?n.name:"any change")+"="+fn;
		var val="/* notify: "+txt+" */\n"+n.notify.toString();
		f.sys_notify.options[c++]=new Option(txt,val,false,false);
	}
	// MACROS
	while (f.sys_macros.options.length > 1) { f.sys_macros.options[1]=null; } // clear list
	var c=1;
	var macros=new Array(); for (var m in config.macros) macros.push(m); macros.sort();
	for(var i=0; i < macros.length; i++)
		f.sys_macros.options[c++]=new Option(macros[i],this.showObject(config.macros[macros[i]]),false,false);
	// TOOLBAR COMMANDS
	while (f.sys_commands.options.length > 1) { f.sys_commands.options[1]=null; } // clear list
	var c=1;
	for(var cmd in config.commands)
		f.sys_commands.options[c++]=new Option(cmd,this.showObject(config.commands[cmd]),false,false);
	// FORMATTERS
	while (f.sys_formatters.options.length > 1) { f.sys_formatters.options[1]=null; } // clear list
	var c=1;
	for(var i=0; i < config.formatters.length; i++)
		f.sys_formatters.options[c++]=new Option(config.formatters[i].name,this.showObject(config.formatters[i]),false,false);
	// PARAMIFIERS
	while (f.sys_params.options.length > 1) { f.sys_params.options[1]=null; } // clear list
	var c=1;
	for(var param in config.paramifiers)
		f.sys_params.options[c++]=new Option(param,this.showObject(config.paramifiers[param]),false,false);
	// GLOBALS
	//global variables and functions (excluding most DOM and ~TiddyWiki core definitions)://
	var DOM0_globals = {
		addEventListener: 1, alert: 1, atob: 1, back: 1, blur: 1, btoa: 1, captureEvents: 1, clearInterval: 1,
		clearTimeout: 1, close: 1, closed: 1, Components: 1, confirm: 1, content: 1, controllers: 1, crypto: 1,
		defaultStatus: 1, defaultStatus: 1, directories: 1, disableExternalCapture: 1, dispatchEvent: 1, document: 1,
		dump: 1, enableExternalCapture: 1, escape: 1, find: 1, focus: 1, forward: 1, frameElement: 1, frames: 1,
		fullScreen: 1, getAttention: 1, getComputedStyle: 1, getSelection: 1, history: 1, home: 1, innerHeight: 1,
		innerWidth: 1, length: 1, location: 1, locationbar: 1, menubar: 1, moveBy: 1, moveTo: 1, name: 1,
		navigator: 1, open: 1, openDialog: 1, opener: 1, outerHeight: 1, outerWidth: 1, pageXOffset: 1,
		pageYOffset: 1, parent: 1, personalbar: 1, pkcs11: 1, print: 1, prompt: 1, prompter: 1, releaseEvents: 1,
		removeEventListener: 1, resizeBy: 1, resizeTo: 1, routeEvent: 1, screen: 1, screenX: 1, screenY: 1,
		scroll: 1, scrollbars: 1, scrollBy: 1, scrollByLines: 1, scrollByPages: 1, scrollMaxX: 1, scrollMaxY: 1,
		scrollTo: 1, scrollX: 1, scrollY: 1, self: 1, setInterval: 1, setResizable: 1, setTimeout: 1, sidebar: 1,
		sizeToContent: 1, status: 1, statusbar: 1, stop: 1, toolbar: 1, top: 1, unescape: 1, updateCommands: 1,
		window: 1, getInterface: 1
	};
	var tw_globals = {
		version: 1, config: 1, DEFAULT_VIEW_TEMPLATE: 1, DEFAULT_EDIT_TEMPLATE: 1, store: 1, story: 1,
		Formatter: 1, anim: 1, readOnly: 1, highlightHack: 1, main: 1, restart: 1, saveTest: 1,  loadSystemConfig: 1,
		processConfig: 1, invokeMacro: 1, Formatter: 1, wikify: 1, wikifyPlain: 1, highlightify: 1, Wikifier: 1, 
		Tiddler: 1, regexpBackSlashEn: 1, regexpBackSlash: 1, regexpBackSlashEss: 1, regexpNewLine: 1, 
		regexpCarriageReturn: 1, TiddlyWiki: 1, displayTiddlers: 1, displayTiddler: 1, Story: 1, displayMessage: 1,
		clearMessage: 1, refreshElements: 1, applyHtmlMacros: 1, refreshPageTemplate: 1, applyPageTemplate: 1,
		refreshDisplay: 1, refreshPageTitle: 1, refreshStyles: 1, loadOptionsCookie: 1, saveOptionCookie: 1,
		saveUsingSafari: 1, startSaveArea: 1, endSaveArea: 1, checkUnsavedChanges: 1, saveChanges: 1,
		getBackupPath: 1, generateRss: 1, allTiddlersAsHtml: 1,
		convertUTF8ToUnicode: 1, manualConvertUTF8ToUnicode: 1, mozConvertUTF8ToUnicode: 1,
		convertUnicodeToUTF8: 1, manualConvertUnicodeToUTF8: 1, mozConvertUnicodeToUTF8: 1,
		saveFile: 1, loadFile: 1, ieSaveFile: 1, ieLoadFile: 1, mozillaSaveFile: 1, mozillaLoadFile: 1,
		operaUrlToFilename: 1, operaSaveFile: 1, operaLoadFile: 1, safariFilenameToUrl: 1, safariLoadFile: 1,
		safariSaveFile: 1, detectPlugin: 1, createTiddlyButton: 1, createTiddlyLink: 1, refreshTiddlyLink: 1,
		createExternalLink: 1, onClickTiddlerLink: 1, createTagButton: 1, onClickTag: 1, onClickTagOpenAll: 1,
		createTiddlyError: 1, Animator: 1, Zoomer: 1, Cascade: 1, Scroller: 1, Slider: 1, Popup: 1,
		createTiddlerPopup: 1, scrollToTiddlerPopup: 1, hideTiddlerPopup: 1, RGB: 1, drawGradient: 1,
		createTiddlyText: 1, createTiddlyElement: 1, addEvent: 1, removeEvent: 1, addClass: 1,
		removeClass: 1, hasClass: 1, resolveTarget: 1, getPlainText: 1, ensureVisible: 1, 
		findWindowWidth: 1, findWindowHeight: 1, findScrollX: 1, findScrollY: 1, findPosX: 1, findPosY: 1,
		insertSpacer: 1, removeChildren: 1, setStylesheet: 1,
		Packages: 1, sun: 1, java: 1, netscape: 1, XPCNativeWrapper: 1, GeckoActiveXObject: 1
	};
	while (f.sys_globals.options.length > 1) { f.sys_globals.options[1]=null; } // clear list
	if (config.browser.isIE) return; // BYPASS - 8/16/2006 // DON'T LIST GLOBALS IN IE... throws object error - WFFL
	try {
		var c=1;
		for (var v in window) if (!(DOM0_globals[v] || tw_globals[v])) {
			var t=window[v];
			if ((typeof window[v])=='object') {
				var t='';
				for (var p in window[v]) {
					t+=((typeof window[v][p])!='function')?('['+typeof window[v][p]+'] '+p):p;
					t+=((typeof window[v][p])!='function')?('='+window[v][p]):'';
					t+='\n';
				}
			}
			f.sys_globals.options[c++]=new Option(((typeof window[v])!='function')?('['+typeof window[v]+'] '+v):v,t,false,false);
		}	
	}
	catch(e) { ; }
}

config.macros.tidIDE.setsys=function(id) {
	var place=document.getElementById(id+"_systempanel"); if (!place) return;
	var f=document.getElementById(id+"_systemform");
	if (f.sys_opts.selectedIndex==0) return; // heading - do nothing
	var name=f.sys_opts.options[f.sys_opts.selectedIndex].text.replace(/\[[Xx_]\] /,'').replace(/ \(cookie\)/,'')
	var value=f.config_view.value;
	config.options[name]=value;
	saveOptionCookie(name);
	f.sys_opts.options[f.sys_opts.selectedIndex].value=value;
	return;
}
//}}}

// // HTML DEFINITIONS
//{{{
config.macros.tidIDE.html = { };
config.macros.tidIDE.html.framework = " \
	<html> %version% <form style='display:inline;margin:0;padding:0;'>%selector%</form> %panels% </html> \
";
//}}}
//{{{
config.macros.tidIDE.html.editorchk = " \
	<input type=checkbox name=editor \
		style='display:inline;width:auto;margin:1px;' \
		title='add/delete/modify tiddlers' %showpanel% \
		onclick='document.getElementById(\"%id%_editorpanel\").style.display=this.checked?\"block\":\"none\"; \
			if (this.checked) config.macros.tidIDE.render(\"%id%\");'>%toolname% \
";
config.macros.tidIDE.html.systemchk = " \
	<input type=checkbox name=system \
		style='display:inline;width:auto;margin:1px;' \
		title='view TiddlyWiki system internals and configurable options' %showpanel% \
		onclick='document.getElementById(\"%id%_systempanel\").style.display=this.checked?\"block\":\"none\"; \
			if (this.checked) config.macros.tidIDE.getsys(\"%id%\");'>%toolname% \
";
config.macros.tidIDE.html.toolschk = " \
	<input type=checkbox name=tools \
		style='display:inline;width:auto;margin:1px;' \
		title='' %showpanel% \
		onclick='document.getElementById(\"%id%_%toolid%_panel\").style.display=this.checked?\"block\":\"none\"; \
			if (this.checked) config.macros.tidIDE.loadPanel(\"%id%\",\"%toolid%\");'>%toolname% \
";
//}}}
//{{{
config.macros.tidIDE.html.toolspanel = " \
	<div id='%id%_%toolid%_panel' style='display:%showpanel%;margin:0;margin-top:0.5em'> \
	</div> \
";
//}}}
//{{{
config.macros.tidIDE.html.systempanel = " \
	<div id='%id%_systempanel' style='display:%showpanel%;margin:0;margin-top:0.5em;white-space:nowrap'> \
		<form id='%id%_systemform' style='display:inline;margin:0;padding:0;'> \
		<!-- configurable options --> \
		<table style='width:100%;border:0;padding:0;margin:0'><tr style='border:0;padding:0;margin:0'> \
		<td style='width:30%;border:0;padding:0;margin:0'> \
			<select size=1 name='sys_opts' style='width:100%;font-size:%fontsize%;' \
				onchange='this.form.config_view.value=this.value'> \
				<option value=\"\">config.options.*</option> \
			</select> \
		</td><td style='width:50%;border:0;padding:0;margin:0;'> \
			<input type=text name='config_view' size=60 style='width:99%;font-size:%fontsize%;' value=''> \
		</td><td style='width:20%;white-space:nowrap;border:0;padding:0;margin:0;'> \
			<input type=button style='width:50%;' value='set option' title='save this TiddlyWiki option value' \
				onclick='config.macros.tidIDE.setsys(\"%id%\");config.macros.tidIDE.getsys(\"%id%\");'><!-- \
			--><input type=button style='width:50%;' value='refresh' title='retrieve current options and system values' \
				onclick='this.form.sysview.style.display=\"none\"; config.macros.tidIDE.getsys(\"%id%\");'> \
		</td></tr><tr style='border:0;padding:0;margin:0'><td colspan=3 \
				style='white-space:nowrap;width:100%;border:0;padding:0;margin:0'> \
			<!-- system objects --> \
			<select size=1  name='sys_styles' style='width:25%;font-size:%fontsize%;' \
				onchange='this.form.sysview.style.display=\"block\"; this.form.%id%_sysview.value=this.value'> \
				<option value=\"\">stylesheets...</option> \
			</select><select size=1  name='sys_shadows' style='width:25%;font-size:%fontsize%;' \
				onchange='this.form.sysview.style.display=\"block\"; this.form.%id%_sysview.value=this.value'> \
				<option value=\"\">shadows...</option> \
			</select><select size=1  name='sys_notify' style='width:25%;font-size:%fontsize%;' \
				onchange='this.form.sysview.style.display=\"block\"; this.form.%id%_sysview.value=this.value'> \
				<option value=\"\">notifications...</option> \
			</select><select size=1  name='sys_globals' style='width:25%;font-size:%fontsize%;' \
				onchange='this.form.sysview.style.display=\"block\"; this.form.%id%_sysview.value=this.value'> \
				<option value=\"\">globals...</option> \
			</select><br><select size=1  name='sys_macros' style='width:25%;font-size:%fontsize%;' \
				onchange='this.form.sysview.style.display=\"block\"; this.form.%id%_sysview.value=this.value'> \
				<option value=\"\">macros...</option> \
			</select><select size=1  name='sys_commands' style='width:25%;font-size:%fontsize%;' \
				onchange='this.form.sysview.style.display=\"block\"; this.form.%id%_sysview.value=this.value'> \
				<option value=\"\">toolbars...</option> \
			</select><select size=1  name='sys_formatters' style='width:25%;font-size:%fontsize%;' \
				onchange='this.form.sysview.style.display=\"block\"; this.form.%id%_sysview.value=this.value'> \
				<option value=\"\">wikifiers...</option> \
			</select><select size=1  name='sys_params' style='width:25%;font-size:%fontsize%;' \
				onchange='this.form.sysview.style.display=\"block\"; this.form.%id%_sysview.value=this.value'> \
				<option value=\"\">paramifiers...</option> \
			</select> \
			<!-- system value display area --> \
			<span style='white-space:normal;'><textarea id='%id%_sysview' name=sysview cols=60 rows=12 \
				onfocus='this.select()' style='width:99.5%;height:16em;font-size:%fontsize%;font-family:%fontface%;display:none'></textarea></span> \
		</td></tr></table> \
		</form> \
	</div> \
";
//}}}
//{{{
config.macros.tidIDE.html.editorpanel = " \
	<div id='%id%_editorpanel' style='display:%showpanel%;margin:0;margin-top:0.5em'> \
	<form id='%id%_editorform' style='display:inline;margin:0;padding:0;'> \
	<!-- tiddler editor list and buttons --> \
	<select size=1 name=tiddlers style='display:inline;width:40%;font-size:%fontsize%;'  \
		onchange='config.macros.tidIDE.set(\"%id%\",this.value); this.value=this.form.current;'> \
	<option value=''>select a tiddler...</option> \
	%tiddlerlist% \
	</select><!-- \
	--><input name=add type=button style='display:inline;width:10%' \
		value='new' title='create a new tiddler' \
		onclick='config.macros.tidIDE.add(\"%id%\")' %disabled%><!-- \
	--><input name=remove type=button style='display:inline;width:10%' \
		value='remove' title='delete this tiddler' \
		onclick='config.macros.tidIDE.remove(\"%id%\")' %disabled%><!-- \
	--><input name=save type=button style='display:inline;width:10%' \
		value='save' title='save changes to this tiddler' \
		onclick='config.macros.tidIDE.save(\"%id%\")' %disabled%><!-- \
	--><input name=saveas type=button style='display:inline;width:10%' \
		value='save as' title='save changes to a new tiddler' \
		onclick='config.macros.tidIDE.save(\"%id%\",true)' %disabled%><!-- \
	--><input name=view type=button style='display:inline;width:10%' \
		value='open' title='open this tiddler for regular viewing' \
		onclick='if (!this.form.current.length) return;	story.displayTiddler(null,this.form.current)'><!-- \
	--><!-- COMMENTED OUT <input name=run type=button style='display:inline;width:9%' \
		value='run' title='evaluate this tiddler as a javascript \"systemConfig\" plugin' \
		onclick='if (!confirm(config.macros.tidIDE.evalMsg.format([this.form.current]))) return false; \
			var err=processConfig(this.form.content.value); \
			if(err)displayMessage(config.messages.customConfigError.format([err,this.form.current]));'> END COMMENT --><!-- \
	--><input name=previewbutton type=button style='display:inline;width:10%;' \
		value='preview' title='show \"live\" preview display' \
		onclick='document.getElementById(\"%id%_previewpanel\").style.display=\"block\"; \
			this.form.preview.checked=true; config.macros.tidIDE.render(\"%id%\")'><!-- \
	hidden field for preview show/hide state: \
	--><input name=preview type=checkbox style='display:none;'>\
	<!-- tiddler content edit --> \
	<div><textarea id='%id%_content' name='content' edit='text' cols=60 rows=%maxrows% \
		style='width:100%;font-size:%fontsize%;font-family:%fontface%;' \
		onkeyup='var f=this.form; f.dirty=true; f.size.value=this.value.length+\" bytes\";  \
			var p=document.getElementById(\"%id%_preview\"); \
			if (f.preview.checked && !f.freeze.checked) { config.macros.tidIDE.render(\"%id%\"); }'></textarea></div> \
	<!-- tag edit and droplist --> \
	<table width='100%' style='border:0;padding:0;margin:0'><tr style='border:0;padding:0;margin:0'> \
	<td style='border:0;padding:0;margin:0'> \
		<input type=text name=tags size=60 style='width:100%;font-size:%fontsize%;' value='' \
			onchange='this.form.dirty=true' %disabled%> \
	</td><td width='1' style='border:0;padding:0;margin:0;'> \
		<select size=1 name=taglist style='font-size:%fontsize%;' \
			onchange='this.form.dirty=true; this.form.tags.value+=\" \"+this.value' %disabled%> \
		<option value=''>select tags...</option> \
		%taglist% \
		</select> \
	</td></tr></table> \
	<!--  created/modified dates, author, current tiddler size --> \
	<div style='float:right;'> \
		created <input type=text name=created size=15 \
			style='display:inline;font-size:%fontsize%;text-align:center;padding:0;' value='' \
			onchange='this.form.dirty=true' %minoredits%> \
		modified <input type=text name=modified size=15 \
			style='display:inline;font-size:%fontsize%;text-align:center;padding:0;' value='' \
			onchange='this.form.dirty=true;' %minoredits%> \
		by <input type=text name=author size=15 \
			style='display:inline;font-size:%fontsize%;padding:0;' value='' \
			onfocus='this.select()' onchange='this.form.dirty=true' %minoredits%> \
		<input type=text name=size size=10 \
			style='display:inline;font-size:%fontsize%;text-align:center;padding:0;' value='' \
			onfocus='this.blur()' onkeydown='return false' DISABLED>  \
	</div> \
	<!-- toggles: read-only, minor edit --> \
	<span style='white-space:nowrap'> \
	<input type=checkbox name=readonly \
		style='display:inline;width:auto;margin:1px;' %readonlychk% \
		title='do not allow tiddler changes to be saved' \
		onclick='readOnly=config.options.chkHttpReadOnly=this.checked;saveOptionCookie(\"chkHttpReadOnly\"); \
			var f=this.form; f.minoredits.disabled=f.tags.disabled=f.taglist.disabled=this.checked; \
			f.add.disabled=f.remove.disabled=f.save.disabled=f.saveas.disabled=this.checked; \
			f.created.disabled=f.modified.disabled=f.author.disabled=this.checked||!f.minoredits.checked;'>readonly \
	<input type=checkbox name=minoredits \
		style='display:inline;width:auto;margin:1px;' %disabled% %minorchk% \
		title='check: save datestamps/author as entered, uncheck: auto-update modified/author' \
		onclick='this.form.created.disabled=this.form.modified.disabled=this.form.author.disabled=!this.checked; \
			config.options.chkForceMinorUpdate=this.checked;saveOptionCookie(\"chkForceMinorUpdate\");'>minor edits \
	</span> \
	<!-- tiddler preview display --> \
	<div id='%id%_previewpanel' style='display:none;white-space:nowrap'> \
	<div id='%id%_preview' class='viewer' style='margin:0;margin-top:.5em;height:25em;overflow:auto;white-space:normal'> \
		&nbsp; \
	</div> \
	<!-- DOM and HTML viewers --> \
	<textarea id='%id%_domview' name=domview cols=60 rows=12 wrap=off \
		onfocus='this.select()' style='display:none;width:100%;height:16em;font-size:%fontsize%;'></textarea><!-- \
	--><textarea id='%id%_htmlview' name=htmlview cols=60 rows=12 wrap=off \
		onfocus='this.select()' style='display:none;width:100%;height:16em;font-size:%fontsize%;'></textarea> \
	<!-- status line, preview option checkboxes, run/refresh buttons --> \
	<table width='100%' style='border:0;padding:0;margin:0'><tr style='border:0;padding:0;margin:0'> \
	<td style='border:0;padding:0;margin:0'> \
		<input type=text '%id%_status' name=status style='padding:0;width:100%;font-size:%fontsize%;'> \
	</td><td style='width:1%;border:0;padding:0;margin:0;text-align:right;white-space:nowrap'> \
		<input type=checkbox name=dom style='display:inline;width:auto;margin:1px;' \
			title='show Document Object Model (DOM) information' \
			onclick='config.macros.tidIDE.renderDOM(\"%id%\");'>DOM \
		<input type=checkbox name=html style='display:inline;width:auto;margin:1px;' \
			title='show rendered HTML' \
			onclick='config.macros.tidIDE.renderHTML(\"%id%\");'>HTML \
		<input type=checkbox name=freeze style='display:inline;width:auto;margin:1px;' \
			title='do not update preview display as changes are made' \
			onclick='var p=document.getElementById(\"%id%_preview\");  \
				if (this.checked) this.form.status.value+=config.macros.tidIDE.freezeMsg; \
				else config.macros.tidIDE.render(\"%id%\");'>freeze \
		<!-- COMMENTED OUT <input type=button style='display:inline;width:auto;' value='run' \
			title='evaluate this tiddler as a javascript \"systemConfig\" plugin' \
			onclick='if (!confirm(config.macros.tidIDE.evalMsg.format([this.form.current]))) return false; \
				var err=processConfig(this.form.content.value); \
				if(err)displayMessage(config.messages.customConfigError.format([err,this.form.current]));'> END COMMENT --><!-- \
		--><input type=button style='display:inline;width:auto;' value='refresh' \
			title='update preview display' \
			onclick='config.macros.tidIDE.render(\"%id%\")'><!-- \
		--><input type=button style='display:inline;width:auto;' value='hide' \
			title='hide preview display' \
			onclick='document.getElementById(\"%id%_previewpanel\").style.display=\"none\"; \
				this.form.preview.checked=false; config.macros.tidIDE.render(\"%id%\")'> \
	</td></tr></table> \
	</div> \
	</form> \
	</div> \
";
//}}}
/***
|Name|TidIDEStyleSheet|
|Source|http://www.TiddlyTools.com/#TidIDEStyleSheet|
|Version||
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <<br>>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|CSS|
|Requires||
|Overrides||
|Description|use default stylesheet with alternative TidIDE templates|
***/

[[StyleSheet]]
<<template TidIDE>>
Add notes to tiddlers without modifying the original content.

http://tw.lewcid.org/#TiddlerNotesPlugin
http://www.twteamserver.de/es/index3.php
http://bbz-dormagen.de/wennmann/TWLernkartei/TWLernkartei.html#%5B%5BAlle%20F%26%23228%3Bcher%5D%5D

''Plugins''
{{{
 AliasPlugin
 AutoTaggerPlugin
 ConfigTweaksUwe
 DataTiddlerPlugin
 DatePlugin
 DatePluginConfig
 DeleteAllTaggedPlugin
 FontSizePlugin
 ForEachTiddlerPlugin
 FormTiddlerPlugin
 GermanTranslation2.2a
 GotoPlugin
 HideWhenPlugin
 Icons statt Macros
 InlineJavascriptPlugin
 MonkeyTaggerMacro
 NestedSlidersPlugin
 PlayerPlugin
 RenameTagsPlugin
 SetUserNamePlugin
 SinglePageModePlugin
 TaggerPlugin
 TaggingWithCountPlugin
 TiddlerTweakerPlugin
 ToggleSideBarMacro
 YourSearchPlugin
 ZoomTextPlugin
 fileDate↓ 
}}}
http://tiddlybank.tiddlyspot.com/

''Plugins''
{{{
DataTiddlerPlugin         
ForEachTiddlerPlugin          
FormTiddlerPlugin         
GrayTestEverSearch            
InlineJavascriptPluginMG             
LegacyStrikeThroughPlugin              
SearchOptionsPluginMG             
TaggedTemplateTweakMG                
ToggleSideBarMacro
TspotSetupPlugin         
UploadPlugin       

}}}
http://www.giffmex.org/tiddlydu3.html

A free, all-in-one, portable personal organizer using TiddlyWiki technology.
http://wolfi.110mb.com/tiddlyDesktop.html
a free personal organizer
http://www.giffmex.org/tiddlydu2.html
http://15black.bluedepot.com/styles/tiddlyrin.html
http://tiddlysnip.com/#About
http://www.maloninc.com/cgi-bin/fswiki/wiki.cgi?page=TiddlySticky+-+Sticky+Notes+for+Web+Browser+-
Themes library
http://tiddlythemes.com/#Home
http://www.tiddlytools.com/

    * AutoRefresh
    * ChecklistScript
    * JavascriptShell
    * MiniBrowser
    * NextTiddler
    * SetDefaultTiddlers
    * ShowAllByTags
    * ShowTiddlerInfo
    * ShowTiddlerStatistics
    * ToggleRightSidebar
    * ToggleTopButton
customized plugins, project, task tracker
http://www.tentacle.net/~psifi/tiddlytracks/
http://tiddlyvault.tiddlyspot.com/
http://tiddlyvault.tiddlyspot.com/
http://softwareas.com/tiddlywiki-internals-1-of-3-architectural-concepts
http://softwareas.com/tiddlywiki-internals-2-of-3-list-of-javascript-files
http://softwareas.com/tiddlywiki-internals-3-of-3-key-javascript-classes-and-files
<<<
//(This is part 1 of a 3-part series. Part 1 introduces the internals and highlights some of the key patterns and concepts. Part 2 introduces each Javascript file. Part 3 focuses on the internals of the more important classes and files.). 

This is the first in a 3-part series on the internal design of Tiddlywiki. The series is more or less stream of consciousness - I'm a green Tiddlywiki developer, so I've been making these notes as I trawl through the source and learn it myself. Thanks to various people at Osmosoft for explaining some of this, and special thanks to Jeremy for some overviews and reviewing the writing here, Saq for a great overview on many feature, and Fred for reviewing the initially published version.//>>>
[[PDF file|http://nothickmanuals.info/lib/exe/fetch.php/cheatsheets:tiddlywiki_cheatsheet.pdf?id=cheatsheets&cache=cache]]
http://www.tiddlywiki.org/wiki/TiddlyWeb
http://peermore.com:8080/recipes/AutoTiddlyWeb/tiddlers.wiki
http://www.uniforum.chi.il.us/slides/TiddlyWiki.html

''Content:''
    *  TiddlyWiki
    * Wiki On A Stick
    * What is TiddlyWiki?
    * What you'll need
    * How I set up the WoaS
    * What happens when I insert my flash drive
    * What's in TiddlyWiki?
    * Starting a new TiddlyWiki
    * Starting GTDTiddlyWiki Video
    * Configuration
    * Terminology
    * WikiSyntax
    * Formatting
    * Embedded pages
    * Keyboard shortcuts
    * Layout
    * Navigation
    * Options
    * Demo
    * Adaptations
    * Cool Extensions
    * Summary
http://bbz-dormagen.de/wennmann/tiddlywikimatheducation/WikiMathEducation/WikiMath.de/index.html#Inhaltsverzeichnis
/%
|Name|ToggleRightSidebar|
|Source|http://www.TiddlyTools.com/#ToggleRightSidebar|
|Version|0.0.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <<br>>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|script|
|Requires||
|Overrides||
|Description||
%/<script label="show/hide right sidebar">
	var show=document.getElementById('sidebar').style.display=='none';
	if (!show) {
		document.getElementById('sidebar').style.display='none';
		var margin='1em';
	}
	else {
		document.getElementById('sidebar').style.display='block';
		var margin=config.options.txtDisplayAreaRightMargin?config.options.txtDisplayAreaRightMargin:"";
	}
	place.innerHTML=(show?"Need More Room?":"Need the Sidebar?"); // SET LINK TEXT
	place.title=show?"hide sidebar":"show sidebar"; // SET TOOLTIP
	document.getElementById('displayArea').style.marginRight=margin;
	config.options.chkShowRightSidebar=show;
	saveOptionCookie('chkShowRightSidebar');
	var sm=document.getElementById("storyMenu"); if (sm) config.refreshers.content(sm);
	return false;
</script><script>
	if (config.options.chkShowRightSidebar==undefined)
		config.options.chkShowRightSidebar=true;
	if (!config.options.txtDisplayAreaRightMargin||!config.options.txtDisplayAreaRightMargin.length)
		config.options.txtDisplayAreaRightMargin="15em";
	var show=config.options.chkShowRightSidebar;
	document.getElementById('sidebar').style.display=show?"block":"none";
	document.getElementById('displayArea').style.marginRight=show?config.options.txtDisplayAreaRightMargin:"1em";
	place.lastChild.innerHTML=(show?"Hide Sidebar;":"Show Sidebar;"); // SET LINK TEXT
	place.lastChild.title=show?"hide sidebar":"show sidebar"; // SET TOOLTIP
	place.lastChild.style.fontWeight="normal";
</script>
/***
| Name|ToggleTagPlugin|
| Description|Makes a checkbox which toggles a tag in a tiddler|
| Version|3.0 ($Rev: 1845 $)|
| Date|$Date: 2007-03-16 15:19:22 +1000 (Fri, 16 Mar 2007) $|
| Source|http://tiddlyspot.com/mptw/#ToggleTagMacro|
| Author|Simon Baird <simon.baird@gmail.com>|
| License|http://mptw.tiddlyspot.com/#TheBSDLicense|
!Usage
{{{<<toggleTag }}}//{{{TagName TiddlerName LabelText}}}//{{{>>}}}
* TagName - the tag to be toggled, default value "checked"
* TiddlerName - the tiddler to toggle the tag in, default value the current tiddler
* LabelText - the text (gets wikified) to put next to the check box, default value is '{{{[[TagName]]}}}' or '{{{[[TagName]] [[TiddlerName]]}}}'
(If a parameter is '.' then the default will be used)

Examples:

|Code|Description|Example|h
|{{{<<toggleTag>>}}}|Toggles the default tag (checked) in this tiddler|<<toggleTag>>|
|{{{<<toggleTag TagName>>}}}|Toggles the TagName tag in this tiddler|<<toggleTag TagName>>|
|{{{<<toggleTag TagName TiddlerName>>}}}|Toggles the TagName tag in the TiddlerName tiddler|<<toggleTag TagName TiddlerName>>|
|{{{<<toggleTag TagName TiddlerName 'click me'>>}}}|Same but with custom label|<<toggleTag TagName TiddlerName 'click me'>>|
|{{{<<toggleTag . . 'click me'>>}}}|dot means use default value|<<toggleTag . . 'click me'>>|
Notes:
* If TiddlerName doesn't exist it will be silently created
* Set label to '-' to specify no label
* See also http://mgtd-alpha.tiddlyspot.com/#ToggleTag2

!Known issues
* Doesn't smoothly handle the case where you toggle a tag in a tiddler that is current open for editing

***/
//{{{

merge(config.macros,{

	toggleTag: {

		doRefreshAll: true,
		createIfRequired: true,
		shortLabel: "[[%0]]",
		longLabel: "[[%0]] [[%1]]",

		handler: function(place,macroName,params,wikifier,paramString,tiddler) {
			var tag = (params[0] && params[0] != '.') ? params[0] : "checked";
			var title = (params[1] && params[1] != '.') ? params[1] : tiddler.title;
			var defaultLabel = (title == tiddler.title ? this.shortLabel : this.longLabel);
			var label = (params[2] && params[2] != '.') ? params[2] : defaultLabel;
			label = (label == '-' ? '' : label);
			var theTiddler =  title == tiddler.title ? tiddler : store.getTiddler(title);
			var cb = createTiddlyCheckbox(place, label.format([tag,title]), theTiddler && theTiddler.isTagged(tag), function(e) {
				if (!store.tiddlerExists(title)) {
					if (config.macros.toggleTag.createIfRequired) {
						var content = store.getTiddlerText(title); // just in case it's a shadow
						store.saveTiddler(title,title,content?content:"",config.options.txtUserName,new Date(),null);
					}
					else 
						return false;
				}
				store.setTiddlerTag(title,this.checked,tag);
				return true;
			});
		}
	}
});

//}}}
<code>
merge(config.macros,{

	toggleTag: {

		doRefreshAll: true,
		createIfRequired: true,
		shortLabel: &quot;[[%0]]&quot;,
		longLabel: &quot;[[%0]] [[%1]]&quot;,

		handler: function(place,macroName,params,wikifier,paramString,tiddler) {
			var tag = (params[0] &amp;&amp; params[0] != '.') ? params[0] : &quot;checked&quot;;
			var title = (params[1] &amp;&amp; params[1] != '.') ? params[1] : tiddler.title;
			var defaultLabel = (title == tiddler.title ? this.shortLabel : this.longLabel);
			var label = (params[2] &amp;&amp; params[2] != '.') ? params[2] : defaultLabel;
			label = (label == '-' ? '' : label);
			var theTiddler =  title == tiddler.title ? tiddler : store.getTiddler(title);
			var cb = createTiddlyCheckbox(place, label.format([tag,title]), theTiddler &amp;&amp; theTiddler.isTagged(tag), function(e) {
				if (!store.tiddlerExists(title)) {
					if (config.macros.toggleTag.createIfRequired) {
						var content = store.getTiddlerText(title); // just in case it's a shadow
						store.saveTiddler(title,title,content?content:&quot;&quot;,config.options.txtUserName,new Date(),null);
					}
					else 
						return false;
				}
				store.setTiddlerTag(title,this.checked,tag);
				return true;
			});
		}
	}
});

//}}}
</code>
/%
|Name|ToggleTopButton|
|Source|http://www.TiddlyTools.com/#ToggleTopButton|
|Version|0.0.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <<br>>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|script|
|Requires|InlineJavascriptPlugin|
|Overrides||
|Description|adds a floating "scroll to top" button in the lower right corner of the window. |
%/<script> 
	window.showTopButton=function(show) {
		// remove existing "top" button (if any)
		var e=document.getElementById("scrollToTopButton"); if (e) e.parentNode.removeChild(e);
		if (config.browser.isIE) return; // IE doesn't do FIXED... do nothing.
		if (!show) return; // hiding button... we're done.
		// create a link that scrolls to the top of page
		e=createTiddlyElement(null,"A",null,null,"top");
		e.id="scrollToTopButton";
		e.title="scroll to top of page";
		e.onclick=function(){window.scrollTo(0,0)};
		// make it hover in the bottom right corner of the window
		var s=e.style;
		s.position="fixed";
		s.zIndex="1001"; // hopefully, this will be on top of ALL other elements!
		s.bottom=".50em";
		s.right=".50em";
		s.cursor="pointer";
		s.backgroundColor="#eee";
		s.color="#009";
		s.border="1px solid";
		s.padding="0 1em";
		s.MozBorderRadius="1em";
		s.fontSize="7pt";
		document.body.insertBefore(e,null);
	}
	if (config.options.chkShowTopButton==undefined) config.options.chkShowTopButton=true;
	window.showTopButton(config.options.chkShowTopButton);
</script><<option chkShowTopButton>><script>
	place.lastChild.onchange=function() {
		window.showTopButton(this.checked);
		config.options.chkShowTopButton=this.checked;
		saveOptionCookie("chkShowTopButton");
	};
</script> "scroll-to-top" button
/***
Contains the stuff you need to use Tiddlyspot
Note you must also have UploadPlugin installed
***/
//{{{

// edit this if you are migrating sites or retrofitting an existing TW
config.tiddlyspotSiteId = 'tw202';

// make it so you can by default see edit controls via http
config.options.chkHttpReadOnly = false;
window.readOnly = false; // make sure of it (for tw 2.2)

// disable autosave in d3
if (window.location.protocol != "file:")
	config.options.chkGTDLazyAutoSave = false;

// tweak shadow tiddlers to add upload button, password entry box etc
with (config.shadowTiddlers) {
	SiteUrl = 'http://'+config.tiddlyspotSiteId+'.tiddlyspot.com';
	SideBarOptions = SideBarOptions.replace(/(<<saveChanges>>)/,"$1<<tiddler TspotSidebar>>");
	OptionsPanel = OptionsPanel.replace(/^/,"<<tiddler TspotOptions>>");
	DefaultTiddlers = DefaultTiddlers.replace(/^/,"[[WelcomeToTiddlyspot]] ");
	MainMenu = MainMenu.replace(/^/,"[[WelcomeToTiddlyspot]] ");
}

// create some shadow tiddler content
merge(config.shadowTiddlers,{

'WelcomeToTiddlyspot':[
 "This document is a ~TiddlyWiki from tiddlyspot.com.  A ~TiddlyWiki is an electronic notebook that is great for managing todo lists, personal information, and all sorts of things.",
 "",
 "@@font-weight:bold;font-size:1.3em;color:#444; //What now?// &nbsp;&nbsp;@@ Before you can save any changes, you need to enter your password in the form below.  Then configure privacy and other site settings at your [[control panel|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/controlpanel]] (your control panel username is //" + config.tiddlyspotSiteId + "//).",
 "<<tiddler TspotControls>>",
 "See also GettingStarted.",
 "",
 "@@font-weight:bold;font-size:1.3em;color:#444; //Working online// &nbsp;&nbsp;@@ You can edit this ~TiddlyWiki right now, and save your changes using the \"save to web\" button in the column on the right.",
 "",
 "@@font-weight:bold;font-size:1.3em;color:#444; //Working offline// &nbsp;&nbsp;@@ A fully functioning copy of this ~TiddlyWiki can be saved onto your hard drive or USB stick.  You can make changes and save them locally without being connected to the Internet.  When you're ready to sync up again, just click \"upload\" and your ~TiddlyWiki will be saved back to tiddlyspot.com.",
 "",
 "@@font-weight:bold;font-size:1.3em;color:#444; //Help!// &nbsp;&nbsp;@@ Find out more about ~TiddlyWiki at [[TiddlyWiki.com|http://tiddlywiki.com]].  Also visit [[TiddlyWiki Guides|http://tiddlywikiguides.org]] for documentation on learning and using ~TiddlyWiki. New users are especially welcome on the [[TiddlyWiki mailing list|http://groups.google.com/group/TiddlyWiki]], which is an excellent place to ask questions and get help.  If you have a tiddlyspot related problem email [[tiddlyspot support|mailto:support@tiddlyspot.com]].",
 "",
 "@@font-weight:bold;font-size:1.3em;color:#444; //Enjoy :)// &nbsp;&nbsp;@@ We hope you like using your tiddlyspot.com site.  Please email [[feedback@tiddlyspot.com|mailto:feedback@tiddlyspot.com]] with any comments or suggestions."
].join("\n"),

'TspotControls':[
 "| tiddlyspot password:|<<option pasUploadPassword>>|",
 "| site management:|<<upload http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/store.cgi index.html . .  " + config.tiddlyspotSiteId + ">>//(requires tiddlyspot password)//<<br>>[[control panel|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/controlpanel]], [[download (go offline)|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/download]]|",
 "| links:|[[tiddlyspot.com|http://tiddlyspot.com/]], [[FAQs|http://faq.tiddlyspot.com/]], [[announcements|http://announce.tiddlyspot.com/]], [[blog|http://tiddlyspot.com/blog/]], email [[support|mailto:support@tiddlyspot.com]] & [[feedback|mailto:feedback@tiddlyspot.com]], [[donate|http://tiddlyspot.com/?page=donate]]|"
].join("\n"),

'TspotSidebar':[
 "<<upload http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/store.cgi index.html . .  " + config.tiddlyspotSiteId + ">><html><a href='http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/download' class='button'>download</a></html>"
].join("\n"),

'TspotOptions':[
 "tiddlyspot password:",
 "<<option pasUploadPassword>>",
 ""
].join("\n")

});
//}}}
Master: 		http://www.pacifica.edu/lib/theses.html
Abstracts: 	http://www.pacifica.edu/lib/abs.html
http://www.tedpavlic.com/kgtd_pre/kgtd_example_deprecated.htm
| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |
| 10/11/2008 18:44:27 | YourName | [[/|http://tw202.tiddlyspot.com/]] | [[store.cgi|http://tw202.tiddlyspot.com/store.cgi]] | . | [[index.html | http://tw202.tiddlyspot.com/index.html]] | . |
| 10/11/2008 18:49:03 | YourName | [[/|http://tw202.tiddlyspot.com/]] | [[store.cgi|http://tw202.tiddlyspot.com/store.cgi]] | . | [[index.html | http://tw202.tiddlyspot.com/index.html]] | . |
| 10/11/2008 18:52:39 | YourName | [[/|http://tw202.tiddlyspot.com/]] | [[store.cgi|http://tw202.tiddlyspot.com/store.cgi]] | . | [[index.html | http://tw202.tiddlyspot.com/index.html]] | . |
| 20/11/2008 14:44:06 | AlfonsoReyes | [[tw202.html|file:///C:/Documents%20and%20Settings/All%20Users.WINX64/Documents/tw202.html]] | [[store.cgi|http://tw202.tiddlyspot.com/store.cgi]] | . | [[index.html | http://tw202.tiddlyspot.com/index.html]] | . |
| 20/11/2008 14:44:26 | AlfonsoReyes | [[tw202.html|file:///C:/Documents%20and%20Settings/All%20Users.WINX64/Documents/tw202.html]] | [[store.cgi|http://tw202.tiddlyspot.com/store.cgi]] | . | [[index.html | http://tw202.tiddlyspot.com/index.html]] | . | ok | ok |
| 20/11/2008 14:52:38 | AlfonsoReyes | [[tw202.html|file:///C:/Documents%20and%20Settings/All%20Users.WINX64/Documents/tw202.html]] | [[store.cgi|http://tw202.tiddlyspot.com/store.cgi]] | . | [[index.html | http://tw202.tiddlyspot.com/index.html]] | . | ok |
| 31/08/2009 08:03:06 | YourName | [[tw202.html|file:///home/shared/Databases/TiddlyWiki/tw202.html]] | [[store.cgi|http://tw202.tiddlyspot.com/store.cgi]] | . | [[index.html | http://tw202.tiddlyspot.com/index.html]] | . | ok |
| 07/10/2009 09:14:58 | AlfonsoReyes | [[tw202.html|file:///home/shared/Databases/TiddlyWiki/tw202.html]] | [[store.cgi|http://tw202.tiddlyspot.com/store.cgi]] | . | [[index.html | http://tw202.tiddlyspot.com/index.html]] | . | ok |
| 13/10/2009 12:16:21 | AlfonsoReyes | [[tw202.html|file:///home/shared/Databases/TiddlyWiki/tw202.html]] | [[store.cgi|http://tw202.tiddlyspot.com/store.cgi]] | . | [[index.html | http://tw202.tiddlyspot.com/index.html]] | . | ok |
| 27/01/2010 09:46:56 | YourName | [[tw202.html|file:///aux/d140g/LinuxWindows/tw/tw202.html]] | [[store.cgi|http://tw202.tiddlyspot.com/store.cgi]] | . | [[index.html | http://tw202.tiddlyspot.com/index.html]] | . |
/***
|''Name:''|PasswordOptionPlugin|
|''Description:''|Extends TiddlyWiki options with non encrypted password option.|
|''Version:''|1.0.2|
|''Date:''|Apr 19, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#PasswordOptionPlugin|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0 (Beta 5)|
***/
//{{{
version.extensions.PasswordOptionPlugin = {
	major: 1, minor: 0, revision: 2, 
	date: new Date("Apr 19, 2007"),
	source: 'http://tiddlywiki.bidix.info/#PasswordOptionPlugin',
	author: 'BidiX (BidiX (at) bidix (dot) info',
	license: '[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D]]',
	coreVersion: '2.2.0 (Beta 5)'
};

config.macros.option.passwordCheckboxLabel = "Save this password on this computer";
config.macros.option.passwordInputType = "password"; // password | text
setStylesheet(".pasOptionInput {width: 11em;}\n","passwordInputTypeStyle");

merge(config.macros.option.types, {
	'pas': {
		elementType: "input",
		valueField: "value",
		eventName: "onkeyup",
		className: "pasOptionInput",
		typeValue: config.macros.option.passwordInputType,
		create: function(place,type,opt,className,desc) {
			// password field
			config.macros.option.genericCreate(place,'pas',opt,className,desc);
			// checkbox linked with this password "save this password on this computer"
			config.macros.option.genericCreate(place,'chk','chk'+opt,className,desc);			
			// text savePasswordCheckboxLabel
			place.appendChild(document.createTextNode(config.macros.option.passwordCheckboxLabel));
		},
		onChange: config.macros.option.genericOnChange
	}
});

merge(config.optionHandlers['chk'], {
	get: function(name) {
		// is there an option linked with this chk ?
		var opt = name.substr(3);
		if (config.options[opt]) 
			saveOptionCookie(opt);
		return config.options[name] ? "true" : "false";
	}
});

merge(config.optionHandlers, {
	'pas': {
 		get: function(name) {
			if (config.options["chk"+name]) {
				return encodeCookie(config.options[name].toString());
			} else {
				return "";
			}
		},
		set: function(name,value) {config.options[name] = decodeCookie(value);}
	}
});

// need to reload options to load passwordOptions
loadOptionsCookie();

/*
if (!config.options['pasPassword'])
	config.options['pasPassword'] = '';

merge(config.optionsDesc,{
		pasPassword: "Test password"
	});
*/
//}}}

/***
|''Name:''|UploadPlugin|
|''Description:''|Save to web a TiddlyWiki|
|''Version:''|4.1.0|
|''Date:''|May 5, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#UploadPlugin|
|''Documentation:''|http://tiddlywiki.bidix.info/#UploadPluginDoc|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0 (#3125)|
|''Requires:''|PasswordOptionPlugin|
***/
//{{{
version.extensions.UploadPlugin = {
	major: 4, minor: 1, revision: 0,
	date: new Date("May 5, 2007"),
	source: 'http://tiddlywiki.bidix.info/#UploadPlugin',
	author: 'BidiX (BidiX (at) bidix (dot) info',
	coreVersion: '2.2.0 (#3125)'
};

//
// Environment
//

if (!window.bidix) window.bidix = {}; // bidix namespace
bidix.debugMode = false;	// true to activate both in Plugin and UploadService
	
//
// Upload Macro
//

config.macros.upload = {
// default values
	defaultBackupDir: '',	//no backup
	defaultStoreScript: "store.php",
	defaultToFilename: "index.html",
	defaultUploadDir: ".",
	authenticateUser: true	// UploadService Authenticate User
};
	
config.macros.upload.label = {
	promptOption: "Save and Upload this TiddlyWiki with UploadOptions",
	promptParamMacro: "Save and Upload this TiddlyWiki in %0",
	saveLabel: "save to web", 
	saveToDisk: "save to disk",
	uploadLabel: "upload"	
};

config.macros.upload.messages = {
	noStoreUrl: "No store URL in parmeters or options",
	usernameOrPasswordMissing: "Username or password missing"
};

config.macros.upload.handler = function(place,macroName,params) {
	if (readOnly)
		return;
	var label;
	if (document.location.toString().substr(0,4) == "http") 
		label = this.label.saveLabel;
	else
		label = this.label.uploadLabel;
	var prompt;
	if (params[0]) {
		prompt = this.label.promptParamMacro.toString().format([this.destFile(params[0], 
			(params[1] ? params[1]:bidix.basename(window.location.toString())), params[3])]);
	} else {
		prompt = this.label.promptOption;
	}
	createTiddlyButton(place, label, prompt, function() {config.macros.upload.action(params);}, null, null, this.accessKey);
};

config.macros.upload.action = function(params)
{
		// for missing macro parameter set value from options
		var storeUrl = params[0] ? params[0] : config.options.txtUploadStoreUrl;
		var toFilename = params[1] ? params[1] : config.options.txtUploadFilename;
		var backupDir = params[2] ? params[2] : config.options.txtUploadBackupDir;
		var uploadDir = params[3] ? params[3] : config.options.txtUploadDir;
		var username = params[4] ? params[4] : config.options.txtUploadUserName;
		var password = config.options.pasUploadPassword; // for security reason no password as macro parameter	
		// for still missing parameter set default value
		if ((!storeUrl) && (document.location.toString().substr(0,4) == "http")) 
			storeUrl = bidix.dirname(document.location.toString())+'/'+config.macros.upload.defaultStoreScript;
		if (storeUrl.substr(0,4) != "http")
			storeUrl = bidix.dirname(document.location.toString()) +'/'+ storeUrl;
		if (!toFilename)
			toFilename = bidix.basename(window.location.toString());
		if (!toFilename)
			toFilename = config.macros.upload.defaultToFilename;
		if (!uploadDir)
			uploadDir = config.macros.upload.defaultUploadDir;
		if (!backupDir)
			backupDir = config.macros.upload.defaultBackupDir;
		// report error if still missing
		if (!storeUrl) {
			alert(config.macros.upload.messages.noStoreUrl);
			clearMessage();
			return false;
		}
		if (config.macros.upload.authenticateUser && (!username || !password)) {
			alert(config.macros.upload.messages.usernameOrPasswordMissing);
			clearMessage();
			return false;
		}
		bidix.upload.uploadChanges(false,null,storeUrl, toFilename, uploadDir, backupDir, username, password); 
		return false; 
};

config.macros.upload.destFile = function(storeUrl, toFilename, uploadDir) 
{
	if (!storeUrl)
		return null;
		var dest = bidix.dirname(storeUrl);
		if (uploadDir && uploadDir != '.')
			dest = dest + '/' + uploadDir;
		dest = dest + '/' + toFilename;
	return dest;
};

//
// uploadOptions Macro
//

config.macros.uploadOptions = {
	handler: function(place,macroName,params) {
		var wizard = new Wizard();
		wizard.createWizard(place,this.wizardTitle);
		wizard.addStep(this.step1Title,this.step1Html);
		var markList = wizard.getElement("markList");
		var listWrapper = document.createElement("div");
		markList.parentNode.insertBefore(listWrapper,markList);
		wizard.setValue("listWrapper",listWrapper);
		this.refreshOptions(listWrapper,false);
		var uploadCaption;
		if (document.location.toString().substr(0,4) == "http") 
			uploadCaption = config.macros.upload.label.saveLabel;
		else
			uploadCaption = config.macros.upload.label.uploadLabel;
		
		wizard.setButtons([
				{caption: uploadCaption, tooltip: config.macros.upload.label.promptOption, 
					onClick: config.macros.upload.action},
				{caption: this.cancelButton, tooltip: this.cancelButtonPrompt, onClick: this.onCancel}
				
			]);
	},
	refreshOptions: function(listWrapper) {
		var uploadOpts = [
			"txtUploadUserName",
			"pasUploadPassword",
			"txtUploadStoreUrl",
			"txtUploadDir",
			"txtUploadFilename",
			"txtUploadBackupDir",
			"chkUploadLog",
			"txtUploadLogMaxLine",
			]
		var opts = [];
		for(i=0; i<uploadOpts.length; i++) {
			var opt = {};
			opts.push()
			opt.option = "";
			n = uploadOpts[i];
			opt.name = n;
			opt.lowlight = !config.optionsDesc[n];
			opt.description = opt.lowlight ? this.unknownDescription : config.optionsDesc[n];
			opts.push(opt);
		}
		var listview = ListView.create(listWrapper,opts,this.listViewTemplate);
		for(n=0; n<opts.length; n++) {
			var type = opts[n].name.substr(0,3);
			var h = config.macros.option.types[type];
			if (h && h.create) {
				h.create(opts[n].colElements['option'],type,opts[n].name,opts[n].name,"no");
			}
		}
		
	},
	onCancel: function(e)
	{
		backstage.switchTab(null);
		return false;
	},
	
	wizardTitle: "Upload with options",
	step1Title: "These options are saved in cookies in your browser",
	step1Html: "<input type='hidden' name='markList'></input><br>",
	cancelButton: "Cancel",
	cancelButtonPrompt: "Cancel prompt",
	listViewTemplate: {
		columns: [
			{name: 'Description', field: 'description', title: "Description", type: 'WikiText'},
			{name: 'Option', field: 'option', title: "Option", type: 'String'},
			{name: 'Name', field: 'name', title: "Name", type: 'String'}
			],
		rowClasses: [
			{className: 'lowlight', field: 'lowlight'} 
			]}
}

//
// upload functions
//

if (!bidix.upload) bidix.upload = {};

if (!bidix.upload.messages) bidix.upload.messages = {
	//from saving
	invalidFileError: "The original file '%0' does not appear to be a valid TiddlyWiki",
	backupSaved: "Backup saved",
	backupFailed: "Failed to upload backup file",
	rssSaved: "RSS feed uploaded",
	rssFailed: "Failed to upload RSS feed file",
	emptySaved: "Empty template uploaded",
	emptyFailed: "Failed to upload empty template file",
	mainSaved: "Main TiddlyWiki file uploaded",
	mainFailed: "Failed to upload main TiddlyWiki file. Your changes have not been saved",
	//specific upload
	loadOriginalHttpPostError: "Can't get original file",
	aboutToSaveOnHttpPost: 'About to upload on %0 ...',
	storePhpNotFound: "The store script '%0' was not found."
};

bidix.upload.uploadChanges = function(onlyIfDirty,tiddlers,storeUrl,toFilename,uploadDir,backupDir,username,password)
{
	var callback = function(status,uploadParams,original,url,xhr) {
		if (!status) {
			displayMessage(bidix.upload.messages.loadOriginalHttpPostError);
			return;
		}
		if (bidix.debugMode) 
			alert(original.substr(0,500)+"\n...");
		// Locate the storeArea div's 
		var posDiv = locateStoreArea(original);
		if((posDiv[0] == -1) || (posDiv[1] == -1)) {
			alert(config.messages.invalidFileError.format([localPath]));
			return;
		}
		bidix.upload.uploadRss(uploadParams,original,posDiv);
	};
	
	if(onlyIfDirty && !store.isDirty())
		return;
	clearMessage();
	// save on localdisk ?
	if (document.location.toString().substr(0,4) == "file") {
		var path = document.location.toString();
		var localPath = getLocalPath(path);
		saveChanges();
	}
	// get original
	var uploadParams = Array(storeUrl,toFilename,uploadDir,backupDir,username,password);
	var originalPath = document.location.toString();
	// If url is a directory : add index.html
	if (originalPath.charAt(originalPath.length-1) == "/")
		originalPath = originalPath + "index.html";
	var dest = config.macros.upload.destFile(storeUrl,toFilename,uploadDir);
	var log = new bidix.UploadLog();
	log.startUpload(storeUrl, dest, uploadDir,  backupDir);
	displayMessage(bidix.upload.messages.aboutToSaveOnHttpPost.format([dest]));
	if (bidix.debugMode) 
		alert("about to execute Http - GET on "+originalPath);
	var r = doHttp("GET",originalPath,null,null,null,null,callback,uploadParams,null);
	if (typeof r == "string")
		displayMessage(r);
	return r;
};

bidix.upload.uploadRss = function(uploadParams,original,posDiv) 
{
	var callback = function(status,params,responseText,url,xhr) {
		if(status) {
			var destfile = responseText.substring(responseText.indexOf("destfile:")+9,responseText.indexOf("\n", responseText.indexOf("destfile:")));
			displayMessage(bidix.upload.messages.rssSaved,bidix.dirname(url)+'/'+destfile);
			bidix.upload.uploadMain(params[0],params[1],params[2]);
		} else {
			displayMessage(bidix.upload.messages.rssFailed);			
		}
	};
	// do uploadRss
	if(config.options.chkGenerateAnRssFeed) {
		var rssPath = uploadParams[1].substr(0,uploadParams[1].lastIndexOf(".")) + ".xml";
		var rssUploadParams = Array(uploadParams[0],rssPath,uploadParams[2],'',uploadParams[4],uploadParams[5]);
		bidix.upload.httpUpload(rssUploadParams,convertUnicodeToUTF8(generateRss()),callback,Array(uploadParams,original,posDiv));
	} else {
		bidix.upload.uploadMain(uploadParams,original,posDiv);
	}
};

bidix.upload.uploadMain = function(uploadParams,original,posDiv) 
{
	var callback = function(status,params,responseText,url,xhr) {
		var log = new bidix.UploadLog();
		if(status) {
			// if backupDir specified
			if ((params[3]) && (responseText.indexOf("backupfile:") > -1))  {
				var backupfile = responseText.substring(responseText.indexOf("backupfile:")+11,responseText.indexOf("\n", responseText.indexOf("backupfile:")));
				displayMessage(bidix.upload.messages.backupSaved,bidix.dirname(url)+'/'+backupfile);
			}
			var destfile = responseText.substring(responseText.indexOf("destfile:")+9,responseText.indexOf("\n", responseText.indexOf("destfile:")));
			displayMessage(bidix.upload.messages.mainSaved,bidix.dirname(url)+'/'+destfile);
			store.setDirty(false);
			log.endUpload("ok");
		} else {
			alert(bidix.upload.messages.mainFailed);
			displayMessage(bidix.upload.messages.mainFailed);
			log.endUpload("failed");			
		}
	};
	// do uploadMain
	var revised = bidix.upload.updateOriginal(original,posDiv);
	bidix.upload.httpUpload(uploadParams,revised,callback,uploadParams);
};

bidix.upload.httpUpload = function(uploadParams,data,callback,params)
{
	var localCallback = function(status,params,responseText,url,xhr) {
		url = (url.indexOf("nocache=") < 0 ? url : url.substring(0,url.indexOf("nocache=")-1));
		if (xhr.status == httpStatus.NotFound)
			alert(bidix.upload.messages.storePhpNotFound.format([url]));
		if ((bidix.debugMode) || (responseText.indexOf("Debug mode") >= 0 )) {
			alert(responseText);
			if (responseText.indexOf("Debug mode") >= 0 )
				responseText = responseText.substring(responseText.indexOf("\n\n")+2);
		} else if (responseText.charAt(0) != '0') 
			alert(responseText);
		if (responseText.charAt(0) != '0')
			status = null;
		callback(status,params,responseText,url,xhr);
	};
	// do httpUpload
	var boundary = "---------------------------"+"AaB03x";	
	var uploadFormName = "UploadPlugin";
	// compose headers data
	var sheader = "";
	sheader += "--" + boundary + "\r\nContent-disposition: form-data; name=\"";
	sheader += uploadFormName +"\"\r\n\r\n";
	sheader += "backupDir="+uploadParams[3] +
				";user=" + uploadParams[4] +
				";password=" + uploadParams[5] +
				";uploaddir=" + uploadParams[2];
	if (bidix.debugMode)
		sheader += ";debug=1";
	sheader += ";;\r\n"; 
	sheader += "\r\n" + "--" + boundary + "\r\n";
	sheader += "Content-disposition: form-data; name=\"userfile\"; filename=\""+uploadParams[1]+"\"\r\n";
	sheader += "Content-Type: text/html;charset=UTF-8" + "\r\n";
	sheader += "Content-Length: " + data.length + "\r\n\r\n";
	// compose trailer data
	var strailer = new String();
	strailer = "\r\n--" + boundary + "--\r\n";
	data = sheader + data + strailer;
	if (bidix.debugMode) alert("about to execute Http - POST on "+uploadParams[0]+"\n with \n"+data.substr(0,500)+ " ... ");
	var r = doHttp("POST",uploadParams[0],data,"multipart/form-data; boundary="+boundary,uploadParams[4],uploadParams[5],localCallback,params,null);
	if (typeof r == "string")
		displayMessage(r);
	return r;
};

// same as Saving's updateOriginal but without convertUnicodeToUTF8 calls
bidix.upload.updateOriginal = function(original, posDiv)
{
	if (!posDiv)
		posDiv = locateStoreArea(original);
	if((posDiv[0] == -1) || (posDiv[1] == -1)) {
		alert(config.messages.invalidFileError.format([localPath]));
		return;
	}
	var revised = original.substr(0,posDiv[0] + startSaveArea.length) + "\n" +
				store.allTiddlersAsHtml() + "\n" +
				original.substr(posDiv[1]);
	var newSiteTitle = getPageTitle().htmlEncode();
	revised = revised.replaceChunk("<title"+">","</title"+">"," " + newSiteTitle + " ");
	revised = updateMarkupBlock(revised,"PRE-HEAD","MarkupPreHead");
	revised = updateMarkupBlock(revised,"POST-HEAD","MarkupPostHead");
	revised = updateMarkupBlock(revised,"PRE-BODY","MarkupPreBody");
	revised = updateMarkupBlock(revised,"POST-SCRIPT","MarkupPostBody");
	return revised;
};

//
// UploadLog
// 
// config.options.chkUploadLog :
//		false : no logging
//		true : logging
// config.options.txtUploadLogMaxLine :
//		-1 : no limit
//      0 :  no Log lines but UploadLog is still in place
//		n :  the last n lines are only kept
//		NaN : no limit (-1)

bidix.UploadLog = function() {
	if (!config.options.chkUploadLog) 
		return; // this.tiddler = null
	this.tiddler = store.getTiddler("UploadLog");
	if (!this.tiddler) {
		this.tiddler = new Tiddler();
		this.tiddler.title = "UploadLog";
		this.tiddler.text = "| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |";
		this.tiddler.created = new Date();
		this.tiddler.modifier = config.options.txtUserName;
		this.tiddler.modified = new Date();
		store.addTiddler(this.tiddler);
	}
	return this;
};

bidix.UploadLog.prototype.addText = function(text) {
	if (!this.tiddler)
		return;
	// retrieve maxLine when we need it
	var maxLine = parseInt(config.options.txtUploadLogMaxLine,10);
	if (isNaN(maxLine))
		maxLine = -1;
	// add text
	if (maxLine != 0) 
		this.tiddler.text = this.tiddler.text + text;
	// Trunck to maxLine
	if (maxLine >= 0) {
		var textArray = this.tiddler.text.split('\n');
		if (textArray.length > maxLine + 1)
			textArray.splice(1,textArray.length-1-maxLine);
			this.tiddler.text = textArray.join('\n');		
	}
	// update tiddler fields
	this.tiddler.modifier = config.options.txtUserName;
	this.tiddler.modified = new Date();
	store.addTiddler(this.tiddler);
	// refresh and notifiy for immediate update
	story.refreshTiddler(this.tiddler.title);
	store.notify(this.tiddler.title, true);
};

bidix.UploadLog.prototype.startUpload = function(storeUrl, toFilename, uploadDir,  backupDir) {
	if (!this.tiddler)
		return;
	var now = new Date();
	var text = "\n| ";
	var filename = bidix.basename(document.location.toString());
	if (!filename) filename = '/';
	text += now.formatString("0DD/0MM/YYYY 0hh:0mm:0ss") +" | ";
	text += config.options.txtUserName + " | ";
	text += "[["+filename+"|"+location + "]] |";
	text += " [[" + bidix.basename(storeUrl) + "|" + storeUrl + "]] | ";
	text += uploadDir + " | ";
	text += "[[" + bidix.basename(toFilename) + " | " +toFilename + "]] | ";
	text += backupDir + " |";
	this.addText(text);
};

bidix.UploadLog.prototype.endUpload = function(status) {
	if (!this.tiddler)
		return;
	this.addText(" "+status+" |");
};

//
// Utilities
// 

bidix.checkPlugin = function(plugin, major, minor, revision) {
	var ext = version.extensions[plugin];
	if (!
		(ext  && 
			((ext.major > major) || 
			((ext.major == major) && (ext.minor > minor))  ||
			((ext.major == major) && (ext.minor == minor) && (ext.revision >= revision))))) {
			// write error in PluginManager
			if (pluginInfo)
				pluginInfo.log.push("Requires " + plugin + " " + major + "." + minor + "." + revision);
			eval(plugin); // generate an error : "Error: ReferenceError: xxxx is not defined"
	}
};

bidix.dirname = function(filePath) {
	if (!filePath) 
		return;
	var lastpos;
	if ((lastpos = filePath.lastIndexOf("/")) != -1) {
		return filePath.substring(0, lastpos);
	} else {
		return filePath.substring(0, filePath.lastIndexOf("\\"));
	}
};

bidix.basename = function(filePath) {
	if (!filePath) 
		return;
	var lastpos;
	if ((lastpos = filePath.lastIndexOf("#")) != -1) 
		filePath = filePath.substring(0, lastpos);
	if ((lastpos = filePath.lastIndexOf("/")) != -1) {
		return filePath.substring(lastpos + 1);
	} else
		return filePath.substring(filePath.lastIndexOf("\\")+1);
};

bidix.initOption = function(name,value) {
	if (!config.options[name])
		config.options[name] = value;
};

//
// Initializations
//

// require PasswordOptionPlugin 1.0.1 or better
bidix.checkPlugin("PasswordOptionPlugin", 1, 0, 1);

// styleSheet
setStylesheet('.txtUploadStoreUrl, .txtUploadBackupDir, .txtUploadDir {width: 22em;}',"uploadPluginStyles");

//optionsDesc
merge(config.optionsDesc,{
	txtUploadStoreUrl: "Url of the UploadService script (default: store.php)",
	txtUploadFilename: "Filename of the uploaded file (default: in index.html)",
	txtUploadDir: "Relative Directory where to store the file (default: . (downloadService directory))",
	txtUploadBackupDir: "Relative Directory where to backup the file. If empty no backup. (default: ''(empty))",
	txtUploadUserName: "Upload Username",
	pasUploadPassword: "Upload Password",
	chkUploadLog: "do Logging in UploadLog (default: true)",
	txtUploadLogMaxLine: "Maximum of lines in UploadLog (default: 10)"
});

// Options Initializations
bidix.initOption('txtUploadStoreUrl','');
bidix.initOption('txtUploadFilename','');
bidix.initOption('txtUploadDir','');
bidix.initOption('txtUploadBackupDir','');
bidix.initOption('txtUploadUserName','');
bidix.initOption('pasUploadPassword','');
bidix.initOption('chkUploadLog',true);
bidix.initOption('txtUploadLogMaxLine','10');


/* don't want this for tiddlyspot sites

// Backstage
merge(config.tasks,{
	uploadOptions: {text: "upload", tooltip: "Change UploadOptions and Upload", content: '<<uploadOptions>>'}
});
config.backstageTasks.push("uploadOptions");

*/


//}}}
|!Plugin|!Description|
|ImportTiddlersPlugin|interactive controls for import/export with filtering|
|SiteMapPlugin|Nested folder like strcture|
|TagsTreePlugin|Displays tags hierachy as a tree of tagged tiddlers.<br>Can be used to create dynamic outline navigation.|
AlfonsoReyes
JanetAguayo
/***
|''Name:''|ValueSwitcherPlugin|
|''Description:''|Gather values from a definition tiddler, and present the user with a UI for setting a value from those available options as an extende field |
|''Version:''|0.1|
|''Date:''|25 Sept, 2007|
|''Source:''|http://www.hawksworx.com/playground/TeamTasks/#ValueTogglerPlugin|
|''Author:''|PhilHawksworth (phawksworth (at) gmail (dot) com)|
|''License:''|[[BSD open source license]]|
|''CoreVersion:''|2.2|
***/

//{{{
// Ensure that this Plugin is only installed once.
if(!version.extensions.ValueSwitcher2) 
{
	version.extensions.ValueSwitcher2 = {installed:true};
	config.macros.ValueSwitcher2 = {
	
		handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		
			var taskTiddler = story.findContainingTiddler(place);
			if(!(taskTiddler && taskTiddler != 'undefined')) {
				return;
			}
			
			var ctrlType = params[0];
			// valueSrc is the name of the field
			var valueSrc = params[1]; // this can be used for DataTiddler
			var id = taskTiddler.id;
			var title = id.substr(7);
			var tiddler = store.getTiddler(title);
			
			// build a drop down control
			if(ctrlType == 'dropdown') {
				// join fieldName and current value with underscore
				var selected = valueSrc + '_' + store.getValue(tiddler,valueSrc);
				
				var values = this.getDefValues(valueSrc);
				var options = [];

				options.push({'caption': 'Please select', 'name': null});
				for (var i=0; i < values.length; i++) {
					options.push({'caption': values[i], 'name': valueSrc + '_' + values[i]});
				}

				var cTDD = createTiddlyDropDown(place,this.setDropDownMetaData,options,selected);	
			}

			// build, create a checkbox control
			else if(ctrlType == 'checkbox') {
				var fieldName = valueSrc + '_' + store.getValue(tiddler,valueSrc);
				var label = valueSrc;
				//var status = store.getValue(tiddler,valueSrc);
				var status = false;
			var e = createTiddlyCheckbox(place,label,status,this.setCheckbox);
			}


			//build a date control
			else if(ctrlType == 'date') {
				//TODO: Build in deadline support
			}
		},
		
		getDefValues: function(src) {
			var text = store.getTiddlerText(src);
			return (text.split('\n'));	
		},

		setCheckbox: function(e) {
			alert();
			//alert(this.chkObj.checked);
			//displayMessage(chkObj.checked);
		},
		
		setDropDownMetaData: function(e) {
			var taskTiddler = story.findContainingTiddler(this);
			if(taskTiddler && taskTiddler != 'undefined') {
				var id = taskTiddler.id;
				var title = id.substr(7);
				var tiddler =  store.getTiddler(title);
				var option = this[this.selectedIndex].value.split('_');

				var extField = option[0];	// creates field name
				var extFieldVal = option[1];	// assign value to field
				store.setValue(tiddler,extField,extFieldVal);
				// store values in JSON with DataTiddler
				DataTiddler.setData(title,option[0],option[1])
				story.saveTiddler(title);
			} 
		} 



	};
}
//}}}
/***
|''Name:''|ValueSwitcherPlugin|
|''Description:''|Gather values from a definition tiddler, and present the user with a UI for setting a value from those available options as an extende field |
|''Version:''|0.1|
|''Date:''|25 Sept, 2007|
|''Source:''|http://www.hawksworx.com/playground/TeamTasks/#ValueTogglerPlugin|
|''Author:''|PhilHawksworth (phawksworth (at) gmail (dot) com)|
|''License:''|[[BSD open source license]]|
|''CoreVersion:''|2.2|
***/

//{{{
// Ensure that this Plugin is only installed once.
if(!version.extensions.ValueSwitcher) 
{
	version.extensions.ValueSwitcher = {installed:true};
	config.macros.ValueSwitcher = {
	
		handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		
			var taskTiddler = story.findContainingTiddler(place);
			if(!(taskTiddler && taskTiddler != 'undefined')) {
				return;
			}
			
			var ctrlType = params[0];
			var valueSrc = params[1]; //this can be used for DataTiddler
			var id = taskTiddler.id;
			var title = id.substr(7);
			var tiddler = store.getTiddler(title);
			
			// build a drop down control
			if(ctrlType == 'dropdown') {
				var selected = valueSrc + '_' + store.getValue(tiddler,valueSrc);
				
				var values = this.getDefValues(valueSrc);
				var options = [];
				//DataTiddler.setData(title,valueSrc,option)
				options.push({'caption': 'Please select', 'name': null});
				for (var i=0; i < values.length; i++) {
					options.push({'caption': values[i], 'name': valueSrc + '_' + values[i]});
				}

				var cTDD = createTiddlyDropDown(place,this.setDropDownMetaData,options,selected);	
				//alert(cTDD.value);

			}
			//build a date control
			else if(ctrlType == 'date'){
				//TODO: Build in deadline support
			}
		},
		
		getDefValues: function(src) {
			var text = store.getTiddlerText(src);
			return (text.split('\n'));	
		},
		
		setDropDownMetaData: function(e) {
			var taskTiddler = story.findContainingTiddler(this);
			if(taskTiddler && taskTiddler != 'undefined') {
				var id = taskTiddler.id;
				var title = id.substr(7);
				var tiddler =  store.getTiddler(title);
				var option = this[this.selectedIndex].value.split('_');

//alert("option[0]=" + option[0]+"\n");
//alert("option[1]=" + option[1]+"\n");

				var extField = option[0];
				var extFieldVal = option[1];
				store.setValue(tiddler,extField,extFieldVal);
				DataTiddler.setData(title,option[0],option[1])

				story.saveTiddler(title);


			}
		}
	};
}
//}}}
<code>
if(!version.extensions.ValueSwitcher) 
{
	version.extensions.ValueSwitcher = {installed:true};
	config.macros.ValueSwitcher = {
	
		handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		
			var taskTiddler = story.findContainingTiddler(place);
			if(!(taskTiddler && taskTiddler != 'undefined')) {
				return;
			}
			
			var ctrlType = params[0];
			var valueSrc = params[1];
			var id = taskTiddler.id;
			var title = id.substr(7);
			var tiddler = store.getTiddler(title);
			
			// build a drop down control
			if(ctrlType == 'dropdown') {
				var selected = valueSrc + '_' + store.getValue(tiddler,valueSrc);
				var values = this.getDefValues(valueSrc);
				var options = [];
				options.push({'caption': 'Please select', 'name': null});
				for (var i=0; i < values.length; i++) {
					options.push({'caption': values[i], 'name': valueSrc + '_' + values[i]});
				}
				createTiddlyDropDown(place,this.setDropDownMetaData,options,selected);	
			}
			//build a date control
			else if(ctrlType == 'date'){
				//TODO: Build in deadline support
			}
		},
		
		getDefValues: function(src) {
			var text = store.getTiddlerText(src);
			return (text.split('\n'));	
		},
		
		setDropDownMetaData: function(e) {
			var taskTiddler = story.findContainingTiddler(this);
			if(taskTiddler && taskTiddler != 'undefined') {
				var id = taskTiddler.id;
				var title = id.substr(7);
				var tiddler =  store.getTiddler(title);
				var option = this[this.selectedIndex].value.split('_');
				var extField = option[0];
				var extFieldVal = option[1];
				store.setValue(tiddler,extField,extFieldVal);
				story.saveTiddler(title);
			}
		}
	};
}

</code>
Link: http://verticaltabs.tiddlyspot.com/
[[MptwViewTemplate]]
<!--{{{-->
<!--
|Name|ViewTemplateHeader|
|Source|http://www.TiddlyTools.com/#ViewTemplateHeader|
|Version||
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|template|
|Requires|see below|
|Overrides||
|Description|custom tiddler toolbar/title definition for inclusion in normal or alternative ViewTemplate|

NOTE: Some portions of this template have been customized for use on
the TiddlyTools.com site, and require additional plugins, scripts, etc. that
may not be installed in your document.  You should edit this template to
remove unneeded content, or install additional plugins to enable the existing
content to function properly.

Alternatively, you can revert to using the default tiddler title display and
toolbar commands by completely replacing the custom template definition
below with the following TiddlyWiki STANDARD HEADER DEFINITION:
(extracted from the built-in shadow ViewTemplate)

---- BEGIN STANDARD HEADER
<div class='toolbar' macro='toolbar closeTiddler closeOthers +editTiddler > fields syncing permalink references jump'></div>
<div class='title' macro='view title'></div>
<div class='subtitle'>
	<span macro='view modifier link'></span>, <span macro='view modified date'></span>
	(<span macro='message views.wikified.createdPrompt'></span> <span macro='view created date'></span>)
</div>
---- END STANDARD HEADER
You can then edit this standard definition to incorporate your own custom
ViewTemplate changes (e.g., extra toolbar commands)

-->
<!-- BEGIN TIDDLYTOOLS CUSTOM VIEW TEMPLATE HEADER -->
<span class='toolbar'><span style='font-size:12pt;'>&nbsp;</span>
	<span macro='toolbar collapseTiddler collapseOthers closeTiddler closeOthers'></span><!--
	-->|<!--
	--><span macro='toolbar +editTiddler permalink'></span><!--
	--><span macro='tiddler ToolbarExtras'></span>
</span></span>
<span class='title'>
	<span class='floatleft' macro='tiddlerIcons' style='cursor:auto !important;'></span>
	<span macro='view title'></span>
</span>
<span class='subtitle'><!--<span macro='view modifier link'></span>, --><span style='white-space:nowrap' macro='view modified date [[DDD, MMM DDth YYYY]]'></span><!-- (created <span macro='view created date [[DD MMM YYYY]]'></span>)--></span>
<div class='tagClear'></div>
<!-- END TIDDLYTOOLS CUSTOM VIEW TEMPLATE HEADER -->
<!--}}}-->
{{{
=SETF(GetRef(User.ODBCConnection),"ODBCDataSource="&Masters[properties]!ThePage!User.DataSource&"|"&"ODBCQualifier="&Masters[properties]!ThePage!User.Database&"|"&"ODBCTable=Table|1|Item ID=Prop.ItemID1|35|_EndCol=Prop._EndCol=0|Annular Fill=Prop.AnnularFill3=0|Bottom=Prop.Bottom=32|C Hazen=Prop.CHazen5=0|Code=Prop.Code=0|Completed=Prop.Completed=0|Connection=Prop.Connection=0|Depth Criteria=Prop.DepthCriteria9=0|FillBkgnd=FillBkgnd=32|FillForegnd=FillForegnd=32|FillPattern=FillPattern=32|Grade=Prop.Grade=0|ID=Prop.ID=32|LineColor=LineColor=32|LinePattern=LinePattern=32|LineWeight=LineWeight=1|Location AnnFill=Prop.LocationAnnFill18=0|Material=Prop.Material=0|n Manning=Prop.nManning20=0|Name=Prop.Name=0|Nominal=Prop.Nominal=0|OD=Prop.OD=32|PipeBkgnd=Prop.PipeBkgnd=32|PipeForegnd=Prop.PipeForegnd=32|PipePattern=Prop.PipePattern=32|Prating=Prop.Prating=0|Shoe Length=Prop.ShoeLength28=32|Spare2=Prop.Spare2=0|Top=Prop.Top=32|Tubular Type=Prop.TubularType31=0|Type=Prop.Type=0|Use=Prop.Use=0|Wall Thickness=Prop.WallThickness34=32|Weight=Prop.Weight=0|Well Type=Prop.WellType36=0|")
}}}
To reference a cell of
 Use this syntax
 Example
 
The same shape
 CellName
 Width
 
A shape, group, or guide
 Shapename!CellName
 Star!Angle
 
A shape, group, or guide in which more than one shape at the same level has the same name
 Shapename.ID!CellName
 Executive.2!Height
 
A named column with indexed rows
 Section.Column[index]
 Char.Font[3]
 
An unnamed column with indexed rows
 Section.ColumnIndex
 Scratch.A5
 
Any shape, page, master, or style
 Sheet.ID!CellName
 Sheet.8!FillForegnd
 
A master
 Masters[MasterName]!SheetName!CellReference
 Masters[Gear]!Shaft!Geometry1.X1
 
The page or master page on which the object is located
 ThePage!CellReference
 ThePage!User.Vanishing_Point
 
Another page in the document
 Pages[PageName]!SheetName!CellReference
 Pages[Page-3]!Sheet.4!BeginX
 
A style
 Styles!SheetName!CellReference
 Styles!Manager!LineColor
 
The document
 TheDoc!CellReference
 TheDoc!PreviewQuality
 
A shape, page, master, document, or style with a nonstandard name.
 'Sheetname'!CellName
 '1-D'!LineColor
 
Vertical
Horizontal
Unknown
<script show>
 return "link to current user: [["+config.options.txtUserName+"]]";
</script>
/***
|''Name:''|YourSearchPlugin|
|''Version:''|2.1.1 (2007-03-11)|
|''Source:''|http://tiddlywiki.abego-software.de/#YourSearchPlugin ([[del.icio.us|http://del.icio.us/post?url=http://tiddlywiki.abego-software.de/index.html%23YourSearchPlugin]])|
|''Author:''|UdoBorkowski (ub [at] abego-software [dot] de)|
|''Licence:''|[[BSD open source license (abego Software)|http://www.abego-software.de/legal/apl-v10.html]]|
|''Copyright:''|&copy; 2005-2006 [[abego Software|http://www.abego-software.de]]|
|''~CoreVersion:''|2.1.0|
|''Browser:''|Firefox 1.0.4+; Firefox 1.5; ~InternetExplorer 6.0|
!About YourSearch
YourSearch gives you a bunch of new features to simplify and speed up your daily searches in TiddlyWiki. It seamlessly integrates into the standard TiddlyWiki search: just start typing into the 'search' field and explore!

For more information see [[Help|YourSearch Help]].
!Compatibility
This plugin requires TiddlyWiki 2.1. 
Check the [[archive|http://tiddlywiki.abego-software.de/archive]] for ~YourSearchPlugins supporting older versions of TiddlyWiki.
!Source Code
***/
/***
This plugin's source code is compressed (and hidden). Use this [[link|http://tiddlywiki.abego-software.de/archive/YourSearchPlugin/Plugin-YourSearch-src.2.1.1.js]] to get the readable source code.
***/
///%
if(!version.extensions.YourSearchPlugin){version.extensions.YourSearchPlugin={major:2,minor:1,revision:1,source:"http://tiddlywiki.abego-software.de/#YourSearchPlugin",licence:"[[BSD open source license (abego Software)|http://www.abego-software.de/legal/apl-v10.html]]",copyright:"Copyright (c) abego Software GmbH, 2005-2007 (www.abego-software.de)"};if(!window.abego){window.abego={};}if(!Array.forEach){Array.forEach=function(_1,_2,_3){for(var i=0,len=_1.length;i<len;i++){_2.call(_3,_1[i],i,_1);}};Array.prototype.forEach=function(_5,_6){for(var i=0,len=this.length;i<len;i++){_5.call(_6,this[i],i,this);}};}abego.toInt=function(s,_9){if(!s){return _9;}var n=parseInt(s);return (n==NaN)?_9:n;};abego.createEllipsis=function(_b){var e=createTiddlyElement(_b,"span");e.innerHTML="&hellip;";};abego.shallowCopy=function(_d){if(!_d){return _d;}var _e={};for(var n in _d){_e[n]=_d[n];}return _e;};abego.copyOptions=function(_10){return !_10?{}:abego.shallowCopy(_10);};abego.countStrings=function(_11,s){if(!s){return 0;}var len=s.length;var n=0;var _15=0;while(1){var i=_11.indexOf(s,_15);if(i<0){return n;}n++;_15=i+len;}return n;};abego.getBracedText=function(_17,_18,_19){if(!_18){_18=0;}var re=/\{([^\}]*)\}/gm;re.lastIndex=_18;var m=re.exec(_17);if(m){var s=m[1];var _1d=abego.countStrings(s,"{");if(!_1d){if(_19){_19.lastIndex=re.lastIndex;}return s;}var len=_17.length;for(var i=re.lastIndex;i<len&&_1d;i++){var c=_17.charAt(i);if(c=="{"){_1d++;}else{if(c=="}"){_1d--;}}}if(!_1d){if(_19){_19.lastIndex=i-1;}return _17.substring(m.index+1,i-1);}}};abego.select=function(_21,_22,_23,_24){if(!_24){_24=[];}_21.forEach(function(t){if(_22.call(_23,t)){_24.push(t);}});return _24;};abego.TiddlerFilterTerm=function(_26,_27){if(!_27){_27={};}var _28=_26;if(!_27.textIsRegExp){_28=_26.escapeRegExp();if(_27.fullWordMatch){_28="\\b"+_28+"\\b";}}var _29=new RegExp(_28,"m"+(_27.caseSensitive?"":"i"));this.tester=new abego.MultiFieldRegExpTester(_29,_27.fields,_27.withExtendedFields);};abego.TiddlerFilterTerm.prototype.test=function(_2a){return this.tester.test(_2a);};abego.parseNewTiddlerCommandLine=function(s){var m=/(.*?)\.(?:\s+|$)([^#]*)(#.*)?/.exec(s);if(!m){m=/([^#]*)()(#.*)?/.exec(s);}if(m){var r;if(m[3]){var s2=m[3].replace(/#/g,"");r=s2.parseParams("tag");}else{r=[[]];}var _2f=m[2]?m[2].trim():"";r.push({name:"text",value:_2f});r[0].text=[_2f];return {title:m[1].trim(),params:r};}else{return {title:s.trim(),params:[[]]};}};abego.parseTiddlerFilterTerm=function(_30,_31,_32){var re=/\s*(?:(?:\{([^\}]*)\})|(?:(=)|([#%!])|(?:(\w+)\s*\:(?!\/\/))|(?:(?:("(?:(?:\\")|[^"])+")|(?:\/((?:(?:\\\/)|[^\/])+)\/)|(\w+\:\/\/[^\s]+)|([^\s\)\-\"]+)))))/mg;var _34={"!":"title","%":"text","#":"tags"};var _35={};var _36;re.lastIndex=_31;while(1){var i=re.lastIndex;var m=re.exec(_30);if(!m||m.index!=i){throw "Word or String literal expected";}if(m[1]){var _39={};var _3a=abego.getBracedText(_30,0,_39);if(!_3a){throw "Invalid {...} syntax";}var f=Function("tiddler","return ("+_3a+");");return {func:f,lastIndex:_39.lastIndex,markRE:null};}if(m[2]){_36=true;}else{if(m[3]){_35[_34[m[3]]]=1;}else{if(m[4]){_35[m[4]]=1;}else{var _3c=m[6];var _3d=m[5]?window.eval(m[5]):m[6]?m[6]:m[7]?m[7]:m[8];var _3e=abego.copyOptions(_3e);_3e.fullWordMatch=_36;_3e.textIsRegExp=_3c;var _3f=[];for(var n in _35){_3f.push(n);}if(_3f.length==0){_3e.fields=_3e.defaultFields;}else{_3e.fields=_3f;_3e.withExtendedFields=false;}var _41=new abego.TiddlerFilterTerm(_3d,_3e);var _42=_3c?_3d:_3d.escapeRegExp();if(_42&&_36){_42="\\b"+_42+"\\b";}return {func:function(_43){return _41.test(_43);},lastIndex:re.lastIndex,markRE:_42?"(?:"+_42+")":null};}}}}};abego.BoolExp=function(s,_45,_46){this.s=s;var _47=_46&&_46.defaultOperationIs_OR;var _48=/\s*(?:(\-|not)|(\())/gi;var _49=/\s*\)/g;var _4a=/\s*(?:(and|\&\&)|(or|\|\|))/gi;var _4b=/\s*[^\)\s]/g;var _4c=/\s*(\-|not)?(\s*\()?/gi;var _4d;var _4e=function(_4f){_4c.lastIndex=_4f;var m=_4c.exec(s);var _51;var _52;if(m&&m.index==_4f){_4f=_4c.lastIndex;_51=m[1];if(m[2]){var e=_4d(_4f);_49.lastIndex=e.lastIndex;if(!_49.exec(s)){throw "Missing ')'";}_52={func:e.func,lastIndex:_49.lastIndex,markRE:e.markRE};}}if(!_52){_52=_45(s,_4f,_46);}if(_51){_52.func=(function(f){return function(_55){return !f(_55);};})(_52.func);_52.markRE=null;}return _52;};_4d=function(_56){var _57=_4e(_56);while(1){var l=_57.lastIndex;_4a.lastIndex=l;var m=_4a.exec(s);var _5a;var _5b;if(m&&m.index==l){_5a=!m[1];_5b=_4e(_4a.lastIndex);}else{try{_5b=_4e(l);}catch(e){return _57;}_5a=_47;}_57.func=(function(_5c,_5d,_5e){return _5e?function(_5f){return _5c(_5f)||_5d(_5f);}:function(_60){return _5c(_60)&&_5d(_60);};})(_57.func,_5b.func,_5a);_57.lastIndex=_5b.lastIndex;if(!_57.markRE){_57.markRE=_5b.markRE;}else{if(_5b.markRE){_57.markRE=_57.markRE+"|"+_5b.markRE;}}}};var _61=_4d(0);this.evalFunc=_61.func;if(_61.markRE){this.markRegExp=new RegExp(_61.markRE,_46.caseSensitive?"mg":"img");}};abego.BoolExp.prototype.exec=function(){return this.evalFunc.apply(this,arguments);};abego.BoolExp.prototype.getMarkRegExp=function(){return this.markRegExp;};abego.BoolExp.prototype.toString=function(){return this.s;};abego.MultiFieldRegExpTester=function(re,_63,_64){this.re=re;this.fields=_63?_63:["title","text","tags"];this.withExtendedFields=_64;};abego.MultiFieldRegExpTester.prototype.test=function(_65){var re=this.re;for(var i=0;i<this.fields.length;i++){var s=store.getValue(_65,this.fields[i]);if(typeof s=="string"&&re.test(s)){return this.fields[i];}}if(this.withExtendedFields){return store.forEachField(_65,function(_69,_6a,_6b){return typeof _6b=="string"&&re.test(_6b)?_6a:null;},true);}return null;};abego.TiddlerQuery=function(_6c,_6d,_6e,_6f,_70){if(_6e){this.regExp=new RegExp(_6c,_6d?"mg":"img");this.tester=new abego.MultiFieldRegExpTester(this.regExp,_6f,_70);}else{this.expr=new abego.BoolExp(_6c,abego.parseTiddlerFilterTerm,{defaultFields:_6f,caseSensitive:_6d,withExtendedFields:_70});}this.getQueryText=function(){return _6c;};this.getUseRegExp=function(){return _6e;};this.getCaseSensitive=function(){return _6d;};this.getDefaultFields=function(){return _6f;};this.getWithExtendedFields=function(){return _70;};};abego.TiddlerQuery.prototype.test=function(_71){if(!_71){return false;}if(this.regExp){return this.tester.test(_71);}return this.expr.exec(_71);};abego.TiddlerQuery.prototype.filter=function(_72){return abego.select(_72,this.test,this);};abego.TiddlerQuery.prototype.getMarkRegExp=function(){if(this.regExp){return "".search(this.regExp)>=0?null:this.regExp;}return this.expr.getMarkRegExp();};abego.TiddlerQuery.prototype.toString=function(){return (this.regExp?this.regExp:this.expr).toString();};abego.PageWiseRenderer=function(){this.firstIndexOnPage=0;};merge(abego.PageWiseRenderer.prototype,{setItems:function(_73){this.items=_73;this.setFirstIndexOnPage(0);},getMaxPagesInNavigation:function(){return 10;},getItemsCount:function(_74){return this.items?this.items.length:0;},getCurrentPageIndex:function(){return Math.floor(this.firstIndexOnPage/this.getItemsPerPage());},getLastPageIndex:function(){return Math.floor((this.getItemsCount()-1)/this.getItemsPerPage());},setFirstIndexOnPage:function(_75){this.firstIndexOnPage=Math.min(Math.max(0,_75),this.getItemsCount()-1);},getFirstIndexOnPage:function(){this.firstIndexOnPage=Math.floor(this.firstIndexOnPage/this.getItemsPerPage())*this.getItemsPerPage();return this.firstIndexOnPage;},getLastIndexOnPage:function(){return Math.min(this.getFirstIndexOnPage()+this.getItemsPerPage()-1,this.getItemsCount()-1);},onPageChanged:function(_76,_77){},renderPage:function(_78){if(_78.beginRendering){_78.beginRendering(this);}try{if(this.getItemsCount()){var _79=this.getLastIndexOnPage();var _7a=-1;for(var i=this.getFirstIndexOnPage();i<=_79;i++){_7a++;_78.render(this,this.items[i],i,_7a);}}}finally{if(_78.endRendering){_78.endRendering(this);}}},addPageNavigation:function(_7c){if(!this.getItemsCount()){return;}var _7d=this;var _7e=function(e){if(!e){var e=window.event;}var _81=abego.toInt(this.getAttribute("page"),0);var _82=_7d.getCurrentPageIndex();if(_81==_82){return;}var _83=_81*_7d.getItemsPerPage();_7d.setFirstIndexOnPage(_83);_7d.onPageChanged(_81,_82);};var _84;var _85=this.getCurrentPageIndex();var _86=this.getLastPageIndex();if(_85>0){_84=createTiddlyButton(_7c,"Previous","Go to previous page (Shortcut: Alt-'<')",_7e,"prev");_84.setAttribute("page",(_85-1).toString());_84.setAttribute("accessKey","<");}for(var i=-this.getMaxPagesInNavigation();i<this.getMaxPagesInNavigation();i++){var _88=_85+i;if(_88<0){continue;}if(_88>_86){break;}var _89=(i+_85+1).toString();var _8a=_88==_85?"currentPage":"otherPage";_84=createTiddlyButton(_7c,_89,"Go to page %0".format([_89]),_7e,_8a);_84.setAttribute("page",(_88).toString());}if(_85<_86){_84=createTiddlyButton(_7c,"Next","Go to next page (Shortcut: Alt-'>')",_7e,"next");_84.setAttribute("page",(_85+1).toString());_84.setAttribute("accessKey",">");}}});abego.LimitedTextRenderer=function(){var _8b=40;var _8c=4;var _8d=function(_8e,_8f,_90){var n=_8e.length;if(n==0){_8e.push({start:_8f,end:_90});return;}var i=0;for(;i<n;i++){var _93=_8e[i];if(_93.start<=_90&&_8f<=_93.end){var r;var _95=i+1;for(;_95<n;_95++){r=_8e[_95];if(r.start>_90||_8f>_93.end){break;}}var _96=_8f;var _97=_90;for(var j=i;j<_95;j++){r=_8e[j];_96=Math.min(_96,r.start);_97=Math.max(_97,r.end);}_8e.splice(i,_95-i,{start:_96,end:_97});return;}if(_93.start>_90){break;}}_8e.splice(i,0,{start:_8f,end:_90});};var _99=function(_9a){var _9b=0;for(var i=0;i<_9a.length;i++){var _9d=_9a[i];_9b+=_9d.end-_9d.start;}return _9b;};var _9e=function(c){return (c>="a"&&c<="z")||(c>="A"&&c<="Z")||c=="_";};var _a0=function(s,_a2){if(!_9e(s[_a2])){return null;}for(var i=_a2-1;i>=0&&_9e(s[i]);i--){}var _a4=i+1;var n=s.length;for(i=_a2+1;i<n&&_9e(s[i]);i++){}return {start:_a4,end:i};};var _a6=function(s,_a8,_a9){var _aa;if(_a9){_aa=_a0(s,_a8);}else{if(_a8<=0){return _a8;}_aa=_a0(s,_a8-1);}if(!_aa){return _a8;}if(_a9){if(_aa.start>=_a8-_8c){return _aa.start;}if(_aa.end<=_a8+_8c){return _aa.end;}}else{if(_aa.end<=_a8+_8c){return _aa.end;}if(_aa.start>=_a8-_8c){return _aa.start;}}return _a8;};var _ab=function(s,_ad){var _ae=[];if(_ad){var _af=0;var n=s.length;var _b1=0;do{_ad.lastIndex=_af;var _b2=_ad.exec(s);if(_b2){if(_af<_b2.index){var t=s.substring(_af,_b2.index);_ae.push({text:t});}_ae.push({text:_b2[0],isMatch:true});_af=_b2.index+_b2[0].length;}else{_ae.push({text:s.substr(_af)});break;}}while(true);}else{_ae.push({text:s});}return _ae;};var _b4=function(_b5){var _b6=0;for(var i=0;i<_b5.length;i++){if(_b5[i].isMatch){_b6++;}}return _b6;};var _b8=function(s,_ba,_bb,_bc,_bd){var _be=Math.max(Math.floor(_bd/(_bc+1)),_8b);var _bf=Math.max(_be-(_bb-_ba),0);var _c0=Math.min(Math.floor(_bb+_bf/3),s.length);var _c1=Math.max(_c0-_be,0);_c1=_a6(s,_c1,true);_c0=_a6(s,_c0,false);return {start:_c1,end:_c0};};var _c2=function(_c3,s,_c5){var _c6=[];var _c7=_b4(_c3);var pos=0;for(var i=0;i<_c3.length;i++){var t=_c3[i];var _cb=t.text;if(t.isMatch){var _cc=_b8(s,pos,pos+_cb.length,_c7,_c5);_8d(_c6,_cc.start,_cc.end);}pos+=_cb.length;}return _c6;};var _cd=function(s,_cf,_d0){var _d1=_d0-_99(_cf);while(_d1>0){if(_cf.length==0){_8d(_cf,0,_a6(s,_d0,false));return;}else{var _d2=_cf[0];var _d3;var _d4;if(_d2.start==0){_d3=_d2.end;if(_cf.length>1){_d4=_cf[1].start;}else{_8d(_cf,_d3,_a6(s,_d3+_d1,false));return;}}else{_d3=0;_d4=_d2.start;}var _d5=Math.min(_d4,_d3+_d1);_8d(_cf,_d3,_d5);_d1-=(_d5-_d3);}}};var _d6=function(_d7,s,_d9,_da,_db){if(_da.length==0){return;}var _dc=function(_dd,s,_df,_e0,_e1){var t;var _e3;var pos=0;var i=0;var _e6=0;for(;i<_df.length;i++){t=_df[i];_e3=t.text;if(_e0<pos+_e3.length){_e6=_e0-pos;break;}pos+=_e3.length;}var _e7=_e1-_e0;for(;i<_df.length&&_e7>0;i++){t=_df[i];_e3=t.text.substr(_e6);_e6=0;if(_e3.length>_e7){_e3=_e3.substr(0,_e7);}if(t.isMatch){createTiddlyElement(_dd,"span",null,"marked",_e3);}else{createTiddlyText(_dd,_e3);}_e7-=_e3.length;}if(_e1<s.length){abego.createEllipsis(_dd);}};if(_da[0].start>0){abego.createEllipsis(_d7);}var _e8=_db;for(var i=0;i<_da.length&&_e8>0;i++){var _ea=_da[i];var len=Math.min(_ea.end-_ea.start,_e8);_dc(_d7,s,_d9,_ea.start,_ea.start+len);_e8-=len;}};this.render=function(_ec,s,_ee,_ef){if(s.length<_ee){_ee=s.length;}var _f0=_ab(s,_ef);var _f1=_c2(_f0,s,_ee);_cd(s,_f1,_ee);_d6(_ec,s,_f0,_f1,_ee);};};(function(){function alertAndThrow(msg){alert(msg);throw msg;}if(version.major<2||(version.major==2&&version.minor<1)){alertAndThrow("YourSearchPlugin requires TiddlyWiki 2.1 or newer.\n\nCheck the archive for YourSearch plugins\nsupporting older versions of TiddlyWiki.\n\nArchive: http://tiddlywiki.abego-software.de/archive");}abego.YourSearch={};var _f3;var _f4;var _f5=function(_f6){_f3=_f6;};var _f7=function(){return _f3?_f3:[];};var _f8=function(){return _f3?_f3.length:0;};var _f9=4;var _fa=10;var _fb=2;var _fc=function(s,re){var m=s.match(re);return m?m.length:0;};var _100=function(_101,_102){var _103=_102.getMarkRegExp();if(!_103){return 1;}var _104=_101.title.match(_103);var _105=_104?_104.length:0;var _106=_fc(_101.getTags(),_103);var _107=_104?_104.join("").length:0;var _108=_101.title.length>0?_107/_101.title.length:0;var rank=_105*_f9+_106*_fb+_108*_fa+1;return rank;};var _10a=function(_10b,_10c,_10d,_10e,_10f,_110){_f4=null;var _111=_10b.reverseLookup("tags",_110,false);try{var _112=[];if(config.options.chkSearchInTitle){_112.push("title");}if(config.options.chkSearchInText){_112.push("text");}if(config.options.chkSearchInTags){_112.push("tags");}_f4=new abego.TiddlerQuery(_10c,_10d,_10e,_112,config.options.chkSearchExtendedFields);}catch(e){return [];}var _113=_f4.filter(_111);var _114=abego.YourSearch.getRankFunction();for(var i=0;i<_113.length;i++){var _116=_113[i];var rank=_114(_116,_f4);_116.searchRank=rank;}if(!_10f){_10f="title";}var _118=function(a,b){var _11b=a.searchRank-b.searchRank;if(_11b==0){if(a[_10f]==b[_10f]){return (0);}else{return (a[_10f]<b[_10f])?-1:+1;}}else{return (_11b>0)?-1:+1;}};_113.sort(_118);return _113;};var _11c=80;var _11d=50;var _11e=250;var _11f=50;var _120=25;var _121=10;var _122="yourSearchResult";var _123="yourSearchResultItems";var _124;var _125;var _126;var _127;var _128;var _129=function(){if(version.extensions.YourSearchPlugin.styleSheetInited){return;}version.extensions.YourSearchPlugin.styleSheetInited=true;setStylesheet(store.getTiddlerText("YourSearchStyleSheet"),"yourSearch");};var _12a=function(){return _125!=null&&_125.parentNode==document.body;};var _12b=function(){if(_12a()){document.body.removeChild(_125);}};var _12c=function(e){_12b();var _12e=this.getAttribute("tiddlyLink");if(_12e){var _12f=this.getAttribute("withHilite");var _130=highlightHack;if(_12f&&_12f=="true"&&_f4){highlightHack=_f4.getMarkRegExp();}story.displayTiddler(this,_12e);highlightHack=_130;}return (false);};var _131=function(){if(!_126){return;}var root=_126;var _133=findPosX(root);var _134=findPosY(root);var _135=root.offsetHeight;var _136=_133;var _137=_134+_135;var _138=findWindowWidth();if(_138<_125.offsetWidth){_125.style.width=(_138-100)+"px";_138=findWindowWidth();}var _139=_125.offsetWidth;if(_136+_139>_138){_136=_138-_139-30;}if(_136<0){_136=0;}_125.style.left=_136+"px";_125.style.top=_137+"px";_125.style.display="block";};var _13a=function(){if(_125){window.scrollTo(0,ensureVisible(_125));}if(_126){window.scrollTo(0,ensureVisible(_126));}};var _13b=function(){_131();_13a();};var _13c;var _13d;var _13e=new abego.PageWiseRenderer();var _13f=function(_140){this.itemHtml=store.getTiddlerText("YourSearchItemTemplate");if(!this.itemHtml){alertAndThrow("YourSearchItemTemplate not found");}this.place=document.getElementById(_123);if(!this.place){this.place=createTiddlyElement(_140,"div",_123);}};merge(_13f.prototype,{render:function(_141,_142,_143,_144){_13c=_144;_13d=_142;var item=createTiddlyElement(this.place,"div",null,"yourSearchItem");item.innerHTML=this.itemHtml;applyHtmlMacros(item,null);refreshElements(item,null);},endRendering:function(_146){_13d=null;}});var _147=function(){if(!_125||!_126){return;}var html=store.getTiddlerText("YourSearchResultTemplate");if(!html){html="<b>Tiddler YourSearchResultTemplate not found</b>";}_125.innerHTML=html;applyHtmlMacros(_125,null);refreshElements(_125,null);var _149=new _13f(_125);_13e.renderPage(_149);_13b();};_13e.getItemsPerPage=function(){var n=(config.options.chkPreviewText)?abego.toInt(config.options.txtItemsPerPageWithPreview,_121):abego.toInt(config.options.txtItemsPerPage,_120);return (n>0)?n:1;};_13e.onPageChanged=function(){_147();};var _14b=function(){if(_126==null||!config.options.chkUseYourSearch){return;}if((_126.value==_124)&&_124&&!_12a()){if(_125&&(_125.parentNode!=document.body)){document.body.appendChild(_125);_13b();}else{abego.YourSearch.onShowResult(true);}}};var _14c=function(){_12b();_125=null;_124=null;};var _14d=function(self,e){while(e!=null){if(self==e){return true;}e=e.parentNode;}return false;};var _150=function(e){if(e.target==_126){return;}if(e.target==_127){return;}if(_125&&_14d(_125,e.target)){return;}_12b();};var _152=function(e){if(e.keyCode==27){_12b();}};addEvent(document,"click",_150);addEvent(document,"keyup",_152);var _154=function(text,_156,_157){_124=text;_f5(_10a(store,text,_156,_157,"title","excludeSearch"));abego.YourSearch.onShowResult();};var _158=function(_159,_15a,_15b,_15c,_15d,_15e){_129();_124="";var _15f=null;var _160=function(txt){if(config.options.chkUseYourSearch){_154(txt.value,config.options.chkCaseSensitiveSearch,config.options.chkRegExpSearch);}else{story.search(txt.value,config.options.chkCaseSensitiveSearch,config.options.chkRegExpSearch);}_124=txt.value;};var _162=function(e){_160(_126);return false;};var _164=function(e){if(!e){var e=window.event;}_126=this;switch(e.keyCode){case 13:if(e.ctrlKey&&_128&&_12a()){_128.onclick.apply(_128,[e]);}else{_160(this);}break;case 27:if(_12a()){_12b();}else{this.value="";clearMessage();}break;}if(String.fromCharCode(e.keyCode)==this.accessKey||e.altKey){_14b();}if(this.value.length<3&&_15f){clearTimeout(_15f);}if(this.value.length>2){if(this.value!=_124){if(!config.options.chkUseYourSearch||config.options.chkSearchAsYouType){if(_15f){clearTimeout(_15f);}var txt=this;_15f=setTimeout(function(){_160(txt);},500);}}else{if(_15f){clearTimeout(_15f);}}}if(this.value.length==0){_12b();}};var _168=function(e){this.select();clearMessage();_14b();};var args=_15d.parseParams("list",null,true);var _16b=getFlag(args,"buttonAtRight");var _16c=getParam(args,"sizeTextbox",this.sizeTextbox);var btn;if(!_16b){btn=createTiddlyButton(_159,this.label,this.prompt,_162);}var txt=createTiddlyElement(_159,"input",null,null,null);if(_15b[0]){txt.value=_15b[0];}txt.onkeyup=_164;txt.onfocus=_168;txt.setAttribute("size",_16c);txt.setAttribute("accessKey",this.accessKey);txt.setAttribute("autocomplete","off");if(config.browser.isSafari){txt.setAttribute("type","search");txt.setAttribute("results","5");}else{txt.setAttribute("type","text");}if(_16b){btn=createTiddlyButton(_159,this.label,this.prompt,_162);}_126=txt;_127=btn;};var _16f=function(){_12b();var _170=_f7();var n=_170.length;if(n){var _172=[];for(var i=0;i<n;i++){_172.push(_170[i].title);}story.displayTiddlers(null,_172);}};var _174=function(_175,_176,_177,_178){invokeMacro(_175,"option",_176,_177,_178);var elem=_175.lastChild;var _17a=elem.onclick;elem.onclick=function(e){var _17c=_17a.apply(this,arguments);_147();return _17c;};return elem;};var _17d=function(s){var _17f=["''","{{{","}}}","//","<<<","/***","***/"];var _180="";for(var i=0;i<_17f.length;i++){if(i!=0){_180+="|";}_180+="("+_17f[i].escapeRegExp()+")";}return s.replace(new RegExp(_180,"mg"),"").trim();};var _182=function(){var i=_13c;return (i>=0&&i<=9)?(i<9?(i+1):0):-1;};var _184=new abego.LimitedTextRenderer();var _185=function(_186,s,_188){_184.render(_186,s,_188,_f4.getMarkRegExp());};var _189=TiddlyWiki.prototype.saveTiddler;TiddlyWiki.prototype.saveTiddler=function(_18a,_18b,_18c,_18d,_18e,tags,_190){_189.apply(this,arguments);_14c();};var _191=TiddlyWiki.prototype.removeTiddler;TiddlyWiki.prototype.removeTiddler=function(_192){_191.apply(this,arguments);_14c();};config.macros.yourSearch={label:"yourSearch",prompt:"Gives access to the current/last YourSearch result",handler:function(_193,_194,_195,_196,_197,_198){if(_195.length==0){return;}var name=_195[0];var func=config.macros.yourSearch.funcs[name];if(func){func(_193,_194,_195,_196,_197,_198);}},tests:{"true":function(){return true;},"false":function(){return false;},"found":function(){return _f8()>0;},"previewText":function(){return config.options.chkPreviewText;}},funcs:{itemRange:function(_19b){if(_f8()){var _19c=_13e.getLastIndexOnPage();var s="%0 - %1".format([_13e.getFirstIndexOnPage()+1,_19c+1]);createTiddlyText(_19b,s);}},count:function(_19e){createTiddlyText(_19e,_f8().toString());},query:function(_19f){if(_f4){createTiddlyText(_19f,_f4.toString());}},version:function(_1a0){var t="YourSearch %0.%1.%2".format([version.extensions.YourSearchPlugin.major,version.extensions.YourSearchPlugin.minor,version.extensions.YourSearchPlugin.revision]);var e=createTiddlyElement(_1a0,"a");e.setAttribute("href","http://tiddlywiki.abego-software.de/#YourSearchPlugin");e.innerHTML="<font color=\"black\" face=\"Arial, Helvetica, sans-serif\">"+t+"<font>";},copyright:function(_1a3){var e=createTiddlyElement(_1a3,"a");e.setAttribute("href","http://www.abego-software.de");e.innerHTML="<font color=\"black\" face=\"Arial, Helvetica, sans-serif\">&copy; 2005-2006 <b><font color=\"red\">abego</font></b> Software<font>";},newTiddlerButton:function(_1a5){if(_f4){var r=abego.parseNewTiddlerCommandLine(_f4.getQueryText());var btn=config.macros.newTiddler.createNewTiddlerButton(_1a5,r.title,r.params,"new tiddler","Create a new tiddler based on search text. (Shortcut: Ctrl-Enter; Separators: '.', '#')",null,"text");var _1a8=btn.onclick;btn.onclick=function(){_12b();_1a8.apply(this,arguments);};_128=btn;}},linkButton:function(_1a9,_1aa,_1ab,_1ac,_1ad,_1ae){if(_1ab<2){return;}var _1af=_1ab[1];var text=_1ab<3?_1af:_1ab[2];var _1b1=_1ab<4?text:_1ab[3];var _1b2=_1ab<5?null:_1ab[4];var btn=createTiddlyButton(_1a9,text,_1b1,_12c,null,null,_1b2);btn.setAttribute("tiddlyLink",_1af);},closeButton:function(_1b4,_1b5,_1b6,_1b7,_1b8,_1b9){var _1ba=createTiddlyButton(_1b4,"close","Close the Search Results (Shortcut: ESC)",_12b);},openAllButton:function(_1bb,_1bc,_1bd,_1be,_1bf,_1c0){var n=_f8();if(n==0){return;}var _1c2=n==1?"open tiddler":"open all %0 tiddlers".format([n]);var _1c3=createTiddlyButton(_1bb,_1c2,"Open all found tiddlers (Shortcut: Alt-O)",_16f);_1c3.setAttribute("accessKey","O");},naviBar:function(_1c4,_1c5,_1c6,_1c7,_1c8,_1c9){_13e.addPageNavigation(_1c4);},"if":function(_1ca,_1cb,_1cc,_1cd,_1ce,_1cf){if(_1cc.length<2){return;}var _1d0=_1cc[1];var _1d1=(_1d0=="not");if(_1d1){if(_1cc.length<3){return;}_1d0=_1cc[2];}var test=config.macros.yourSearch.tests[_1d0];var _1d3=false;try{if(test){_1d3=test(_1ca,_1cb,_1cc,_1cd,_1ce,_1cf)!=_1d1;}else{_1d3=(!eval(_1d0))==_1d1;}}catch(ex){}if(!_1d3){_1ca.style.display="none";}},chkPreviewText:function(_1d4,_1d5,_1d6,_1d7,_1d8,_1d9){var _1da=_1d6.slice(1).join(" ");var elem=_174(_1d4,"chkPreviewText",_1d7,_1d9);elem.setAttribute("accessKey","P");elem.title="Show text preview of found tiddlers (Shortcut: Alt-P)";return elem;}}};config.macros.foundTiddler={label:"foundTiddler",prompt:"Provides information on the tiddler currently processed on the YourSearch result page",handler:function(_1dc,_1dd,_1de,_1df,_1e0,_1e1){var name=_1de[0];var func=config.macros.foundTiddler.funcs[name];if(func){func(_1dc,_1dd,_1de,_1df,_1e0,_1e1);}},funcs:{title:function(_1e4,_1e5,_1e6,_1e7,_1e8,_1e9){if(!_13d){return;}var _1ea=_182();var _1eb=_1ea>=0?"Open tiddler (Shortcut: Alt-%0)".format([_1ea.toString()]):"Open tiddler";var btn=createTiddlyButton(_1e4,null,_1eb,_12c,null);btn.setAttribute("tiddlyLink",_13d.title);btn.setAttribute("withHilite","true");_185(btn,_13d.title,_11c);if(_1ea>=0){btn.setAttribute("accessKey",_1ea.toString());}},tags:function(_1ed,_1ee,_1ef,_1f0,_1f1,_1f2){if(!_13d){return;}_185(_1ed,_13d.getTags(),_11d);},text:function(_1f3,_1f4,_1f5,_1f6,_1f7,_1f8){if(!_13d){return;}_185(_1f3,_17d(_13d.text),_11e);},field:function(_1f9,_1fa,_1fb,_1fc,_1fd,_1fe){if(!_13d){return;}var name=_1fb[1];var len=_1fb.length>2?abego.toInt(_1fb[2],_11f):_11f;var v=store.getValue(_13d,name);if(v){_185(_1f9,_17d(v),len);}},number:function(_202,_203,_204,_205,_206,_207){var _208=_182();if(_208>=0){var text="%0)".format([_208.toString()]);createTiddlyElement(_202,"span",null,"shortcutNumber",text);}}}};var opts={chkUseYourSearch:true,chkPreviewText:true,chkSearchAsYouType:true,chkSearchInTitle:true,chkSearchInText:true,chkSearchInTags:true,chkSearchExtendedFields:true,txtItemsPerPage:_120,txtItemsPerPageWithPreview:_121};for(var n in opts){if(config.options[n]==undefined){config.options[n]=opts[n];}}config.shadowTiddlers.AdvancedOptions+="\n<<option chkUseYourSearch>> Use 'Your Search' //([[more options|YourSearch Options]]) ([[help|YourSearch Help]])// ";config.shadowTiddlers["YourSearch Help"]="!Field Search\nWith the Field Search you can restrict your search to certain fields of a tiddler, e.g"+" only search the tags or only the titles. The general form is //fieldname//'':''//textToSearch// (e."+"g. {{{title:intro}}}). In addition one-character shortcuts are also supported for the standard field"+"s {{{title}}}, {{{text}}} and {{{tags}}}:\n|!What you want|!What you type|!Example|\n|Search ''titles "+"only''|start word with ''!''|{{{!jonny}}} (shortcut for {{{title:jonny}}})|\n|Search ''contents/text "+"only''|start word with ''%''|{{{%football}}} (shortcut for {{{text:football}}})|\n|Search ''tags only"+"''|start word with ''#''|{{{#Plugin}}} (shortcut for {{{tags:Plugin}}})|\n\nUsing this feature you may"+" also search the extended fields (\"Metadata\") introduced with TiddlyWiki 2.1, e.g. use {{{priority:1"+"}}} to find all tiddlers with the priority field set to \"1\".\n\nYou may search a word in more than one"+" field. E.g. {{{!#Plugin}}} (or {{{title:tags:Plugin}}} in the \"long form\") finds tiddlers containin"+"g \"Plugin\" either in the title or in the tags (but does not look for \"Plugin\" in the text). \n\n!Boole"+"an Search\nThe Boolean Search is useful when searching for multiple words.\n|!What you want|!What you "+"type|!Example|\n|''All words'' must exist|List of words|{{{jonny jeremy}}} (or {{{jonny and jeremy}}}"+")|\n|''At least one word'' must exist|Separate words by ''or''|{{{jonny or jeremy}}}|\n|A word ''must "+"not exist''|Start word with ''-''|{{{-jonny}}} (or {{{not jonny}}})|\n\n''Note:'' When you specify two"+" words, separated with a space, YourSearch finds all tiddlers that contain both words, but not neces"+"sarily next to each other. If you want to find a sequence of word, e.g. '{{{John Brown}}}', you need"+" to put the words into quotes. I.e. you type: {{{\"john brown\"}}}.\n\nUsing parenthesis you may change "+"the default \"left to right\" evaluation of the boolean search. E.g. {{{not (jonny or jeremy)}}} finds"+" all tiddlers that contain neither \"jonny\" nor \"jeremy. In contrast to this {{{not jonny or jeremy}}"+"} (i.e. without parenthesis) finds all tiddlers that either don't contain \"jonny\" or that contain \"j"+"eremy\".\n\n!'Exact Word' Search\nBy default a search result all matches that 'contain' the searched tex"+"t. E.g. if you search for {{{Task}}} you will get all tiddlers containing 'Task', but also '~Complet"+"edTask', '~TaskForce' etc.\n\nIf you only want to get the tiddlers that contain 'exactly the word' you"+" need to prefix it with a '='. E.g. typing '=Task' will find the tiddlers that contain the word 'Tas"+"k', ignoring words that just contain 'Task' as a substring.\n\n!~CaseSensitiveSearch and ~RegExpSearch"+"\nThe standard search options ~CaseSensitiveSearch and ~RegExpSearch are fully supported by YourSearc"+"h. However when ''~RegExpSearch'' is on Filtered and Boolean Search are disabled.\n\nIn addition you m"+"ay do a \"regular expression\" search even with the ''~RegExpSearch'' set to false by directly enterin"+"g the regular expression into the search field, framed with {{{/.../}}}. \n\nExample: {{{/m[ae][iy]er/"+"}}} will find all tiddlers that contain either \"maier\", \"mayer\", \"meier\" or \"meyer\".\n\n!~JavaScript E"+"xpression Filtering\nIf you are familiar with JavaScript programming and know some TiddlyWiki interna"+"ls you may also use JavaScript expression for the search. Just enter a JavaScript boolean expression"+" into the search field, framed with {{{ { ... } }}}. In the code refer to the variable tiddler and e"+"valuate to {{{true}}} when the given tiddler should be included in the result. \n\nExample: {{{ { tidd"+"ler.modified > new Date(\"Jul 4, 2005\")} }}} returns all tiddler modified after July 4th, 2005.\n\n!Com"+"bined Search\nYou are free to combine the various search options. \n\n''Examples''\n|!What you type|!Res"+"ult|\n|{{{!jonny !jeremy -%football}}}|all tiddlers with both {{{jonny}}} and {{{jeremy}}} in its tit"+"les, but no {{{football}}} in content.|\n|{{{#=Task}}}|All tiddlers tagged with 'Task' (the exact wor"+"d). Tags named '~CompletedTask', '~TaskForce' etc. are not considered.|\n\n!Access Keys\nYou are encour"+"aged to use the access keys (also called \"shortcut\" keys) for the most frequently used operations. F"+"or quick reference these shortcuts are also mentioned in the tooltip for the various buttons etc.\n\n|"+"!Key|!Operation|\n|{{{Alt-F}}}|''The most important keystroke'': It moves the cursor to the search in"+"put field so you can directly start typing your query. Pressing {{{Alt-F}}} will also display the pr"+"evious search result. This way you can quickly display multiple tiddlers using \"Press {{{Alt-F}}}. S"+"elect tiddler.\" sequences.|\n|{{{ESC}}}|Closes the [[YourSearch Result]]. When the [[YourSearch Resul"+"t]] is already closed and the cursor is in the search input field the field's content is cleared so "+"you start a new query.|\n|{{{Alt-1}}}, {{{Alt-2}}},... |Pressing these keys opens the first, second e"+"tc. tiddler from the result list.|\n|{{{Alt-O}}}|Opens all found tiddlers.|\n|{{{Alt-P}}}|Toggles the "+"'Preview Text' mode.|\n|{{{Alt-'<'}}}, {{{Alt-'>'}}}|Displays the previous or next page in the [[Your"+"Search Result]].|\n|{{{Return}}}|When you have turned off the 'as you type' search mode pressing the "+"{{{Return}}} key actually starts the search (as does pressing the 'search' button).|\n\n//If some of t"+"hese shortcuts don't work for you check your browser if you have other extensions installed that alr"+"eady \"use\" these shortcuts.//";config.shadowTiddlers["YourSearch Options"]="|>|!YourSearch Options|\n|>|<<option chkUseYourSearch>> Use 'Your Search'|\n|!|<<option chkPreviewText"+">> Show Text Preview|\n|!|<<option chkSearchAsYouType>> 'Search As You Type' Mode (No RETURN required"+" to start search)|\n|!|Default Search Filter:<<option chkSearchInTitle>>Title ('!') <<option chk"+"SearchInText>>Text ('%') <<option chkSearchInTags>>Tags ('#') <<option chkSearchExtendedFiel"+"ds>>Extended Fields<html><br><font size=\"-2\">The fields of a tiddlers that are searched when you don"+"'t explicitly specify a filter in the search text <br>(Explictly specify fields using one or more '!"+"', '%', '#' or 'fieldname:' prefix before the word/text to find).</font></html>|\n|!|Number of items "+"on search result page: <<option txtItemsPerPage>>|\n|!|Number of items on search result page with pre"+"view text: <<option txtItemsPerPageWithPreview>>|\n";config.shadowTiddlers["YourSearchStyleSheet"]="/***\n!~YourSearchResult Stylesheet\n***/\n/*{{{*/\n.yourSearchResult {\n\tposition: absolute;\n\twidth: 800"+"px;\n\n\tpadding: 0.2em;\n\tlist-style: none;\n\tmargin: 0;\n\n\tbackground: #ffd;\n\tborder: 1px solid DarkGra"+"y;\n}\n\n/*}}}*/\n/***\n!!Summary Section\n***/\n/*{{{*/\n.yourSearchResult .summary {\n\tborder-bottom-width:"+" thin;\n\tborder-bottom-style: solid;\n\tborder-bottom-color: #999999;\n\tpadding-bottom: 4px;\n}\n\n.yourSea"+"rchRange, .yourSearchCount, .yourSearchQuery {\n\tfont-weight: bold;\n}\n\n.yourSearchResult .summary ."+"button {\n\tfont-size: 10px;\n\n\tpadding-left: 0.3em;\n\tpadding-right: 0.3em;\n}\n\n.yourSearchResult .summa"+"ry .chkBoxLabel {\n\tfont-size: 10px;\n\n\tpadding-right: 0.3em;\n}\n\n/*}}}*/\n/***\n!!Items Area\n***/\n/*{{{*"+"/\n.yourSearchResult .marked {\n\tbackground: none;\n\tfont-weight: bold;\n}\n\n.yourSearchItem {\n\tmargin-to"+"p: 2px;\n}\n\n.yourSearchNumber {\n\tcolor: #808080;\n}\n\n\n.yourSearchTags {\n\tcolor: #008000;\n}\n\n.yourSearc"+"hText {\n\tcolor: #808080;\n\tmargin-bottom: 6px;\n}\n\n/*}}}*/\n/***\n!!Footer\n***/\n/*{{{*/\n.yourSearchFoote"+"r {\n\tmargin-top: 8px;\n\tborder-top-width: thin;\n\tborder-top-style: solid;\n\tborder-top-color: #999999;"+"\n}\n\n.yourSearchFooter a:hover{\n\tbackground: none;\n\tcolor: none;\n}\n/*}}}*/\n/***\n!!Navigation Bar\n***/"+"\n/*{{{*/\n.yourSearchNaviBar a {\n\tfont-size: 16px;\n\tmargin-left: 4px;\n\tmargin-right: 4px;\n\tcolor: bla"+"ck;\n\ttext-decoration: underline;\n}\n\n.yourSearchNaviBar a:hover {\n\tbackground-color: none;\n}\n\n.yourSe"+"archNaviBar .prev {\n\tfont-weight: bold;\n\tcolor: blue;\n}\n\n.yourSearchNaviBar .currentPage {\n\tcolor: #"+"FF0000;\n\tfont-weight: bold;\n\ttext-decoration: none;\n}\n\n.yourSearchNaviBar .next {\n\tfont-weight: bold"+";\n\tcolor: blue;\n}\n/*}}}*/\n";config.shadowTiddlers["YourSearchResultTemplate"]="<!--\n{{{\n-->\n<span macro=\"yourSearch if found\">\n<!-- The Summary Header ============================"+"================ -->\n<table class=\"summary\" border=\"0\" width=\"100%\" cellspacing=\"0\" cellpadding=\"0\">"+"<tbody>\n <tr>\n\t<td align=\"left\">\n\t\tYourSearch Result <span class=\"yourSearchRange\" macro=\"yourSearc"+"h itemRange\"></span>\n\t\t&nbsp;of&nbsp;<span class=\"yourSearchCount\" macro=\"yourSearch count\"></span>\n"+"\t\tfor&nbsp;<span class=\"yourSearchQuery\" macro=\"yourSearch query\"></span>\n\t</td>\n\t<td class=\"yourSea"+"rchButtons\" align=\"right\">\n\t\t<span macro=\"yourSearch chkPreviewText\"></span><span class=\"chkBoxLabel"+"\">preview text</span>\n\t\t<span macro=\"yourSearch newTiddlerButton\"></span>\n\t\t<span macro=\"yourSearch openAllButton\"></span>\n\t\t<span macro=\"yourSearch lin"+"kButton 'YourSearch Options' options 'Configure YourSearch'\"></span>\n\t\t<span macro=\"yourSearch linkB"+"utton 'YourSearch Help' help 'Get help how to use YourSearch'\"></span>\n\t\t<span macro=\"yourSearch clo"+"seButton\"></span>\n\t</td>\n </tr>\n</tbody></table>\n\n<!-- The List of Found Tiddlers ================="+"=========================== -->\n<div id=\"yourSearchResultItems\" itemsPerPage=\"25\" itemsPerPageWithPr"+"eview=\"10\"></div>\n\n<!-- The Footer (with the Navigation) ==========================================="+"= -->\n<table class=\"yourSearchFooter\" border=\"0\" width=\"100%\" cellspacing=\"0\" cellpadding=\"0\"><tbody"+">\n <tr>\n\t<td align=\"left\">\n\t\tResult page: <span class=\"yourSearchNaviBar\" macro=\"yourSearch naviBar"+"\"></span>\n\t</td>\n\t<td align=\"right\"><span macro=\"yourSearch version\"></span>, <span macro=\"yourSearc"+"h copyright\"></span>\n\t</td>\n </tr>\n</tbody></table>\n<!-- end of the 'tiddlers found' case ========="+"================================== -->\n</span>\n\n\n<!-- The \"No tiddlers found\" case ================="+"========================== -->\n<span macro=\"yourSearch if not found\">\n<table class=\"summary\" border="+"\"0\" width=\"100%\" cellspacing=\"0\" cellpadding=\"0\"><tbody>\n <tr>\n\t<td align=\"left\">\n\t\tYourSearch Resu"+"lt: No tiddlers found for <span class=\"yourSearchQuery\" macro=\"yourSearch query\"></span>.\n\t</td>\n\t<t"+"d class=\"yourSearchButtons\" align=\"right\">\n\t\t<span macro=\"yourSearch newTiddlerButton\"></span>\n\t\t<span macro=\"yourSearch linkButton 'YourSearch Options'"+" options 'Configure YourSearch'\"></span>\n\t\t<span macro=\"yourSearch linkButton 'YourSearch Help' help"+" 'Get help how to use YourSearch'\"></span>\n\t\t<span macro=\"yourSearch closeButton\"></span>\n\t</td>\n <"+"/tr>\n</tbody></table>\n</span>\n\n\n<!--\n}}}\n-->\n";config.shadowTiddlers["YourSearchItemTemplate"]="<!--\n{{{\n-->\n<span class='yourSearchNumber' macro='foundTiddler number'></span>\n<span class='yourSea"+"rchTitle' macro='foundTiddler title'/></span>&nbsp;-&nbsp;\n<span class='yourSearchTags' macro='found"+"Tiddler field tags 50'/></span>\n<span macro=\"yourSearch if previewText\"><div class='yourSearchText' macro='fo"+"undTiddler field text 250'/></div></span>\n<!--\n}}}\n-->";config.shadowTiddlers["YourSearch"]="<<tiddler [[YourSearch Help]]>>";config.shadowTiddlers["YourSearch Result"]="The popup-like window displaying the result of a YourSearch query.";config.macros.search.handler=_158;var _20c=function(){if(config.macros.search.handler!=_158){alert("Message from YourSearchPlugin:\n\n\nAnother plugin has disabled the 'Your Search' features.\n\n\nYou may "+"disable the other plugin or change the load order of \nthe plugins (by changing the names of the tidd"+"lers)\nto enable the 'Your Search' features.");}};setTimeout(_20c,5000);abego.YourSearch.getStandardRankFunction=function(){return _100;};abego.YourSearch.getRankFunction=function(){return abego.YourSearch.getStandardRankFunction();};abego.YourSearch.getCurrentTiddler=function(){return _13d;};abego.YourSearch.closeResult=function(){_12b();};abego.YourSearch.getFoundTiddlers=function(){return _f3;};abego.YourSearch.getQuery=function(){return _f4;};abego.YourSearch.onShowResult=function(_20d){highlightHack=_f4?_f4.getMarkRegExp():null;if(!_20d){_13e.setItems(_f7());}if(!_125){_125=createTiddlyElement(document.body,"div",_122,"yourSearchResult");}else{if(_125.parentNode!=document.body){document.body.appendChild(_125);}}_147();highlightHack=null;};})();}
//%/<data>{"StatusDefinitions":""}</data>
<script>
addRow = function(id) {
    var tbody = document.getElementById(id).getElementsByTagName("TBODY")[0];
    var row = document.createElement("TR")
    var td1 = document.createElement("TD")
    td1.appendChild(document.createTextNode("column 1"))
    var td2 = document.createElement("TD")
    td2.appendChild (document.createTextNode("column 2"))
    row.appendChild(td1);

    row.appendChild(td2);
    tbody.appendChild(row);
  }
//  End -->
</script>


<html>
<BODY>
<a href="javascript:addRow('myTable')">Add row</a>

<table id="myTable" cellspacing="0" border="1">
  <tbody>
    <tr>
      <td>row1_column1</td><td>row1_column1</td>
    </tr>
  </tbody>
</table>


<p><center>
<font face="arial, helvetica" size"-2">Free JavaScripts provided<br>
by <a href="http://javascriptsource.com">The JavaScript Source</a></font>
</center><p>

</html>
<html>
<form>
<input type="button" value="Insert" 
onclick="ios++;insertOldSchool(this.form.selos, 'Insert' + ios, 'insert' + ios);" />
<input type="button" value="Append" onclick="aos++;
appendOldSchool(this.form.selos, 'Append' + aos, 'append' + aos);" />
<input type="button" value="Remove" 
onclick="removeOldSchool(this.form.selos);" />
<br />
<select name="selos" size="10" multiple="multiple">
<option value="original1">Orig1</option>
<option value="original2">Orig2</option>
<option value="original2" selected="selected">Orig3</option>
<option value="original2">Orig4</option>
</select>
</form>
</html>

<script>
<!--
var ios = 0;
var aos = 0;
insertOldSchool = function (theSel, newText, newValue)
{
  if (theSel.length == 0) {
    var newOpt1 = new Option(newText, newValue);
    theSel.options[0] = newOpt1;
    theSel.selectedIndex = 0;
  } else if (theSel.selectedIndex != -1) {
    var selText = new Array();
    var selValues = new Array();
    var selIsSel = new Array();
    var newCount = -1;
    var newSelected = -1;
    var i;
    for(i=0; i<theSel.length; i++)
    {
      newCount++;
      if (newCount == theSel.selectedIndex) {
        selText[newCount] = newText;
        selValues[newCount] = newValue;
        selIsSel[newCount] = false;
        newCount++;
        newSelected = newCount;
      }
      selText[newCount] = theSel.options[i].text;
      selValues[newCount] = theSel.options[i].value;
      selIsSel[newCount] = theSel.options[i].selected;
    }
    for(i=0; i<=newCount; i++)
    {
      var newOpt = new Option(selText[i], selValues[i]);
      theSel.options[i] = newOpt;
      theSel.options[i].selected = selIsSel[i];
    }
  }
}

appendOldSchool = function (theSel, newText, newValue)
{
  if (theSel.length == 0) {
    var newOpt1 = new Option(newText, newValue);
    theSel.options[0] = newOpt1;
    theSel.selectedIndex = 0;
  } else if (theSel.selectedIndex != -1) {
    var selText = new Array();
    var selValues = new Array();
    var selIsSel = new Array();
    var newCount = -1;
    var newSelected = -1;
    var i;
    for(i=0; i<theSel.length; i++)
    {
      newCount++;
      selText[newCount] = theSel.options[i].text;
      selValues[newCount] = theSel.options[i].value;
      selIsSel[newCount] = theSel.options[i].selected;
      
      if (newCount == theSel.selectedIndex) {
        newCount++;
        selText[newCount] = newText;
        selValues[newCount] = newValue;
        selIsSel[newCount] = false;
        newSelected = newCount - 1;
      }
    }
    for(i=0; i<=newCount; i++)
    {
      var newOpt = new Option(selText[i], selValues[i]);
      theSel.options[i] = newOpt;
      theSel.options[i].selected = selIsSel[i];
    }
  }
}

removeOldSchool = function (theSel)
{
  var selIndex = theSel.selectedIndex;
  if (selIndex != -1) {
    for(i=theSel.length-1; i>=0; i--)
    {
      if(theSel.options[i].selected)
      {
        theSel.options[i] = null;
      }
    }
    if (theSel.length > 0) {
      theSel.selectedIndex = selIndex == 0 ? 0 : selIndex - 1;
    }
  }
}
//-->
</script>
<html>
<table id="TableA">
  <tr>
    <td>Old top row</td>
  </tr>
</table>
</html>

<script>

  addRow = function (tableID)
  {

    // Get a reference to the table
    var tableRef = document.getElementById(tableID);

    // Insert a row in the table at row index 0
    var newRow   = tableRef.insertRow(0);

    // Insert a cell in the row at index 0
    var newCell  = newRow.insertCell(0);

    // Append a text node to the cell
    var newText  = document.createTextNode('New top row')
    newCell.appendChild(newText);
  }

// Call addRow() with the ID of a table
addRow('TableA');

</script>
source: http://developer.mozilla.org/en/docs/DOM:table.insertRow
<html>
<form action="tableaddrow_nw.html" method="get">
<p>
<input type="button" value="Add" onclick="addRowToTable();" />
<input type="button" value="Remove" onclick="removeRowFromTable();" />
<input type="button" value="Submit" onclick="validateRow(this.form);" />
<input type="checkbox" id="chkValidate" /> Validate Submit
</p>
<p>
<input type="checkbox" id="chkValidateOnKeyPress" checked="checked" /> Display OnKeyPress
<span id="spanOutput" style="border: 1px solid #000; padding: 3px;"> </span>
</p>
<table border="1" id="tblSample">
  <tr>
    <th colspan="3">Sample table</th>
  </tr>
  <tr>
    <td>1</td>
    <td><input type="text" name="txtRow1"
     id="txtRow1" size="40" onkeypress="keyPressTest(event, this);" /></td>
    <td>
    <select name="selRow0">
    <option value="value0">text zero</option>
    <option value="value1">text one</option>
    </select>
    </td>
  </tr>
</table>
</form>
</html>

<script>
// Last updated 2006-02-21
addRowToTable = function()
{
  var tbl = document.getElementById('tblSample');
  var lastRow = tbl.rows.length;
  // if there's no header row in the table, then iteration = lastRow + 1
  var iteration = lastRow;
  var row = tbl.insertRow(lastRow);
  
  // left cell
  var cellLeft = row.insertCell(0);
  var textNode = document.createTextNode(iteration);
  cellLeft.appendChild(textNode);
  
  // right cell
  var cellRight = row.insertCell(1);
  var el = document.createElement('input');
  el.type = 'text';
  el.name = 'txtRow' + iteration;
  el.id = 'txtRow' + iteration;
  el.size = 40;
  
  el.onkeypress = keyPressTest;
  cellRight.appendChild(el);
  
  // select cell
  var cellRightSel = row.insertCell(2);
  var sel = document.createElement('select');
  sel.name = 'selRow' + iteration;
  sel.options[0] = new Option('text zero', 'value0');
  sel.options[1] = new Option('text one', 'value1');
  cellRightSel.appendChild(sel);
}
keyPressTest = function (e, obj)
{
  var validateChkb = document.getElementById('chkValidateOnKeyPress');
  if (validateChkb.checked) {
    var displayObj = document.getElementById('spanOutput');
    var key;
    if(window.event) {
      key = window.event.keyCode; 
    }
    else if(e.which) {
      key = e.which;
    }
    var objId;
    if (obj != null) {
      objId = obj.id;
    } else {
      objId = this.id;
    }
    displayObj.innerHTML = objId + ' : ' + String.fromCharCode(key);
  }
}
removeRowFromTable = function()
{
  var tbl = document.getElementById('tblSample');
  var lastRow = tbl.rows.length;
  if (lastRow > 2) tbl.deleteRow(lastRow - 1);
}
openInNewWindow = function(frm)
{
  // open a blank window
  var aWindow = window.open('', 'TableAddRowNewWindow',
   'scrollbars=yes,menubar=yes,resizable=yes,toolbar=no,width=400,height=400');
   
  // set the target to the blank window
  frm.target = 'TableAddRowNewWindow';
  
  // submit
  frm.submit();
}
validateRow = function(frm)
{
  var chkb = document.getElementById('chkValidate');
  if (chkb.checked) {
    var tbl = document.getElementById('tblSample');
    var lastRow = tbl.rows.length - 1;
    var i;
    for (i=1; i<=lastRow; i++) {
      var aRow = document.getElementById('txtRow' + i);
      if (aRow.value.length <= 0) {
        alert('Row ' + i + ' is empty');
        return;
      }
    }
  }
  openInNewWindow(frm);
}
</script>
Source: http://www.mredkj.com/tutorials/tableaddrow.html
{{new{''<<newTiddler label:'+' title:'New Context 2' tag: Context GTD>>''}}}
<script>
// mredkj.com
// 2006-07-21
insertRowPHP= function ()
{
  var tbl = document.getElementById('tblInsertRowPHP');
  var iteration = tbl.tBodies[0].rows.length;
  newRow = tbl.tBodies[0].insertRow(-1);
  var newCell = newRow.insertCell(0);
  newCell.innerHTML = 'row ' + iteration;
  var newCell1 = newRow.insertCell(1);
  var el = document.createElement('input');
  el.type = 'text';
  el.name = 'txtRow[]';
  el.id = 'txtRow' + iteration;
  el.size = 40;
  newCell1.appendChild(el);
}
deleteAllRows= function (tblId)
{
  var tbl = document.getElementById(tblId);
  for (var i=tbl.tBodies[0].rows.length-1; i>=0; i--) {
    tbl.tBodies[0].deleteRow(i);
  }
}
</script>
<html>
<form action="http://innovationlost.org/mredkj/tablebasics5.php" method="post">
<p>
<input type="button" value="Add" onclick="insertRowPHP();" />
<input type="button" value="Reset" onclick="deleteAllRows('tblInsertRowPHP');" />
<input type="submit" value="Submit" />
</p>
<table border="0" cellspacing="0" id="tblInsertRowPHP">
  <thead>
  <tr>
    <th colspan="2">tblInsertRowPHP header</th>

  </tr>
  </thead>
  <tbody></tbody>
</table>
</form>
</html>

Source: http://www.mredkj.com/tutorials/tablebasics5.html
<script>
// mredkj.com
// 2006-07-21
insertRowPHP= function ()
{
  var tbl = document.getElementById('tblInsertRowPHP2');
  var iteration = tbl.tBodies[0].rows.length;
  newRow = tbl.tBodies[0].insertRow(-1);
  var newCell = newRow.insertCell(0);
  newCell.innerHTML = 'row ' + iteration;
  var newCell1 = newRow.insertCell(1);
  var el = document.createElement('input');
  el.type = 'text';
  el.name = 'txtRow[]';
  el.id = 'txtRow' + iteration;
  el.size = 40;
  newCell1.appendChild(el);
}
deleteAllRows= function (tblId)
{
  var tbl = document.getElementById(tblId);
  for (var i=tbl.tBodies[0].rows.length-1; i>=0; i--) {
    tbl.tBodies[0].deleteRow(i);
  }
}
</script>
<html>
<form action="http://innovationlost.org/mredkj/tablebasics5.php" method="post">
<p>
<input type="button" value="Add" onclick="insertRowPHP();" />
<input type="button" value="Reset" onclick="deleteAllRows('tblInsertRowPHP2');" />
<input type="submit" value="Submit" />
</p>
<table border="0" cellspacing="0" id="tblInsertRowPHP2">
  <thead>
  <tr>
    <th colspan="2">tblInsertRowPHP2 header</th>

  </tr>
  </thead>
  <tbody></tbody>
</table>
</form>
</html>

Source: http://www.mredkj.com/tutorials/tablebasics5.html
    * [[New Row (1)]]
    * [[New code]]
    * [[add row to table]]
    * [[addRowsTemplate]]

<script>
// mredkj.com
// 2006-07-21
insertRowPHP= function ()
{
  var tbl = document.getElementById('tblInsertRowPHP');
  var iteration = tbl.tBodies[0].rows.length;
  newRow = tbl.tBodies[0].insertRow(-1);
  var newCell = newRow.insertCell(0);
  newCell.innerHTML = 'row ' + iteration;
  var newCell1 = newRow.insertCell(1);
  var el = document.createElement('input');
  el.type = 'text';
  el.name = 'txtRow[]';
  el.id = 'txtRow' + iteration;
  el.size = 40;
  newCell1.appendChild(el);
}
deleteAllRows= function (tblId)
{
  var tbl = document.getElementById(tblId);
  for (var i=tbl.tBodies[0].rows.length-1; i>=0; i--) {
    tbl.tBodies[0].deleteRow(i);
  }
}
</script>
<html>
<form action="http://innovationlost.org/mredkj/tablebasics5.php" method="post">
<p>
<input type="button" value="Add" onclick="insertRowPHP();" />
<input type="button" value="Reset" onclick="deleteAllRows('tblInsertRowPHP');" />
<input type="submit" value="Submit" />
</p>
<table border="0" cellspacing="0" id="tblInsertRowPHP">
  <thead>
  <tr>
    <th colspan="2">tblInsertRowPHP header</th>

  </tr>
  </thead>
  <tbody></tbody>
</table>
</form>
</html>

Source: http://www.mredkj.com/tutorials/tablebasics5.html
<script>
function getValue()
{
var x=document.getElementById("myHeader")
alert(x.innerHTML)
}
</script>

<html>
<body>
<h1 id="myHeader" onclick="getValue()">This is a header</h1>
<p>Click on the header to alert its value</p>
</body>
</html>
    * [[Function Hello World!]]
    * [[button to get value from form]]
    * [[click on header]]
Type some text and then press DONE to view the task controls
* janet
* rodrigo
* lucia
<script show>
var x ;
var mycars = new Array();
mycars[0] = "Saab";
mycars[1] = "Volvo";
mycars[2] = "BMW";

for (x in mycars) document.write(mycars[x])

</script>
<script>
var mycars = new Array()
mycars[0] = "Saab"
mycars[1] = "Volvo"
mycars[2] = "BMW"

for (i=0;i<mycars.length;i++)
{
document.write(mycars[i] + "<br />")
}
document.write("length of array: "+mycars.length + " elements")
</script>
http://www.giffmex.org/bibblywiki.html
{{borderless{
|!Col1|!Col2|!Col3|
|r1c1| r1r2c2 |r1c3|
|r2c1|~|r2c3|
}}}

{{borderlessL{
|!Col1|!Col2|!Col3|
|r1c1| r1r2c2 |r1c3|
|r2c1|~|r2c3|
}}}
http://www.osmosoft.com/bt/
<html>
<form name="test">
<input type="text" size="10" value="good" name="boxes">
</form>
</html>
<html>
<input type="button" value="Click Here>>"
onclick="alert(document.test.boxes.value)">
</html>
<html>
<form name="example">
<input type="text" size="20" name="calculator">
<input type="button" name="B1" value="Calculate" onclick="cal()">
<input type="reset" name="B2" value="Reset">
Answer:<input type="text" size="20" name="answer">
</form>
</html>

<script>
cal = function()
{
document.example.answer.value = "100"
//eval(document.example.calculator.value)
}
</script>
<html>
<!--
Tempature Converter
By Kai Yuet (kaiy911@hotmail.com)
For this script and more,
Visit http://javascriptkit.com
-->

<FORM>
Fahrenheit:<INPUT TYPE="text" NAME="F" VALUE="" SIZE="6" MAXLENGTH="6" onChange="eval('C.value = ' + this.form.C_expr.value);eval('K.value = ' + this.form.K_expr.value)">
              <INPUT TYPE="hidden" NAME="F_expr" VALUE="(Math.round(((212-32)/100 * C.value + 32)*100))/100;">
<INPUT TYPE="hidden" NAME="F_expr2" VALUE="(Math.round(((212-32)/100 *(K.value - 273) + 32)*100))/100; ">
 Celsius:<INPUT TYPE="text" NAME="C" VALUE="" SIZE="6" MAXLENGTH="6" onChange="eval('F.value = ' + this.form.F_expr.value);eval('K.value = ' + this.form.K_expr.value)">
              <INPUT TYPE="hidden" NAME="C_expr" VALUE="(Math.round((100/(212-32) * (F.value - 32))*100))/100"> <INPUT TYPE="hidden" NAME="C_expr2" VALUE="(Math.round(K.value - 273))">&nbsp;
Kelvin:<INPUT TYPE="text" NAME="K" VALUE="" SIZE="6" MAXLENGTH="6" onChange="eval('F.value = ' + this.form.F_expr2.value);eval('C.value = ' + this.form.C_expr2.value)">
              <INPUT TYPE="hidden" NAME="K_expr" VALUE="(Math.round((100/(212-32) * (F.value - 32))*100))/100 + 273">&nbsp;
  
<INPUT TYPE="button" NAME="Reset" VALUE="Submit">
<INPUT TYPE="Reset" NAME="Reset" VALUE="Reset">
</FORM>
</html>
<<helloWorld "Hi">>
<<listMacros>>
<<myCloseAll>>
<<MyPlugins>>
<<test>>
<<tidIDE id:example "font:Courier New" size:8pt system>>
<<today>>
<<version>>
<<listMacros>>
<<myTest>>
<<tiddler popTags2>>
<<tiddler ScriptArgSimple with: simple>>
<html>
<head>
<script>
function myfunction()
{
alert("HELLO")
}
</script>
</head>

<body>
<form>
<input type="button" 
onclick="myfunction()" 
value="Call function">
</form>

<p>By pressing the button, a function will be called. The function will alert a message.</p>

</body>
</html>
<<myToday>>
[[myToday macro]]
<<newCloseAll>>
<<rev>>
<html>
<form name="txtComboForm">
<input type="text" size="20" name="txtBox">
<input type="button" name="B1" value="" onclick="pop('called from button')">
<input type="reset" name="B2" value="Reset">
</form>
</html>

<script>
pop = function(str)
{
//document.example.answer.value = "100"
//eval(document.example.calculator.value)
alert(str)
}
</script>
{{{
<<tiddler test>>
}}}
<<tiddler test>>

[[simple macro]]
<<formTiddler checkboxGroupTemplate>><data>{"referBy1":false,"referBy2":false,"referBy3":false,"referBy4":false}</data><<myToday>>
<<formTiddler checkboxGroupTemplate>><data>{"referBy1":false,"referBy2":false,"referBy4":true}</data><<myToday>>
<script>
changeSize=function ()
{
document.getElementById("mySelect").size=4;
}
</script>

<html>
<head>
</head>
<body>

<form>
<select id="mySelect">
  <option>Apple</option>
  <option>Banana</option>
  <option>Orange</option>
  <option>Melon</option>
</select>
<input type="button" onclick="changeSize()" value="Change size">
</form>

</body>
</html>
<<<
[x(questions)] Ask questions
[x(answers)] Seek answers
[x(fun)] Have fun
[x(difference)] Make a difference
[x(smile)] Smile
<<<
<html>
<input type="checkbox" name="referBy" value="td"/> Test driven a vehicle<br/>
<input type="checkbox" name="referBy" value="dlr"/> Visited an autotmotive dealer<br/>
<input type="checkbox" name="referBy" value="veh"/> Purchased/Leased a vehicle<br/>
<input type="checkbox" name="referBy" value="ins"/> Purchased automobile insurance<br/>
</html>
<script>
checkBoxChange = function(event) {
alert(e.checked);
}

label = 'my checkbox';
currentStatus = true;
var e = createTiddlyCheckbox(place,label,currentStatus,checkBoxChange);



</script>
<html><input type="checkBox" id='c' onClick="try{cb()} catch(e) {cb()}"></html>

<script>
cb = function() {
var f=document.getElementById('c');
//alert(f.checked);
if (f.checked) 
	{alert(f.checked+" box checked") }
else
	{alert(f.checked+" box unchecked") }
}
</script>
    * [[cbg1]]
    * [[ch1]]
[[checkboxGroup]]

<html>
<input type="checkbox" name="referBy1" value="td"/> Test driven a vehicle<br/>
<input type="checkbox" name="referBy2" value="dlr"/> Visited an autotmotive dealer<br/>
<input type="checkbox" name="referBy3" value="veh"/> Purchased/Leased a vehicle<br/>
<input type="checkbox" name="referBy4" value="ins"/> Purchased automobile insurance<br/>
</html>
<code>
 checkboxList: {
	 handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		 var itemType = params[0];
		 for (var i=0;i<config.mGTD.config[itemType].length;i++)
			 wikify("<<toggleTag [["+config.mGTD.config[itemType][i]+"]]>>",place,null,tiddler);
		 }
	 },
</code>
//{{{
// this part is not actually required but useful to other people using your plugin
version.extensions.checkboxMacro = { major: 1, minor: 0, revision: 3, date: new Date(2006,3,3),
 source: ""
};

config.macros.checkBox= {
	label: "checkBox",
	prompt: "This will send a message" 
};
config.macros.checkBox.handler = function (place,macroName,params,wikifier,paramString,tiddler) {

//	var itemType = params.length > 0 ? params[0] : "javascript";
//	var who = itemType;

 var parms = paramString.parseParams("name",null,true,false,true);
 var names = parms[0]["name"];
 var para1 = names[0]; // key tag
 var para2 = names[1]; // ? names[1] : "defaultFieldName"; // field for JSON


// var values = store.getByTagExpr(para1); // tag
var who = para1;


	var values = store.getByTagExpr(who); // tag
	wikify(values+"\n", place);

//         for (var i=0; i<values.length; i++)
//             wikify("<<toggleTag [[" + values[i] + "]]>>",place,null,tiddler);
         
	
	wikify("Hello //" + who + "// from the '" + macroName + "' macro in tiddler [[" + tiddler.title + "]].\n", place);

}

// a one liner...
config.macros.cbShout = { handler: function(place,name,params) { wikify("//''@@font-size:5em;color:#696;"+ params[0] + "!@@''//", place); } };


//}}}

/***
!Another example
{{{<<cbShout Yeah>>}}}


<<cbShout Yeah>>

***/
<script>
getValue = function()
{
var x=document.getElementById("myHeader");
alert(x.innerHTML);
}
</script>

<html>
<head>
</head>
<body>
<h1 id="myHeader" onclick="getValue()">This is a header</h1>
<p>Click on the header to alert its value</p>
</body>
</html>
<html><!--
--><input type="button" value="<" title="back" style="font-size:8pt;width:3%" onclick="try{window.goB(-1)}catch(e){window.goB(-1)}" ></nobr></form></html>

<script>
window.goB = function(form) {
alert("-1");
//story.refreshTiddler("Copy 2 of MiniBrowser",1,true);
	//store.setDirty(true);
}

</script>
<html><input type="checkBox" onClick="try{cb()} catch(e) {cb()}"></html>

<script>
cb = function() {
alert("on")
}
//
</script>
<script label="click here" title="clicking link will show an 'alert' box" show>
   if (!window.story) window.story=window;
   alert("Hello World!\nlinktext = '" + place.firstChild.data + "'\ntiddler = '" + story.findContainingTiddler(place).id.substr(7) + "'");
</script>
    * [[Change the text of the selected option]]
    * [[change size of list box]]
    * [[text box filled by Combo box]]
{{{
// single-line comment

/* multi-line comment */

/*** wikified multi-line comment ***/
}}}
{{consoleClass{
msfz751@a3800xp64 /cygdrive/f/PortableEclipse/jython_osp
$ tree
.
`-- code
    |
    `-- SurfaceArrayApp.py

1 directory, 2 files}}}
<script>
convert = function(degree){
if (degree=="C")
 {
 F=document.getElementById("c").value * 9 / 5 + 32
 document.getElementById("f").value=Math.round(F)
 }
else	
 {
 C=(document.getElementById("f").value -32) * 5 / 9
 document.getElementById("c").value=Math.round(C)
 }
}

clear = function(){
story.refreshTiddler("convert temperature",1,true);
}
</script>

<html>
<b>Insert a number into one of the input fields below:</b></p>
<input id="c" name="c" onkeyup="try{convert('C')} catch(e) {convert('C')}" onBlur="try{clear()} catch(e) {clear()}"> degrees Celsius<br />
equals<br /> 
<input id="f" name="f" onkeyup="try{convert('F')} catch(e) {convert('F')}" onBlur="try{clear()} catch(e) {clear()}"> degrees Fahrenheit 
<p>Note that the <b>Math.round()</b> method is used, so that the result will be returned as an integer.</p>
</html>
<script>
function convertToUcase()
{
document.getElementById("fname").value=document.getElementById("fname").value.toUpperCase()
document.getElementById("lname").value=document.getElementById("lname").value.toUpperCase()
}

cb = function()
{
var f=document.getElementById('c');
//alert(f.checked);
if (f.checked) {
	alert(f.checked+" ...will convert now")
	convertToUcase() 
    }
}
</script>
<html>
First name: <input type="text" id="fname" size="20" />
Last name: <input type="text" id="lname" size="20" />
Convert to upper case 
<input type="checkBox" id="c" onclick="try{cb()} catch(e) {cb()}">
</html>
<code>
var foo = createTiddlyCheckbox(place,r,!mHideRealm(r),null);
var cb = createTiddlyCheckbox(place, label.format([tag,title]), \
	theTiddler &amp;&amp; theTiddler.isTagged(tag), function(e) );
var ct = createTiddlyElement(place,"textarea",null,"ctBox");
var btn = createTiddlyButton(place,"add to inbox","add to inbox",function(e)
</code>
<script>
addRow = function(a,b) {
      var r  = document.createElement('tr');
      var ca = document.createElement('td');
      var cb = document.createElement('td');
      var ta = document.createTextNode(a);
      var tb = document.createTextNode(b);
      var t  = document.getElementById('tbl');

      ca.appendChild(ta);
      cb.appendChild(tb);

      r.appendChild(ca);
      r.appendChild(cb);

      t.tBodies(0).appendChild(r);
    }
</script>

<html>
<head>
</head>
<body>
   <form>
      Column A: <input type=text name=a>
  <br>Column B: <input type=text name=b>
  <br><input type=button value='add Row' onClick="javascript:addRow(a.value, b.value)">
   </form>

   <table id=tbl>
     <tr><td>Column A</td><td>Column B</td></tr>
   </table>

</body>
</html>
<script>
addRow = function(a,b) {
      var r  = document.createElement('tr');
      var ca = document.createElement('td');
      var cb = document.createElement('td');
      var ta = document.createTextNode(a);
      var tb = document.createTextNode(b);
      var t  = document.getElementById('tbl');

      ca.appendChild(ta);
      cb.appendChild(tb);

      r.appendChild(ca);
      r.appendChild(cb);

      t.tBodies(0).appendChild(r);
    }
</script>

<html>
<head>
</head>
<body>
   <form>
      Column A: <input type=text name=a value="123">
  <br>Column B: <input type=text name=b value="4567">
  <br><input type=button value='add Row' onClick="addRow(a.value, b.value)">
   </form>

   <table id=tbl>
     <tr><td>Column A</td><td>Column B</td></tr>
   </table>

</body>
</html>
<<newTiddler title:"Blank Note type" label:"new Note type" tag:"notetype" text:{{store.getTiddlerText("NoteTypeMacroInfo")}}>>
    * SampleTask 11
    * SampleTask 33i
    * alfonso task
    * foncho task
    * janet task
    * task 11101
    * tsk 888
<script>
    set fso = CreateObject("Scripting.FileSystemObject");  
    set s = fso.CreateTextFile("C:\test.txt", True);
    s.writeline("HI");
    s.writeline("Bye");
    s.writeline("-----------------------------");
    s.Close();
</script>
<script>
/**
* An alternative function to document.createElement() which accepts name=value pair arguments for specifying attributes
* 
* @param ele The tagname of the element you want to create
* @param [args] The attribute arguments in the format name=value
* @return returns a created element with the specified attributes
* @author Kyle D. Hayes (contact ~at~ kylehayes ~dot~ info)
* @version 0.1, July 4, 2006
* usage:
* txtbox = createElement('input','type=text','name=myTextBox','value=Enter Text Here','id=myTextBox');
* which yields the following element:
* <input type="text" name="myTextBox" value="Enter Text Here" id="myTextBox">
*/

function createElement(ele) {
var items = createElement.arguments.length;
element = document.createElement(ele);
if(items.length > 1) {
  for(i=1;i<items;i++) {
    attribute = createElement.arguments[i].split("=");
    element.setAttribute(attribute[0],attribute[1]);
    }
  }
return element;
}

var txtbox = createElement('input','name=myTextBox','type=text','value=Your Text Here');
//document.write(txtbox);
</script>
* [[createTiddlyButton()]]
* [[createTiddlyCheckbox()]]
* [[createTiddlyDropdown()]]
* [[createTiddlyElement()]]
* [[createTiddlyPopup()]]
    * [[LaunchApplication - createTiddlyButton]]
    * [[Macro definitions - example]]
<code>
var e = createTiddlyCheckbox(place,null,listObject[field],null);
</code>
<code>
function createTiddlyCheckbox(theParent,caption,checked,onChange)
{
	var cb = document.createElement("input");
	cb.setAttribute("type","checkbox");
	cb.onclick = onChange;
	theParent.appendChild(cb);
	cb.checked = checked;
	cb.className = "chkOptionInput";
	if(caption)
		wikify(caption,theParent);
	return cb;
}
</code>
    * [[ToggleTagPlugin - example]]
    * [[checkbox test]]
    * [[createTiddlyCheckbox - example]]
    * [[createTiddlyCheckbox - the function]]
<script>
 // Extending this to put in a defaultValue
createTiddlyDropDown2 = function(place,onchange,options,defaultValue) {
var sel = createTiddlyElement(place,"select");
sel.onchange = onchange;
var foo = 0;
for(var t=0; t<options.length; t++)
  {
  var e = createTiddlyElement(sel,"option",null,null,options[t].caption);
  if (options[t].name == defaultValue) foo = t;
  e.value = options[t].name;
  }
sel.selectedIndex = foo;
return sel;
}

createTiddlyDropDown2(place,onchange,options,defaultValue);
</script>
<code>
function createTiddlyDropDown(place,onchange,options,defaultValue)
{
	var sel = createTiddlyElement(place,"select");
	sel.onchange = onchange;
	for(var t=0; t<options.length; t++) {
		var e = createTiddlyElement(sel,"option",null,null,options[t].caption);
		e.value = options[t].name;
		if(options[t].name == defaultValue)
			e.selected = true;
	}
	return sel;
}
</code>
<script>
 // Extending this to put in a defaultValue
 createTiddlyDropDown: function(place,onchange,options,defaultValue) {
 var sel = createTiddlyElement(place,"select");
 sel.onchange = onchange;
 var foo = 0;
 for(var t=0; t<options.length; t++)
 {
 var e = createTiddlyElement(sel,"option",null,null,options[t].caption);
 if (options[t].name == defaultValue) foo = t;
 e.value = options[t].name;
 }
 sel.selectedIndex = foo;
 return sel;
 },
</script>
    * [[createTiddlyDropDown - the function]]
    * [[setPalette - example]]
<code>
function createTiddlyElement(theParent,theElement,theID,theClass,theText,attribs)
{
	var e = document.createElement(theElement);
	if(theClass != null)
		e.className = theClass;
	if(theID != null)
		e.setAttribute("id",theID);
	if(theText != null)
		e.appendChild(document.createTextNode(theText));
	if(attribs){
		for(var n in attribs){
			e.setAttribute(n,attribs[n]);
		}
	}
	if(theParent != null)
		theParent.appendChild(e);
	return e;
}
</code>
<script>
var tiddlerName = config.macros.formTiddler.getContainingTiddlerName(place);
var tid = store.getTiddler(tiddlerName);
//var title = tid.title

//wikify(tiddlerName,place) 
//wikify(tid,place) // this does not generate an output
//wikify(title,place)

var tiddler = tid;
var checkboxName = "chkBox";
var title = tiddler.title;
var c = createTiddlyElement(place, "input", null, null, null);
idStr="dc" + "1122" + title + checkboxName;
c.setAttribute("id", idStr);
c.setAttribute("type", "checkbox");
c.setAttribute("name", checkboxName);
c.setAttribute("tiddler", title);


</script>
    * [[TagglyTaggingPlugin:drawTable - Example]]
    * [[createTiddlyElement - the function]]
<code>
function createTiddlyPopup(place,caption,tooltip,tiddler)
{
	if(tiddler.text) {
		createTiddlyLink(place,caption,true);
		var btn = createTiddlyButton(place,glyph("downArrow"),tooltip,onClickTiddlyPopup,"tiddlerPopupButton");
		btn.tiddler = tiddler;
	} else {
		createTiddlyText(place,caption);
	}
}

function onClickTiddlyPopup(ev)
{
	var e = ev ? ev : window.event;
	var tiddler = this.tiddler;
	if(tiddler.text) {
		var popup = Popup.create(this,"div","popupTiddler");
		wikify(tiddler.text,popup,null,tiddler);
		Popup.show();
	}
	if(e) e.cancelBubble = true;
	if(e && e.stopPropagation) e.stopPropagation();
	return false;
}
</code>


<data>{}</data><<myToday>>
<data>{}</data><<myToday>>
<<formTiddler DropdownRecordTemplate>><data>{"":"StatusDefinitions_Complete"}</data><<myToday>>
<<formTiddler DropdownRecordTemplate>><data>{"":"StatusDefinitions_InProgress"}</data><<myToday>>

Things to make programming easier.

For the inline sandbox, use document.write to write things, and the ''this''  keyword refers to a HTML DIV object

Also use the new code formatter if you like.
<code>
var t = 45;
for(var i = 0; i < 10; i++)alert(i);
//This is just a test
if(t > 40)document.appendChild(document.createElement("hr"));
</code>
    * [[Dropdowns (4)]]
    * [[New Dropdown]]
    * [[dropdown record]]
    * [[newDropdown]]
<html>
<form target="browser_$1" style="margin:0;padding:0"
	onsubmit="this.action=this.url.value; this.form.done.disabled=false" style="margin:0;padding:0"><nobr>
<select name="bookmarks" id="browser_bookmarks_$1" size="1" style="font-size:8pt;width:21%"
	onchange="var f=document.getElementById('browser_$1'); this.form.url.value=this.value; this.form.action=this.value; this.form.done.disabled=false">
<option value="">bookmarks...</option>
</select>
<input type="text" name="url" size="60" value="" style="font-size:8pt;width:35%">

</html>
<script>
	// load bookmarks droplist from HR-separated "MiniBrowserList" tiddler contents
	var here = document.getElementById("browser_bookmarks_$1");
	while (here.length) here.options[0] = null; // remove current list items
	here.options[here.length] = new Option("bookmarks...","",true,true);
	var list = store.getTiddlerText("MiniBrowserList");
	if (list && list.trim().length) {
		var parts = list.split("\n----\n");
		for (var p=0; p<parts.length; p++) {
			var lines = parts[p].split("\n");
			var label = lines.shift(); // 1st line=display text
			var value = lines.shift(); // 2nd line=item value
			var indent = value&&value.length?"\xa0\xa0":"";
			here.options[here.length] = new Option(indent+label,value,false,false);
		}
	}
</script>
<html>
<form target="browser_$1" style="margin:0;padding:0"
	onsubmit="this.action=this.url.value; this.form.done.disabled=false" style="margin:0;padding:0"><nobr>
<select name="bookmarks" id="browser_bookmarks_$1" size="1" style="font-size:8pt;width:21%"
	onchange="var f=document.getElementById('browser_$1'); this.form.url.value=this.value; this.form.action=this.value; this.form.done.disabled=false">
<option value="">bookmarks...</option>
</select>
<input type="text" name="url" size="60" value="" style="font-size:8pt;width:35%">

</html>
<script>
	// load bookmarks droplist from tag
	var here = document.getElementById("browser_bookmarks_$1");
	while (here.length) here.options[0] = null; // remove current list items
	here.options[here.length] = new Option("bookmarks...","",true,true);

	valueSrc = "javascript";
	tiddler = store.getTiddler(valueSrc);
	var tagged = store.getTaggedTiddlers(tiddler.title);

	if (tagged) {

		// show content in "tagged" array
		for (var i=0; i < tagged.length; i++) {
			//wikify("values(" + i + ") "  + tagged[i].title + '\n', place);  
			indent="";
			label = i;
			value = tagged[i].title;
			here.options[here.length] = new Option(indent+label,value,false,false);
		}
	}
</script>
<<formTiddler DropdownTemplate>><data>{"":"StatusDefinitions_Pending"}</data>
<!--{{{-->
<div class='task'>
	<div class='taskBody'>
		<div class='title' macro='view title'></div>
		<div class='viewer' macro='view text wikified'></div>
	</div>
	<div class='taskControls'>
		<div class='toolbar' macro='toolbar  delete +editTiddler closeTiddler closeOthers deleteTiddler'></div>
	</div>
</div>
<!--}}}-->
<html>
<form target="browser_$1" style="margin:0;padding:0"
	onsubmit="this.action=this.url.value; this.form.done.disabled=false" style="margin:0;padding:0"><nobr>
<select name="bookmarks" id="browser_bookmarks_$1" size="1" style="font-size:8pt;width:21%"
	onchange="var f=document.getElementById('browser_$1'); if (!this.value.length) return window.miniBrowserResetSize(); else window.miniBrowserSetSize(this.form); this.form.url.value=this.value; this.form.action=this.value; this.form.submit(); this.form.done.disabled=false">
<option value="">bookmarks...</option>
</select>
</html>

<script>
	// load bookmarks droplist from HR-separated "MiniBrowserList" tiddler contents
	var here=document.getElementById("browser_bookmarks_$1");
	while (here.length) here.options[0]=null; // remove current list items
	here.options[here.length]=new Option("bookmarks...","",true,true);
	var list=store.getTiddlerText("MiniBrowserList");
	if (list && list.trim().length) {
		var parts=list.split("\n----\n");
		for (var p=0; p<parts.length; p++) {
			var lines=parts[p].split("\n");
			var label=lines.shift(); // 1st line=display text
			var value=lines.shift(); // 2nd line=item value
			var indent=value&&value.length?"\xa0\xa0":"";
			here.options[here.length]=new Option(indent+label,value,false,false);
		}
	}


window.miniBrowserSetSize = function(form) {
	var f=document.getElementById('browser_$1');
	var w=form.w.value.trim(); if (!w||!w.length) w='100%'; if (!w.replace(/[0-9]*/,'').length) w+='px'; 
	var h=form.h.value.trim(); if (!h||!h.length) h='400'; if (!h.replace(/[0-9]*/,'').length) h+='px';
	f.style.width=w; f.style.height=h; f.style.display="block";
	document.getElementById('browser_resize_$1').style.display="block";
	return false;
}

window.miniBrowserResetSize = function() {
	var f=document.getElementById('browser_$1');
	if (f.src.length) f.src="";
	f.style.width='100%'; f.style.height='1em'; f.style.display="none";
	document.getElementById('browser_resize_$1').style.display="none";
	return false;
}

</script>
<code>
 dropdownSelect: {
 	handler: function(place,macroName,params,wikifier,paramString,tiddler) {

	 var values = store.getByTagExpr(paramString);

	 var selectFrom = [];
	 var currentVal = "";
	 selectFrom.push({name:"", caption:"(none)"});
	 for (var i=0;i<values.length;i++) {
		 if (tiddler.tags.contains(values[i].title))
		 currentVal = values[i].title; 
		 selectFrom.push({name:values[i].title, caption:values[i].title});
	 }

	 var onChangeHandler = function() {
		 // this will be better when we use fields:
		 store.setTiddlerTag(tiddler.title,false,currentVal);
		 tiddler.mSet("project",null);
		 if (this.value != "") {
			 tiddler.mSet("project",this.value);
			 store.setTiddlerTag(tiddler.title,true,this.value);
		 }
		 return true;
	 };

	 var selector = createTiddlyDropDown(place,onChangeHandler,selectFrom,currentVal);
	 if (currentVal != "")
	 wikify(" [[>>|"+currentVal+"]]",place);
	 }
 },

</code>
<code>
- - - - - - - - - - handler - - - - - - - - - -
function(place,macroName,params,wikifier,paramString,tiddler) {

 var values = store.getByTagExpr(paramString);

 var selectFrom = [];
 var currentVal = "";
 selectFrom.push({name:"", caption:"(none)"});
 for (var i=0;i<values.length;i++) {
 if (tiddler.tags.contains(values[i].title))
 currentVal = values[i].title; 
 selectFrom.push({name:values[i].title, caption:values[i].title});
 }

 var onChangeHandler = function() {
 // this will be better when we use fields:
 store.setTiddlerTag(tiddler.title,false,currentVal);
 tiddler.mSet("project",null);
 if (this.value != "") {
 tiddler.mSet("project",this.value);
 store.setTiddlerTag(tiddler.title,true,this.value);
 }
 return true;
 };

 var selector = createTiddlyDropDown(place,onChangeHandler,selectFrom,currentVal);
 if (currentVal != "")
 wikify(" [[>>|"+currentVal+"]]",place);
 }
- - - - - - - - - - END: handler - - - - - - - - - -

</code>
<code>
 dropdownSelect: {
 handler: function(place,macroName,params,wikifier,paramString,tiddler) {

 var parms = paramString.parseParams("name",null,true,false,true);
 var names = parms[0]["name"];
 var para1 = names[0]; // key tag
 var para2 = names[1]; // ? names[1] : "defaultFieldName"; // field for JSON
 //var para3 = names[2]; // ? names[2] : "defaultValue"; // default value

 var fieldJSON = para2;
 var values = store.getByTagExpr(para1); // tag
 var selectFrom = [];
 var currentVal = "";
 selectFrom.push({name:"", caption:"(none)"});

 curFieldValue = DataTiddler.getData(tiddler,fieldJSON);
 //displayMessage(fieldJSON+"="+curFieldValue);

 for (var i=0;i<values.length;i++) {
 if (curFieldValue == (values[i].title) )
 currentVal = values[i].title; 
 selectFrom.push({name:values[i].title, caption:values[i].title});
 }
 
 var onChangeHandler = function() {
 var option = this[this.selectedIndex].value
 store.setTiddlerTag(tiddler.title,false,currentVal);
 if (option != "") {
 // store in JSON format using DataTiddler
 DataTiddler.setData(tiddler,fieldJSON,option);
 // refresh to reflect the added tiddler title to the key field
 store.setTiddlerTag(tiddler.title,true,option);
 story.refreshTiddler(title,null,true);
 }
 return true;
 };


 var selector = createTiddlyDropDown(place,onChangeHandler,selectFrom,currentVal);
 if (currentVal != "")
 wikify(" [[>>|"+currentVal+"]]",place);
 }
 },


</code>
<html>
<form target="browser_$1" style="margin:0;padding:0"
	onsubmit="this.action=this.url.value; this.form.done.disabled=false" style="margin:0;padding:0"><nobr>
<select name="bookmarks" id="browser_bookmarks_$1" size="1" style="font-size:8pt;width:21%"
	onchange="var f=document.getElementById('browser_$1'); this.form.url.value=this.value; this.form.action=this.value; this.form.done.disabled=false">
<option value="">bookmarks...</option>
</select>
<input type="text" name="url" size="60" value="" style="font-size:8pt;width:35%">
</form>
</html>
<script>
	// load bookmarks droplist from tag
	var here = document.getElementById("browser_bookmarks_$1");
	while (here.length) here.options[0] = null; // remove current list items
	here.options[here.length] = new Option("bookmarks...","",true,true);

	valueSrc = "javascript";
	tiddler = store.getTiddler(valueSrc);
	var tagged = store.getTaggedTiddlers(tiddler.title);

	if (tagged) {

		// show content in "tagged" array
		for (var i=0; i < tagged.length; i++) {
			//wikify("values(" + i + ") "  + tagged[i].title + '\n', place);  
			indent="";
			label = tagged[i].title;
			value = tagged[i].title;
			here.options[here.length] = new Option(indent+label,value,false,false);
		}
	}
</script>
<script>
setList = function(theList) {
   switch (theList) {

      case 1 : {
      document.theForm.mySelect.options[0].value="50THD-OZAM";
      document.theForm.mySelect.options[1].value="ABABA-BALB";
      document.theForm.mySelect.options[2].value="BALAB-KIDA";
      document.theForm.mySelect.options[3].value="CALIC-BABA";
      document.theForm.mySelect.options[4].value="GUTAO-DINE";
      document.theForm.mySelect.options[5].value="";
      document.theForm.mySelect.options[6].value="";
      document.theForm.mySelect.options[7].value="";
      document.theForm.mySelect.options[0].selected=true;
      document.theForm.radioButton[0].checked=true;
      break;

   }

      case 2 : {
      document.theForm.mySelect.options[0].value="AGON";
      document.theForm.mySelect.options[1].value="AJUY";
      document.theForm.mySelect.options[2].value="BALM";
      document.theForm.mySelect.options[3].value="CAGW";
      document.theForm.mySelect.options[4].value="CAJI";
      document.theForm.mySelect.options[5].value="LUPI";
      document.theForm.mySelect.options[6].value="MABT";
      document.theForm.mySelect.options[7].value="";
      document.theForm.mySelect.options[0].selected=true;
      document.theForm.radioButton[1].checked=true;
      break;

   }

      case 3 : {
      document.theForm.mySelect.options[0].value="KAL";
      document.theForm.mySelect.options[1].value="ILO ";
      document.theForm.mySelect.options[2].value="LEY";
      document.theForm.mySelect.options[3].value="ILN ";
      document.theForm.mySelect.options[4].value="SUL";
      document.theForm.mySelect.options[5].value="MET";
      document.theForm.mySelect.options[6].value="ANT";
      document.theForm.mySelect.options[7].value="SUL";
      document.theForm.mySelect.options[0].selected=true;
      document.theForm.radioButton[2].checked=true;
      break;
   }
}

}


</script>
<<tiddler ReplaceTiddlerTitle with: "replacing dynamically changing menu">>
<script>
setList = function(theList) {
   switch (theList) {

      case 1 : {
      document.theForm.mySelect.options[0].value="50THD-OZAM";
      document.theForm.mySelect.options[1].value="ABABA-BALB";
      document.theForm.mySelect.options[2].value="BALAB-KIDA";
      document.theForm.mySelect.options[3].value="CALIC-BABA";
      document.theForm.mySelect.options[4].value="GUTAO-DINE";
      document.theForm.mySelect.options[5].value="";
      document.theForm.mySelect.options[6].value="";
      document.theForm.mySelect.options[7].value="";
      document.theForm.mySelect.options[0].selected=true;
      document.theForm.radioButton[0].checked=true;
      break;

   }

      case 2 : {
      document.theForm.mySelect.options[0].value="AGON";
      document.theForm.mySelect.options[1].value="AJUY";
      document.theForm.mySelect.options[2].value="BALM";
      document.theForm.mySelect.options[3].value="CAGW";
      document.theForm.mySelect.options[4].value="CAJI";
      document.theForm.mySelect.options[5].value="LUPI";
      document.theForm.mySelect.options[6].value="MABT";
      document.theForm.mySelect.options[7].value="";
      document.theForm.mySelect.options[0].selected=true;
      document.theForm.radioButton[1].checked=true;
      break;

   }

      case 3 : {
      document.theForm.mySelect.options[0].value="KAL";
      document.theForm.mySelect.options[1].value="ILO ";
      document.theForm.mySelect.options[2].value="LEY";
      document.theForm.mySelect.options[3].value="ILN ";
      document.theForm.mySelect.options[4].value="SUL";
      document.theForm.mySelect.options[5].value="MET";
      document.theForm.mySelect.options[6].value="ANT";
      document.theForm.mySelect.options[7].value="SUL";
      document.theForm.mySelect.options[0].selected=true;
      document.theForm.radioButton[2].checked=true;
      break;
   }
}

setOptionText();
}

setOptionText = function setOptionText() {
  document.theForm.mySelect.options[0].text=document.theForm.mySelect.options[0].value;
  document.theForm.mySelect.options[1].text=document.theForm.mySelect.options[1].value;
  document.theForm.mySelect.options[2].text=document.theForm.mySelect.options[2].value;
  document.theForm.mySelect.options[3].text=document.theForm.mySelect.options[3].value;
  document.theForm.mySelect.options[4].text=document.theForm.mySelect.options[4].value;
  document.theForm.mySelect.options[5].text=document.theForm.mySelect.options[5].value;
  document.theForm.mySelect.options[6].text=document.theForm.mySelect.options[6].value;
  document.theForm.mySelect.options[7].text=document.theForm.mySelect.options[7].value;
}
</script>


<html>
<body onload="setList(1)">
<form name="theForm" onreset="setList(1)">
BirthPlace is:<br>

<input checked name="radioButton" type="radio" value="Brgy" onclick="setList(1)">Brgy&&
<input name="radioButton" type="radio" value="MuniCity" onclick="setList(2)">Muni/city&&
<input name="radioButton" type="radio" value="Province" onclick="setList(3)">Province<hr>

BirthPlace:<br>

<select name="BirthPlace">
<option value="Marikina" selected>MARIKINA
<option value="Mandaluyong">MANDALUYONG
<option value="Malabon">MALABON
<option value="Makati">MAKATI
</select>

<select name="mySelect">
<option value="50THD-OZAM" selected>50THD-OZAM</option>
<option value="ABABA-BALB">ABABA-BALB</option>
<option value="BALAB-KIDA">BALAB-KIDA</option>
<option value="CALIC-BABA">CALIC-BABA</option>
<option value="GUTAO-DINE">GUTAO-DINE</option>
<option value=""></option>
<option value=""></option>
<option value=""></option>
</select>
<br><br>

<input type="submit">
</form>
</body>
</html>
{{{
~WikiWord
}}}
https://wesfiles.wesleyan.edu/home/espringer/web/
<script>
var tiddlerName = config.macros.formTiddler.getContainingTiddlerName(place);
//var tid = store.getTiddler(tiddlerName);

var tidObj = store.getTiddler(tiddlerName);
var fieldName = "Title"
var field = store.getValue(tidObj, fieldName)

document.write(tiddlerName+"<br>");
document.write(tidObj+"<br>")
document.write(field+"<br>")

//v = "new"
//tidObj.fields[fieldName] = v;
//story.refreshTiddler(tiddlerName, "ViewTemplate", true);


</script>
<script>
var str="Hello world!"
document.write(str.match("world") + "<br />")
document.write(str.match("World") + "<br />")
document.write(str.match("worlld") + "<br />")
document.write(str.match("world!"))

</script>
<code>
var here=story.findContainingTiddler(place);
</code>
Type some text and then press DONE to view the task controls<data>{"ScopeDefinitions":"Play","PriorityDefinitions":"Medium","UserDefinitions":"AlfonsoReyes","StatusDefinitions":"Complete"}</data>
<script>
for (i = 0; i <= 5; i++)
{
document.write("The number is " + i)
document.write("<br />")
}
</script>
<html>
<p>Explanation:</p>
<p>This for loop starts with i=0.</p>
<p>As long as <b>i</b> is less than, or equal to 5, the loop will continue to run.</p>
<p><b>i</b> will increase by 1 each time the loop runs.</p>
</html>
<script>
isEmpty = function(elem, helperMsg) {
	if(elem.value.length == 0){
		alert(helperMsg);
		elem.focus();
		return true;
	}
	return false;
}
</script>
<html>
<form>
Required Field: <input type='text' id='req1'/>
<input type='button' 
	onclick="isEmpty(document.getElementById('req1'), 'Please Enter a Value!')"
	value='Check Field' />
</form>
</html>
{{{
<script>
emailcheck = function(){
var string1=document.example.email.value
if (string1.indexOf("@")==-1){
   alert("Please input a valid email address!")
   document.example.email.focus()
   }
}
</script>

<html>
<form name="example"><input type="text" size="20" name="email" onblur="emailcheck()">
<strong>Feedback please:</strong>
<textarea name="S1" rows="2" cols="20"></textarea>
<input type="button" name="B1" value="Submit">
</form>
</html>
}}}
<script>
emailcheck = function(){
var string1=document.example.email.value
if (string1.indexOf("@")==-1){
   alert("Please input a valid email address!")
   document.example.email.focus()
   }
}
</script>

<html>
<form name="example"><input type="text" size="20" name="email" onblur="emailcheck()">
<strong>Feedback please:</strong>
<textarea name="S1" rows="2" cols="20"></textarea>
<input type="button" name="B1" value="Submit">
</form>
</html>

{{{
<script>
    var Person = {
    height : 5.1,
    weight: 0,
    getHeight : function(){
    return this.height;   }
    }

//    And you can call the function like:

//    alert( Person.getHeight() ); 
    document.write(Person.getHeight())

// Assuming you’ve set a height, otherwise returns 0 
<script>
}}}
<script>    
    var Person = {
    height: 5.10,
    weight: 0,

    getHeight: function() {
    return this.height;
    }
    }    

//alert( Person.getHeight() ); 
document.write(Person.getHeight())

</script>    
<script>
var print = function() {
//document.write(arguments[0]);
arg = arguments[0];
s = arg.toString();
t = arg.substring(2,3);
u = s.valueOf();
v = s.toSource();
x = s.charCodeAt(0)
document.write(arg);
document.write(s);
document.write(t);
document.write(u);
document.write(v);
document.write(x);

//document.write(arguments[0]+'<BR>'); 

}

print ("\x40");
</script>
<script show>
function myFunction()
{
return ("Hello, have a nice day!");
}

document.write(myFunction())
</script>
<script>
function (place, macroName, params, wikifier, paramString, tiddler) {
    var values = store.getByTagExpr(paramString);
    var selectFrom = [];
    var currentVal = "";
    selectFrom.push({name:"", caption:"(none)"});
    for (var i = 0; i < values.length; i++) {
        if (tiddler.tags.contains(values[i].title)) {
            currentVal = values[i].title;
            document.write(currentVal);
        }
}
</script>
    * [[ChangeText]]
    * [[change size of list box]]
<script>
// get all tags but systemConfig
var tiddlers = store.reverseLookup("tiddlers","script",false); 
wikify("Number of Tiddlers = "+ tiddlers.length+"\n",place);
for(var t=0; t<tiddlers.length; t++) {  
   tiddler = tiddlers[t];
   wikify("[["+tiddler.title + "]]; ",place);
}
</script>
<script>
// get all tags but systemConfig
var tiddlers = store.reverseLookup("tags","systemConfig",false); 
wikify("Number of Tiddlers = "+ tiddlers.length+"\n",place);
for(var t=0; t<tiddlers.length; t++) {  
   tiddler = tiddlers[t];
   wikify("[["+tiddler.title + "]]; ",place);
}
</script>
http://www.giffmex.org/emptynotestw.html
<html>
<form name="example">
<input type="checkbox" name="myboxes"><br>
<input type="checkbox" name="myboxes"><br>
<input type="checkbox" name="myboxes"><br>
<input type="checkbox" name="myboxes"><br>
<input type="checkbox" name="myboxes"><br>
<input type="checkbox" name="myboxes"><br>
<input type="checkbox" name="myboxes"><br>
<input type="checkbox" name="myboxes"><br>
<input type="checkbox" name="myboxes"><br>
<input type="checkbox" name="myboxes"><br>
</form>
</html>

<script>
//accesses the 3rd checkbox
//document.write( document.example.myboxes.value[2] )
//accesses the last checkbox
//document.example.myboxes[9]

//accesses each and every one of the boxes
//for (i=0; i < document.example.myboxes.length; i++) {
//   document.write(document.example.myboxes[i]) }

</script>
<script>
getElements = function()
{
var x=document.getElementsByName("myInput");
alert(x.length);
}
</script>

<html>
<head>

</head>

<body>
<input name="myInput" type="text" size="20" /><br />
<input name="myInput" type="text" size="20" /><br />
<input name="myInput" type="text" size="20" /><br />
<br />
<input type="button" onclick="getElements()" value="How many elements named 'myInput'?" />
</body>

</html>
    * AutoRefresh
    * CopyTiddlerPlugin
    * InlineJavascriptPlugin
    * NewDocumentPlugin
    * SetDefaultTiddlers
    * ShowTiddlerInfo
    * ViewTemplateHeader
<html>
<input type="text" name="docTitle" size="80" />
</html>
Type some text and then press DONE to view the task controls<data>{"ScopeDefinitions":"Work","PriorityDefinitions":"Medium"}</data>
<html>
<form name="doublecombo">
<p><select name="example" size="1" onChange="redirect(this.options.selectedIndex)">
<option>Technology Sites</option>
<option>News Sites</option>
<option>Search Engines</option>
</select>
<select name="stage2" size="1">
<option value="http://javascriptkit.com">JavaScript Kit</option>
<option value="http://www.news.com">News.com</option>
<option value="http://www.wired.com">Wired News</option>
</select>
<input type="button" name="test" value="Go!"
onClick="go()">
</p>
</form>

<p align="center"><font face="arial" size="-2">This free script provided by</font><br>
<font face="arial, helvetica" size="-2"><a href="http://javascriptkit.com">JavaScript
Kit</a></font></p>
</html>



<script>
/*
Double Combo Script Credit
By JavaScript Kit (www.javascriptkit.com)
Over 200+ free JavaScripts here!
*/

var groups=document.doublecombo.example.options.length
var group=new Array(groups)
for (i=0; i<groups; i++)
group[i]=new Array()

group[0][0]=new Option("JavaScript Kit","http://javascriptkit.com")
group[0][1]=new Option("News.com","http://www.news.com")
group[0][2]=new Option("Wired News","http://www.wired.com")

group[1][0]=new Option("CNN","http://www.cnn.com")
group[1][1]=new Option("ABC News","http://www.abcnews.com")

group[2][0]=new Option("Hotbot","http://www.hotbot.com")
group[2][1]=new Option("Infoseek","http://www.infoseek.com")
group[2][2]=new Option("Excite","http://www.excite.com")
group[2][3]=new Option("Lycos","http://www.lycos.com")

var temp=document.doublecombo.stage2

function redirect(x){
  for (m=temp.options.length-1;m>0;m--)
  temp.options[m]=null
  for (i=0;i<group[x].length;i++){
  temp.options[i]=new Option(group[x][i].text,group[x][i].value)
}
temp.options[0].selected=true
}

function go(){
  location=temp.options[temp.selectedIndex].value
}
//-->
</script>
http://genisis329.googlepages.com/TWMath.html
http://mgtd-alpha.tiddlyspot.com/
http://groups.google.co.uk/group/The-Efficient-Academic/browse_thread/thread/47a5e63d3c08fbb5
[[script DataTiddler assistance]]
<script>
whichButton = function(event) {
if (event.button==2)
{
alert("You clicked the right mouse button!")
}
else
{
alert("You clicked the left mouse button!")
}
}
</script>

<html>
<body onmouseClick="whichButton(event)" onmousedown="whichButton(event)">
<p>Click in the document. An alert box will alert which mouse button you clicked.</p>
</body>

</html>
<script>
testClick=function(e) {
  if (!e) var e = window.event;
  var target = resolveTarget(e);
  alert(target.getAttribute("tiddler", "bah!"));
  return false;
}
</script>
<html>
<input type="submit" value="X" 
onclick="testClick(event)" tiddler="testTiddler" 
style="color:#660000; padding: 0;
   font-family:Arial Black;
   background-color:#fff;
   border:1px solid;
   border-color:#660000;" />
</html>
<script>
whichButton=function(event)
{
if (event.button==2)
  {
  alert("You clicked the right mouse button!");
  }
else
  {
  alert("You clicked the left mouse button!");
  }
}
</script>

<html>
<head>
</head>
<body onmousedown="whichButton(event)">
<p>Click in the document. An alert box will alert which mouse button you clicked.</p>
</body>
</html>
{{{
<!-- multi-line comment -->
}}}
<script>
<!--

/*
*** Multiple dynamic combo boxes
*** by Mirko Elviro, 9 Mar 2005
*** Script featured and available on JavaScript Kit (http://www.javascriptkit.com)
***
***Please do not remove this comment
*/

// This script supports an unlimited number of linked combo boxed
// Their id must be "combo_0", "combo_1", "combo_2" etc.
// Here you have to put the data that will fill the combo boxes
// ie. data_2_1 will be the first option in the second combo box
// when the first combo box has the second option selected


// first combo box

	data_1 = new Option("1", "$");
	data_2 = new Option("2", "$$");

// second combo box

	data_1_1 = new Option("11", "-");
	data_1_2 = new Option("12", "-");
	data_2_1 = new Option("21", "--");
	data_2_2 = new Option("22", "--");
	data_2_3 = new Option("23", "--");
	data_2_4 = new Option("24", "--");
	data_2_5 = new Option("25", "--");

// third combo box

	data_1_1_1 = new Option("111", "*");
	data_1_1_2 = new Option("112", "*");
	data_1_1_3 = new Option("113", "*");
	data_1_2_1 = new Option("121", "*");
	data_1_2_2 = new Option("122", "*");
	data_1_2_3 = new Option("123", "*");
	data_1_2_4 = new Option("124", "*");
	data_2_1_1 = new Option("211", "**");
	data_2_1_2 = new Option("212", "**");
	data_2_2_1 = new Option("221", "**");
	data_2_2_2 = new Option("222", "**");
	data_2_3_1 = new Option("231", "***");
	data_2_3_2 = new Option("232", "***");

// fourth combo box

	data_2_2_1_1 = new Option("2211","%")
	data_2_2_1_2 = new Option("2212","%%")

// other parameters

    displaywhenempty=""
    valuewhenempty=-1

    displaywhennotempty="-select-"
    valuewhennotempty=0


function change(currentbox) {
alert("1")
	numb = currentbox.id.split("_");
	currentbox = numb[1];

    i=parseInt(currentbox)+1

// I empty all combo boxes following the current one

    while ((eval("typeof(document.getElementById(\"combo_"+i+"\"))!='undefined'")) &&
           (document.getElementById("combo_"+i)!=null)) {
         son = document.getElementById("combo_"+i);
	     // I empty all options except the first one (it isn't allowed)
	     for (m=son.options.length-1;m>0;m--) son.options[m]=null;
	     // I reset the first option
	     son.options[0]=new Option(displaywhenempty,valuewhenempty)
	     i=i+1
    }


// now I create the string with the "base" name ("stringa"), ie. "data_1_0"
// to which I'll add _0,_1,_2,_3 etc to obtain the name of the combo box to fill

    stringa='data'
    i=0
    while ((eval("typeof(document.getElementById(\"combo_"+i+"\"))!='undefined'")) &&
           (document.getElementById("combo_"+i)!=null)) {
           eval("stringa=stringa+'_'+document.getElementById(\"combo_"+i+"\").selectedIndex")
           if (i==currentbox) break;
           i=i+1
    }


// filling the "son" combo (if exists)

    following=parseInt(currentbox)+1

    if ((eval("typeof(document.getElementById(\"combo_"+following+"\"))!='undefined'")) &&
       (document.getElementById("combo_"+following)!=null)) {
       son = document.getElementById("combo_"+following);
       stringa=stringa+"_"
       i=0
       while ((eval("typeof("+stringa+i+")!='undefined'")) || (i==0)) {

       // if there are no options, I empty the first option of the "son" combo
	   // otherwise I put "-select-" in it

	   	  if ((i==0) && eval("typeof("+stringa+"0)=='undefined'"))
	   	      if (eval("typeof("+stringa+"1)=='undefined'"))
	   	         eval("son.options[0]=new Option(displaywhenempty,valuewhenempty)")
	   	      else
	             eval("son.options[0]=new Option(displaywhennotempty,valuewhennotempty)")
	      else
              eval("son.options["+i+"]=new Option("+stringa+i+".text,"+stringa+i+".value)")
	      i=i+1
	   }
       //son.focus()
       i=1
       combostatus=''
       cstatus=stringa.split("_")
       while (cstatus[i]!=null) {
          combostatus=combostatus+cstatus[i]
          i=i+1
          }
       return combostatus;
    }
}

//-->
</script>

<html>
<form>
<select name="combo0" id="combo_0" onChange="change(this);" style="width:200px;">
	<option value="value1">-select-</option>
	<option value="value2">1</option>
	<option value="value3">2</option>

</select>
<BR><BR>
<select name="combo1" id="combo_1" onChange="change(this)" style="width:200px;">
	<option value="value1">  </option>
</select>
<BR><BR>
<select name="combo2" id="combo_2" onChange="change(this);" style="width:200px;">
	<option value="value1">  </option>
</select>
<BR><BR>
<select name="combo3" id="combo_3" onChange="change(this);" style="width:200px;">
	<option value="value1">  </option>

</select>

</form>

<p align="center"><font face="arial" size="-2">This free script provided by</font><br>
<font face="arial, helvetica" size="-2"><a href="http://javascriptkit.com">JavaScript
Kit</a></font></p>
</html>
<html>
<!-- SyntaxHighlighter CSS and JavaScript -->
<link type="text/css" rel="stylesheet" href="dp.SyntaxHighlighter/Styles/SyntaxHighlighter.css"></link>
</html>
<script src="dp.SyntaxHighlighter/Scripts/shCore.js"></script>
<script src="dp.SyntaxHighlighter/Scripts/shBrushJava.js"></script>
<script>
dp.SyntaxHighlighter.ClipboardSwf = 'dp.SyntaxHighlighter/Scripts/clipboard.swf';
dp.SyntaxHighlighter.HighlightAll('code');
</script>
//{{{
config.macros.myToday = {}
config.macros.myToday.handler = function (place, macroName, params) {
    var now = new Date();
    var text;
    if (params[0]) {
        text = now.formatString(params[0].trim());
    } else {
        text = now.toLocaleString();
    }
    createTiddlyElement(place, "span", null, null, text);
}

//}}}
this is testing export
/%
|Author|Alfonso Reyes|
|Type|script|
|Requires|InlineJavascriptPlugin|
|Overrides|None|
|Description|adds new item|

Usage: <<tiddler newDropdownRecord>>

%/<script label="new dropdown Record">

 var tags = "[[Dropdowns]]";

 var title = prompt("Please enter name for this item", "");
 if( (title == null) || (title == "") ){
 return;
 }//if

cmds = "<<formTiddler DropdownTemplate>><data>{}</data><<myToday>>";
store.saveTiddler(title, title, cmds, config.options.txtUserName, new Date(), tags);
story.displayTiddler(null,title,DEFAULT_VIEW_TEMPLATE);
// add the tiddler title to the key field
//DataTiddler.setData(title,"StatusDefinitions","")
// refresh to reflect the added tiddler title to the key field
story.refreshTiddler(title,null,true);

</script>
<script>
// function WriteToFile()
// {
var fso = new ActiveXObject("Scripting.FileSystemObject");
var s = fso.CreateTextFile("C:\\Test.txt", true);
s.WriteLine('Hello');
s.Close();
//}
</script>

<html>
<head>
</head>
<body onLoad="WriteToFile()">
</body>
</html>
<html>
<!--        Script by hscripts.com          -->
<!--        copyright of HIOX INDIA         -->
<!-- more scripts @ http://www.hscripts.com -->
</html>

<script>
window.onload = init;

init = function() {
  if (window.Event) {
    document.captureEvents(Event.MOUSEMOVE);
  }
  document.onmousemove = getXY;
}

getXY=function(e) {
  x = (window.Event) ? e.pageX : event.clientX;
  y = (window.Event) ? e.pageY : event.clientY;

  // Use x and y to do what ever you want
  window.status = x+":"+y;
  document.write(x+":"+y)
}
</script>
<code>
// Starting up
function main()
{
	var now, then = new Date();
	startingUp = true;
	window.onbeforeunload = function(e) {if(window.confirmExit) return confirmExit();};
	params = getParameters();
	if(params)
		params = params.parseParams("open",null,false);
	store = new TiddlyWiki();
	invokeParamifier(params,"oninit");

...
...
...
</code>
<code>
config.macros.newTiddler.handler = function(place,macroName,params,wikifier,paramString,tiddler)
{
	if(!readOnly)
		{
		params = paramString.parseParams("anon",null,true,false,false);
		var title = params[1] && params[1].name == "anon" ? params[1].value : this.title;
		title = getParam(params,"title",title);
		this.createNewTiddlerButton(place,title,params,this.label,this.prompt,this.accessKey,"title",false);
		}
}

</code>
<code>
// Returns the first value of the given named parameter.
//#
//# @param params
//#         as returned by parseParams or null/undefined
//# @return [may be null/undefined]
//#
function getParam(params, name, defaultValue) {
	if (!params)
		return defaultValue;
	var p = params[0][name];
	return p ? p[0] : defaultValue;
}
</code>
<code>
// Parse a space-separated string of name:value parameters where:
//   - the name or the value can be optional (in which case separate defaults are used instead)
//     - in case of ambiguity, a lone word is taken to be a value
//     - if 'cascadeDefaults' is set to true, then the defaults are modified by updated by each specified name or value
//     - name prefixes are not allowed if the 'noNames' parameter is true
//   - if both the name and value are present they must be separated by a colon
//   - the name and the value may both be quoted with single- or double-quotes, double-square brackets
//   - names or values quoted with {{double-curly braces}} are evaluated as a JavaScript expression
//     - as long as the 'allowEval' parameter is true
// The result is an array of objects:
//   result[0] = object with a member for each parameter name, value of that member being an array of values
//   result[1..n] = one object for each parameter, with 'name' and 'value' members
String.prototype.parseParams = function(defaultName,defaultValue,allowEval,noNames,cascadeDefaults)
{
	var parseToken = function(match,p)
		{
		var n;
		if(match[p]) // Double quoted
			n = match[p];
		else if(match[p+1]) // Single quoted
			n = match[p+1];
		else if(match[p+2]) // Double-square-bracket quoted
			n = match[p+2];
		else if(match[p+3]) // Double-brace quoted
			try
				{
				n = match[p+3];
				if(allowEval)
					n = window.eval(n);
				}
			catch(e)
				{
				throw "Unable to evaluate {{" + match[p+3] + "}}: " + exceptionText(e);
				}
		else if(match[p+4]) // Unquoted
			n = match[p+4];
		else if(match[p+5]) // empty quote
			n = "";
		return n;
		};
	var r = [{}];
	var dblQuote = "(?:\"((?:(?:\\\\\")|[^\"])+)\")";
	var sngQuote = "(?:'((?:(?:\\\\\')|[^'])+)')";
	var dblSquare = "(?:\\[\\[((?:\\s|\\S)*?)\\]\\])";
	var dblBrace = "(?:\\{\\{((?:\\s|\\S)*?)\\}\\})";
	var unQuoted = noNames ? "([^\"'\\s]\\S*)" : "([^\"':\\s][^\\s:]*)";
	var emptyQuote = "((?:\"\")|(?:''))";
	var skipSpace = "(?:\\s*)";
	var token = "(?:" + dblQuote + "|" + sngQuote + "|" + dblSquare + "|" + dblBrace + "|" + unQuoted + "|" + emptyQuote + ")";
	var re = noNames
		? new RegExp(token,"mg")
		: new RegExp(skipSpace + token + skipSpace + "(?:(\\:)" + skipSpace + token + ")?","mg");
	var params = [];
	do {
		var match = re.exec(this);
		if(match)
			{
			var n = parseToken(match,1);
			if(noNames)
				r.push({name: "", value: n});
			else
				{
				var v = parseToken(match,8);
				if(v == null && defaultName)
					{
					v = n;
					n = defaultName;
					}
				else if(v == null && defaultValue)
					v = defaultValue;
				r.push({name: n, value: v});
				if(cascadeDefaults)
					{
					defaultName = n;
					defaultValue = v;
					}
				}
			}
	} while(match);
	// Summarise parameters into first element
	for(var t=1; t<r.length; t++)
		{
		if(r[0][r[t].name])
			r[0][r[t].name].push(r[t].value);
		else
			r[0][r[t].name] = [r[t].value];
		}
	return r;
}

</code>
<code>
config.macros.tiddler.handler = function(place,macroName,params,wikifier,paramString,tiddler)
{
	params = paramString.parseParams("name",null,true,false,true);
	var names = params[0]["name"];
	var tiddlerName = names[0];
	var className = names[1] ? names[1] : null;
	var args = params[0]["with"];
	var wrapper = createTiddlyElement(place,"span",null,className);
	if(!args)
	...	{
	...
	...
</code>


<script show>
popTags3=function(selTag) {
str = selTag;
return str;
}

var out="";
out = popTags3("WellType");
return out;
</script>
<html>
<form name="txtComboForm">
<input type="text" size="25" name="txtBox">
<input type="button" name="B1" value="..." onclick="popText('called from button')">
<input type="reset" name="B2" value="Reset">
</form>
</html>

<script>
popText = function(str)
{
//document.example.answer.value = "100"
//eval(document.example.calculator.value)
alert(str);
document.txtComboForm.txtBox.value = str;
//a = popup(MainMenu, "MainMenu$");
// <<popup MainMenu [[<<tiddler MainMenu$))]]>>
}
</script>
<script label="my popup test">
// var here=story.findContainingTiddler(this); 
// if (!here) return; 
alert("here")
//displayMessage("hi")
var p = Popup.create(this); 
if (!p) return; 
// var who = here.getAttribute('tiddler'); 
for(var t=0; t<10; t++)
   createTiddlyLink(createTiddlyElement(popup,"li"),t,true);
createTiddlyElement(p, 'hr'); 
createTiddlyElement(p,'br');
Popup.show(p,false); 
event.cancelBubble = true; 
if (event.stopPropagation) event.stopPropagation(); 
return(false);
</script>
<script label="my popup test 2">
dropTagging();

droptagging = function(e) { 
 if (!e) var e = window.event;
 var popup = Popup.create(this);

tagged[0] = "1";
tagged[1] = "2";
tagged[2] = "3";
tagged[3] = "4";

 for(var t=0; t<tagged.length; t++)
 createTiddlyLink(createTiddlyElement(popup,"li"),tagged[t],true);

 Popup.show(popup,false);
 e.cancelBubble = true;
 if (e.stopPropagation)
 e.stopPropagation();
 return(false);
 }
</script>
<code>
config.quickOpenTag = {

	dropdownChar: (document.all ? &quot;\u25bc&quot; : &quot;\u25be&quot;), // the little one doesn't work in IE?

	createTagButton: function(place,tag,excludeTiddler) {
		// little hack so we can to &lt;&lt;tag PrettyTagName|RealTagName&gt;&gt;
		var splitTag = tag.split(&quot;|&quot;);
		var pretty = tag;
		if (splitTag.length == 2) {
			tag = splitTag[1];
			pretty = splitTag[0];
		}
		
		var sp = createTiddlyElement(place,&quot;span&quot;,null,&quot;quickopentag&quot;);
		createTiddlyText(createTiddlyLink(sp,tag,false),pretty);
		
		var theTag = createTiddlyButton(sp,config.quickOpenTag.dropdownChar,
                        config.views.wikified.tag.tooltip.format([tag]),onClickTag);
		theTag.setAttribute(&quot;tag&quot;,tag);
		if (excludeTiddler)
			theTag.setAttribute(&quot;tiddler&quot;,excludeTiddler);
    		return(theTag);
	},
</code>
<script>

document.write(Math.random())

</script>
{{{
<html><a href="file://///HOUICIS001C\Alfonso.Reyes$\cached\My Documents\@images\NFTVerticalWellsComparison.png" target="_blank"><img src="file://///HOUICIS001C\Alfonso.Reyes$\cached\My Documents\@images\NFTVerticalWellsComparison.png" style="height: 700px; "/></a></html>
}}}
<script>

var txt="Hello World!"
document.write(txt.length)

</script>
<script show>
if (!window.story) window.story=window;
var title=story.findContainingTiddler(place).id.substr(1);
wikify(title,place);
//var catid=DataTiddler.getData(title,worldcatkey);
//document.write("[["+title+"|http://worldcat.org/oclc/"+catid+"?page=endnote&client=worldcat.org-detailed_record]]");

</script> 
Type the text for 'script-createElement'
Type the text for 'scrip-NewItem'
Type the text for 'script-array'
Type the text for 'script-developer'
Type the text for 'script-form'
Type the text for 'script-functions'
Type the text for 'script-gui'
Type the text for 'script-message'
Type the text for 'scriopt-table'
Type the text for 'script-tiddler'
Type the text for 'script-wikify'
Type the text for 'event'
Type the text for 'scriptExample'
JSON for JavaScript Object Notation.
Type the text for 'MyJavascript'


<html>
<form name="tv">
NBC: <input type="radio" name="station"><br>
CBS: <input type="radio" name="station"><br>
ABC: <input type="radio" name="station"><br>
CNN: <input type="radio" name="station"><br>
ESPN:<input type="radio" name="station"><br>
</form>
</html>

<script>
//a variable that will hold the index number of the selected radio button
var theone
for (i=0;i<document.tv.station.length;i++){
    if (document.tv.station[i].checked==true){
       theone = i
       document.write(document.tv.station[i])
       break //exist for loop, as target acquired.
    }
}
</script>
<html>
<form name="f1">
NBC: <input type="radio" name="r1" Value="NBC" onClick="GetSelectedItem()"><br>
CBS: <input type="radio" name="r1" Value="CBS" onClick="GetSelectedItem()"><br>
ABC: <input type="radio" name="r1" Value="ABC" onClick="GetSelectedItem()"><br>
CNN: <input type="radio" name="r1" Value="CNN" onClick="GetSelectedItem()"><br>
ESPN:<input type="radio" name="r1" Value="ESPN" onClick="GetSelectedItem()"><br>
</form>
</html>

<script>
GetSelectedItem = function() {
chosen = ""
len = document.f1.r1.length
for (i = 0; i <len; i++) {
    if (document.f1.r1[i].checked) {
    chosen = document.f1.r1[i].value
    }
}
if (chosen == "") {
   alert("No Location Chosen")
   }
   else {
      alert(chosen)
   }
}
</script>
<html>
NBC: <input type="radio" id="r1" Value="NBC"  onClick="GetSelectedItem()"><br>
CBS: <input type="radio" id="r2" Value="CBS"  onClick="GetSelectedItem()"><br>
ABC: <input type="radio" id="r3" Value="ABC"  onClick="GetSelectedItem()"><br>
CNN: <input type="radio" id="r4" Value="CNN"  onClick="GetSelectedItem()"><br>
ESPN:<input type="radio" id="r5" Value="ESPN" onClick="GetSelectedItem()"><br>

</html>

<script>
GetSelectedItem = function() {
chosen = ""
var sel = 0;
//len = document.getElementById('r'+i).length
for (var i = 1;document.getElementById('r'+i); i++) {
    if (document.getElementById('r'+i).checked) {
	chosen = document.getElementById('r'+i).value
	sel = i; 
	// alert(chosen)
	}
     } //end for
if (chosen == "") {
   alert("No Location Chosen")
   }
   else {
      alert(chosen)
   }
}
</script>
<<selectPalette Smoke>>
Data("age",42)
<code>
merge(config.macros,{

	setPalette: {

		handler: function(place,macroName,params,wikifier,paramString,tiddler) {
			var paletteName = params[0] ? params[0] : tiddler.title;
			createTiddlyButton(place,&quot;apply&quot;,&quot;Apply this palette&quot;,function(e) {
				config.macros.selectPalette.updatePalette(tiddler.title);
				return false;
			});
		}
	},

	selectPalette: {

		handler: function(place,macroName,params,wikifier,paramString,tiddler) {
			createTiddlyDropDown(place,this.onPaletteChange,this.getPalettes());
		},

		getPalettes: function() {
			var result = [
				{caption:&quot;-palette-&quot;, name:&quot;&quot;},
				{caption:&quot;(Default)&quot;, name:&quot;(default)&quot;}
			];
			var tagged = store.getTaggedTiddlers(&quot;palette&quot;,&quot;title&quot;);
			for(var t=0; t&lt;tagged.length; t++) {
				var caption = tagged[t].title;
				var sliceTitle = store.getTiddlerSlice(caption,&quot;Name&quot;);
				if (sliceTitle)
					caption = sliceTitle;
				result.push({caption:sliceTitle, name:tagged[t].title});
			}
			return result;
		},

		onPaletteChange: function(e) {
			config.macros.selectPalette.updatePalette(this.value);
			return true;
		},

		updatePalette: function(title) {
			if (title != &quot;&quot;) {
				store.deleteTiddler(&quot;ColorPalette&quot;);
				if (title != &quot;(default)&quot;)
					store.saveTiddler(&quot;ColorPalette&quot;,&quot;ColorPalette&quot;,store.getTiddlerText(title),
								config.options.txtUserName,undefined,&quot;&quot;);
				this.refreshPalette();
				if(config.options.chkAutoSave)
					saveChanges(true);
			}
		},

		refreshPalette: function() {
			config.macros.refreshDisplay.onClick();
		}
	}
});
</code>
<script>
setupSomeGlobals = function() {
  // Local variable that ends up within closure
  var num = 666;
  // Store some references to functions as global variables
  gAlertNumber = function() { alert(num); }
  gIncreaseNumber = function() { num++; }
  gSetNumber = function(x) { num = x; }
}
</script>
<html><input type="button" name="clickThis" value="setupSomeGlobals()" onclick="try{setupSomeGlobals()} catch(e) {setupSomeGlobals()}"></html>
<<forEachTiddler 
 where 
 'tiddler.tags.contains(["macro"])'
>>

See also [[ForEachTiddlerExamples]].
* one: first line 1
* two: second line 2
100
200
<script>
getDefValues = function(src) {
  var text = store.getTiddlerText(src);
  return (text.split('\n'));
  }
 
var taskTiddler = story.findContainingTiddler(place);
var valueSrc = "javascript";

var id = taskTiddler.id;
var title = id.substr(7);
var tiddler = store.getTiddler(title);
var selected = store.getValue(tiddler,valueSrc);
var title2 = tiddler.title
var values = this.getDefValues(valueSrc); 	  //get array of strings in tiddler

wikify("No.values= " + values.length + '\n',place);  // how many values in array

var options = [];

// show content in "values" array
for (var i=0; i < values.length; i++) {
  wikify("values(" + i + ")"  + values[i] + '\n', place);  
  }


wikify("id= " + id + "\n",place);
wikify("title= "+ title + "\n",place);
wikify("title2= "+ title2 + "\n",place);
wikify("tiddler= "+ tiddler + "\n",place);
wikify("valueSrc= " + valueSrc + "\n",place);
wikify("selected= "+ selected + "\n", place);


</script>
<script>
 
var valueSrc = "javascript";

tiddler = store.getTiddler(valueSrc);
var tagged = store.getTaggedTiddlers(tiddler.title);

wikify("No.Tagged= " + tagged.length + '\n',place);  // how many values in array

var options = [];

// show content in "tagged" array
for (var i=0; i < tagged.length; i++) {
  wikify("values(" + i + ") "  + tagged[i].title + '\n', place);  
  }


wikify("tiddler.title= "+ tiddler.title + "\n",place);
wikify("valueSrc= " + valueSrc + "\n",place);

//wikify("id= " + id + "\n",place);
//wikify("title= "+ title + "\n",place);
//wikify("selected= "+ selected + "\n", place);

</script>
<script>
	var show = 'none'
	place.innerHTML=(show?"&gt;&gt;&gt;":"&lt;&lt;&lt;"); // SET LINK TEXT
	place.title=show?"hide sidebar":"show sidebar"; // SET TOOLTIP

</script>
<<forEachTiddler 
 where 
 'tiddler.tags.contains(["scriptExample"])'
>>

See also [[ForEachTiddlerExamples]].
<<forEachTiddler 
 where 
 'tiddler.tags.contains(["script"])'
>>

See also [[ForEachTiddlerExamples]].
config.macros.test = 
{
  handler: function()
  {
    alert('Hello world.');
  }
}
<script>

function sortNumber(a, b)
{
return a - b
}

var arr = new Array(6)
arr[0] = "10"
arr[1] = "5"
arr[2] = "40"
arr[3] = "25"
arr[4] = "1000"
arr[5] = "1"

document.write(arr + "<br />")
document.write(arr.sort(sortNumber))

</script>
{{stretch{[img[ReactionApp.jpg]]}}}
<<formTiddler addRowsTemplate>>
version.extensions.tagCloud = {major: 1, minor: 0 , revision: 1, date: new Date(2005,8,16)};
//Created by Clint Checketts, contributions by Jonny Leroy and Eric Shulman

config.macros.tagCloud = {
 noTags: "No tag cloud created because there are no tags.",
 tooltip: "%1 tiddlers tagged with '%0'"
};

config.macros.tagCloud.handler = function(place,macroName,params) {
 
var tagCloudWrapper = createTiddlyElement(place,"div",null,"tagCloud",null);

var tags = store.getTags();
for (t=0; t<tags.length; t++) {
  for (p=0;p<params.length; p++) if (tags[t][0] == params[p]) tags[t][0] = "";
}

 if(tags.length == 0) 
   createTiddlyElement(tagCloudWrapper,"span",null,null,this.noTags);
 //Findout the maximum number of tags
 var mostTags = 0;
 for (t=0; t<tags.length; t++) if (tags[t][0].length > 0){
  if (tags[t][1] > mostTags) mostTags = tags[t][1];
 }
 //divide the mostTags into 4 segments for the 4 different tagCloud sizes
 var tagSegment = mostTags / 4;

  for (t=0; t<tags.length; t++) if (tags[t][0].length > 0){
 var tagCloudElement = createTiddlyElement(tagCloudWrapper,"span",null,null,null);
 tagCloudWrapper.appendChild(document.createTextNode(" "));
 var theTag = createTiddlyButton(tagCloudElement,tags[t][0],this.tooltip.format(tags[t]),onClickTag,"tagCloudtag tagCloud" + (Math.round(tags[t][1]/tagSegment)+1));
  theTag.setAttribute("tag",tags[t][0]);
 }

};

setStylesheet(".tagCloud span{height: 1.8em;margin: 3px;}.tagCloud1{font-size: 1.2em;}.tagCloud2{font-size: 1.4em;}.tagCloud3{font-size: 1.6em;}.tagCloud4{font-size: 1.8em;}.tagCloud5{font-size: 1.8em;font-weight: bold;}","tagCloudsStyles");
http://15black.bluedepot.com/twtests/tagcloud.htm
<<dropTagging 'scripts' 'scripts'>>
Type some text and then press DONE to view the task controls<data>{"ScopeDefinitions":"Work","PriorityDefinitions":"Medium","StatusDefinitions":"Pending","UserDefinitions":"AlfonsoReyes"}</data>
<!--{{{-->
<!--
|Name|TaskViewTemplate|
|Source|http://www.TiddlyTools.com/#TaskViewTemplate|
|Version||
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|template|
|Requires|ViewTemplateHeader, TaskTemplateTweak, ListboxPlugin, CheckboxPlugin, TaskTimerPlugin, ... |
|Overrides||
|Description|custom version of view template used when tiddler is tagged with "task"|
-->
[[ViewTemplateHeader]]
<div class='tagging' macro='tagging'></div>
<div class='tagged' macro='tags'></div>
<!-- TASK CONTROLS one line hanging "bubble" (bottom right) -->
<div class='viewer'>
	<div macro='view text wikified'></div>
	<div class="floatright block" style="height:2em;padding-top:2px;">
		<div class="center viewer smallform" style="padding:.5em 1em">
			<span class='fine subtitle'>task status:</span>
			<span macro='select status rows:1 allowOther "not started" "in progress" "on hold" "completed"'></span>
			<span class='fine subtitle'>assigned to:</span>
			<span macro='select assigned rows:1 allowBlank allowOther +TaskAssignmentList allowEdit'></span>
			<span macro='checkbox urgent@'></span>
			<span class='fine subtitle'>urgent</span>
			<span macro='taskTimer'></span>
			<span class='fine subtitle' macro='tiddler CommentScript with: reverse' style='padding-left:1em'></span>
		</div>
	</div>
</div>
<div class='tagClear'></div>
<!--}}}-->
Type the text for 'html'
<<tiddler popupTest>>
<<tiddler popupTest2>>
<<tiddler FunctionArguments with 1 2 3>>
<<tiddler ScriptArg with: alfonso "this is a comment">>
<<SliderFolder alfonso "my comment">>
<<SliderFolder rodrigo "another comment">>
<script show>
var out = "<html><b>this is an output wrote by javascript</b></html>";
// will print to the screen without a print statement
return out;
</script>
<html><input type="button" name="clickMe" value="Click me and wait!" onclick="try{sto()} catch(e) {sto()}"></html>

<script>
sto = function() {
setTimeout('alert(\'Surprise!\')', 1500)
}
</script>
<html>
  <head>    
    <title>Untitled Document</title>
    <script>
        var test = new Array();
        var num;
        test[0] = 'This is a test <br/>';
        test[1] = "This is another test <br/>";    
    </script>
    </head>
    <body>
        <div id="pHere"></div>
        <script>
             //document.getElementById('pHere').innerHTML = test;
             document.getElementById('pHere').innerHTML = test.join('');
        </script>
    </body>
</html>
<script>
//<script>
//testForm = function(place,macroName,params) {
var here=story.findContainingTiddler(place);
var id=""; 
if (here) id=here.id.substr(7);
wikify(id,place);
//var place=document.getElementById(id+"_editorpanel"); 
//if (!place) return;
var f = document.getElementById(id + "_editorform");

//}
</script>
<html>
<head>
<title>Combo Box Demo</title>

</head>
<body>
<p>This is a sample of how to use the combo box.</p>

<form action="/" method="get">
<select name="editable" onKeyPress="edit(event)" onBlur="this.editing =false;">
<option>To create a new option, just start typing</option>
</select>
</form>
</body>
</html>

<script>
/*
 * Copyright (C) 2004 Baron Schwartz <baron at sequent dot org>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by the
 * Free Software Foundation, version 2.1.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
 * details.
 */

var key;
var combo;

document.onkeydown = function(e) {
    if (combo && combo.editing && window.event && window.event.keyCode == 8) {
        window.event.cancelBubble = true;
        window.event.returnValue = false;
        if (combo.insertSpace) {
            combo.insertSpace = false;
        }
        else {
            with (combo.options[combo.options.length - 1]) {
                text = text.substring(0, text.length - 1);
            }
        }
    }
}

edit = function(e) {
    if (window.event){
        key = window.event.keyCode;
        combo = window.event.srcElement;
        // Stop the browser from scrolling through <option>s
        window.event.cancelBubble = true;
        window.event.returnValue = false;
    }
    else if (e) {
        key = e.which;
        combo = e.target;
    }
    else {
        return true;
    }

    if (key == 13 || key == 8 || (key > 31 && key < 127)) {
        if (combo.editing && key == 13) {
            // Done editing
            combo.editing = false;
            combo = null;
            return false;
        }
        else if (!combo.editing) {
            combo.editing = true;
            combo.options[combo.options.length] = new Option("");
        }

        // Normal key
        if (key > 32 && key < 127) {
            with (combo.options[combo.options.length - 1]) {
                if (combo.insertSpace) {
                    combo.insertSpace = false;
                    text = text + " " + String.fromCharCode(key);
                }
                else {
                    text = text + String.fromCharCode(key);
                }
            }
        }
        // The backspace key
        else if (key == 8 && combo.options[combo.options.length - 1].text.length) {
            if (combo.insertSpace) {
                combo.insertSpace = false;
            }
            else {
                with (combo.options[combo.options.length - 1]) {
                    text = text.substring(0, text.length - 1);
                }
            }
        }
        // Space key requires special treatment; some browsers will not append a space
        else if (key == 32) {
            combo.insertSpace = true;
        }
        combo.selectedIndex = combo.options.length - 1;
        return false;
    }
}

</script>
    * [[calculate on click]]
    * [[call selection popup when clicked]]
    * [[convert temperature]]
    * [[popup when clicked and fill text box]]
    * [[text box filled by Combo box]]
<<tidIDE id:example "font:Courier New" size:8pt system +edit:GettingStarted>>
* get tiddlers that were modified
{{{
var tiddlers = store.getTiddlers('modified');
}}}

*  get list of DefaultTiddlers
{{{
var names = store.getTiddlerText("DefaultTiddlers").readBracketedList();
}}}

* get a set of tiddlers to ignore
{{{
var ignore_tags = ['systemConfig', 'systemTiddlers', 'plugin', 'system', 'stylesheet', 'template', 'folder', 'menu'];
var ignore_tiddlers = [];
for(var i=0; i<ignore_tags.length; i++)
  ignore_tiddlers=ignore_tiddlers.concat(store.getTaggedTiddlers(ignore_tags[i]));
}}}

* get set of tiddlers from array of tags
{{{
 ... store.getTaggedTiddlers(ignore_tags[i])
}}}

* get all tiddlers
{{{
#  // Get all tiddlers  
#  var tiddlers = store.reverseLookup("tags","excludeLists",false); 
}}}

* loop through all tiddler list
{{{
#  for(var t=0; t<tiddlers.length; t++) {  
#  tiddler = tiddlers[t]; 
}}}
http://tiddlywiki.bidix.info/
* comments
* parsing

http://www.tiddlywiki.org/wiki/Escaping
http://www.tiddlywiki.org/index.php?title=Main_Page&useskin=tw4mw
http://tiddlywikitips.com/TiddlyWikiTasks_work_tab.html
Type some text and then press DONE to view the task controls<data>{"ScopeDefinitions":"Work","PriorityDefinitions":"Unknown","UserDefinitions":"JanetAguayo","StatusDefinitions":"InProgress"}</data>
http://www.tiddly-twab.com/
http://twnotes.tiddlyspot.com/
http://twt-notes.tiddlyspot.com/
http://twt-treeview-executive.tiddlyspot.com/
[[twnotes]]
[[twt-notes]]
<script>
var wrapper = document.createElement("div");
var text = "";
place.appendChild(wrapper);

for (var i=100; i<110; i++) {
  text+="|" + i + "|\n";
  }
  wikify(text,wrapper);
</script>
<code>
 wikify("<<toggleTag [["+config.mGTD.config[itemType][i]+"]]>>",place,null,tiddler);
</code>
<script>
<!--
validate = function (){
if ((document.example2.naming.value=="") || (document.example2.feed.value=="")) {
   alert ("You must fill in all of the required .fields!")
   return false
   }
 else
 return true
}
//-->
</script>

<html>
<form name="example2" onclick="return validate()">
<input type="text" size="20" name="naming"><br>
<strong>Feedback please: (*required)</strong><br>
<textarea name="feed" rows="3" cols="25"></textarea><br>
<strong>Your home address (*NOT required)</strong><br>
<input type="text" size="35" name="address">
<input type="button" name="B1" value="Submit">
</form>
</html>

http://aiddlywiki.sourceforge.net/wikibar_demo_2.html
<script>
	var fso = new ActiveXObject("Scripting.FileSystemObject");
	var file = fso.OpenTextFile("c:\test",2,-1,0);
	var content = "123";
	file.Write(content);
	file.Close();
	return true;
</script>
<script>
function WriteToFile(passForm) {
//    set fso = CreateObject("Scripting.FileSystemObject");  
/*    set s = fso.CreateTextFile("C:\test.txt", True);
    s.writeline("HI");
    s.writeline("Bye");
    s.writeline("-----------------------------");
    s.Close();
*/
}
</script>

<html>
</head>

<body>
<p>To sign up for the Excel workshop please fill out the form below:
</p>
<form onSubmit="WriteToFile(this)">
Type your first name:
<input type="text" name="FirstName" size="20">
<br>Type your last name:
<input type="text" name="LastName" size="20">
<br>
<input type="submit" value="submit">
</form> 
</html>
<script show>
a = 10
document.write(a*10)
</script>
<script>
var name = "Hege"
document.write(name)
document.write("<h1>"+name+"</h1>")
</script>
<script>
var minutes = 1000*60
var hours = minutes*60
var days = hours*24
var years = days*365
var d = new Date()
var t = d.getTime()
var y = t/years

document.write("It's been: " + y + " years since 1970/01/01!")

</script>
config.options.txtBackupFolder="backup"; // this will avoid saving in root TW folder
config.options.chkSaveBackups=true;  // true:will save backups indicated by ".txtBackupFolder"
config.options.chkInsertTabs = true;    // tab inserts a tab when editing a tiddler

//"); //]]>