<!--{{{-->
<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml' />
<!--}}}-->
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]];}

.wizard .notChanged {background:transparent;}
.wizard .changedLocally {background:#80ff80;}
.wizard .changedServer {background:#8080ff;}
.wizard .changedBoth {background:#ff8080;}
.wizard .notFound {background:#ffff80;}
.wizard .putToServer {background:#ff80ff;}
.wizard .gotFromServer {background:#80ffff;}

#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]];}
.readOnly {background:[[ColorPalette::TertiaryPale]];}

#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 0 1em 1em; left:-1px; top:-1px;}
.headerForeground {position:absolute; padding:4.5em 0 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:0 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 0.3em 0;}
#sidebarTabs .tabContents {width:15em; overflow:hidden;}

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

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

.tiddlerPopupButton {padding:0.2em;}
.popupTiddler {position: absolute; z-index:300; padding: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 0;}
.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 0 0 0.5em;}
.tab {margin:0 0 0 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 0 14em;}

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

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

.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:0 0.25em; padding:0 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 0; font-size:.9em;}
.editorFooter .button {padding-top:0px; padding-bottom:0px;}

.fieldsetFix {border:0; padding:0; margin: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;}
#backstageToolbar {position:relative;}
#backstageArea a {font-weight:bold; margin-left:0.5em; padding:0.3em 0.5em;}
#backstageButton {display:none; position:absolute; z-index:175; top:0; right:0;}
#backstageButton a {padding:0.1em 0.4em; margin:0.1em;}
#backstage {position:relative; width:100%; z-index:50;}
#backstagePanel {display:none; z-index:100; position:absolute; width:90%; margin-left:3em; padding:1em;}
.backstagePanelFooter {padding-top:0.2em; float:right;}
.backstagePanelFooter a {padding: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 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;}
/*}}}*/
/*{{{*/
@media print {
#mainMenu, #sidebar, #messageArea, .toolbar, #backstageButton, #backstageArea {display: none !important;}
#displayArea {margin: 1em 1em 0em;}
noscript {display:none;} /* Fixes a feature in Firefox 1.5.0.2 where print preview displays the noscript content */
}
/*}}}*/
<!--{{{-->
<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 [[ToolbarCommands::ViewToolbar]]'></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 [[ToolbarCommands::EditToolbar]]'></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 excludeLists'></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]]
<<importTiddlers>>
Name: (Default) MD
HeaderTop: #014
HeaderMid: #fff
HeaderBottom: #04b
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
!!!Urgent
~~Urgent Items~~
<script>
	var tag=store.getMatchingTiddlers("TaskManager && Urgent && ! Completed && ! Trash","+title");
	var hdr="|sortable|k\n| !Title | !Task | !Reminders | !Urgent? | !Complete? |h";
	var fmt="| [[%0|%0]] | %1 | ~~<<tiddler [[%0##Due]]>>~~ | [X(%0:Urgent)] | [X(%0:Completed)] |";
	var out=[hdr];
		if (!tag.length) out=["No Tiddlers found"];
	for (var i=0; i<tag.length; i++)
		out.push(fmt.format([tag[i].title,store.getTiddlerSlice(tag[i].title, "Task") ]));
	return out.join('\n');
</script>
!!!Pending
~~Pending Items~~
<script>
	var tag=store.getMatchingTiddlers("TaskManager && ! Urgent && ! Completed && ! Trash","+title");
	var hdr="|sortable|k\n| !Title | !Task | !Reminders | !Urgent? | !Complete? |h";
	var fmt="| [[%0|%0]] | %1 | ~~<<tiddler [[%0##Due]]>>~~ | [X(%0:Urgent)] | [X(%0:Completed)] |";
	var out=[hdr];
		if (!tag.length) out=["No Tiddlers found"];
	for (var i=0; i<tag.length; i++)
		out.push(fmt.format([tag[i].title,store.getTiddlerSlice(tag[i].title, "Task") ]));
	return out.join('\n');
</script>
!!!Completed
~~Completed Items~~
<script>
	var tag=store.getMatchingTiddlers("TaskManager && Completed && ! Trash","+title");
	var hdr="|sortable|k\n| !Title | !Task | !Urgent? | !Complete? |h";
	var fmt="| [[%0|%0]] | %1 | [X(%0:Urgent)] | [X(%0:Completed)] |";
	var out=[hdr];
		if (!tag.length) out=["No Tiddlers found"];
	for (var i=0; i<tag.length; i++)
		out.push(fmt.format([tag[i].title,store.getTiddlerSlice(tag[i].title, "Task") ]));
	return out.join('\n');
</script>
<script show>
	var projects= store.getTaggedTiddlers("TaskTabs").length.toString();
	var tasks= store.getTaggedTiddlers("Task").length.toString();
	var urgent= store.getMatchingTiddlers("Urgent && !Completed").length.toString();
	var pending= store.getMatchingTiddlers("Task && !Urgent && !Completed").length.toString();
	var completed= store.getTaggedTiddlers("Completed").length.toString();
return ("Status: " + projects + " Projects, " + tasks + " Tasks (" + urgent + " Urgent, " + pending + " Pending, " + completed + " Completed) ");
</script>
<script label="Create Tiddler with multiple hidden sections for the containing text">
 var newTiddler = new Tiddler();
	var test1 = store.getTiddlerText("Test 042809##Test1", "");
	var test2 = store.getTiddlerText("Test 042809##Test2", "");
	var combined = (test1 +"\n"+ test2);
 newTiddler.title = "Create Test 042809";
 newTiddler.tags[0] = "Test 042809";
 newTiddler.tags[1] = "Task";
 newTiddler.tags[2] = "excludeLists";
 newTiddler.modifier = config.options.txtUserName;
 newTiddler.text = combined;
 store.addTiddler(newTiddler);
 story.displayTiddler(null,newTiddler.title,DEFAULT_EDIT_TEMPLATE);
 story.focusTiddler(newTiddler.title,"title");
</script>
@@display:none;
!!!Test1
test section text1
!!!Test2
test section text 2
!!!End
@@
<script label="Silent Create Tiddler with multiple hidden sections for the containing text">
   var title= "Silent Test 042809";
	var project = store.getTiddlerText("Test 042809##Project", "");
	var urgent = store.getTiddlerText("Test 042809##Urgent", "");
	var pending = store.getTiddlerText("Test 042809##Pending", "");
	var completed = store.getTiddlerText("Test 042809##Completed", "");
	var combined = (project +"\n"+"@@display:none;"+"\n"+ urgent +"\n"+ pending +"\n"+ completed);
   var txt= combined;
   var who=config.options.txtUserName;
   var when=new Date();
   var tags='"Test 042809" "TaskTabs" "excludeLists"';
   var fields={};
   store.saveTiddler(title,title,txt,who,when,tags,fields);
   story.refreshTiddler(story.findContainingTiddler(place).getAttribute("tiddler"),null,true);
</script>

Auto Create Tiddler (Auto Test 042809) with multiple hidden sections for the containing text
<script label="Remove this label to create tiddler automatically on render">
   var title= "Auto Test 042809";
	var project = store.getTiddlerText("Test 042809##Project", "");
	var urgent = store.getTiddlerText("Test 042809##Urgent", "");
	var pending = store.getTiddlerText("Test 042809##Pending", "");
	var completed = store.getTiddlerText("Test 042809##Completed", "");
	var combined = (project +"\n"+"@@display:none;"+"\n"+ urgent +"\n"+ pending +"\n"+ completed);
   var txt= combined;
   var who=config.options.txtUserName;
   var when=new Date();
   var tags='"Test 042809" "TaskTabs" "excludeLists"';
   var fields={};
if(store.tiddlerExists(title)){
/*	displayMessage(title +' has already been created');*/
} else {
   store.saveTiddler(title,title,txt,who,when,tags,fields);
   story.refreshTiddler(story.findContainingTiddler(place).getAttribute("tiddler"),null,true);
displayMessage(title +' has been created');
}
</script>

@@display:none;
!!!Project
<<tabs txtProject1
'Urgent Project1' 'Urgent Project1 Tab' Project1##Urgent
'Pending Project1' 'Pending Project1 Tab' Project1##Pending
'Completed Project1' 'Completed Project1 Tab' Project1##Completed
>>
{{button{<script label="New Task">
 var newTiddler = new Tiddler();
 newTiddler.title = prompt('Enter a new task title','New Project Task');
 newTiddler.tags[0] = "Project1";
 newTiddler.tags[1] = "Task";
 newTiddler.tags[2] = "excludeLists";
 newTiddler.modifier = config.options.txtUserName;
 if(config.macros.reminders){
 newTiddler.text = "Task:\nReminder: <<newReminder>>\nItems:\n\n!!!Notes\n\n!!!Due";
 } else {newTiddler.text = "Task:\nItems:\n\n!!!Notes\n\n!!!Due\n";}
 store.addTiddler(newTiddler);
 story.displayTiddler(null,newTiddler.title,DEFAULT_EDIT_TEMPLATE);
 story.focusTiddler(newTiddler.title,"title");
</script>}}} <<deleteAllTagged "Delete this Project" delete>>

!!!Urgent
~~Urgent Items~~
<<forEachTiddler
      where 'tiddler.tags.contains("Project1") &&
      tiddler.tags.contains("Urgent") &&
      ! tiddler.tags.contains("Completed")'
      sortBy 'tiddler.title'
write
'"| [["+tiddler.title+"|"+tiddler.title+"]] | "+store.getTiddlerSlice(tiddler.title, "Task")+" | ~~<<tiddler [["+tiddler.title+"##Due"+"]]\>\>~~ | [X("+tiddler.title+":Urgent)] | [X("+tiddler.title+":Completed)] |\n"'
        begin '"|sortable|k\n| !Title | !Task | !Reminders | !Urgent? | !Complete? |h\n"'
        none '"No Tiddlers found\n"'>>

!!!Pending
~~Pending Items~~
<<forEachTiddler
      where 'tiddler.tags.contains("Project1") &&
      ! tiddler.tags.contains("Urgent") &&
      ! tiddler.tags.contains("Completed")'
      sortBy 'tiddler.title'
write
'"| [["+tiddler.title+"|"+tiddler.title+"]] | "+store.getTiddlerSlice(tiddler.title, "Task")+" | ~~<<tiddler [["+tiddler.title+"##Due"+"]]\>\>~~ | [X("+tiddler.title+":Urgent)] | [X("+tiddler.title+":Completed)] |\n"'
        begin '"|sortable|k\n| !Title | !Task | !Reminders | !Urgent? | !Complete? |h\n"'
        none '"No Tiddlers found\n"'>>

!!!Completed
~~Completed Items~~
<<forEachTiddler
      where 'tiddler.tags.contains("Project1") &&
      tiddler.tags.contains("Completed")'
      sortBy 'tiddler.title'
write
'"| [["+tiddler.title+"|"+tiddler.title+"]] | "+store.getTiddlerSlice(tiddler.title, "Task")+" | [X("+tiddler.title+":Urgent)] | [X("+tiddler.title+":Completed)] |\n"'
        begin '"|sortable|k\n| !Title | !Task | !Urgent? | !Complete? |h\n"'
        none '"No Tiddlers found\n"'>>
@@
<script>
var out = "" ;
story.forEachTiddler(
  function (title, element) {
 out += "[["+title+"]]\n" ;
});

return out ;
</script> 
<script>
  var out=[];
  var tids=store.getTiddlers("title","tagToExclude");
  for (var t=0; t<tids.length; t++)
out.push('[['+tids[t].title+']]');
  return out.join("\n");
</script>
/%
!info
|Name|AllThumbs|
|Source|http://www.TiddlyTools.com/#AllThumbs|
|Version|1.2.0|
|Author|Eric Shulman|
|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|ThumbThing, InlineJavascriptPlugin|
|Overrides||
|Description|generate a SET of thumbnails with full-sized popup images|
Usage:
<<<
{{{
<<tiddler AllThumbs with: TiddlerName thumbsPerRow thumbWidth>>
}}}
*{{{TiddlerName}}} is the title of a tiddler containing a space-separated list of image references
*{{{thumbsPerRow}}} is the number of images to display on each row of output.  Omit or use 'auto' for a single row.
*{{{thumbWidth, thumbHeight, fullHeight, fullWidth}}} specify CSS measurements for thumbnails and popup images.<br>See [[ThumbThing]] for details.  Note: when thumbWidth is 'auto' (or is omitted), thumbnails are scaled to fit across entire row.
<<<
Examples:
<<<
{{{
<<tiddler AllThumbs with: [[AllThumbs##SampleList]]>>
}}}
Sample List:
><<tiddler AllThumbs##SampleList>>
<<tiddler AllThumbs with: [[AllThumbs##SampleList]]>>
<<<
!end

!SampleList
images/california.gif
images/cool_illusion.gif
AttachFileSample2
images/fish.jpg
images/sunset.jpg
!end

%/<script>
	var list=store.getTiddlerText('$1','').readBracketedList(false);
	if (!list.length || !store.tiddlerExists('ThumbThing'))	return '<<tiddler AllThumbs##info>>';
	var rowsize='$2'; if (rowsize=='$'+'2' || rowsize=='auto') rowsize=list.length;
	var width='$3';	  if (  width=='$'+'3' || width=='auto')   width=95/rowsize+'%';
	var out=[];
	var thumb='<<tiddler ThumbThing with: [[%0]] [[%1]] [[%2] [[%3]] [[%4]]>>';
	for (var i=0; i<list.length; i++) {
		if (i && i%rowsize==0) out.push('\n');
		out.push(thumb.format([list[i],width,'$4','$5','$6']));
	}
	return out.join('');
</script>
Name: Apples
HeaderTop: #fff
HeaderMid: #C8F526
HeaderBottom: #440000
Background: #ffc
Foreground: #000
PrimaryPale: #bbee66
PrimaryLight: #aa0033
PrimaryMid: #440000
PrimaryDark: #000
SecondaryPale: #ffc
SecondaryLight: #9c0
SecondaryMid: #db4
SecondaryDark: #400
TertiaryPale: #be6
TertiaryLight: #ddff88
TertiaryMid: #404
TertiaryDark: #000
function ArraySubtract(ara1,ara2) {
  var aRes = new Array() ;
  for(var i=0;i<ara1.length;i++) {
    if( ! (ara2.contains(ara1[i]) )) {
      aRes.push(ara1[i]) ;
    }
  }
  return aRes ;

}
window.oldDisplayMessage = displayMessage;
displayMessage = function (text,linkText)
{ oldDisplayMessage(text,linkText);
setTimeout( 'clearMessage()', 7000 );}
/***
|Name|BackstageSR|
|Version|1.0.0|
|Author|MTP|
|Type|plugin|
|Description|Add Save & Reload Functionality to backstage|
More Info:
http://www.tiddlywiki.org/wiki/Dev:Backstage#Customization
***/
//{{{
config.tasks.MyTab01 = {
	text: "save & reload",
	tooltip: "save & reload",
	action: function()
	{
	saveChanges();
	window.location.reload( false );
	}
};
config.backstageTasks.push("MyTab01");
//}}}
!!!Notes:
<script label="batch tag +" show>
var tag="Cigar";
var tagnew="test";
var tids=store.getTaggedTiddlers(tag);
store.suspendNotifications();
for (var i=0; i<tids.length; i++) { var t=tids[i];
store.setTiddlerTag(t.title,true,tagnew); 
   store.saveTiddler
(t.title,t.title,t.text,t.modifier,t.modified,t.tags,t.fields);
}

store.resumeNotifications();
</script> 
<script label="batch append" show>
store.suspendNotifications();
store.forEachTiddler(function(title, tiddler) {
     if(tiddler.tags.contains("Cigar")) {
         var body = tiddler.text + "\n!!!Review";
         store.saveTiddler(title, title, body, tiddler.modifier,
             tiddler.modified, tiddler.tags, tiddler.fields, false,
             tiddler.created, tiddler.creator);
     }
});

store.resumeNotifications();
</script>
<script label="batch prepend" show>
store.suspendNotifications();
store.forEachTiddler(function(title, tiddler) {
     if(tiddler.tags.contains("Cigar")) {
        // TODO: check for existing Review section first
	var body = "!!!Review\n" + tiddler.text;
	store.saveTiddler(title, title, body, tiddler.modifier,
             tiddler.modified, tiddler.tags, tiddler.fields, false,
             tiddler.created, tiddler.creator);
     }
});

store.resumeNotifications();
</script>
<script label="batch tag -" show>
var tag="Cigar";
var tagnew="test";
var tids=store.getTaggedTiddlers(tag);
store.suspendNotifications();
for (var i=0; i<tids.length; i++) { var t=tids[i];
store.setTiddlerTag(t.title,false,tagnew); 
   store.saveTiddler
(t.title,t.title,t.text,t.modifier,t.modified,t.tags,t.fields);
}

store.resumeNotifications();
</script> 
<script label="batch replace" show>
store.suspendNotifications();
store.forEachTiddler(function(title, tiddler) {
     if(tiddler.tags.contains("Cigar")) {
	var txt = tiddler.text;
	var body = txt.replace(/!!!Notes:/g, "!!!Notes");
	store.saveTiddler(title, title, body, tiddler.modifier,
             tiddler.modified, tiddler.tags, tiddler.fields, false,
             tiddler.created, tiddler.creator);
     }
});

store.resumeNotifications();
</script>
Name: Black n Blue
HeaderTop: #14163d
HeaderMid: #06c
HeaderBottom: #fff
Background:#000
Foreground: #06c
PrimaryPale: #9eccf9
PrimaryLight: #fff
PrimaryMid: #fff
PrimaryDark: #72a3e4
SecondaryPale: #0252b1
SecondaryLight: #1e90ff
SecondaryMid: #9be1ff
SecondaryDark: #9be1ff
TertiaryPale: #ddd
TertiaryLight: #fff
TertiaryMid: #555
TertiaryDark: #000
Error: #f00
Test: #0f0
Name: Black2Khaki
HeaderTop: #cc9
HeaderMid: #000
HeaderBottom: #9F9F5F
Background: #FFF
Foreground: #000
PrimaryPale: #cc9
PrimaryLight: #000
PrimaryMid: #9F9F5F
PrimaryDark: #000
SecondaryPale: #666
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #841
TertiaryPale: #eee
TertiaryLight: #cc9
TertiaryMid: #000
TertiaryDark: #cc9
Error: #000
Test: #F6F
|''Name''|Blood1Theme|
|''Description''|Custom Theme Spawned from MPTW by MTP 11.08.08|
|''Last Revision''|MTP 12.31.08|

!Author Mode
|PageTemplate|ImgPageTemplate|
|ViewTemplate|CustomViewTemplate|
|EditTemplate|CustomEditTemplate|
|StyleSheet|##StyleSheet|
|ColorPalette|ColorPalette|


!StyleSheet
/*{{{*/
[[CustomStyleSheet]]
[[StyleSheetShortcuts]]
[[PluginStyles]]

/* Background Image */
body {
	background-image: url("theme/blood1.jpeg") !important;
	background-repeat: repeat;
}
#topMenu, .header, .headerNow {
	background: transparent !important;
}
/*}}}*/
|''Name''|Blood2Theme|
|''Description''|Custom Theme Spawned from MPTW by MTP 11.08.08|
|''Last Revision''|MTP 12.31.08|

!Author Mode
|PageTemplate|ImgPageTemplate|
|ViewTemplate|CustomViewTemplate|
|EditTemplate|CustomEditTemplate|
|StyleSheet|##StyleSheet|
|ColorPalette|ColorPalette|


!StyleSheet
/*{{{*/
[[CustomStyleSheet]]
[[StyleSheetShortcuts]]
[[PluginStyles]]

/* Background Image */
body {
	background-image: url("theme/blood2.jpeg") !important;
	background-repeat: repeat;
}
#topMenu, .header, .headerNow {
	background: transparent !important;
}
/*}}}*/
|''Name''|Blood3Theme|
|''Description''|Custom Theme Spawned from MPTW by MTP 11.08.08|
|''Last Revision''|MTP 12.31.08|

!Author Mode
|PageTemplate|ImgPageTemplate|
|ViewTemplate|CustomViewTemplate|
|EditTemplate|CustomEditTemplate|
|StyleSheet|##StyleSheet|
|ColorPalette|ColorPalette|


!StyleSheet
/*{{{*/
[[CustomStyleSheet]]
[[StyleSheetShortcuts]]
[[PluginStyles]]

/* Background Image */
body {
	background-image: url("theme/blood3.jpeg") !important;
	background-repeat: repeat;
}
#topMenu, .header, .headerNow {
	background: transparent !important;
}
/*}}}*/
|''Name''|Blood6Theme|
|''Description''|Custom Theme Spawned from MPTW by MTP 11.08.08|
|''Last Revision''|MTP 12.31.08|

!Author Mode
|PageTemplate|ImgPageTemplate|
|ViewTemplate|CustomViewTemplate|
|EditTemplate|CustomEditTemplate|
|StyleSheet|##StyleSheet|
|ColorPalette|ColorPalette|


!StyleSheet
/*{{{*/
[[CustomStyleSheet]]
[[StyleSheetShortcuts]]
[[PluginStyles]]

/* Background Image */
body {
	background-image: url("theme/blood6.jpeg") !important;
	background-repeat: repeat;
}
#topMenu, .header, .headerNow {
	background: transparent !important;
}
/*}}}*/
|''Name''|Blood7Theme|
|''Description''|Custom Theme Spawned from MPTW by MTP 11.08.08|
|''Last Revision''|MTP 12.31.08|

!Author Mode
|PageTemplate|ImgPageTemplate|
|ViewTemplate|CustomViewTemplate|
|EditTemplate|CustomEditTemplate|
|StyleSheet|##StyleSheet|
|ColorPalette|ColorPalette|


!StyleSheet
/*{{{*/
[[CustomStyleSheet]]
[[StyleSheetShortcuts]]
[[PluginStyles]]

/* Background Image */
body {
	background-image: url("theme/blood7.jpeg") !important;
	background-repeat: repeat;
}
#topMenu, .header, .headerNow {
	background: transparent !important;
}
/*}}}*/
Name: Bloody
HeaderTop: #a00
HeaderMid: #f00
HeaderBottom: #300
Background: #b22222
Foreground: #fff
PrimaryPale: #b22222
PrimaryLight: #400
PrimaryMid: #300
PrimaryDark: #b22222
SecondaryPale: #000
SecondaryLight: #d00
SecondaryMid: #ffc
SecondaryDark: #fff
TertiaryPale: #fff
TertiaryLight: #300
TertiaryMid: #600
TertiaryDark: #800
Error: #F30
Test: #0F0
Name: Bloody2
HeaderTop: #300
HeaderMid: #f00
HeaderBottom: #300
Background: #b22222
Foreground: #fff
PrimaryPale: #b22222
PrimaryLight: #400
PrimaryMid: #300
PrimaryDark: #900
SecondaryPale: #800
SecondaryLight: #d00
SecondaryMid: #ccc
SecondaryDark: #fff
TertiaryPale: #fff
TertiaryLight: #300
TertiaryMid: #600
TertiaryDark: #800
Error: #F30
Test: #0F0
Name: Blue2Blue
HeaderTop: #00f
HeaderMid: #00bfff
HeaderBottom: #00f
Background: #FFF
Foreground: #000
PrimaryPale: #9be1ff
PrimaryLight: #00bfff
PrimaryMid: #00f
PrimaryDark: #fff
SecondaryPale: #e0ffff
SecondaryLight: #1e90ff
SecondaryMid: #9be1ff
SecondaryDark: #9be1ff
TertiaryPale: #eee
TertiaryLight: #00f
TertiaryMid: #oeffff
TertiaryDark: #000
Error: #000
Test: #F00
|''Name''|Blue2Theme|
|''Description''|Custom Theme Spawned from MPTW by MTP 11.08.08|
|''Last Revision''|MTP 12.31.08|

!Author Mode
|PageTemplate|ImgPageTemplate|
|ViewTemplate|CustomViewTemplate|
|EditTemplate|CustomEditTemplate|
|StyleSheet|##StyleSheet|
|ColorPalette|ColorPalette|


!StyleSheet
/*{{{*/
[[CustomStyleSheet]]
[[StyleSheetShortcuts]]
[[PluginStyles]]

/* Background Image */
body {
	background-image: url("theme/blue2.jpeg") !important;
	background-repeat: repeat;
}
#topMenu, .header, .headerNow {
	background: transparent !important;
}
/*}}}*/
|''Name''|Blue3Theme|
|''Description''|Custom Theme Spawned from MPTW by MTP 11.08.08|
|''Last Revision''|MTP 12.31.08|

!Author Mode
|PageTemplate|ImgPageTemplate|
|ViewTemplate|CustomViewTemplate|
|EditTemplate|CustomEditTemplate|
|StyleSheet|##StyleSheet|
|ColorPalette|ColorPalette|


!StyleSheet
/*{{{*/
[[CustomStyleSheet]]
[[StyleSheetShortcuts]]
[[PluginStyles]]

/* Background Image */
body {
	background-image: url("theme/blue3.jpeg") !important;
	background-repeat: repeat;
}
#topMenu, .header, .headerNow {
	background: transparent !important;
}
/*}}}*/
|''Name''|Blue4Theme|
|''Description''|Custom Theme Spawned from MPTW by MTP 11.08.08|
|''Last Revision''|MTP 12.31.08|

!Author Mode
|PageTemplate|ImgPageTemplate|
|ViewTemplate|CustomViewTemplate|
|EditTemplate|CustomEditTemplate|
|StyleSheet|##StyleSheet|
|ColorPalette|ColorPalette|


!StyleSheet
/*{{{*/
[[CustomStyleSheet]]
[[StyleSheetShortcuts]]
[[PluginStyles]]

/* Background Image */
body {
	background-image: url("theme/blue4.jpeg") !important;
	background-repeat: repeat;
}
#topMenu, .header, .headerNow {
	background: transparent !important;
}
/*}}}*/
|''Name''|Blue6Theme|
|''Description''|Custom Theme Spawned from MPTW by MTP 11.08.08|
|''Last Revision''|MTP 12.31.08|

!Author Mode
|PageTemplate|ImgPageTemplate|
|ViewTemplate|CustomViewTemplate|
|EditTemplate|CustomEditTemplate|
|StyleSheet|##StyleSheet|
|ColorPalette|ColorPalette|


!StyleSheet
/*{{{*/
[[CustomStyleSheet]]
[[StyleSheetShortcuts]]
[[PluginStyles]]

/* Background Image */
body {
	background-image: url("theme/blue6.jpeg") !important;
	background-repeat: repeat;
}
#topMenu, .header, .headerNow {
	background: transparent !important;
}
/*}}}*/
|''Name''|Blue7Theme|
|''Description''|Custom Theme Spawned from MPTW by MTP 11.08.08|
|''Last Revision''|MTP 12.31.08|

!Author Mode
|PageTemplate|ImgPageTemplate|
|ViewTemplate|CustomViewTemplate|
|EditTemplate|CustomEditTemplate|
|StyleSheet|##StyleSheet|
|ColorPalette|ColorPalette|


!StyleSheet
/*{{{*/
[[CustomStyleSheet]]
[[StyleSheetShortcuts]]
[[PluginStyles]]

/* Background Image */
body {
	background-image: url("theme/blue7.jpeg") !important;
	background-repeat: repeat;
}
#topMenu, .header, .headerNow {
	background: transparent !important;
}
/*}}}*/
Name: Blueberry
HeaderTop: #fff
HeaderMid: #99f
HeaderBottom: #002244
Background: #bbbbff
Foreground: #000
PrimaryPale: #99aacc
PrimaryLight: #006699
PrimaryMid: #002244
PrimaryDark: #000
SecondaryPale: #ffc
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #002244
TertiaryPale: #99aacc
TertiaryLight: #aaaaff
TertiaryMid: #000
TertiaryDark: #8B7355
Name: Brown
HeaderTop: #000
HeaderMid: #410
HeaderBottom: #8B4C39
Background: #fff
Foreground: #000
PrimaryPale: #fff
PrimaryLight: #841
PrimaryMid: #8B4C39
PrimaryDark: #410
SecondaryPale: #fe8
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #841
TertiaryPale: #FFD39B
TertiaryLight: #EEC591
TertiaryMid: #CDAA7D
TertiaryDark: #8B7355
Name: Brown2Black
HeaderTop: #930
HeaderMid: #dc9
HeaderBottom: #000
Background: #FFF
Foreground: #666
PrimaryPale: #DDD
PrimaryLight: #930
PrimaryMid: #000
PrimaryDark: #930
SecondaryPale: #CCC
SecondaryLight: #EEE
SecondaryMid: #930
SecondaryDark: #000
TertiaryPale: #CCC
TertiaryLight: #000
TertiaryMid: #666
TertiaryDark: #930
Error: #930
Test: #F6F
Name: BrownnBlack
HeaderTop: #930
HeaderMid: #dc9
HeaderBottom: #000
Background: #FFF
Foreground: #666
PrimaryPale: #DDD
PrimaryLight: #930
PrimaryMid: #000
PrimaryDark: #000
SecondaryPale: #CCC
SecondaryLight: #EEE
SecondaryMid: #930
SecondaryDark: #000
TertiaryPale: #CCC
TertiaryLight: #666
TertiaryMid: #999
TertiaryDark: #930
Error: #930
Test: #F6F
{{groupbox{{{small{
<<calendar thismonth>><script>
	place.lastChild.style.width="100%";
</script>}}}}}}
/***
|Name|CalendarPlugin|
|Source|http://www.TiddlyTools.com/#CalendarPlugin|
|Version|2008.02.27|
|Author|Eric Shulman|
|Original Author|SteveRumsby|
|License|unknown|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|display monthly and yearly calendars|

NOTE: For enhanced date display (including popups), you must also install [[DatePlugin]]
!!!!!Usage:
<<<
|{{{<<calendar>>}}}|Produce a full-year calendar for the current year|
|{{{<<calendar year>>}}}|Produce a full-year calendar for the given year|
|{{{<<calendar year month>>}}}|Produce a one-month calendar for the given month and year|
|{{{<<calendar thismonth>>}}}|Produce a one-month calendar for the current month|
|{{{<<calendar lastmonth>>}}}|Produce a one-month calendar for last month|
|{{{<<calendar nextmonth>>}}}|Produce a one-month calendar for next month|
<<<
!!!!!Configuration:
<<<
|''First day of week:''<br>{{{config.options.txtCalFirstDay}}}|<<option txtCalFirstDay>>|(Monday = 0, Sunday = 6)|
|''First day of weekend:''<br>{{{config.options.txtCalStartOfWeekend}}}|<<option txtCalStartOfWeekend>>|(Monday = 0, Sunday = 6)|

<<option chkDisplayWeekNumbers>> Display week numbers //(note: Monday will be used as the start of the week)//
|''Week number display format:''<br>{{{config.options.txtWeekNumberDisplayFormat }}}|<<option txtWeekNumberDisplayFormat >>|
|''Week number link format:''<br>{{{config.options.txtWeekNumberLinkFormat }}}|<<option txtWeekNumberLinkFormat >>|
<<<
!!!!!Revisions
<<<
2008.02.27: in handler(), DON'T set hard-coded default date format, so that *customized* value (pre-defined in config.macros.calendar.journalDateFmt is used.
2008.02.17: in createCalendarYear(), fix next/previous year calculation (use parseInt() to convert to numeric value).  Also, use journalDateFmt for date linking when NOT using [[DatePlugin]].
2008.02.16: in createCalendarDay(), week numbers now created as TiddlyLinks, allowing quick creation/navigation to 'weekly' journals (based on request from Kashgarinn)
2008.01.08: in createCalendarMonthHeader(), "month year" heading is now created as TiddlyLink, allowing quick creation/navigation to 'month-at-a-time' journals
2007.11.30: added "return false" to onclick handlers (prevent IE from opening blank pages)
2006.08.23: added handling for weeknumbers (code supplied by Martin Budden (see "wn**" comment marks).  Also, incorporated updated by Jeremy Sheeley to add caching for reminders (see [[ReminderMacros]], if installed)
2005.10.30: in config.macros.calendar.handler(), use "tbody" element for IE compatibility.  Also, fix year calculation for IE's getYear() function (which returns '2005' instead of '105'). Also, in createCalendarDays(), use showDate() function (see [[DatePlugin]], if installed) to render autostyled date with linked popup.  Updated calendar stylesheet definition: use .calendar class-specific selectors, add text centering and margin settings
2006.05.29: added journalDateFmt handling
<<<
***/
/***
!!!!!Code section:
***/
//{{{
version.extensions.calendar = { major: 0, minor: 6, revision: 0, date: new Date(2008, 2, 27)};

if(config.options.txtCalFirstDay == undefined)
  config.options.txtCalFirstDay = 0;
if(config.options.txtCalStartOfWeekend == undefined)
  config.options.txtCalStartOfWeekend = 5;
if(config.options.chkDisplayWeekNumbers == undefined)//wn**
  config.options.chkDisplayWeekNumbers = false;
if(config.options.chkDisplayWeekNumbers)
  config.options.txtCalFirstDay = 0;
if(config.options.txtWeekNumberDisplayFormat == undefined)//wn**
  config.options.txtWeekNumberDisplayFormat = "w0WW";
if(config.options.txtWeekNumberLinkFormat == undefined)//wn**
  config.options.txtWeekNumberLinkFormat = "YYYY-w0WW";

config.macros.calendar = {};
config.macros.calendar.monthnames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
config.macros.calendar.daynames = ["M", "T", "W", "T", "F", "S", "S"];
config.macros.calendar.weekendbg = "#c0c0c0";
config.macros.calendar.monthbg = "#e0e0e0";
config.macros.calendar.holidaybg = "#ffc0c0";
config.macros.calendar.journalDateFmt = "DD MMM YYYY";
config.macros.calendar.monthdays = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
config.macros.calendar.holidays = [ ]; // Not sure this is required anymore - use reminders instead
//}}}
//{{{
function calendarIsHoliday(date) // Is the given date a holiday?
{
	var longHoliday = date.formatString("0DD/0MM/YYYY");
	var shortHoliday = date.formatString("0DD/0MM");
	for(var i = 0; i < config.macros.calendar.holidays.length; i++) {
		if(config.macros.calendar.holidays[i] == longHoliday || config.macros.calendar.holidays[i] == shortHoliday)
			return true;
	}
	return false;
}
//}}}
//{{{
config.macros.calendar.handler = function(place,macroName,params) {
	var calendar = createTiddlyElement(place, "table", null, "calendar", null);
	var tbody = createTiddlyElement(calendar, "tbody", null, null, null);
	var today = new Date();
	var year = today.getYear();
	if (year<1900) year+=1900;

 	// get format for journal link by reading from SideBarOptions (ELS 5/29/06 - based on suggestion by Martin Budden)
	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]) this.journalDateFmt = pa[0]; }

	if (params[0] == "thismonth") {
		cacheReminders(new Date(year, today.getMonth(), 1, 0, 0), 31);
		createCalendarOneMonth(tbody, year, today.getMonth());
	} 
	else if (params[0] == "lastmonth") {
		var month = today.getMonth()-1; if (month==-1) { month=11; year--; }
		cacheReminders(new Date(year, month, 1, 0, 0), 31);
		createCalendarOneMonth(tbody, year, month);
	}
	else if (params[0] == "nextmonth") {
		var month = today.getMonth()+1; if (month>11) { month=0; year++; }
		cacheReminders(new Date(year, month, 1, 0, 0), 31);
		createCalendarOneMonth(tbody, year, month);
	} else {
		if (params[0]) year = params[0];
		if(params[1]) {
			cacheReminders(new Date(year, params[1]-1, 1, 0, 0), 31);
			createCalendarOneMonth(tbody, year, params[1]-1);
		} else {
			cacheReminders(new Date(year, 0, 1, 0, 0), 366);
			createCalendarYear(tbody, year);
		}
	}
	window.reminderCacheForCalendar = null;
}
//}}}
//{{{
//This global variable is used to store reminders that have been cached
//while the calendar is being rendered.  It will be renulled after the calendar is fully rendered.
window.reminderCacheForCalendar = null;
//}}}
//{{{
function cacheReminders(date, leadtime)
{
	if (window.findTiddlersWithReminders == null) return;
	window.reminderCacheForCalendar = {};
	var leadtimeHash = [];
	leadtimeHash [0] = 0;
	leadtimeHash [1] = leadtime;
	var t = findTiddlersWithReminders(date, leadtimeHash, null, 1);
	for(var i = 0; i < t.length; i++) {
		//just tag it in the cache, so that when we're drawing days, we can bold this one.
		window.reminderCacheForCalendar[t[i]["matchedDate"]] = "reminder:" + t[i]["params"]["title"]; 
	}
}
//}}}
//{{{
function createCalendarOneMonth(calendar, year, mon)
{
	var row = createTiddlyElement(calendar, "tr", null, null, null);
	createCalendarMonthHeader(calendar, row, config.macros.calendar.monthnames[mon] + " " + year, true, year, mon);
	row = createTiddlyElement(calendar, "tr", null, null, null);
	createCalendarDayHeader(row, 1);
	createCalendarDayRowsSingle(calendar, year, mon);
}
//}}}
//{{{
function createCalendarMonth(calendar, year, mon)
{
	var row = createTiddlyElement(calendar, "tr", null, null, null);
	createCalendarMonthHeader(calendar, row, config.macros.calendar.monthnames[mon] + " " + year, false, year, mon);
	row = createTiddlyElement(calendar, "tr", null, null, null);
	createCalendarDayHeader(row, 1);
	createCalendarDayRowsSingle(calendar, year, mon);
}
//}}}
//{{{
function createCalendarYear(calendar, year)
{
	var row;
	row = createTiddlyElement(calendar, "tr", null, null, null);
	var back = createTiddlyElement(row, "td", null, null, null);
	var backHandler = function() {
		removeChildren(calendar);
		createCalendarYear(calendar, parseInt(year)-1);
		return false; // consume click
	};
	createTiddlyButton(back, "<", "Previous year", backHandler);
	back.align = "center";
	var yearHeader = createTiddlyElement(row, "td", null, "calendarYear", year);
	yearHeader.align = "center";
	yearHeader.setAttribute("colSpan",config.options.chkDisplayWeekNumbers?22:19);//wn**
	var fwd = createTiddlyElement(row, "td", null, null, null);
	var fwdHandler = function() {
		removeChildren(calendar);
		createCalendarYear(calendar, parseInt(year)+1);
		return false; // consume click
	};
	createTiddlyButton(fwd, ">", "Next year", fwdHandler);
	fwd.align = "center";
	createCalendarMonthRow(calendar, year, 0);
	createCalendarMonthRow(calendar, year, 3);
	createCalendarMonthRow(calendar, year, 6);
	createCalendarMonthRow(calendar, year, 9);
}
//}}}
//{{{
function createCalendarMonthRow(cal, year, mon)
{
	var row = createTiddlyElement(cal, "tr", null, null, null);
	createCalendarMonthHeader(cal, row, config.macros.calendar.monthnames[mon], false, year, mon);
	createCalendarMonthHeader(cal, row, config.macros.calendar.monthnames[mon+1], false, year, mon);
	createCalendarMonthHeader(cal, row, config.macros.calendar.monthnames[mon+2], false, year, mon);
	row = createTiddlyElement(cal, "tr", null, null, null);
	createCalendarDayHeader(row, 3);
	createCalendarDayRows(cal, year, mon);
}
//}}}
//{{{
function createCalendarMonthHeader(cal, row, name, nav, year, mon)
{
	var month;
	if (nav) {
		var back = createTiddlyElement(row, "td", null, null, null);
		back.align = "center";
		back.style.background = config.macros.calendar.monthbg;

		var backMonHandler = function() {
			var newyear = year;
			var newmon = mon-1;
			if(newmon == -1) { newmon = 11; newyear = newyear-1;}
			removeChildren(cal);
			cacheReminders(new Date(newyear, newmon , 1, 0, 0), 31);
			createCalendarOneMonth(cal, newyear, newmon);
			return false; // consume click
		};
		createTiddlyButton(back, "<", "Previous month", backMonHandler);
		month = createTiddlyElement(row, "td", null, "calendarMonthname")
		createTiddlyLink(month,name,true);
		month.setAttribute("colSpan", config.options.chkDisplayWeekNumbers?6:5);//wn**
		var fwd = createTiddlyElement(row, "td", null, null, null);
		fwd.align = "center";
		fwd.style.background = config.macros.calendar.monthbg; 

		var fwdMonHandler = function() {
			var newyear = year;
			var newmon = mon+1;
			if(newmon == 12) { newmon = 0; newyear = newyear+1;}
			removeChildren(cal);
			cacheReminders(new Date(newyear, newmon , 1, 0, 0), 31);
			createCalendarOneMonth(cal, newyear, newmon);
			return false; // consume click
		};
		createTiddlyButton(fwd, ">", "Next month", fwdMonHandler);
	} else {
		month = createTiddlyElement(row, "td", null, "calendarMonthname", name)
		month.setAttribute("colSpan",config.options.chkDisplayWeekNumbers?8:7);//wn**
	}
	month.align = "center";
	month.style.background = config.macros.calendar.monthbg;
}
//}}}
//{{{
function createCalendarDayHeader(row, num)
{
	var cell;
	for(var i = 0; i < num; i++) {
		if (config.options.chkDisplayWeekNumbers) createTiddlyElement(row, "td");//wn**
		for(var j = 0; j < 7; j++) {
			var d = j + (config.options.txtCalFirstDay - 0);
			if(d > 6) d = d - 7;
			cell = createTiddlyElement(row, "td", null, null, config.macros.calendar.daynames[d]);
			if(d == (config.options.txtCalStartOfWeekend-0) || d == (config.options.txtCalStartOfWeekend-0+1))
				cell.style.background = config.macros.calendar.weekendbg;
		}
	}
}
//}}}
//{{{
function createCalendarDays(row, col, first, max, year, mon) {
	var i;
	if (config.options.chkDisplayWeekNumbers){
		if (first<=max) {
			var ww = new Date(year,mon,first);
			var td=createTiddlyElement(row, "td");//wn**
			var link=createTiddlyLink(td,ww.formatString(config.options.txtWeekNumberLinkFormat),false);
			link.appendChild(document.createTextNode(ww.formatString(config.options.txtWeekNumberDisplayFormat)));
		}
		else createTiddlyElement(row, "td", null, null, null);//wn**
	}
	for(i = 0; i < col; i++)
		createTiddlyElement(row, "td", null, null, null);
	var day = first;
	for(i = col; i < 7; i++) {
		var d = i + (config.options.txtCalFirstDay - 0);
		if(d > 6) d = d - 7;
		var daycell = createTiddlyElement(row, "td", null, null, null);
		var isaWeekend = ((d == (config.options.txtCalStartOfWeekend-0) || d == (config.options.txtCalStartOfWeekend-0+1))? true:false);
		if(day > 0 && day <= max) {
			var celldate = new Date(year, mon, day);
			// ELS 2005.10.30: use <<date>> macro's showDate() function to create popup
			// ELS 5/29/06 - use journalDateFmt 
			if (window.showDate)
				showDate(daycell,celldate,"popup","DD",config.macros.calendar.journalDateFmt,true, isaWeekend);
			else {
				if(isaWeekend) daycell.style.background = config.macros.calendar.weekendbg;
				var title = celldate.formatString(config.macros.calendar.journalDateFmt);
				if(calendarIsHoliday(celldate))
					daycell.style.background = config.macros.calendar.holidaybg;
				if(window.findTiddlersWithReminders == null) {
					var link = createTiddlyLink(daycell, title, false);
					link.appendChild(document.createTextNode(day));
				} else
					var button = createTiddlyButton(daycell, day, title, onClickCalendarDate);
			}
		}
		day++;
	}
}
//}}}
//{{{
// We've clicked on a day in a calendar - create a suitable pop-up of options.
// The pop-up should contain:
//  * a link to create a new entry for that date
//  * a link to create a new reminder for that date
//  * an <hr>
//  * the list of reminders for that date
// NOTE: The following code is only used when [[DatePlugin]] is not present
function onClickCalendarDate(e)
{
	var button = this;
	var date = button.getAttribute("title");
	var dat = new Date(date.substr(6,4), date.substr(3,2)-1, date.substr(0, 2));

	date = dat.formatString(config.macros.calendar.journalDateFmt);
	var popup = createTiddlerPopup(this);
	popup.appendChild(document.createTextNode(date));
	var newReminder = function() {
		var t = store.getTiddlers(date);
		displayTiddler(null, date, 2, null, null, false, false);
		if(t) {
			document.getElementById("editorBody" + date).value += "\n<<reminder day:" + dat.getDate() +
				" month:" + (dat.getMonth()+1) + " year:" + (dat.getYear()+1900) + " title: >>";
		} else {
			document.getElementById("editorBody" + date).value = "<<reminder day:" + dat.getDate() +
				" month:" + (dat.getMonth()+1) +" year:" + (dat.getYear()+1900) + " title: >>";
		}
		return false; // consume click
	};
	var link = createTiddlyButton(popup, "New reminder", null, newReminder); 
	popup.appendChild(document.createElement("hr"));
	var t = findTiddlersWithReminders(dat, [0,14], null, 1);
	for(var i = 0; i < t.length; i++) {
		link = createTiddlyLink(popup, t[i].tiddler, false);
		link.appendChild(document.createTextNode(t[i].tiddler));
	}
	return false; // consume click
}
//}}}
//{{{
function calendarMaxDays(year, mon)
{
	var max = config.macros.calendar.monthdays[mon];
	if(mon == 1 && (year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0)) max++;
	return max;
}
//}}}
//{{{
function createCalendarDayRows(cal, year, mon)
{
	var row = createTiddlyElement(cal, "tr", null, null, null);
	var first1 = (new Date(year, mon, 1)).getDay() -1 - (config.options.txtCalFirstDay-0);
	if(first1 < 0) first1 = first1 + 7;
	var day1 = -first1 + 1;
	var first2 = (new Date(year, mon+1, 1)).getDay() -1 - (config.options.txtCalFirstDay-0);
	if(first2 < 0) first2 = first2 + 7;
	var day2 = -first2 + 1;
	var first3 = (new Date(year, mon+2, 1)).getDay() -1 - (config.options.txtCalFirstDay-0);
	if(first3 < 0) first3 = first3 + 7;
	var day3 = -first3 + 1;

	var max1 = calendarMaxDays(year, mon);
	var max2 = calendarMaxDays(year, mon+1);
	var max3 = calendarMaxDays(year, mon+2);

	while(day1 <= max1 || day2 <= max2 || day3 <= max3) {
		row = createTiddlyElement(cal, "tr", null, null, null);
		createCalendarDays(row, 0, day1, max1, year, mon); day1 += 7;
		createCalendarDays(row, 0, day2, max2, year, mon+1); day2 += 7;
		createCalendarDays(row, 0, day3, max3, year, mon+2); day3 += 7;
	}
}
//}}}
//{{{
function createCalendarDayRowsSingle(cal, year, mon)
{
	var row = createTiddlyElement(cal, "tr", null, null, null);
	var first1 = (new Date(year, mon, 1)).getDay() -1 - (config.options.txtCalFirstDay-0);
	if(first1 < 0) first1 = first1+ 7;
	var day1 = -first1 + 1;
	var max1 = calendarMaxDays(year, mon);
	while(day1 <= max1) {
		row = createTiddlyElement(cal, "tr", null, null, null);
		createCalendarDays(row, 0, day1, max1, year, mon); day1 += 7;
	}
}
//}}}
//{{{
setStylesheet(".calendar, .calendar table, .calendar th, .calendar tr, .calendar td { text-align:center; } .calendar, .calendar a { margin:0px !important; padding:0px !important; }", "calendarStyles");
//}}}
/***
|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]]
!!!!!Revisions
<<<
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 [[CheckboxPluginInfo]] 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;
	}
}
//}}}
!!!!!Usage
<<<
The checkbox syntax, including all optional parameters, is contained inside a matched set of [ and ] brackets.
{{{ [x=id(title|tag){init_script}{onclick_script}] }}}

An alternative syntax lets you place the optional parameters ''outside'' the [ and ] brackets, and is provided for backward-compatibility with existing content that may include checkbox definitions based on earlier releases of this plugin:
{{{ [x]=id(title|tag){init_script}{onclick_script} }}}

//{{{
[ ]or[_] and [x]or[X]
//}}}
Simple checkboxes.  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
//{{{
[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 ("TogglyTagging") 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 //unselected//.  When the checkbox is subsequently changed to //selected//, it will automatically (and silently) 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{javascript}{javascript}]
//}}}
You can define optional javascript code segments to add custom initialization and/or 'onClick' handling 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 the default context-object, 'this'.

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, so that you can perform programmed responses or intercept and override the checkbox state based on complex logic using the TW core API or custom functions defined in plugins (e.g. testing a particular tiddler title to see if certain tags are set or setting some tags when the checkbox is clicked).

Note: if you want to use the default checkbox initialization processing with a custom onclick function, use this syntax: {{{ [x=id{}{javascript}] }}} 
<<<
!!!!!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:
{{{[_{this.refresh.container=false}]}}}
<<<
!!!!!Examples
<<<
//{{{
[X] label
[_] label
//}}}
>checked and unchecked static default values
>[_] label
>[_] label
//{{{
[_=demo] label
//}}}
>document-based value (id='demo', no cookie)
>[_=demo] label
//{{{
[_=chkDemo] label
//}}}
>cookie-based value  (id='chkDemo')
>[_=chkDemo] label
/%
|Name|CheckboxToggleTag|
|Source|http://www.TiddlyTools.com/#CheckboxToggleTag|
|Version|1.3.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|toggle betwen two alternative tag values using HTML checkbox|

Usage:
	<<tiddler CheckboxToggleTag with: tag1 tag2 TiddlerName>> text label goes here
where:
	tag1 is the tag to use when the checkbox is set
	tag2 is the tag to use when the checkbox is cleared
	TiddlerName (optional) is the tiddler to be tagged

%/<html><input type="checkbox" onclick="
	/* ONCLICK: toggle onTag/offTag based on checkbox state */
	store.suspendNotifications();
	var tid=this.getAttribute('tid');
	var ontag=this.getAttribute('onTag');
	var offtag=this.getAttribute('offTag');
	if (ontag && ontag.length)  store.setTiddlerTag(tid,this.checked,ontag);
	if (offtag && offtag.length) store.setTiddlerTag(tid,!this.checked,offtag);
	store.resumeNotifications();
	store.notify(tid,true);
	var here=story.findContainingTiddler(this);
	if (here) story.refreshTiddler(here.getAttribute('tiddler'),null,true);
	return false;
"><hide linebreaks></html><script>
	/* ONINIT: save onTag/offTag and init checkbox based on current tag value (if any) */
	var tid="$3";
	if (tid=="$"+"3") {
		var here=story.findContainingTiddler(place); if (!here) return;
		var tid=here.getAttribute('tiddler');
	}
	if (!store.tiddlerExists(tid)) return;
	var c=place.lastChild.firstChild;
	if ("$1"!="$"+"1") c.setAttribute('onTag',"$1");
	if ("$2"!="$"+"2") c.setAttribute('offTag',"$2");
	c.setAttribute('tid',tid);
	c.checked=store.getTiddler(tid).isTagged(c.getAttribute('onTag'));
</script>
/%
|Name|ChecklistScript|
|Source|http://www.TiddlyTools.com/#ChecklistScript|
|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||
%/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,null,null,null,null,newTags);
		story.refreshTiddler(t.title,null,true); // force
	}
	return false;
</script>
Name: Chrome
HeaderTop: #fff
HeaderMid: #ccc
HeaderBottom: #000
Background: #FFF
Foreground: #000
PrimaryPale: #ccc
PrimaryLight: #666
PrimaryMid: #111
PrimaryDark: #666
SecondaryPale: #666
SecondaryLight: #ccc
SecondaryMid: #ccc
SecondaryDark: #ccc
TertiaryPale: #eee
TertiaryLight: #000
TertiaryMid: #ccc
TertiaryDark: #666
Error: #000
Test: #F00
/***
|Name|ClickifyPlugin|
|Source|http://www.TiddlyTools.com/#ClickifyPlugin|
|Documentation|http://www.TiddlyTools.com/#ClickifyPlugin|
|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|plugin|
|Requires||
|Overrides||
|Description|re-compute parameters when a 'command link' macro is clicked|
!!!!!Usage
<<<
Normally, when you use a //computed parameter// in a macro, it's value is determined when the macro is rendered.  The {{{<<clickify>>}}} macro can be used to force the macro parameters of an 'on-click' command link (such as created by the {{{<<newTiddler>>}}} macro) to be automatically re-computed when the command link is clicked, rather than when it is initially displayed.  This allows use of computed values that depend upon data that may change between the time the macro is rendered and when it's action is actually triggered by a click.

To apply this extended processing to any macro that creates a command link, simply insert the 'clickify' keyword in front of the usual macro name, like this:
{{{
<<clickify macroName param param param ...>>
}}}
<<<
!!!!!Example
<<<
When {{{<<newTiddler>>}}} is clicked, prompt for a title and set default text to current timestamp:
{{{
<<clickify newTiddler title:{{prompt('enter a title','NewTiddler')}} text:{{new Date()}}>>
}}}
><<clickify newTiddler title:{{prompt('enter a title','NewTiddler')}} text:{{new Date()}}>>
<<<
!!!!!Revisions
<<<
2009.02.08 [1.0.1] make sure command link has been rendered before trying to modify it
2009.01.25 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.ClickifyPlugin={major: 1, minor: 0, revision: 1, date: new Date(2009,2,8)};
config.macros.clickify={
	handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		var cmd='<<'+paramString+'>>';
		var e=createTiddlyElement(place,'span');
		wikify(cmd.replace(/alert\(|prompt\(|confirm\(/g,'isNaN('),e);
		var b=e.getElementsByTagName('a')[0]; if (!b) return;
		b.setAttribute('cmd',cmd);
		b.onclick=function(ev) {
			var cmd=this.getAttribute('cmd');
			var e=createTiddlyElement(this.parentNode,'span');
			e.style.display='none';
			wikify(cmd,e);
			e.getElementsByTagName('a')[0].onclick();
			this.parentNode.removeChild(e);
		}
	}
}
//}}}
/***
| 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;
	}

});

//}}}
<!--{{{-->
<!--- http://mptw.tiddlyspot.com/#MptwViewTemplate ($Rev: 2247 $) --->
<!--- moved toolbar to ToolbarCommands MTP 10.23.08 --->

<div class='toolbar' macro='toolbar [[ToolbarCommands::ViewToolbar]]'></div>

<div class="tagglyTagged" macro="tags"></div>

<span class='titleContainer'>
	<span class='title' macro='view title'></span>
	<span macro="miniTag"></span>
</span>

<span class='subtitle'>
	<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>)
</span>

<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>

<!--}}}-->
/***
|Name|CollapseTiddlersPlugin|
|Source|http://gensoft.revhost.net/Collapse.html|
|Version|2008.10.05|
|Author|Bradley Meck (modified by ELS)|
|License|unknown|
|~CoreVersion|2.1|
|Type|plugin|
|Requires|CollapsedTemplate|
|Overrides||
|Description|show/hide content of a tiddler while leaving tiddler title visible|

|ELS 10/5/2008: collapseAll() and expandAll(): added "return false" to button handlers to prevent IE page transition |
|ELS 3/6/2008: refactored code for size reduction, readability, and I18N/L10N-readiness.  Also added 'folded' flag to tiddler elements (for use by other plugins that need to know if tiddler is folded (e.g., [[SinglePageModePlugin]]) |
|ELS 10/11/2007: moved [[FoldFirst]] inline script and converted to {{{<<foldFirst>>}}} macro. |
|ELS 9/12/2007: suspend/resume SinglePageMode (SPM/TPM/BPM) when folding/unfolding tiddlers |
|ELS 6/5/2007: add "return false" at the end of each command handler to prevent IE 'page transition' problem. |
|ELS 3/30/2007: add a shadow definition for CollapsedTemplate.  Tweak ViewTemplate shadow so "fold/unfold" and "focus" toolbar items automatically appear when using default templates.  Remove error check for "CollapsedTemplate" existence, since shadow version will now always work as a fallback. |
|ELS 2/24/2006: added fallback to "CollapsedTemplate" if "WebCollapsedTemplate" is not found |
|ELS 2/6/2006: added check for 'readOnly' flag to use alternative "WebCollapsedTemplate" |

***/

//{{{
config.shadowTiddlers.CollapsedTemplate=
	"<!--{{{-->\
	<div class='toolbar' macro='toolbar expandTiddler collapseOthers closeTiddler closeOthers +editTiddler permalink references jump'></div>\
	<div class='title' macro='view title'></div>\
	<!--}}}-->";

// automatically tweak shadow ViewTemplate to add "collapseTiddler collapseOthers" commands
config.shadowTiddlers.ViewTemplate=config.shadowTiddlers.ViewTemplate.replace(/closeTiddler/,"collapseTiddler collapseOthers closeTiddler");

config.commands.collapseTiddler = {
	text: "fold",
	tooltip: "Collapse this tiddler",
	collapsedTemplate: "CollapsedTemplate",
	webCollapsedTemplate: "WebCollapsedTemplate",
	handler: function(event,src,title) {
		var e = story.findContainingTiddler(src); if (!e) return false;
		// don't fold tiddlers that are being edited!
		if(story.isDirty(e.getAttribute("tiddler"))) return false;
		var t=config.commands.collapseTiddler.getCollapsedTemplate();
		config.commands.collapseTiddler.saveTemplate(e);
		config.commands.collapseTiddler.display(title,t);
		e.setAttribute("folded","true");
		return false;
	},
	getCollapsedTemplate: function() {
		if (readOnly&&store.tiddlerExists(this.webCollapsedTemplate))
			return this.webCollapsedTemplate;
		else
			return this.collapsedTemplate
	},
	saveTemplate: function(e) {
		if (e.getAttribute("savedTemplate")==undefined)
			e.setAttribute("savedTemplate",e.getAttribute("template"));

	},
	// fold/unfold tiddler with suspend/resume of single/top/bottom-of-page mode
	display: function(title,t) {
		var opt=config.options;
		var saveSPM=opt.chkSinglePageMode; opt.chkSinglePageMode=false;
		var saveTPM=opt.chkTopOfPageMode; opt.chkTopOfPageMode=false;
		var saveBPM=opt.chkBottomOfPageMode; opt.chkBottomOfPageMode=false;
		story.displayTiddler(null,title,t);
		opt.chkBottomOfPageMode=saveBPM;
		opt.chkTopOfPageMode=saveTPM;
		opt.chkSinglePageMode=saveSPM;
	}
}

config.commands.expandTiddler = {
	text: "unfold",
	tooltip: "Expand this tiddler",
	handler: function(event,src,title) {
		var e = story.findContainingTiddler(src); if (!e) return false;
		var t = e.getAttribute("savedTemplate");
		config.commands.collapseTiddler.display(title,t);
		e.setAttribute("folded","false");
		return false;
	}
}

config.macros.collapseAll = {
	text: "collapse all",
	tooltip: "Collapse all tiddlers",
	handler: function(place,macroName,params,wikifier,paramString,tiddler){
		createTiddlyButton(place,this.text,this.tooltip,function(){
			story.forEachTiddler(function(title,tiddler){
				if(story.isDirty(title)) return;
				var t=config.commands.collapseTiddler.getCollapsedTemplate();


				config.commands.collapseTiddler.saveTemplate(tiddler);
				config.commands.collapseTiddler.display(title,t);
				tiddler.folded=true;
			});
			return false;
		})
	}
}

config.macros.expandAll = {
	text: "expand all",
	tooltip: "Expand all tiddlers",
	handler: function(place,macroName,params,wikifier,paramString,tiddler){
		createTiddlyButton(place,this.text,this.tooltip,function(){
			story.forEachTiddler(function(title,tiddler){
				var t=config.commands.collapseTiddler.getCollapsedTemplate();
				if(tiddler.getAttribute("template")!=t) return; // re-display only if collapsed
				var t=tiddler.getAttribute("savedTemplate");
				config.commands.collapseTiddler.display(title,t);
				tiddler.folded=false;
			});
			return false;
		})
	}
}

config.commands.collapseOthers = {
	text: "focus",
	tooltip: "Expand this tiddler and collapse all others",
	handler: function(event,src,title) {
		var e = story.findContainingTiddler(src); if (!e) return false;
		story.forEachTiddler(function(title,tiddler) {
			if(story.isDirty(title)) return;
			var t=config.commands.collapseTiddler.getCollapsedTemplate();
			if (e==tiddler) t=e.getAttribute("savedTemplate");
			config.commands.collapseTiddler.saveTemplate(tiddler);
			config.commands.collapseTiddler.display(title,t);
			tiddler.folded=(e!=tiddler);
		})
		return false;
	}
}

// {{{<<foldFirst>>}}} macro forces tiddler to be folded when *initially* displayed.
// Subsequent re-render does NOT re-fold tiddler, but closing/re-opening tiddler DOES cause it to fold first again.
config.macros.foldFirst = {
	handler: function(place,macroName,params,wikifier,paramString,tiddler){
		var e=story.findContainingTiddler(place);
		if (e.getAttribute("foldedFirst")=="true") return; // already been folded once
		var title=e.getAttribute("tiddler")
		var t=config.commands.collapseTiddler.getCollapsedTemplate();
		config.commands.collapseTiddler.saveTemplate(e);
		config.commands.collapseTiddler.display(title,t);
		e.setAttribute("folded","true");
		e.setAttribute("foldedFirst","true"); // only when tiddler is first rendered
		return false;
	}
}
//}}}
<!--{{{-->
<!--- Style for Collasped Tiddler Cleaned Up Code 10.23.08 --->
<!--- Description: alternative to ViewTemplate, used by CollapseTiddlersPlugin to display tiddler when 'folded' --->
<span class='toolbar' macro='toolbar [[ToolbarCommands::CollapsedToolbar]]'></span>
<div class='title' macro='view title'></div>
<div class='tagClear'></div>
<!--}}}-->
<html>


<table width="300" bgcolor="#0063F7" border="0" cellspacing="0" cellpadding="5">

<tr><td width="300" bgcolor="#0063F7" align="right" valign="top" colspan="2">

<A HREF="quicklinks.html">


<TABLE BORDER="1" CELLPADDING="10" CELLSPACING="2" width="544" bgcolor="#0063F7">

<TR><TD align="left" valign="middle" bgcolor="#ffffff">



<table width="518" border="1" cellspacing="0" cellpadding="0">

<tr align=center>



<td bgcolor=#eeeeee><font color=#000000>EEE</font></td>



<td bgcolor=#dddddd><font color=#000000>DDD</font></td>



<td bgcolor=#cccccc><font color=#000000>CCC</font></td>



<td bgcolor=#bbbbbb><font color=#000000>BBB</font></td>



<td bgcolor=#aaaaaa><font color=#000000>AAA</font></td>



<td bgcolor=#999999><font color=#ffffff>999</font></td>



</TR>







<tr align=center>



<td bgcolor=#888888><font color=#ffffff>888</font></td>



<td bgcolor=#777777><font color=#ffffff>777</font></td>



<td bgcolor=#666666><font color=#ffffff>666</font></td>



<td bgcolor=#555555><font color=#ffffff>555</font></td>



<td bgcolor=#444444><font color=#ffffff>444</font></td>



<td bgcolor=#333333><font color=#ffffff>333</font></td>



</tr>







<tr align=center>



<td bgcolor=#222222><font color=#ffffff>222</font></td>



<td bgcolor=#111111><font color=#ffffff>111</font></td>



<td bgcolor=#000000><font color=#ffffff>000</font></td>



<td bgcolor=#ff0000><font color=#ffffff>F00</font></td>



<td bgcolor=#ee0000><font color=#ffffff>E00</font></td>



<td bgcolor=#dd0000><font color=#ffffff>D00</font></td>



</tr>







<tr align=center>



<td bgcolor=#cc0000><font color=#ffffff>C00</font></td>



<td bgcolor=#bb0000><font color=#ffffff>B00</font></td>



<td bgcolor=#aa0000><font color=#ffffff>A00</font></td>



<td bgcolor=#990000><font color=#ffffff>900</font></td>



<td bgcolor=#880000><font color=#ffffff>800</font></td>



<td bgcolor=#770000><font color=#ffffff>700</font></td>



</tr>







<tr align=center>



<td bgcolor=#660000><font color=#ffffff>600</font></td>



<td bgcolor=#550000><font color=#ffffff>500</font></td>



<td bgcolor=#440000><font color=#ffffff>400</font></td>



<td bgcolor=#330000><font color=#ffffff>300</font></td>



<td bgcolor=#220000><font color=#ffffff>200</font></td>



<td bgcolor=#110000><font color=#ffffff>100</font></td>



</tr>







<tr align=center>



<td bgcolor=#ffffff><font color=#000000>FFF</font></td>



<td bgcolor=#ffffcc><font color=#000000>FFC</font></td>



<td bgcolor=#ffff99><font color=#000000>FF9</font></td>



<td bgcolor=#ffff66><font color=#000000>FF6</font></td>



<td bgcolor=#ffff33><font color=#000000>FF3</font></td>



<td bgcolor=#ffff00><font color=#000000>FF0</font></td>



</tr>







<tr align=center>



<td bgcolor=#ccffff><font color=#000000>CFF</font></td>



<td bgcolor=#ccffcc><font color=#000000>CFC</font></td>



<td bgcolor=#ccff99><font color=#000000>CF9</font></td>



<td bgcolor=#ccff66><font color=#000000>CF6</font></td>



<td bgcolor=#ccff33><font color=#000000>CF3</font></td>



<td bgcolor=#ccff00><font color=#000000>CF0</font></td>



</tr>







<tr align=center>



<td bgcolor=#99ffff><font color=#000000>9FF</font></td>



<td bgcolor=#99ffcc><font color=#000000>9FC</font></td>



<td bgcolor=#99ff99><font color=#000000>9F9</font></td>



<td bgcolor=#99ff66><font color=#000000>9F6</font></td>



<td bgcolor=#99ff33><font color=#000000>9F3</font></td>



<td bgcolor=#99ff00><font color=#000000>9F0</font></td>



</tr>







<tr align=center>



<td bgcolor=#66ffff><font color=#000000>6FF</font></td>



<td bgcolor=#66ffcc><font color=#000000>6FC</font></td>



<td bgcolor=#66ff99><font color=#000000>6F9</font></td>



<td bgcolor=#66ff66><font color=#000000>6F6</font></td>



<td bgcolor=#66ff33><font color=#000000>6F3</font></td>



<td bgcolor=#66ff00><font color=#000000>6F0</font></td>



</tr>







<tr align=center>



<td bgcolor=#33ffff><font color=#000000>3FF</font></td>



<td bgcolor=#33ffcc><font color=#000000>3FC</font></td>



<td bgcolor=#33ff99><font color=#000000>3F9</font></td>



<td bgcolor=#33ff66><font color=#000000>3F6</font></td>



<td bgcolor=#33ff33><font color=#000000>3F3</font></td>



<td bgcolor=#33ff00><font color=#000000>3F0</font></td>



</tr>







<tr align=center>



<td bgcolor=#00ffff><font color=#000000>0FF</font></td>



<td bgcolor=#00ffcc><font color=#000000>0FC</font></td>



<td bgcolor=#00ff99><font color=#000000>0F9</font></td>



<td bgcolor=#00ff66><font color=#000000>0F6</font></td>



<td bgcolor=#00ff33><font color=#000000>0F3</font></td>



<td bgcolor=#00ff00><font color=#000000>0F0</font></td>



</tr>







<tr align=center>



<td bgcolor=#ffccff><font color=#000000>FCF</font></td>



<td bgcolor=#ffcccc><font color=#000000>FCC</font></td>



<td bgcolor=#ffcc99><font color=#000000>FC9</font></td>



<td bgcolor=#ffcc66><font color=#000000>FC6</font></td>



<td bgcolor=#ffcc33><font color=#000000>FC3</font></td>



<td bgcolor=#ffcc00><font color=#000000>FC0</font></td>



</tr>







<tr align=center>



<td bgcolor=#ccccff><font color=#000000>CCF</font></td>



<td bgcolor=#cccccc><font color=#000000>CCC</font></td>



<td bgcolor=#cccc99><font color=#000000>CC9</font></td>



<td bgcolor=#cccc66><font color=#000000>CC6</font></td>



<td bgcolor=#cccc33><font color=#000000>CC3</font></td>



<td bgcolor=#cccc00><font color=#000000>CC0</font></td>



</tr>







<tr align=center>



<td bgcolor=#99ccff><font color=#000000>9CF</font></td>



<td bgcolor=#99cccc><font color=#000000>9CC</font></td>



<td bgcolor=#99cc99><font color=#000000>9C9</font></td>



<td bgcolor=#99cc66><font color=#000000>9C6</font></td>



<td bgcolor=#99cc33><font color=#000000>9C3</font></td>



<td bgcolor=#99cc00><font color=#000000>9C0</font></td>



</tr>







<tr align=center>



<td bgcolor=#66ccff><font color=#000000>6CF</font></td>



<td bgcolor=#66cccc><font color=#000000>6CC</font></td>



<td bgcolor=#66cc99><font color=#000000>6C9</font></td>



<td bgcolor=#66cc66><font color=#000000>6C6</font></td>



<td bgcolor=#66cc33><font color=#000000>6C3</font></td>



<td bgcolor=#66cc00><font color=#000000>6C0</font></td>



</tr>







<tr align=center>



<td bgcolor=#33ccff><font color=#000000>3CF</font></td>



<td bgcolor=#33cccc><font color=#000000>3CC</font></td>



<td bgcolor=#33cc99><font color=#000000>3C9</font></td>



<td bgcolor=#33cc66><font color=#000000>3C6</font></td>



<td bgcolor=#33cc33><font color=#000000>3C3</font></td>



<td bgcolor=#33cc00><font color=#000000>3C0</font></td>



</tr>







<tr align=center>



<td bgcolor=#00ccff><font color=#000000>0CF</font></td>



<td bgcolor=#00cccc><font color=#000000>0CC</font></td>



<td bgcolor=#33cc66><font color=#000000>3C6</font></td>



<td bgcolor=#33cc33><font color=#000000>3C3</font></td>



<td bgcolor=#00cc99><font color=#000000>0C9</font></td>



<td bgcolor=#00cc66><font color=#000000>0C6</font></td>



</tr>







<tr align=center>



<td bgcolor=#00cc33><font color=#000000>0C3</font></td>



<td bgcolor=#00cc00><font color=#000000>0C0</font></td>



<td bgcolor=#ff99ff><font color=#000000>F9F</font></td>



<td bgcolor=#ff99cc><font color=#000000>F9C</font></td>



<td bgcolor=#ff9999><font color=#000000>F99</font></td>



<td bgcolor=#ff9966><font color=#000000>F96</font></td>



</tr>







<tr align=center>



<td bgcolor=#ff9933><font color=#ffffff>F93</font></td>



<td bgcolor=#ff9900><font color=#ffffff>F90</font></td>



<td bgcolor=#cc99ff><font color=#ffffff>C9F</font></td>



<td bgcolor=#cc99cc><font color=#ffffff>C9C</font></td>



<td bgcolor=#cc9999><font color=#ffffff>C99</font></td>



<td bgcolor=#cc9966><font color=#ffffff>C96</font></td>



</tr>







<tr align=center>



<td bgcolor=#cc9933><font color=#ffffff>C93</font></td>



<td bgcolor=#cc9900><font color=#ffffff>C90</font></td>



<td bgcolor=#9999ff><font color=#ffffff>99F</font></td>



<td bgcolor=#9999cc><font color=#ffffff>99C</font></td>



<td bgcolor=#999999><font color=#ffffff>999</font></td>



<td bgcolor=#999966><font color=#ffffff>996</font></td>



</tr>







<tr align=center>



<td bgcolor=#999933><font color=#ffffff>993</font></td>



<td bgcolor=#999900><font color=#ffffff>990</font></td>



<td bgcolor=#6699ff><font color=#ffffff>69F</font></td>



<td bgcolor=#6699cc><font color=#ffffff>69C</font></td>



<td bgcolor=#669999><font color=#ffffff>699</font></td>



<td bgcolor=#669966><font color=#ffffff>696</font></td>



</tr>









<tr align=center>



<td bgcolor=#669933><font color=#ffffff>693</font></td>



<td bgcolor=#669900><font color=#ffffff>690</font></td>



<td bgcolor=#3399ff><font color=#ffffff>39F</font></td>



<td bgcolor=#3399cc><font color=#ffffff>39C</font></td>



<td bgcolor=#339999><font color=#ffffff>399</font></td>



<td bgcolor=#339966><font color=#ffffff>396</font></td>



</tr>







<tr align=center>



<td bgcolor=#339933><font color=#ffffff>393</font></td>



<td bgcolor=#339900><font color=#ffffff>390</font></td>



<td bgcolor=#0099ff><font color=#ffffff>09F</font></td>



<td bgcolor=#0099cc><font color=#ffffff>09C</font></td>



<td bgcolor=#009999><font color=#ffffff>099</font></td>



<td bgcolor=#009966><font color=#ffffff>096</font></td>



</tr>







<tr align=center>



<td bgcolor=#009933><font color=#ffffff>093</font></td>



<td bgcolor=#009900><font color=#ffffff>090</font></td>



<td bgcolor=#ff66ff><font color=#ffffff>F6F</font></td>



<td bgcolor=#ff66cc><font color=#ffffff>F6C</font></td>



<td bgcolor=#ff6699><font color=#ffffff>F69</font></td>



<td bgcolor=#ff6666><font color=#ffffff>F66</font></td>



</tr>







<tr align=center>



<td bgcolor=#ff6633><font color=#ffffff>F63</font></td>



<td bgcolor=#ff6600><font color=#ffffff>F60</font></td>



<td bgcolor=#cc66ff><font color=#ffffff>C6F</font></td>



<td bgcolor=#cc66cc><font color=#ffffff>C6C</font></td>



<td bgcolor=#cc6699><font color=#ffffff>C69</font></td>



<td bgcolor=#cc6666><font color=#ffffff>C66</font></td>



</tr>







<tr align=center>



<td bgcolor=#cc6633><font color=#ffffff>C63</font></td>



<td bgcolor=#cc6600><font color=#ffffff>C60</font></td>



<td bgcolor=#9966ff><font color=#ffffff>96F</font></td>



<td bgcolor=#9966cc><font color=#ffffff>96C</font></td>



<td bgcolor=#996699><font color=#ffffff>969</font></td>



<td bgcolor=#996666><font color=#ffffff>966</font></td>



</tr>







<tr align=center>



<td bgcolor=#996633><font color=#ffffff>963</font></td>



<td bgcolor=#996600><font color=#ffffff>960</font></td>



<td bgcolor=#6666ff><font color=#ffffff>66F</font></td>



<td bgcolor=#6666cc><font color=#ffffff>66C</font></td>



<td bgcolor=#666699><font color=#ffffff>669</font></td>



<td bgcolor=#666666><font color=#ffffff>666</font></td>



</tr>







<tr align=center>



<td bgcolor=#666633><font color=#ffffff>663</font></td>



<td bgcolor=#666600><font color=#ffffff>660</font></td>



<td bgcolor=#3366ff><font color=#ffffff>36F</font></td>



<td bgcolor=#0063F7><font color=#ffffff>36C</font></td>



<td bgcolor=#336699><font color=#ffffff>369</font></td>



<td bgcolor=#336666><font color=#ffffff>366</font></td>



</tr>







<tr align=center>



<td bgcolor=#336633><font color=#ffffff>363</font></td>



<td bgcolor=#336600><font color=#ffffff>360</font></td>



<td bgcolor=#0066ff><font color=#ffffff>06F</font></td>



<td bgcolor=#0066cc><font color=#ffffff>06C</font></td>



<td bgcolor=#006699><font color=#ffffff>069</font></td>



<td bgcolor=#006666><font color=#ffffff>066</font></td>



</tr>







<tr align=center>



<td bgcolor=#006633><font color=#ffffff>063</font></td>



<td bgcolor=#006600><font color=#ffffff>060</font></td>



<td bgcolor=#ff33ff><font color=#ffffff>F3F</font></td>



<td bgcolor=#ff33cc><font color=#ffffff>F3C</font></td>



<td bgcolor=#ff3399><font color=#ffffff>F39</font></td>



<td bgcolor=#ff3366><font color=#ffffff>F36</font></td>



</tr>







<tr align=center>



<td bgcolor=#ff3333><font color=#ffffff>F33</font></td>



<td bgcolor=#ff3300><font color=#ffffff>F30</font></td>



<td bgcolor=#cc33ff><font color=#ffffff>C3F</font></td>



<td bgcolor=#cc33cc><font color=#ffffff>C3C</font></td>



<td bgcolor=#cc3399><font color=#ffffff>C39</font></td>



<td bgcolor=#cc3366><font color=#ffffff>C36</font></td>



</TR>







<tr align=center>



<td bgcolor=#cc3333><font color=#ffffff>C33</font></td>



<td bgcolor=#cc3300><font color=#ffffff>C30</font></td>



<td bgcolor=#9933ff><font color=#ffffff>93F</font></td>



<td bgcolor=#9933cc><font color=#ffffff>93C</font></td>



<td bgcolor=#993399><font color=#ffffff>939</font></td>



<td bgcolor=#993366><font color=#ffffff>936</font></td>



</tr>







<tr align=center>



<td bgcolor=#993333><font color=#ffffff>933</font></td>



<td bgcolor=#993300><font color=#ffffff>930</font></td>



<td bgcolor=#6633ff><font color=#ffffff>63F</font></td>



<td bgcolor=#6633cc><font color=#ffffff>63C</font></td>



<td bgcolor=#663399><font color=#ffffff>639</font></td>



<td bgcolor=#663366><font color=#ffffff>636</font></td>



</tr>







<tr align=center>



<td bgcolor=#663333><font color=#ffffff>633</font></td>



<td bgcolor=#663300><font color=#ffffff>630</font></td>



<td bgcolor=#3333ff><font color=#ffffff>33F</font></td>



<td bgcolor=#3333cc><font color=#ffffff>33C</font></td>



<td bgcolor=#333399><font color=#ffffff>339</font></td>



<td bgcolor=#333366><font color=#ffffff>336</font></td>



</tr>







<tr align=center>



<td bgcolor=#333333><font color=#ffffff>333</font></td>



<td bgcolor=#333300><font color=#ffffff>330</font></td>



<td bgcolor=#0033ff><font color=#ffffff>03F</font></td>



<td bgcolor=#ff3333><font color=#ffffff>F33</font></td>



<td bgcolor=#0033cc><font color=#ffffff>03C</font></td>



<td bgcolor=#003399><font color=#ffffff>039</font></td>



</tr>







<tr align=center>



<td bgcolor=#003366><font color=#ffffff>036</font></td>



<td bgcolor=#003333><font color=#ffffff>033</font></td>



<td bgcolor=#003300><font color=#ffffff>030</font></td>



<td bgcolor=#ff00ff><font color=#ffffff>F0F</font></td>



<td bgcolor=#ff00cc><font color=#ffffff>F0C</font></td>



<td bgcolor=#ff0099><font color=#ffffff>F09</font></td>



</tr>







<tr align=center>



<td bgcolor=#ff0066><font color=#ffffff>F06</font></td>



<td bgcolor=#ff0033><font color=#ffffff>F03</font></td>



<td bgcolor=#ff0000><font color=#ffffff>F00</font></td>



<td bgcolor=#cc00ff><font color=#ffffff>C0F</font></td>



<td bgcolor=#cc00cc><font color=#ffffff>C0C</font></td>



<td bgcolor=#cc0099><font color=#ffffff>C09</font></td>



</tr>







<tr align=center>



<td bgcolor=#cc0066><font color=#ffffff>C06</font></td>



<td bgcolor=#cc0033><font color=#ffffff>C03</font></td>



<td bgcolor=#cc0000><font color=#ffffff>C00</font></td>



<td bgcolor=#9900ff><font color=#ffffff>90F</font></td>



<td bgcolor=#9900cc><font color=#ffffff>90C</font></td>



<td bgcolor=#990099><font color=#ffffff>909</font></td>



</tr>







<tr align=center>



<td bgcolor=#990066><font color=#ffffff>906</font></td>



<td bgcolor=#990033><font color=#ffffff>903</font></td>



<td bgcolor=#990000><font color=#ffffff>900</font></td>



<td bgcolor=#6600ff><font color=#ffffff>60F</font></td>



<td bgcolor=#6600cc><font color=#ffffff>60C</font></td>



<td bgcolor=#660099><font color=#ffffff>609</font></td>



</tr>







<tr align=center>



<td bgcolor=#660066><font color=#ffffff>606</font></td>



<td bgcolor=#660033><font color=#ffffff>603</font></td>



<td bgcolor=#660000><font color=#ffffff>600</font></td>



<td bgcolor=#3300ff><font color=#ffffff>30F</font></td>



<td bgcolor=#3300cc><font color=#ffffff>30C</font></td>



<td bgcolor=#330099><font color=#ffffff>309</font></td>



</tr>







<tr align=center>



<td bgcolor=#330066><font color=#ffffff>306</font></td>



<td bgcolor=#330033><font color=#ffffff>303</font></td>



<td bgcolor=#330000><font color=#ffffff>300</font></td>



<td bgcolor=#0000ff><font color=#ffffff>00F</font></td>



<td bgcolor=#0000cc><font color=#ffffff>00C</font></td>



<td bgcolor=#000099><font color=#ffffff>009</font></td>



</tr>







<tr align=center>



<td bgcolor=#000066><font color=#ffffff>006</font></td>



<td bgcolor=#000033><font color=#ffffff>003</font></td>



<td bgcolor=#00ff00><font color=#000000>0F0</font></td>



<td bgcolor=#00ee00><font color=#000000>0E0</font></td>



<td bgcolor=#00dd00><font color=#000000>0D0</font></td>



<td bgcolor=#00cc00><font color=#000000>0C0</font></td>



</tr>







<tr align=center>



<td bgcolor=#00bb00><font color=#ffffff>0B0</font></td>



<td bgcolor=#00aa00><font color=#ffffff>0A0</font></td>



<td bgcolor=#009900><font color=#ffffff>090</font></td>



<td bgcolor=#008800><font color=#ffffff>080</font></td>



<td bgcolor=#007700><font color=#ffffff>070</font></td>



<td bgcolor=#006600><font color=#ffffff>060</font></td>



</tr>







<tr align=center>



<td bgcolor=#005500><font color=#ffffff>050</font></td>



<td bgcolor=#004400><font color=#ffffff>040</font></td>



<td bgcolor=#003300><font color=#ffffff>030</font></td>



<td bgcolor=#002200><font color=#ffffff>020</font></td>



<td bgcolor=#001100><font color=#ffffff>010</font></td>



<td bgcolor=#0000ff><font color=#ffffff>00F</font></td>



</tr>







<tr align=center>



<td bgcolor=#0000ee><font color=#ffffff>00E</font></td>



<td bgcolor=#0000dd><font color=#ffffff>00D</font></td>



<td bgcolor=#0000cc><font color=#ffffff>00C</font></td>



<td bgcolor=#0000bb><font color=#ffffff>00B</font></td>



<td bgcolor=#0000aa><font color=#ffffff>00A</font></td>



<td bgcolor=#000099><font color=#ffffff>009</font></td>



</tr>







<tr align=center>



<td bgcolor=#000088><font color=#ffffff>008</font></td>



<td bgcolor=#000077><font color=#ffffff>007</font></td>



<td bgcolor=#000055><font color=#ffffff>005</font></td>



<td bgcolor=#000044><font color=#ffffff>004</font></td>



<td bgcolor=#000022><font color=#ffffff>002</font></td>



<td bgcolor=#000011><font color=#ffffff>001</font></td>



</tr>

</table>


</html>
Name: Bloody2
HeaderTop: #300
HeaderMid: #f00
HeaderBottom: #300
Background: #b22222
Foreground: #fff
PrimaryPale: #b22222
PrimaryLight: #400
PrimaryMid: #300
PrimaryDark: #900
SecondaryPale: #800
SecondaryLight: #d00
SecondaryMid: #ccc
SecondaryDark: #fff
TertiaryPale: #fff
TertiaryLight: #300
TertiaryMid: #600
TertiaryDark: #800
Error: #F30
Test: #0F0
<br><br>
A list of the color codes in the ColorPalette, and the sections of this TiddlyWiki that they affect.
<br><br>
HeaderTop:	Added top section into gradient on PageTemplate
<br>
HeaderMid:	Added mid section into gradient on PageTemplate
<br>
HeaderBottom:	Added bottom section into gradient on PageTemplate
<br>
Background:	tiddler background 
<br>
Foreground:	non link Text, dots, backstage background
<br>
PrimaryPale:	Name, Getting Started, Options background, MainMenu
<br>
PrimaryLight:	Notebook, Getting Started, Options border, Tiddler Group Name
<br>
PrimaryMid:	Link Text, Tiddler Name, tiddler edit border, Main Menu Background, SiteTitle, SiteSubtitle
<br>
PrimaryDark:	Search / Action text, Tag front text, Minor Drop Down Arrows
<br>
SecondaryPale:	Save Changes, Close Text Highlight, Code Text Background 
<br>
SecondaryLight:	Action Text background 
<br>
SecondaryMid:	title cells in tables, save box background, tiddler buttons on select, Action Text border 
<br>
SecondaryDark:	Action Text border on select 
<br>
TertiaryPale:	background behind tag block, task manager and contents background .
<br>
TertiaryLight:	background behind tiddler 
<br>
TertiaryMid:	Content tab background, tiddler shadow and toolbar text 
<br>
TertiaryDark:	tiddler subtitle, Tiddler Drop down edit border 
<br>
Error:		Error Color
<br>
Test:		Test Color for troubleshooting palette
//{{{
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 
//}}}
/***
<<tiddler CookieManager>>
***/
/***
!!![[Baked cookies:|CookieManagerPlugin]]
^^Press {{smallform{<<cookieManager button>>}}} to save the current browser cookies... then hand-edit this section to customize the results.^^
***/

// 28 cookies saved on Monday, August 3rd 2009 at 16:10:42 by Mike//
//^^(edit/remove username check and/or individual option settings as desired)^^//
//{{{
if (config.options.txtUserName=="Mike") {
	config.options.chkAllowBrowserCookies=true;
	config.options.chkBackstage=true;
	config.options.chkCookieManagerAddToAdvancedOptions=false;
	config.options.chkDisableTabsBar=false;
	config.options.chkMonitorBrowserCookies=true;
	config.options.chkRandomTheme=true;
	config.options.chkSliderMainMenu_faq=false;
	config.options.chkSliderOptionsPanel=false;
	config.options.txtFontSize="100";
	config.options.txtMainTab="No Tag";
	config.options.txtMoreTab="Shadow";
	config.options.txtTheme="Blood7Theme";
}
//}}}


// 65 options saved on Tuesday, April 27th 2010 at 12:54:52 by Mike//
//^^(edit/remove username check and/or individual option settings as desired)^^//
//{{{
if (config.options.txtUserName=="Mike") {
	config.options.chkAllowBrowserCookies=true;
	config.options.chkAnimate=false;
	config.options.chkAutoSave=false;
	config.options.chkBackstage=true;
	config.options.chkCaseSensitiveSearch=false;
	config.options.chkConfirmDelete=true;
	config.options.chkCookieManagerAddToAdvancedOptions=true;
	config.options.chkDisableAutoSelect=true;
	config.options.chkDisableTabsBar=false;
	config.options.chkDisplayInstrumentation=false;
	config.options.chkDisplayWeekNumbers=false;
	config.options.chkExcludeEncryptedFromLists=false;
	config.options.chkExcludeEncryptedFromSearch=false;
	config.options.chkFloatingSlidersAnimate=false;
	config.options.chkForceMinorUpdate=false;
	config.options.chkGenerateAnRssFeed=false;
	config.options.chkHideMissingMacros=false;
	config.options.chkHideTabsBarWhenSingleTab=false;
	config.options.chkHttpReadOnly=false;
	config.options.chkImportReport=true;
	config.options.chkIncrementalSearch=true;
	config.options.chkInsertTabs=true;
	config.options.chkMonitorBrowserCookies=false;
	config.options.chkOpenInNewWindow=true;
	config.options.chkPreviewText=true;
	config.options.chkRandomTheme=true;
	config.options.chkRegExpSearch=false;
	config.options.chkResizeEditor=true;
	config.options.chkSaveBackups=true;
	config.options.chkSaveEmptyTemplate=false;
	config.options.chkSearchAsYouType=true;
	config.options.chkSearchExtendedFields=true;
	config.options.chkSearchInTags=true;
	config.options.chkSearchInText=true;
	config.options.chkSearchInTitle=true;
	config.options.chkShowQuickEdit=true;
	config.options.chkSlidercalendar=false;
	config.options.chkStickyPopups=false;
	config.options.chkTextAreaExtensions=true;
	config.options.chkToggleLinks=false;
	config.options.chkUsePreForStorage=true;
	config.options.chkUseYourSearch=true;
	config.options.txtBackupFolder="Backup";
	config.options.txtCalFirstDay="0";
	config.options.txtCalStartOfWeekend="5";
	config.options.txtCookieJar="CookieJar";
	config.options.txtEditorFocus="text";
	config.options.txtFileSystemCharSet="UTF-8";
	config.options.txtFontSize="100";
	config.options.txtItemsPerPage="25";
	config.options.txtItemsPerPageWithPreview="10";
	config.options.txtMainTab="Tags";
	config.options.txtMaxEditRows="30";
	config.options.txtMoreTab="moreTabAll";
	config.options.txtNextTabKey="";
	config.options.txtPreviousTabKey="";
	config.options.txtPrivWizardDefaultStep="1";
	config.options.txtSelectedTiddlerTabButton="closeOthers";
	config.options.txtTheme="Skull5bTheme";
	config.options.txtTiddlerLinkTooltipDate="DDD, MMM DDth YYYY 0hh12:0mm AM";
	config.options.txtTiddlerLinkTootip="%0 - %1, %2 (%3 bytes) - %4";
	config.options.txtTweakerSortBy="modified";
	config.options.txtUserName="Mike";
	config.options.txtWeekNumberDisplayFormat="w0WW";
	config.options.txtWeekNumberLinkFormat="YYYY-w0WW";
}
//}}}

// 2 cookies saved on Tuesday, April 27th 2010 at 12:55:10 by Mike//
//^^(edit/remove username check and/or individual option settings as desired)^^//
//{{{
if (config.options.txtUserName=="Mike") {
	config.options.chkBackstage=true;
	config.options.txtMainTab="Tags";
}
//}}}

// 4 cookies saved on Tuesday, April 27th 2010 at 12:56:29 by Mike//
//^^(edit/remove username check and/or individual option settings as desired)^^//
//{{{
if (config.options.txtUserName=="Mike") {
	config.options.chkBackstage=true;
	config.options.chkMonitorBrowserCookies=true;
	config.options.chkSaveBackups=true;
	config.options.txtMainTab="Tags";
}
//}}}

// 4 cookies saved on Tuesday, April 27th 2010 at 12:56:51 by Mike//
//^^(edit/remove username check and/or individual option settings as desired)^^//
//{{{
if (config.options.txtUserName=="Mike") {
	config.options.chkBackstage=true;
	config.options.chkMonitorBrowserCookies=true;
	config.options.chkSaveBackups=true;
	config.options.txtMainTab="Tags";
}
//}}}

// 65 options saved on Tuesday, April 27th 2010 at 12:56:52 by Mike//
//^^(edit/remove username check and/or individual option settings as desired)^^//
//{{{
if (config.options.txtUserName=="Mike") {
	config.options.chkAllowBrowserCookies=true;
	config.options.chkAnimate=false;
	config.options.chkAutoSave=false;
	config.options.chkBackstage=true;
	config.options.chkCaseSensitiveSearch=false;
	config.options.chkConfirmDelete=true;
	config.options.chkCookieManagerAddToAdvancedOptions=true;
	config.options.chkDisableAutoSelect=true;
	config.options.chkDisableTabsBar=false;
	config.options.chkDisplayInstrumentation=false;
	config.options.chkDisplayWeekNumbers=false;
	config.options.chkExcludeEncryptedFromLists=false;
	config.options.chkExcludeEncryptedFromSearch=false;
	config.options.chkFloatingSlidersAnimate=false;
	config.options.chkForceMinorUpdate=false;
	config.options.chkGenerateAnRssFeed=false;
	config.options.chkHideMissingMacros=false;
	config.options.chkHideTabsBarWhenSingleTab=false;
	config.options.chkHttpReadOnly=false;
	config.options.chkImportReport=true;
	config.options.chkIncrementalSearch=true;
	config.options.chkInsertTabs=true;
	config.options.chkMonitorBrowserCookies=true;
	config.options.chkOpenInNewWindow=true;
	config.options.chkPreviewText=true;
	config.options.chkRandomTheme=true;
	config.options.chkRegExpSearch=false;
	config.options.chkResizeEditor=true;
	config.options.chkSaveBackups=true;
	config.options.chkSaveEmptyTemplate=false;
	config.options.chkSearchAsYouType=true;
	config.options.chkSearchExtendedFields=true;
	config.options.chkSearchInTags=true;
	config.options.chkSearchInText=true;
	config.options.chkSearchInTitle=true;
	config.options.chkShowQuickEdit=true;
	config.options.chkSlidercalendar=false;
	config.options.chkStickyPopups=false;
	config.options.chkTextAreaExtensions=true;
	config.options.chkToggleLinks=false;
	config.options.chkUsePreForStorage=true;
	config.options.chkUseYourSearch=true;
	config.options.txtBackupFolder="Backup";
	config.options.txtCalFirstDay="0";
	config.options.txtCalStartOfWeekend="5";
	config.options.txtCookieJar="CookieJar";
	config.options.txtEditorFocus="text";
	config.options.txtFileSystemCharSet="UTF-8";
	config.options.txtFontSize="100";
	config.options.txtItemsPerPage="25";
	config.options.txtItemsPerPageWithPreview="10";
	config.options.txtMainTab="Tags";
	config.options.txtMaxEditRows="30";
	config.options.txtMoreTab="moreTabAll";
	config.options.txtNextTabKey="";
	config.options.txtPreviousTabKey="";
	config.options.txtPrivWizardDefaultStep="1";
	config.options.txtSelectedTiddlerTabButton="closeOthers";
	config.options.txtTheme="Skull4Theme";
	config.options.txtTiddlerLinkTooltipDate="DDD, MMM DDth YYYY 0hh12:0mm AM";
	config.options.txtTiddlerLinkTootip="%0 - %1, %2 (%3 bytes) - %4";
	config.options.txtTweakerSortBy="modified";
	config.options.txtUserName="Mike";
	config.options.txtWeekNumberDisplayFormat="w0WW";
	config.options.txtWeekNumberLinkFormat="YYYY-w0WW";
}
//}}}
/***
|Name|CookieManagerPlugin|
|Source|http://www.TiddlyTools.com/#CookieManagerPlugin|
|Version|2.3.2|
|Author|Eric Shulman|
|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||
|Options|##Configuration|
|Description|view/add/delete browser-based cookies and "bake" cookies to CookieJar tiddler for 'sticky' settings|
!!!!!Usage
<<<
This plugin provides an interactive control panel that lets you select, view, modify, or delete any of the current values for TiddlyWiki options that have been stored as local, private, //browser cookies//.  You can also use the control panel to "bake cookies", which generates a set of javascript statements that assign hard-coded option values to the TiddlyWiki internal variables that correspond to the current browser cookie settings.  These hard-coded values are then stored in the [[CookieJar]] tiddler, which is tagged with<<tag systemConfig>> so that each time the document is loaded, the baked cookie settings will be automatically applied.

When a set of baked cookies is added to the [[CookieJar]], it is automatically surrounded by a conditional test so that the hard-coded settings will only be applied for the username that was in effect when they were initially generated.  In this way, if you publish or share your document with others, //your// particular baked cookie settings are not automatically applied to others, so that their own browser-based cookie settings (if defined) will be applied as usual.

Whenever you "bake cookies", new hard-coded javascript assignment statements are *appended* to the end of the [[CookieJar]].  However, any baked cookies that were previously generated and stored in the [[CookieJar]] are not automatically removed from the tiddler.  As a result, because the most recently baked cookie settings in the [[CookieJar]] are always the last to be processed, the values assigned by older baked cookies are immediately overridden by the values from the newest baked cookies, so that the newest values will be in effect when the CookieJar startup processing is completed.

Each time you bake a new batch of cookies, it is recommended that you should review and hand-edit the [[CookieJar]] to remove any "stale cookies" or merge the old and new sets of baked cookies into a single block to simplify readability (as well as saving a little tiddler storage space).  Of course, you can also hand-edit the [[CookieJar]] tiddler at any time simply to remove a few individual //baked cookies// if they are no longer needed, and you can even delete the entire [[CookieJar]] tiddler and start fresh, if that is appropriate.  Please note that changing or deleting a baked cookie does not alter the current value of the corresponding option setting, and any changes you make to the [[CookieJar]] will only be applied after you have saved and reloaded the document in your browser.
<<<
!!!!!Examples
<<<
{{{<<cookieManager>>}}}
{{smallform small center{
@@display:block;width:35em;<<cookieManager>>@@}}}
<<<
!!!!!Configuration
<<<
<<option chkAllowBrowserCookies>> store ~TiddlyWiki option settings using private browser cookies
<<option chkMonitorBrowserCookies>> monitor browser cookie activity (show a message whenever a cookie is set or deleted)
<<option chkCookieManagerAddToAdvancedOptions>> display [[CookieManager]] in [[AdvancedOptions]]
//note: this setting does not take effect until you reload the document//
<<<
!!!!!Revisions
<<<
2008.09.14 [2.3.2] fixed handling for blocked cookies (was still allowing some blocked cookies to be set)
2008.09.12 [2.3.1] added blocked[] array and allowBrowserCookie() test function for selective blocking of changes to browser cookies based on cookie name
2008.09.08 [2.3.0] extensive code cleanup: defined removeCookie(), renamed cookies, added 'button' param for stand-alone "bake cookies" button, improved init of shadow [[CookieManager]] and [[CookieJar]] tiddlers for compatibility with new [[CookieSaverPlugin]]. 
2008.07.11 [2.2.1] fixed recursion error in hijack for saveOptionCookie()
2008.06.26 [2.2.0] added chkCookieManagerNoNewCookies option
2008.06.05 [2.1.3] replaced hard-coded definition for "CookieJar" title with option variable
2008.05.12 [2.1.2] add "cookies" task to backstage (moved from BackstageTasks)
2008.04.09 [2.1.0] added options: chkCookieManagerAddToAdvancedOptions
2008.04.08 [2.0.1] automatically include CookieManager control panel in AdvancedOptions shadow tiddler
2007.08.02 [2.0.0] converted from inline script
2007.04.29 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.CookieManagerPlugin= {major: 2, minor: 3, revision: 1, date: new Date(2008,9,12)};
//}}}
//{{{
config.macros.cookieManager = {
	target:
		config.options.txtCookieJar||"CookieJar",
	blockedCookies:
		[],
	allowBrowserCookie: function(name) {
		return true;
	},
	displayStatus: function(msg) {
		if (config.options.chkMonitorBrowserCookies && !startingUp)
			displayMessage("CookieManager: "+msg);
	},
	init: function() {
		if (config.options.txtCookieJar===undefined)
			config.options.txtCookieJar=this.target;
		if (config.options.chkAllowBrowserCookies===undefined)
			config.options.chkAllowBrowserCookies=true;
		if (config.options.chkMonitorBrowserCookies===undefined)
			config.options.chkMonitorBrowserCookies=false;

		config.shadowTiddlers.CookieManager=
			 "/***\n"
			+"!!![[Browser cookies:|CookieManagerPlugin]] "
			+"{{fine{<<option chkAllowBrowserCookies>>enable <<option chkMonitorBrowserCookies>>monitor}}}\n"
			+"^^Review, modify, or delete browser cookies..."
			+"To block specific cookies, see [[CookieManagerPluginConfig]].^^\n"
			+"@@display:block;width:30em;{{smallform small{\n<<cookieManager>>}}}@@\n"
			+"***/\n";

		// add CookieManager to shadow CookieJar
		var h="/***\n<<tiddler CookieManager>>\n***/\n";
		var t=(config.shadowTiddlers[this.target]||"").replace(new RegExp(h.replace(/\*/g,'\\*'),''),'')
		config.shadowTiddlers[this.target]=h+t;

		if (config.options.chkCookieManagerAddToAdvancedOptions===undefined)
			config.options.chkCookieManagerAddToAdvancedOptions=true;
		if (config.options.chkCookieManagerAddToAdvancedOptions)
			config.shadowTiddlers.AdvancedOptions+="\n!!CookieManager\n><<tiddler CookieManager>>";

		// add "cookies" backstage task
		if (config.tasks && !config.tasks.cookies) { // for TW2.2b3 or above
			config.tasks.cookies = {
				text: "cookies",
				tooltip: "manage cookie-based option settings",
				content: "{{groupbox{<<tiddler CookieManager>><<tiddler [["+this.target+"]]>>}}}"
			}
			config.backstageTasks.push("cookies");
		}
	},
	handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		var span=createTiddlyElement(place,"span");
		span.innerHTML=(params[0]&&params[0].toLowerCase()=="button")?this.button:this.panel;
		this.setList(span.firstChild.list);
	},
	panel: '<form style="display:inline;margin:0;padding:0" onsubmit="return false"><!--\
		--><select style="width:99%" name="list" \
			onchange="this.form.val.value=this.value.length?config.options[this.value]:\'\';"><!--\
		--></select><br>\
		<input type="text" style="width:98%;margin:0;" name="val" title="enter an option value"><br>\
		<input type="button" style="width:33%;margin:0;" value="get" title="refresh list" \
			onclick="config.macros.cookieManager.setList(this.form.list);"><!--\
		--><input type="button" style="width:33%;margin:0;" value="set" title="save cookie value" \
			onclick="var cmc=config.macros.cookieManager;\
				var opt=this.form.list.value; var v=this.form.val.value; \
				var msg=opt+\' is a blocked cookie.  OK to proceed?\';\
				if ((!cmc.blockedCookies.contains(opt) && cmc.allowBrowserCookie(opt))||confirm(msg)) {\
					config.options[opt]=opt.substr(0,3)==\'txt\'?v:(v.toLowerCase()==\'true\'); \
					saveOptionCookie(opt);config.macros.cookieManager.setList(this.form.list);\
				}"><!--\
		--><input type="button" style="width:33%;margin:0;" value="del" title="remove cookie" \
			onclick="var cmc=config.macros.cookieManager; var opt=this.form.list.value; \
				var msg=opt+\' is a blocked cookie.  OK to proceed?\';\
				if ((!cmc.blockedCookies.contains(opt) && cmc.allowBrowserCookie(opt))||confirm(msg)) {\
					removeCookie(this.form.list.value,true); \
					cmc.setList(this.form.list);\
				}"><br>\
		<input type="button" style="width:50%;margin:0;" value="bake cookies" \
			title="save current cookie-based option values into a tiddler" \
			onclick="return config.macros.cookieManager.bake(this,false)"><!--\
		--><input type="button" style="width:50%;margin:0;" value="bake all options" \
			title="save ALL option values (including NON-COOKIE values) into a tiddler" \
			onclick="return config.macros.cookieManager.bake(this,true)"><!--\
		--></form>\
	',
	button: '<form style="display:inline;margin:0;padding:0" onsubmit="return false"><!--\
		--><input type="button" style="margin:0;" value="bake cookies" \
			title="save current browser-based cookie values into a tiddler" \
			onclick="return config.macros.cookieManager.bake(this,false)"><!--\
		--></form>\
	',
	getCookieList: function() {
		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 opt=new Array(); for (var i in config.options) if (cookies[i]) opt.push(i); opt.sort();
		return opt;
	},
	setList: function(list) {
		if (!list) return false;
		var opt=this.getCookieList();
		var sel=list.selectedIndex;
		while (list.options.length > 1) { list.options[1]=null; } // clear list (except for header item)
		list.options[0]=new Option("There are "+opt.length+" cookies...","",false,false);
		if (!opt.length) { list.form.val.value=""; return; } // no cookies
		var c=1;
		for(var i=0; i<opt.length; i++) {
			var txt="";
			if  (opt[i].substr(0,3)=="chk")
				txt+="["+(config.options[opt[i]]?"\u221A":"_")+"] ";
			txt+=opt[i];
			list.options[c++]=new Option(txt,opt[i],false,false);
		}
		list.selectedIndex=sel>0?sel:0;
		list.form.val.value=sel>0?config.options[list.options[sel].value]:"";
	},
	header:
		"/***\n"
		+"!!![[Baked cookies:|CookieManagerPlugin]]\n"
		+"^^Press {{smallform{<<cookieManager button>>}}} to save the current browser cookies... "
		+"then hand-edit this section to customize the results.^^\n"
		+"***/\n",
	format: function(name) {
		if (name.substr(0,3)=='chk')
			return '\tconfig.options.'+name+'='+(config.options[name]?'true;':'false;');
		return '\tconfig.options.'+name+'="'+config.options[name]+'";';
	},
	bake: function(here,all) {
		if (story.isDirty(this.target)) return false; // target is being hand-edited... do nothing
		var text=store.getTiddlerText(this.target);
		if (text.indexOf(this.header)==-1) {
			text+=this.header;
			displayMessage("CookieManager: added 'Baked Cookies' section to CookieJar");
		}
		var who=config.options.txtUserName;
		var when=new Date();
		var tags=['systemConfig'];
		var tid=store.getTiddler(this.target)||store.saveTiddler(this.target,this.target,text,who,when,tags,{});
		if (!tid) return false; // if no target... do nothing
		if (all) { 
			var opts=new Array();
			for (var i in config.options) if (i.substr(0,3)=='chk'||i.substr(0,3)=='txt') opts.push(i);
			opts.sort();
		}
		else var opts=this.getCookieList();
		var t=tid.text;
		if (t.indexOf(this.header)==-1) t+=this.header;
		t+='\n// '+opts.length+(all?' options':' cookies')+' saved ';
		t+=when.formatString('on DDD, MMM DDth YYYY at 0hh:0mm:0ss');
		t+=' by '+who+'//\n';
		t+='//^^(edit/remove username check and/or individual option settings as desired)^^//\n';
		t+='//{{{\n';
		t+='if (config.options.txtUserName=="'+who+'") {\n';
		for (i=0; i<opts.length; i++) t+=config.macros.cookieManager.format(opts[i])+"\n";
		t+='}\n//}}}\n';
		store.saveTiddler(this.target,this.target,t,who,when,tags,tid?tid.fields:{});
		story.displayTiddler(story.findContainingTiddler(this),this.target);
		story.refreshTiddler(this.target,null,true);
		var msg=opts.length+(all?' options':' cookies')+' have been saved in '+this.target+'.  ';
		msg+='Please review all stored settings.';
		displayMessage(msg);
		return false;
	}
}
//}}}
//{{{
// Hijack saveOptionCookie() to add cookie blocking and monitoring messages
config.macros.cookieManager.saveOptionCookie=saveOptionCookie;
window.saveOptionCookie=function(name,force)
{
	var cmc=config.macros.cookieManager; // abbrev
	if (force || ((config.options.chkAllowBrowserCookies || name=="chkAllowBrowserCookies")
		&& !cmc.blockedCookies.contains(name) && cmc.allowBrowserCookie(name))) {
		cmc.saveOptionCookie.apply(this,arguments);
		cmc.displayStatus(name+"="+config.options[name]);
	} else cmc.displayStatus("setting of '"+name+"' is blocked");
}

// if removeCookie() function is not defined by TW core, define it here.
if (window.removeCookie===undefined) {
	window.removeCookie=function(name) {
		document.cookie = name+'=; expires=Thu, 01-Jan-1970 00:00:01 UTC; path=/;'; 
	}
}

// ... and then hijack it to add cookie blocking and monitoring messages
config.macros.cookieManager.removeCookie=removeCookie;
window.removeCookie=function(name,force)
{
	var cmc=config.macros.cookieManager; // abbrev
	if (!cmc.getCookieList().contains(name))
		return; // not a current cookie!
	if (force || ((config.options.chkAllowBrowserCookies || name=="chkAllowBrowserCookies")
		&& !cmc.blockedCookies.contains(name) && cmc.allowBrowserCookie(name))) {
		cmc.removeCookie.apply(this,arguments);
		cmc.displayStatus("deleted "+name);
	} else cmc.displayStatus("deletion of '"+name+"' is blocked");
}
//}}}
/***
|Name|CoreTweaks|
|Source|http://www.TiddlyTools.com/#CoreTweaks|
|Version||
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.2.0|
|Type|plugin|
|Description|a small collection of overrides to TW core functions|
This tiddler contains small changes to TW core functions that correct or enhance standard features or behaviors.
***/
//{{{
// calculate TW version number - used to determine which tweaks should be applied
var ver=version.major+version.minor/10+version.revision/100;
//}}}
/***
----

***/
// // open tickets:
// // {{block{
/***
!!!1151 adjust popup placement when root element is in scrolled DIV
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/1151
When a popup link is placed inside a DIV with style "overflow:scroll" or "overflow:auto" and that DIV is then scrolled, the position of the resulting popup appears further down the page that intended, because it is not adjusting for the relative scroll offset of the containing DIV.  This tweak patches the Popup.place() function to calculate and subtract the current scroll offset from the computed popup position, so that it appears in the correct location on the page.

Test case: //(scroll to the bottom of this DIV and click on "test popup")//
{{groupbox{
 <<tiddler ScrollBox with: CoreTweaks##1151test 12em>>}}}/%
!1151test
<<tiddler About>>
<<tiddler ShowPopup with: About "test popup" About button auto sticky>>
!end
%/
***/
//{{{
window.findScrollOffsetX=function(obj) {
	var x=0;
	while(obj) {
		if (obj.scrollLeft && obj.nodeName!='HTML')
			x+=obj.scrollLeft;
		obj=obj.parentNode;
	}
	return -x;
}

window.findScrollOffsetY=function(obj) {
	var y=0;
	while(obj) {
		if (obj.scrollTop && obj.nodeName!='HTML')
			y+=obj.scrollTop;
		obj=obj.parentNode;
	}
	return -y;
}

var fn=Popup.place.toString();
if (fn.indexOf('findScrollOffsetX')==-1) { // only once
	fn=fn.replace(/var\s*rootLeft\s*=/,'var rootLeft = window.findScrollOffsetX(root) +');
	fn=fn.replace(/var\s*rootTop\s*=/,'var rootTop = window.findScrollOffsetY(root) +');
	eval('Popup.place='+fn);
}
//}}}
// // }}}}}}// // {{block{
/***
!!!1147 tiddler macro with params does not refresh
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/1147
when the {{{<<tiddler SomeTiddler>>}}} macro is handled, the resulting span has extra attributes: {{{refresh='content'}}} and {{{tiddler='SomeTiddler'}}}.  If SomeTiddler is changed, {{{store.notify('SomeTiddler')}}} triggers {{{refreshDisplay()}}}, which automatically re-renders transcluded content in any span that has these extra attributes.  However, when additional arguments are passed by using {{{<<tiddler SomeTiddler with: arg arg arg ...>>}}} then the resulting span does NOT get the extra attributes noted above and, as a consequence, the transcluded content is not being refreshed, even though the underlying tiddler has changed

To correct this, in {{{config.macros.tiddler.handler}}}:
*set the 'refresh' and 'tiddler' attributes even when arguments are present in the macro
*store the arguments themselves in an attribute (e.g, 'args'), using as a space-separated, bracketed list
Then, in {{{config.refreshers.content}}}:
*retrieve the stored arguments (if any) and the tiddler source
*substitute arguments into source and re-render the span with the updated content

***/
//{{{
config.refreshers.content=function(e,changeList) {
		var title = e.getAttribute("tiddler");
		var force = e.getAttribute("force");
		var args = e.getAttribute("args"); // ADDED
		if(force != null || changeList == null || changeList.indexOf(title) != -1) {
			removeChildren(e);
//			wikify(store.getTiddlerText(title,""),e,null,store.fetchTiddler(title)); // REMOVED
			config.macros.tiddler.transclude(e,title,args); // ADDED
			return true;
		} else
			return false;
};

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] || null;
	var args = params[0]["with"];
	var wrapper = createTiddlyElement(place,"span",null,className);
//	if(!args) { // REMOVED
		wrapper.setAttribute("refresh","content");
		wrapper.setAttribute("tiddler",tiddlerName);
// 	} // REMOVED
	if(args!==undefined) wrapper.setAttribute("args",'[['+args.join(']] [[')+']]'); // ADDED
	this.transclude(wrapper,tiddlerName,args); // REFACTORED TO ...tiddler.transclude
}

// REFACTORED FROM ...tiddler.handler
config.macros.tiddler.transclude=function(wrapper,tiddlerName,args) {
	var text = store.getTiddlerText(tiddlerName); if (!text) return;
	var stack = config.macros.tiddler.tiddlerStack;
	if(stack.indexOf(tiddlerName) !== -1) return;
	stack.push(tiddlerName);
	try {
		if (typeof args == "string") args=args.readBracketedList(); // ADDED
		var n = args ? Math.min(args.length,9) : 0;
		for(var i=0; i<n; i++) {
			var placeholderRE = new RegExp("\\$" + (i + 1),"mg");
			text = text.replace(placeholderRE,args[i]);
		}
		config.macros.tiddler.renderText(wrapper,text,tiddlerName,null); // REMOVED UNUSED 'params'
	} finally {
		stack.pop();
	}
};
//}}}
// // }}}}}}// // {{block{
/***
!!!1134 allow leading whitespace in section headings / TBD handle shadow tiddler sections
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/1134
This tweak REPLACES and extends {{{store.getTiddlerText()}}} so it can return sections defined in shadow tiddlers as well as permitting use of leading whitespace in section headings.
***/
//{{{
TiddlyWiki.prototype.getTiddlerText = function(title,defaultText)
{
	if(!title) return defaultText;
	var parts = title.split(config.textPrimitives.sectionSeparator);
	var title = parts[0];
	var section = parts[1];
	var parts = title.split(config.textPrimitives.sliceSeparator);
	var title = parts[0];
	var slice = parts[1]?this.getTiddlerSlice(title,parts[1]):null;
	if(slice) return slice;
	var tiddler = this.fetchTiddler(title);
	var text = defaultText;
	if(this.isShadowTiddler(title))
		text = this.getShadowTiddlerText(title);
	if(tiddler)
		text = tiddler.text;
	if(!section) return text;
	var re = new RegExp("(^!{1,6}[ \t]*" + section.escapeRegExp() + "[ \t]*\n)","mg");
	re.lastIndex = 0;
	var match = re.exec(text);
	if(match) {
		var t = text.substr(match.index+match[1].length);
		var re2 = /^!/mg;
		re2.lastIndex = 0;
		match = re2.exec(t); //# search for the next heading
		if(match)
			t = t.substr(0,match.index-1);//# don't include final \n
		return t;
	}
	return defaultText;
};
//}}}
// // }}}}}}// // {{block{
/***
!!!890 add conditional test to """<<tiddler>>""" macro
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/890 - OPEN
This tweak extends the {{{<<tiddler>>}}} macro syntax so you can include a javascript-based //test expression// to determine if the tiddler transclusion should be performed:
{{{
<<tiddler TiddlerName if:{{...}} with: param param etc.>>
}}}
If the test is ''true'', then the tiddler is transcluded as usual.  If the test is ''false'', then the transclusion is skipped and //no output is produced//.
***/
//{{{
config.macros.tiddler.if_handler = config.macros.tiddler.handler;
config.macros.tiddler.handler = function(place,macroName,params,wikifier,paramString,tiddler)
{
	params = paramString.parseParams('name',null,true,false,true);
	if (!getParam(params,'if',true)) return;
	this.if_handler.apply(this,arguments);
};
//}}}
// // }}}}}}// // {{block{
/***
!!!831 backslash-quoting for embedding newlines in 'line-mode' formats
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/831 - OPEN
This tweak pre-processes source content to convert 'double-backslash-newline' into {{{<br>}}} before wikify(), so that literal newlines can be embedded in line-mode wiki syntax (e.g., tables, bullets, etc.)
***/
//{{{
window.coreWikify = wikify;
window.wikify = function(source,output,highlightRegExp,tiddler)
{
	if (source) arguments[0]=source.replace(/\\\\\n/mg,'<br>');
	coreWikify.apply(this,arguments);
}
//}}}
// // }}}}}}// // {{block{
/***
!!!824 ~WindowTitle - alternative to combined ~SiteTitle/~SiteSubtitle in window titlebar
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/824 - OPEN
This tweak allows definition of an optional [[WindowTitle]] tiddler that, when present, provides alternative text for display in the browser window's titlebar, instead of using the combined text content from [[SiteTitle]] and [[SiteSubtitle]] (which will still be displayed as usual in the TiddlyWiki document header area).

Note: this ticket replaces http://trac.tiddlywiki.org/ticket/401 (closed), which proposed using a custom [[PageTitle]] tiddler for this purpose.  ''If you were using the previous '401 ~PageTitle' tweak, you will need to rename [[PageTitle]] to [[WindowTitle]] to continue to use your custom window title text''
***/
//{{{
config.shadowTiddlers.WindowTitle='<<tiddler SiteTitle>> - <<tiddler SiteSubtitle>>';
window.getPageTitle=function() { return wikifyPlain('WindowTitle'); }
store.addNotification('WindowTitle',refreshPageTitle); // so title stays in sync with tiddler changes
//}}}
// // }}}}}}// // {{block{
/***
!!!683 FireFox3 Import bug: 'browse' button replacement
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/683 - OPEN
The web standard 'type=file' input control that has been used as a local path/file picker for TiddlyWiki no longer works as expected in FireFox3, which has, for security reasons, limited javascript access to this control so that *no* local filesystem path information can be revealed, even when it is intentional and necessary, as it is with TiddlyWiki.  This tweak provides alternative HTML source that patches the backstage import panel.  It replaces the 'type=file' input control with a text+button combination of controls that invokes a system-native secure 'file-chooser' dialog box to provide TiddlyWiki with access to a complete path+filename so that TW functions properly locate user-selected local files.
>Note: ''This tweak also requires http://trac.tiddlywiki.org/ticket/604 - cross-platform askForFilename()''
***/
//{{{
if (window.Components) {
	var fixhtml='<input name="txtBrowse" style="width:30em"><input type="button" value="..."'
		+' onClick="window.browseForFilename(this.previousSibling,true)">';
	var cmi=config.macros.importTiddlers;
	cmi.step1Html=cmi.step1Html.replace(/<input type='file' size=50 name='txtBrowse'>/,fixhtml);
}

merge(config.messages,{selectFile:'Please enter or select a file'}); // ready for I18N translation

window.browseForFilename=function(target,mustExist) { // note: both params are optional
	var msg=config.messages.selectFile;
	if (target && target.title) msg=target.title; // use target field tooltip (if any) as dialog prompt text
	// get local path for current document
	var path=getLocalPath(document.location.href);
	var p=path.lastIndexOf('/'); if (p==-1) p=path.lastIndexOf('\\'); // Unix or Windows
	if (p!=-1) path=path.substr(0,p+1); // remove filename, leave trailing slash
	var file=''
	var result=window.askForFilename(msg,path,file,mustExist); // requires #604
	if (target && result.length) // set target field and trigger handling
		{ target.value=result; target.onchange(); }
	return result; 
}
//}}}
// // }}}}}}// // {{block{
/***
!!!604 cross-platform askForFilename()
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/604 - OPEN
invokes a system-native secure 'file-chooser' dialog box to provide TiddlyWiki with access to a complete path+filename so that TW functions properly locate user-selected local files.
***/
//{{{
window.askForFilename=function(msg,path,file,mustExist) {
	var r = window.mozAskForFilename(msg,path,file,mustExist);
	if(r===null || r===false)
		r = window.ieAskForFilename(msg,path,file,mustExist);
	if(r===null || r===false)
		r = window.javaAskForFilename(msg,path,file,mustExist);
	if(r===null || r===false)
		r = prompt(msg,path+file);
	return r||'';
}

window.mozAskForFilename=function(msg,path,file,mustExist) {
	if(!window.Components) return false;
	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, mustExist?nsIFilePicker.modeOpen: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(ex) { displayMessage(ex.toString()); }
	return result;
}

window.ieAskForFilename=function(msg,path,file,mustExist) {
	if(!config.browser.isIE) return false;
	try {
		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;
		return s.showOpen()?s.FileName:'';
	}
	catch(ex) { displayMessage(ex.toString()); }
	return result;
}

window.javaAskForFilename=function(msg,path,file,mustExist) {
	if(!document.applets['TiddlySaver']) return false;
	// TBD: implement java-based askFile(...) function
	try { return document.applets['TiddlySaver'].askFile(msg,path,file,mustExist); } 
	catch(ex) { displayMessage(ex.toString()); }
}
//}}}
// // }}}}}}// // {{block{
/***
!!!657 wrap tabs onto multiple lines
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/657 - OPEN
This tweak inserts an extra space element following each tab, allowing them to wrap onto multiple lines if needed.
***/
//{{{
config.macros.tabs.handler = function(place,macroName,params)
{
	var cookie = params[0];
	var numTabs = (params.length-1)/3;
	var wrapper = createTiddlyElement(null,'div',null,'tabsetWrapper ' + cookie);
	var tabset = createTiddlyElement(wrapper,'div',null,'tabset');
	tabset.setAttribute('cookie',cookie);
	var validTab = false;
	for(var t=0; t<numTabs; t++) {
		var label = params[t*3+1];
		var prompt = params[t*3+2];
		var content = params[t*3+3];
		var tab = createTiddlyButton(tabset,label,prompt,this.onClickTab,'tab tabUnselected');
		createTiddlyElement(tab,'span',null,null,' ',{style:'font-size:0pt;line-height:0px'}); // ELS
		tab.setAttribute('tab',label);
		tab.setAttribute('content',content);
		tab.title = prompt;
		if(config.options[cookie] == label)
			validTab = true;
	}
	if(!validTab)
		config.options[cookie] = params[1];
	place.appendChild(wrapper);
	this.switchTab(tabset,config.options[cookie]);
};
//}}}
// // }}}}}}// // {{block{
/***
!!!628 hide 'no such macro' errors
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/628 - OPEN
When invoking a macro that is not defined, this tweak prevents the display of the 'error in macro... no such macro' message.  This is useful when rendering tiddler content or templates that reference macros that are defined by //optional// plugins that have not been installed in the current document.

<<option chkHideMissingMacros>> hide 'no such macro' error messages
***/
//{{{
if (config.options.chkHideMissingMacros===undefined)
	config.options.chkHideMissingMacros=false;

window.coreTweaks_missingMacro_invokeMacro = window.invokeMacro;
window.invokeMacro = function(place,macro,params,wikifier,tiddler) {
	if (!config.macros[macro] || !config.macros[macro].handler)
		if (config.options.chkHideMissingMacros) return;
	window.coreTweaks_missingMacro_invokeMacro.apply(this,arguments);
}
//}}}
// // }}}}}}// // {{block{
/***
!!!608/609/610 toolbars - toggles, separators and transclusion
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/608 - OPEN (more/less toggle)
http://trac.tiddlywiki.org/ticket/609 - OPEN (separators)
http://trac.tiddlywiki.org/ticket/610 - OPEN (wikify tiddler/slice/section content)

This combination tweak extends the """<<toolbar>>""" macro to add use of '<' to insert a 'less' menu command (the opposite of '>' == 'more'), as well as use of '*' to insert linebreaks and "!" to insert a vertical line separator between toolbar items.  In addition, this tweak add the ability to use references to tiddlernames, slices, or sections and render their content inline within the toolbar, allowing easy creation of new toolbar commands using TW content (such as macros, links, inline scripts, etc.)

To produce a one-line style, with "less" at the end, use
| ViewToolbar| foo bar baz > yabba dabba doo < |
or to use a two-line style with more/less toggle:
| ViewToolbar| foo bar baz > < * yabba dabba doo |
***/
//{{{
merge(config.macros.toolbar,{
	moreLabel: 'more\u25BC',
	morePrompt: 'Show additional commands',
	lessLabel: '\u25C4less',
	lessPrompt: 'Hide additional commands',
	separator: '|'
});
config.macros.toolbar.onClickMore = function(ev) {
	var e = this.nextSibling;
	e.style.display = 'inline'; // show menu
	this.style.display = 'none'; // hide button
	return false;
};
config.macros.toolbar.onClickLess = function(ev) {
	var e = this.parentNode;
	var m = e.previousSibling;
	e.style.display = 'none'; // hide menu
	m.style.display = 'inline'; // show button
	return false;
};
config.macros.toolbar.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
	for(var t=0; t<params.length; t++) {
		var c = params[t];
		switch(c) {
			case '!':  // ELS - SEPARATOR (added)
				createTiddlyText(place,this.separator);
				break;
			case '*':  // ELS - LINEBREAK (added)
				createTiddlyElement(place,'BR');
				break;
			case '<': // ELS - LESS COMMAND (added)
				var btn = createTiddlyButton(place,
					this.lessLabel,this.lessPrompt,config.macros.toolbar.onClickLess,'moreCommand');
				break;
			case '>':
				var btn = createTiddlyButton(place,
					this.moreLabel,this.morePrompt,config.macros.toolbar.onClickMore,'moreCommand');
				var e = createTiddlyElement(place,'span',null,'moreCommand');
				e.style.display = 'none';
				place = e;
				break;
			default:
				var theClass = '';
				switch(c.substr(0,1)) {
					case '+':
						theClass = 'defaultCommand';
						c = c.substr(1);
						break;
					case '-':
						theClass = 'cancelCommand';
						c = c.substr(1);
						break;
				}
				if(c in config.commands)

					this.createCommand(place,c,tiddler,theClass);
				else { // ELS - WIKIFY TIDDLER/SLICE/SECTION (added)
					if (c.substr(0,1)=='~') c=c.substr(1); // ignore leading ~
					var txt=store.getTiddlerText(c);
					if (txt) {
						// trim any leading/trailing newlines
						txt=txt.replace(/^\n*/,'').replace(/\n*$/,'');
						// trim PRE format wrapper if any
						txt=txt.replace(/^\{\{\{\n/,'').replace(/\n\}\}\}$/,'');
						// render content into toolbar
						wikify(txt,createTiddlyElement(place,'span'),null,tiddler);
					}
				} // ELS - end WIKIFY CONTENT
				break;
		}
	}
};
//}}}
// // }}}}}}// // {{block{
/***
!!!529 IE fixup - case-sensitive element lookup of tiddler elements
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/529 - OPEN
This tweak hijacks the standard browser function, document.getElementById(), to work-around the case-INsensitivity error in Internet Explorer (all versions up to and including IE7) //''Note: This tweak is only applied when using IE, and only for lookups of rendered tiddler elements within the containing 'tiddlerDisplay' element.''//
***/
//{{{
if (config.browser.isIE) {
document.coreTweaks_coreGetElementById=document.getElementById;
document.getElementById=function(id) {
	var e=document.coreTweaks_coreGetElementById(id);
	if (!e || !e.parentNode || e.parentNode.id!='tiddlerDisplay') return e;
	for (var i=0; i<e.parentNode.childNodes.length; i++)
		if (id==e.parentNode.childNodes[i].id) return e.parentNode.childNodes[i];
	return null;
};
}
//}}}
// // }}}}}}// // {{block{
/***
!!!471 'creator' field for new tiddlers
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/471 - OPEN
This tweak HIJACKS the core's saveTiddler() function to automatically add a 'creator' field to a tiddler when it is FIRST created. You can use """<<view creator>>""" (or """<<view creator wikified>>""" if you prefer) to show this value embedded directly within the tiddler content, or {{{<span macro="view creator"></span>}}} in the ViewTemplate and/or EditTemplate to display the creator value in each tiddler.  
***/
//{{{
// hijack saveTiddler()
TiddlyWiki.prototype.CoreTweaks_creatorSaveTiddler=TiddlyWiki.prototype.saveTiddler;
TiddlyWiki.prototype.saveTiddler=function(title,newTitle,newBody,modifier,modified,tags,fields)
{
	var existing=store.tiddlerExists(title);
	var tiddler=this.CoreTweaks_creatorSaveTiddler.apply(this,arguments);
	if (!existing) store.setValue(title,'creator',config.options.txtUserName);
	return tiddler;
}
//}}}
// // }}}}}}
// // closed: won't fix //(leave as core tweaks)//
// // {{block{
/***
!!!637 TiddlyLink tooltip - custom formatting
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/637 - CLOSED: WON'T FIX
This tweak modifies the tooltip format that appears when you mouseover a link to a tiddler.  It adds an option to control the date format, as well as displaying the size of the tiddler (in bytes)

Tiddler link tooltip format:
{{stretch{<<option txtTiddlerLinkTootip>>}}}
^^where: %0=title, %1=username, %2=modification date, %3=size in bytes, %4=description slice^^
Tiddler link tooltip date format:
{{stretch{<<option txtTiddlerLinkTooltipDate>>}}}
***/
//{{{
config.messages.tiddlerLinkTooltip='%0 - %1, %2 (%3 bytes) - %4';
config.messages.tiddlerLinkTooltipDate='DDD, MMM DDth YYYY 0hh12:0mm AM';

config.options.txtTiddlerLinkTootip=
	config.options.txtTiddlerLinkTootip||config.messages.tiddlerLinkTooltip;
config.options.txtTiddlerLinkTooltipDate=
	config.options.txtTiddlerLinkTooltipDate||config.messages.tiddlerLinkTooltipDate;

Tiddler.prototype.getSubtitle = function() {
	var modifier = this.modifier;
	if(!modifier) modifier = config.messages.subtitleUnknown;
	var modified = this.modified;
	if(modified) modified = modified.formatString(config.options.txtTiddlerLinkTooltipDate);
	else modified = config.messages.subtitleUnknown;
	var descr=store.getTiddlerSlice(this.title,'Description')||'';
	return config.options.txtTiddlerLinkTootip.format([this.title,modifier,modified,this.text.length,descr]);
};
//}}}
// // }}}}}}// // {{block{
/***
!!!607 add HREF link on permaview command
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/607 - CLOSED: WON'T FIX
This tweak automatically sets the HREF for the 'permaview' sidebar command link so you can use the 'right click' context menu for faster, easier bookmarking.  Note that this does ''not'' automatically set the permaview in the browser's current location URL... it just sets the HREF on the command link.  You still have to click the link to apply the permaview.
***/
//{{{
config.macros.permaview.handler = function(place)
{
	var btn=createTiddlyButton(place,this.label,this.prompt,this.onClick);
	addEvent(btn,'mouseover',this.setHREF);
	addEvent(btn,'focus',this.setHREF);
};
config.macros.permaview.setHREF = function(event){
	var links = [];
	story.forEachTiddler(function(title,element) {
		links.push(String.encodeTiddlyLink(title));
	});
	var newURL=document.location.href;
	var hashPos=newURL.indexOf('#');
	if (hashPos!=-1) newURL=newURL.substr(0,hashPos);
	this.href=newURL+'#'+encodeURIComponent(links.join(' '));
}
//}}}
// // }}}}}}// // {{block{
/***
!!!458 add permalink-like HREFs on internal TiddlyLinks
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/458 - CLOSED: WON'T FIX
This tweak assigns a permalink-like HREF to internal Tiddler links (which normally do not have any HREF defined).  This permits the link's context menu (right-click) to include 'open link in another window/tab' command.  Based on a request from Dustin Spicuzza.
***/
//{{{
window.coreTweaks_createTiddlyLink=window.createTiddlyLink;
window.createTiddlyLink=function(place,title,includeText,theClass,isStatic,linkedFromTiddler,noToggle)
{
	// create the core button, then add the HREF (to internal links only)
	var link=window.coreTweaks_createTiddlyLink.apply(this,arguments);
	if (!isStatic)
		link.href=document.location.href.split('#')[0]+'#'+encodeURIComponent(String.encodeTiddlyLink(title));
	return link;
}
//}}}
// // }}}}}}
// // fixed in ~TW2.4.3
// // {{block{
/***
!!!444 'tiddler' and 'place' - global variables for use in computed macro parameters
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/444 - CLOSED:FIXED - TW2.4.3 - http://trac.tiddlywiki.org/changeset/8367
When invoking a macro, this tweak makes the current containing tiddler object and DOM rendering location available as global variables (window.tiddler and window.place, respectively).  These globals can then be used within //computed macro parameters// to retrieve tiddler-relative and/or DOM-relative values or perform tiddler-specific side-effect functionality.
***/
//{{{
if (ver<2.43) {
window.coreTweaks_invokeMacro = window.invokeMacro;
window.invokeMacro = function(place,macro,params,wikifier,tiddler) {
	var here=story.findContainingTiddler(place);
	window.tiddler=here?store.getTiddler(here.getAttribute('tiddler')):tiddler;
	window.place=place;
	window.coreTweaks_invokeMacro.apply(this,arguments);
}
}
//}}}
// // }}}}}}
// // fixed in ~TW2.4.2:
// // {{block{
/***
!!!823 apply option values via paramifiers (e.g. #chk...and #txt...)
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/823 - CLOSED:FIXED - TW2.4.2 http://trac.tiddlywiki.org/changeset/7988
This tweak extends and ''//replaces//'' the core {{{invokeParamifier()}}} function to support use of ''option paramifiers'' that set TiddlyWiki option values on-the-fly, directly from a document URL.

If a paramifier begins with 'chk' (checkbox) or 'txt' (text field), it's value will be automatically stored in {{{config.options.*}}}, adding to or overriding any existing 'chk' or 'txt' option values that may have already been loaded from browser cookies and/or assigned by the TW core or plugin initialization functions using hard-coded default values.  Note: option values that have been overriden by paramifiers are only applied during the current document session, and are not //automatically// retained.  However, if you edit an overridden option value during that session, then the modified value is, of course, saved in a browser cookie, as usual.
***/
//{{{
if (ver<2.42) {
function invokeParamifier(params,handler)
{
	if(!params || params.length == undefined || params.length <= 1)
		return;
	for(var t=1; t<params.length; t++) {
		var p = config.paramifiers[params[t].name];
		if(p && p[handler] instanceof Function)
			p[handler](params[t].value);
		else { // not a paramifier with handler()... check for an 'option' prefix
			var h=config.optionHandlers[params[t].name.substr(0,3)];
			if (h && h.set instanceof Function)
				h.set(params[t].name,params[t].value);
		}
	}
}
}
//}}}
// // }}}}}}
// // <<foldHeadings>>
<!--{{{-->
<!-- Last Revision 11.21.08 -->
<!--- moved toolbar to ToolbarCommands MTP 10.23.08 --->
<div class='toolbar' macro='toolbar [[ToolbarCommands::EditToolbar]]'></div>
<div class="title" macro="view title"></div>
<div class="editLabel">Title</div><div class="editor" macro="edit title"></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>
<div macro='tiddler QuickEditToolbar'></div>
<div class="editor" macro="edit text"></div>
<div macro="showWhenTagged palette">[[ColorPaletteColors]]</div>
<span macro='resizeEditor'></span>
<span macro='setUserName'></span>
<!--}}}-->
<!--{{{-->
<!-- Last Revision 11.20.08 -->
<!-- Modified for Quote & Footer div change PageTemplate link to use new template -->
<div class='header' macro='gradient vert  [[ColorPalette::HeaderTop]] [[ColorPalette::HeaderMid]] [[ColorPalette::HeaderBottom]] '>
	<div class='headerNow'>
		<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 class='hD' id='hD' refresh='content' tiddler='contentHeader'></div>
<div id='tiddlersBar' refresh='none' ondblclick='config.macros.tiddlersBar.onTiddlersBarAction(event)'></div>
	<div id='messageArea'></div>
	<div id='tiddlerDisplay'></div>
	<div class='fD' id='fD' refresh='content' tiddler='contentFooter'></div>
</div>
<!--}}}-->
/***
Last Revision 01.28.09
***/

[[StyleSheetShortcuts]]
[[PluginStyles]]

/*Experimental Style*/
/*{{{*/
/* Top Menu External link to look like internal link */
#topMenu .externalLink {
	font-weight:bold;text-decoration:none
} 
/* auto tiddler expansion expand tiddler to fit contents if needed */
.tiddler {overflow: auto;}
/* Forced header Height for use with a LOGO */
/* .header {height: 110px;} */
/* .popup {max-height:275px; min-height:auto; width: auto; overflow: auto; margin:auto; } */
/*}}}*/

/*Title & Menu Shadows ~FF3.1*/
/*{{{*/
.siteSubtitle {text-shadow: 0px 0px 1px #fff, 0px 0px 2px #fff, 0px 0px 3px #fff}
.siteTitle {text-shadow: 2px 0px 4px #fff, 0px 2px 4px #fff }
#topMenu {text-shadow: -1px -1px 0px #fff;}
/*}}}*/

/*Rounded Corners Style*/
/*{{{*/
.tiddler, .viewer {
	-moz-border-radius: 2em;
}
.toolbar .button, .toolbar a, #messageArea, .tagging, .tagged, .tabContents, #sidebarOptions .sliderPanel {
	-moz-border-radius: 1em;
}
#sidebarTabs .tab, .tabSelected, .tabUnselected {
	-moz-border-radius-topleft:.5em;
	-moz-border-radius-topright:.5em;
}
/*}}}*/

/*Center Header & topMenu*/
/*{{{*/
.header, .headerNow {
	text-align: center;
	color: [[ColorPalette::PrimaryMid]];
	font-family: times, serif;
	padding:.5em;
}
#topMenu 	{
	text-align: center;
}
/*}}}*/

/*a contrasting background so I can see where one tiddler ends and the other begins*/
/*{{{*/
body {
	background: [[ColorPalette::TertiaryLight]];
}
/*}}}*/

/* prefer monospace for editing */
/*{{{*/
.editor textarea {
	font-family: 'Consolas' monospace;
}
/*}}}*/

/* sexy tiddler titles */
/*{{{*/
.title {
	font-size: 250%;
	color: [[ColorPalette::PrimaryLight]];
	font-family: times, 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-bottom: 1em;
	padding-top: 0.75em;
}
/*}}}*/

/* 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 {
	float:right;
	display:inline;
	padding-bottom:0;
	visibility:hidden;
}
.selected .toolbar {
	visibility:visible;
}
/*}}}*/

/* for Tagger Plugin, thanks sb56637 */
/*{{{*/
.popup li a {
	display:inline;
}
/*}}}*/

/* makes theme selector look a little better */
/*{{{*/
#sidebarOptions .sliderPanel .select .button {
	padding:0.5em;
	display:block;
	font-size:8pt;
	
}
#sidebarOptions .sliderPanel .select br {
	display:none;
	font-size:8pt;
}
/*}}}*/
|''Name''|CustomTheme|
|''Description''|Custom Theme Spawned from MPTW by MTP 11.08.08|
|''Last Revision''|MTP 11.20.08|

!Author Mode
|PageTemplate|CustomPageTemplate|
|ViewTemplate|CustomViewTemplate|
|EditTemplate|CustomEditTemplate|
|StyleSheet|CustomStyleSheet|
|ColorPalette|ColorPalette|

!Read-Only Mode
|PageTemplateReadOnly|PageTemplate|
|ViewTemplateReadOnly|ViewTemplate|
|EditTemplateReadOnly|EditTemplate|
|StyleSheetReadOnly|##StyleSheet|
|ColorPalette|ColorPalette|

!StyleSheet
/*{{{*/
#sidebarTabs {javascript:;
	display: none;
}
/*}}}*/
<!--{{{-->
<!-- Last Revision 12.18.08 -->
<!--- moved toolbar to ToolbarCommands MTP 10.23.08 --->
<!--- added code for paletteView & viewPalette --->
<!--- Created & Modified Date "pppp" requires PrettyDatePlugin --->

<div class='toolbar' macro='toolbar [[ToolbarCommands::ViewToolbar]]'></div>

<div class="tagglyTagged" macro="tags"></div>

<span class='titleContainer'>
	<span class='title' macro='view title'></span>
	<span macro="miniTag"></span>
</span>

<span class='subtitle'><br>
	<span macro='view modified date "modified pppp"'></span>
	(<span macro='message views.wikified.createdPrompt'></span>
	<span macro='view created date "0MM.0DD.YY"'></span>)
</span>

<div macro="showWhenTaggedAll palette view" style='overflow: auto;'>
<span style="width:45%; float:left; padding:1em; 0 0 0.5em;"><span macro="paletteView"></span></span>
<span style="width:45%; float:right; padding:5em 1.5em 0 0;"><span macro="viewPalette"></span></span>
</div>

<div macro="else">
	<div class='viewer' macro='view text wikified'></div>
</div>
<br>
<div class="tagglyTagging" macro="tagglyTagging"></div>
<!--}}}-->
/***
|Name|DatePlugin|
|Source|http://www.TiddlyTools.com/#DatePlugin|
|Documentation|http://www.TiddlyTools.com/#DatePluginInfo|
|Version|2.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|formatted dates plus popup menu with 'journal' link, changes and (optional) reminders|
There are quite a few calendar generators, reminders, to-do lists, 'dated tiddlers' journals, blog-makers and GTD-like schedule managers that have been built around TW.  While they all have different purposes, and vary in format, interaction, and style, in one way or another each of these plugins displays and/or uses date-based information to make finding, accessing and managing relevant tiddlers easier.  This plugin provides a general approach to embedding dates and date-based links/menus within tiddler content.
!!!!!Documentation
>see [[DatePluginInfo]]
!!!!!Configuration
>see [[DatePluginConfig]]
!!!!!Revisions
<<<
2008.03.08 [2.7.0] in addModifiedsToPopup(), if a tiddler was created on the specified date, don't list it in the 'changed' section of the popup.  Based on a request from Kashgarinn.
|please see [[DatePluginInfo]] for additional revision details|
2005.10.30 [0.9.0] pre-release
<<<
!!!!!Code
***/
//{{{
version.extensions.date = {major: 2, minor: 7, revision: 0, date: new Date(2008,3,8)};

config.macros.date = {
	format: "YYYY.0MM.0DD", // default date display format
	linkformat: "YYYY.0MM.0DD", // 'dated tiddler' link format
	linkedbg: "#babb1e", // "babble"
	todaybg: "#ffab1e", // "fable"
	weekendbg: "#c0c0c0", // "cocoa"
	holidaybg: "#ffaace", // "face"
	createdbg: "#bbeeff", // "beef"
	modifiedsbg: "#bbeeff", // "beef"
	remindersbg: "#c0ffee", // "coffee"
	holidays: [ "01/01", "07/04", "07/24", "11/24" ], // NewYearsDay, IndependenceDay(US), Eric's Birthday (hooray!), Thanksgiving(US)
	weekend: [ 1,0,0,0,0,0,1 ] // [ day index values: sun=0, mon=1, tue=2, wed=3, thu=4, fri=5, sat=6 ]
};

config.macros.date.handler = function(place,macroName,params)
{
	// do we want to see a link, a popup, or just a formatted date?
	var mode="display";
	if (params[0]=="display") { mode=params[0]; params.shift(); }
	if (params[0]=="popup") { mode=params[0]; params.shift(); }
	if (params[0]=="link") { mode=params[0]; params.shift(); }
	// get the date
	var now = new Date();
	var date = now;
	if (!params[0] || params[0]=="today")
		{ params.shift(); }
	else if (params[0]=="filedate")
		{ date=new Date(document.lastModified); params.shift(); }
	else if (params[0]=="tiddler")
		{ date=store.getTiddler(story.findContainingTiddler(place).id.substr(7)).modified; params.shift(); }
	else if (params[0].substr(0,8)=="tiddler:")
		{ var t; if ((t=store.getTiddler(params[0].substr(8)))) date=t.modified; params.shift(); }
	else {
		var y = eval(params.shift().replace(/Y/ig,(now.getYear()<1900)?now.getYear()+1900:now.getYear()));
		var m = eval(params.shift().replace(/M/ig,now.getMonth()+1));
		var d = eval(params.shift().replace(/D/ig,now.getDate()+0));
		date = new Date(y,m-1,d);
	}
	// date format with optional custom override
	var format=this.format; if (params[0]) format=params.shift();
	var linkformat=this.linkformat; if (params[0]) linkformat=params.shift();
	showDate(place,date,mode,format,linkformat);
}

window.showDate=showDate;
function showDate(place,date,mode,format,linkformat,autostyle,weekend)
{
	if (!mode) mode="display";
	if (!format) format=config.macros.date.format;
	if (!linkformat) linkformat=config.macros.date.linkformat;
	if (!autostyle) autostyle=false;

	// format the date output
	var title = date.formatString(format);
	var linkto = date.formatString(linkformat);

	// just show the formatted output
	if (mode=="display") { place.appendChild(document.createTextNode(title)); return; }

	// link to a 'dated tiddler'
	var link = createTiddlyLink(place, linkto, false);
	link.appendChild(document.createTextNode(title));
	link.title = linkto;
	link.date = date;
	link.format = format;
	link.linkformat = linkformat;

	// if using a popup menu, replace click handler for dated tiddler link
	// with handler for popup and make link text non-italic (i.e., an 'existing link' look)
	if (mode=="popup") {
		link.onclick = onClickDatePopup;
		link.style.fontStyle="normal";
	}
	// format the popup link to show what kind of info it contains (for use with calendar generators)
	if (autostyle) setDateStyle(place,link,weekend);
}
//}}}

//{{{
// NOTE: This function provides default logic for setting the date style when displayed in a calendar
// To customize the date style logic, please see[[DatePluginConfig]]
function setDateStyle(place,link,weekend) {
	// alias variable names for code readability
	var date=link.date;
	var fmt=link.linkformat;
	var linkto=date.formatString(fmt);
	var cmd=config.macros.date;

	if ((weekend!==undefined?weekend:isWeekend(date))&&(cmd.weekendbg!=""))
		{ place.style.background = cmd.weekendbg; }
	if (hasModifieds(date)||hasCreateds(date)||hasTagged(date,fmt))
		{ link.style.fontStyle="normal"; link.style.fontWeight="bold"; }
	if (hasReminders(date))
		{ link.style.textDecoration="underline"; }
	if (isToday(date))
		{ link.style.border="1px solid black"; }
	if (isHoliday(date)&&(cmd.holidaybg!=""))
		{ place.style.background = cmd.holidaybg; }
	if (hasCreateds(date)&&(cmd.createdbg!=""))
		{ place.style.background = cmd.createdbg; }
	if (hasModifieds(date)&&(cmd.modifiedsbg!=""))
		{ place.style.background = cmd.modifiedsbg; }
	if ((hasTagged(date,fmt)||store.tiddlerExists(linkto))&&(cmd.linkedbg!=""))
		{ place.style.background = cmd.linkedbg; }
	if (hasReminders(date)&&(cmd.remindersbg!=""))
		{ place.style.background = cmd.remindersbg; }
	if (isToday(date)&&(cmd.todaybg!=""))
		{ place.style.background = cmd.todaybg; }
}
//}}}

//{{{
function isToday(date) // returns true if date is today
	{ var now=new Date(); return ((now-date>=0) && (now-date<86400000)); }

function isWeekend(date) // returns true if date is a weekend
	{ return (config.macros.date.weekend[date.getDay()]); }

function isHoliday(date) // returns true if date is a holiday
{
	var longHoliday = date.formatString("0MM/0DD/YYYY");
	var shortHoliday = date.formatString("0MM/0DD");
	for(var i = 0; i < config.macros.date.holidays.length; i++) {
		var holiday=config.macros.date.holidays[i];
		if (holiday==longHoliday||holiday==shortHoliday) return true;
	}
	return false;
}
//}}}

//{{{
// Event handler for clicking on a day popup
function onClickDatePopup(e)
{
	if (!e) var e = window.event;
	var theTarget = resolveTarget(e);
	var popup = Popup.create(this);
	if(popup) {
		// always show dated tiddler link (or just date, if readOnly) at the top...
		if (!readOnly || store.tiddlerExists(this.date.formatString(this.linkformat)))
			createTiddlyLink(popup,this.date.formatString(this.linkformat),true);
		else
			createTiddlyText(popup,this.date.formatString(this.linkformat));
		if (!config.options.chkDatePopupHideCreated)
			addCreatedsToPopup(popup,this.date,this.format);
		if (!config.options.chkDatePopupHideChanged)
			addModifiedsToPopup(popup,this.date,this.format);
		if (!config.options.chkDatePopupHideTagged)
			addTaggedToPopup(popup,this.date,this.linkformat);
		if (!config.options.chkDatePopupHideReminders)
			addRemindersToPopup(popup,this.date,this.linkformat);
	}
	Popup.show(popup,false);
	e.cancelBubble = true;
	if (e.stopPropagation) e.stopPropagation();
	return(false);
}
//}}}

//{{{
function indexCreateds() // build list of tiddlers, hash indexed by creation date
{
	var createds= { };
	var tiddlers = store.getTiddlers("title","excludeLists");
	for (var t = 0; t < tiddlers.length; t++) {
		var date = tiddlers[t].created.formatString("YYYY0MM0DD")
		if (!createds[date])
			createds[date]=new Array();
		createds[date].push(tiddlers[t].title);
	}
	return createds;
}
function hasCreateds(date) // returns true if date has created tiddlers
{
	if (!config.macros.date.createds) config.macros.date.createds=indexCreateds();
	return (config.macros.date.createds[date.formatString("YYYY0MM0DD")]!=undefined);
}

function addCreatedsToPopup(popup,when,format)
{
	var force=(store.isDirty() && when.formatString("YYYY0MM0DD")==new Date().formatString("YYYY0MM0DD"));
	if (force || !config.macros.date.createds) config.macros.date.createds=indexCreateds();
	var indent=String.fromCharCode(160)+String.fromCharCode(160);
	var createds = config.macros.date.createds[when.formatString("YYYY0MM0DD")];
	if (createds) {
		createds.sort();
		var e=createTiddlyElement(popup,"div",null,null,"created ("+createds.length+")");
		for(var t=0; t<createds.length; t++) {
			var link=createTiddlyLink(popup,createds[t],false);
			link.appendChild(document.createTextNode(indent+createds[t]));
			createTiddlyElement(popup,"br",null,null,null);
		}
	}
}
//}}}

//{{{
function indexModifieds() // build list of tiddlers, hash indexed by modification date
{
	var modifieds= { };
	var tiddlers = store.getTiddlers("title","excludeLists");
	for (var t = 0; t < tiddlers.length; t++) {
		var date = tiddlers[t].modified.formatString("YYYY0MM0DD")
		if (!modifieds[date])
			modifieds[date]=new Array();
		modifieds[date].push(tiddlers[t].title);
	}
	return modifieds;
}
function hasModifieds(date) // returns true if date has modified tiddlers
{
	if (!config.macros.date.modifieds) config.macros.date.modifieds = indexModifieds();
	return (config.macros.date.modifieds[date.formatString("YYYY0MM0DD")]!=undefined);
}

function addModifiedsToPopup(popup,when,format)
{
	var date=when.formatString("YYYY0MM0DD");
	var force=(store.isDirty() && date==new Date().formatString("YYYY0MM0DD"));
	if (force || !config.macros.date.modifieds) config.macros.date.modifieds=indexModifieds();
	var indent=String.fromCharCode(160)+String.fromCharCode(160);
	var mods = config.macros.date.modifieds[date];
	if (mods) {
		// if a tiddler was created on this date, don't list it in the 'changed' section
		if (config.macros.date.createds && config.macros.date.createds[date]) {
			var temp=[];
			for(var t=0; t<mods.length; t++)
				if (!config.macros.date.createds[date].contains(mods[t]))
					temp.push(mods[t]);
			mods=temp;
		}
		mods.sort();
		var e=createTiddlyElement(popup,"div",null,null,"changed ("+mods.length+")");
		for(var t=0; t<mods.length; t++) {
			var link=createTiddlyLink(popup,mods[t],false);
			link.appendChild(document.createTextNode(indent+mods[t]));
			createTiddlyElement(popup,"br",null,null,null);
		}
	}
}
//}}}

//{{{
function hasTagged(date,format) // returns true if date is tagging other tiddlers
{
	return store.getTaggedTiddlers(date.formatString(format)).length>0;
}

function addTaggedToPopup(popup,when,format)
{
	var indent=String.fromCharCode(160)+String.fromCharCode(160);
	var tagged=store.getTaggedTiddlers(when.formatString(format));
	if (tagged.length) var e=createTiddlyElement(popup,"div",null,null,"tagged ("+tagged.length+")");
	for(var t=0; t<tagged.length; t++) {
		var link=createTiddlyLink(popup,tagged[t].title,false);
		link.appendChild(document.createTextNode(indent+tagged[t].title));
		createTiddlyElement(popup,"br",null,null,null);
	}
}
//}}}

//{{{
function indexReminders(date,leadtime) // build list of tiddlers with reminders, hash indexed by reminder date
{
	var reminders = { };
	if(window.findTiddlersWithReminders!=undefined) { // reminder plugin is installed
		// DEBUG var starttime=new Date();
		var t = findTiddlersWithReminders(date, [0,leadtime], null, null, 1);
		for(var i=0; i<t.length; i++) reminders[t[i].matchedDate]=true;
		// DEBUG var out="Found "+t.length+" reminders in "+((new Date())-starttime+1)+"ms\n";
		// DEBUG out+="startdate: "+date.toLocaleDateString()+"\n"+"leadtime: "+leadtime+" days\n\n";
		// DEBUG for(var i=0; i<t.length; i++) { out+=t[i].matchedDate.toLocaleDateString()+" "+t[i].params.title+"\n"; }
		// DEBUG alert(out);
	}
	return reminders;
}

function hasReminders(date) // returns true if date has reminders
{
	if (window.reminderCacheForCalendar)
		return window.reminderCacheForCalendar[date]; // use calendar cache
	if (!config.macros.date.reminders)
		config.macros.date.reminders = indexReminders(date,90); // create a 90-day leadtime reminder cache
	return (config.macros.date.reminders[date]);
}

function addRemindersToPopup(popup,when,format)
{
	if(window.findTiddlersWithReminders==undefined) return; // reminder plugin not installed

	var indent = String.fromCharCode(160)+String.fromCharCode(160);
	var reminders=findTiddlersWithReminders(when, [0,31],null,null,1);
	createTiddlyElement(popup,"div",null,null,"reminders ("+(reminders.length||"none")+")");
	for(var t=0; t<reminders.length; t++) {
		link = createTiddlyLink(popup,reminders[t].tiddler,false);
		var diff=reminders[t].diff;
		diff=(diff<1)?"Today":((diff==1)?"Tomorrow":diff+" days");
		var txt=(reminders[t].params["title"])?reminders[t].params["title"]:reminders[t].tiddler;
		link.appendChild(document.createTextNode(indent+diff+" - "+txt));
		createTiddlyElement(popup,"br",null,null,null);
	}
	if (readOnly) return;	// omit "new reminder..." link
	var link = createTiddlyLink(popup,indent+"new reminder...",true); createTiddlyElement(popup,"br");
	var title = when.formatString(format);
	link.title="add a reminder to '"+title+"'";
	link.onclick = function() {
		// show tiddler editor
		story.displayTiddler(null, title, 2, null, null, false, false);
		// find body 'textarea'
		var c =document.getElementById("tiddler" + title).getElementsByTagName("*");
		for (var i=0; i<c.length; i++) if ((c[i].tagName.toLowerCase()=="textarea") && (c[i].getAttribute("edit")=="text")) break;
		// append reminder macro to tiddler content
		if (i<c.length) {
			if (store.tiddlerExists(title)) c[i].value+="\n"; else c[i].value="";
			c[i].value += "<<reminder";
			c[i].value += " day:"+when.getDate();
			c[i].value += " month:"+(when.getMonth()+1);
			c[i].value += " year:"+when.getFullYear();
			c[i].value += ' title:"Enter a title" >>';
		}
	};
}
//}}}
// // [[DatePluginConfigColors]]

//{{{
config.macros.date.weekend=[ 1,0,0,0,0,0,1 ]; // day index values: sun=0, mon=1, tue=2, wed=3, thu=4, fri=5, sat=6
config.macros.date.format="0MM.0DD.YYYY"; // default date display format
config.macros.date.linkformat="0MM.0DD.YYYY"; // 'dated tiddler' link format
config.macros.date.weekendbg="#fff";
config.macros.date.holidaybg="#600";
config.macros.date.modifiedsbg="#960";
config.macros.date.linkedbg="#360";
config.macros.date.remindersbg="#ff3";
//}}}
/%
|Code modified for this site, do not distribute|MTP|
|Based On|DigitalClock|
|Source|http://www.TiddlyTools.com/#DigitalClock|
%/<script>
	window.DC=function(id){
		var e=document.getElementById(id); if (!e) return;
		e.innerHTML=new Date().formatString(e.fmt);
		setTimeout('window.DC('+id+')',e.tick*1000);
	}
	var e=createTiddlyElement(place,'a',new Date().getTime()+Math.random());
	e.style.cursor='pointer';
	e.fmt=('$1'=='$'+'1')?'DDD, mmm DD YYYY, hh12:0mm:0ss am':'$1';
	e.tick=('$2'=='$'+'2')?'1':'$2';
	window.DC(e.id);
</script>



[tag[DefaultTiddlers AND NOT excludeLists]]
/***
|Name|DeleteAllTaggedPlugin|
|Source|http://ido-xp.tiddlyspot.com/#DeleteAllTaggedPlugin|
|Version|1.0|

An adaptation of DeleteDoneTasks (Simon Baird) by Ido Magal
To use this insert {{{<<deleteAllTagged>>}}} into the desired tiddler.

Example usage:
{{{<<deleteAllTagged>>}}}
<<deleteAllTagged>>
***/
//{{{

config.macros.deleteAllTagged = {
 handler: function ( place,macroName,params,wikifier,paramString,tiddler ) {
 var buttonTitle = params[0] ? params[0] : "Delete Tagged w/ '"+tiddler.title+"'"; // simon's tweak
 var alsoDeleteThisTiddler = params[1] ? params[1] : "";
 createTiddlyButton( place, buttonTitle, "Delete every tiddler tagged with '"+tiddler.title+"'", this.deleteAllTagged( tiddler.title, alsoDeleteThisTiddler == "delete" ));
 },

 deleteAllTagged: function(tag,deleteMe) {
 return function() {
 var collected = [];
 store.forEachTiddler( function ( title,tiddler ) {
 if ( tiddler.tags.contains( tag ))
 {
 collected.push( title );
 }
 });
 if ( collected.length == 0 )
 {
 alert( "No tiddlers found tagged with '"+tag+"'." );
 }
 else
 {
 if ( confirm( "These tiddlers are tagged with '"+tag+"'\n'"
 + collected.join( "', '" ) + "'\n\n\n"
 + "Are you sure you want to delete these?" ))
 {
 for ( var i=0;i<collected.length;i++ )
 {
 store.deleteTiddler( collected[i] );
 story.closeTiddler( collected[i], true );
 displayMessage( "Deleted '"+collected[i]+"'" );
 }
 }
 }
 if (deleteMe)
 {
 if ( confirm( "Also delete this tiddler ('"+tag+"')?" ) )
 {
 store.deleteTiddler( tag );
 story.closeTiddler( tag, true );
 displayMessage( "Deleted '"+tag+"'" );
 }
 }
 }
 }
};

//}}}
/***
|Name|DeleteCompletedPlugin|
|Modified|01.29.09 MTP|

Based on DeleteAllTagged (An adaptation of DeleteDoneTasks (Simon Baird) by Ido Magal)
http://ido-xp.tiddlyspot.com/#DeleteAllTaggedPlugin

Example usage: (For Items tagged Completed & Task)
{{{<<deleteCompleted>>}}}
<<deleteCompleted>>
{{{<<deleteCompleted daysOld:5 title:'Delete 5d'>>}}}
<<deleteCompleted daysOld:5 title:'Delete 5d'>>
{{{<<deleteCompleted daysOld:0 title:'Delete 0d'>>}}}
<<deleteCompleted daysOld:0 title:'Delete 0d'>>
***/
//{{{

config.macros.deleteCompleted = {
 handler: function (place,macroName,params,wikifier,paramString,tiddler) {
 var namedParams = (paramString.parseParams('daysOld'))[0];
 var daysOld = namedParams['daysOld'] ? namedParams['daysOld'][0] : 30; // default
 var buttonTitle = namedParams['title'] ? namedParams['title'][0] : "Delete Completed Actions";
 createTiddlyButton(place,buttonTitle,"Delete Completed actions older than "+daysOld+" days old",this.deleteCompleted(daysOld));
 },

 deleteCompleted: function(daysOld) {
 return function() {
 var collected = [];
 var compareDate = new Date();
 compareDate.setDate(compareDate.getDate() - daysOld);
 store.forEachTiddler(function (title,tiddler) {
 if (tiddler.tags.containsAll(["Completed" , "Task"])
 && tiddler.modified < compareDate) {
 collected.push(title);
 }
 });
 if (collected.length == 0) {
 alert("No Completed actions found older than "+daysOld+" days");
 }
 else {
 if (confirm("Completed actions older than "+daysOld+" days:\n'"
 + collected.join("', '") + "'\n\n\n"
 + "Are you sure you want to delete these actions?")) {
 for (var i=0;i<collected.length;i++) {
 store.removeTiddler(collected[i]);
 displayMessage("Deleted '"+collected[i]+"'");
 story.closeTiddler( collected[i], true );
 }
 }
 }
 }
 }
};

//}}}


/***
|''Name''|DeprecatedFunctionsPlugin|
|''Description''|Provides support for functions removed from the TiddlyWiki core|
|''Version''|1.0.0|
|''Status''|stable|
|''Source''|http://www.tiddlywiki.com/coreplugins.html#DeprecatedFunctionsPlugin|
|''~CodeRepository:''|http://svn.tiddlywiki.org/Trunk/association/plugins/DeprecatedFunctionsPlugin/DeprecatedFunctionsPlugin.js |
|''License''|[[BSD open source license]]|
|''~CoreVersion''|2.3.0|
|''Feedback''|[[TiddlyWiki community|http://groups.google.com/group/TiddlyWiki]] |
|''Keywords''|legacySupport|
!Code
***/
//{{{
if(!version.extensions.DeprecatedFunctionsPlugin) {
version.extensions.DeprecatedFunctionsPlugin = {installed:true};

//--
//-- Deprecated code
//--

// @Deprecated: Use createElementAndWikify and this.termRegExp instead
config.formatterHelpers.charFormatHelper = function(w)
{
	w.subWikify(createTiddlyElement(w.output,this.element),this.terminator);
};

// @Deprecated: Use enclosedTextHelper and this.lookaheadRegExp instead
config.formatterHelpers.monospacedByLineHelper = 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 text = lookaheadMatch[1];
		if(config.browser.isIE)
			text = text.replace(/\n/g,"\r");
		createTiddlyElement(w.output,"pre",null,null,text);
		w.nextMatch = lookaheadRegExp.lastIndex;
	}
};

// @Deprecated: Use <br> or <br /> instead of <<br>>
config.macros.br = {};
config.macros.br.handler = function(place)
{
	createTiddlyElement(place,"br");
};

// Find an entry in an array. Returns the array index or null
// @Deprecated: Use indexOf instead
Array.prototype.find = function(item)
{
	var i = this.indexOf(item);
	return i == -1 ? null : i;
};

// Load a tiddler from an HTML DIV. The caller should make sure to later call Tiddler.changed()
// @Deprecated: Use store.getLoader().internalizeTiddler instead
Tiddler.prototype.loadFromDiv = function(divRef,title)
{
	return store.getLoader().internalizeTiddler(store,this,title,divRef);
};

// Format the text for storage in an HTML DIV
// @Deprecated Use store.getSaver().externalizeTiddler instead.
Tiddler.prototype.saveToDiv = function()
{
	return store.getSaver().externalizeTiddler(store,this);
};

// @Deprecated: Use store.allTiddlersAsHtml() instead
function allTiddlersAsHtml()
{
	return store.allTiddlersAsHtml();
}

// @Deprecated: Use refreshPageTemplate instead
function applyPageTemplate(title)
{
	refreshPageTemplate(title);
}

// @Deprecated: Use story.displayTiddlers instead
function displayTiddlers(srcElement,titles,template,unused1,unused2,animate,unused3)
{
	story.displayTiddlers(srcElement,titles,template,animate);
}

// @Deprecated: Use story.displayTiddler instead
function displayTiddler(srcElement,title,template,unused1,unused2,animate,unused3)
{
	story.displayTiddler(srcElement,title,template,animate);
}

// @Deprecated: Use functions on right hand side directly instead
var createTiddlerPopup = Popup.create;
var scrollToTiddlerPopup = Popup.show;
var hideTiddlerPopup = Popup.remove;

// @Deprecated: Use right hand side directly instead
var regexpBackSlashEn = new RegExp("\\\\n","mg");
var regexpBackSlash = new RegExp("\\\\","mg");
var regexpBackSlashEss = new RegExp("\\\\s","mg");
var regexpNewLine = new RegExp("\n","mg");
var regexpCarriageReturn = new RegExp("\r","mg");

}
//}}}
|''Name''|DevilTheme|
|''Description''|Custom Theme Spawned from MPTW by MTP 11.08.08|
|''Last Revision''|MTP 12.31.08|

!Author Mode
|PageTemplate|ImgPageTemplate|
|ViewTemplate|CustomViewTemplate|
|EditTemplate|CustomEditTemplate|
|StyleSheet|##StyleSheet|
|ColorPalette|ColorPalette|


!StyleSheet
/*{{{*/
[[CustomStyleSheet]]
[[StyleSheetShortcuts]]
[[PluginStyles]]

/* Background Image */
body {
	background-image: url("theme/devil1.jpeg") !important;
	background-repeat: repeat;
}
#topMenu, .header, .headerNow {
	background: transparent !important;
}
/*}}}*/
/***
|''Name:''|Dice|
|''Version:''|0.5 (21 Oct 2005)|
|''Source:''|Tiddly W;nks (http://danielbaird.com/tiddlywinks/)|
|''Author:''|[[Daniel Baird]]|
|''Type:''|Macro|
!Description
Tell it what dice you want, and it'll let you roll them.

!Syntax/Example usage

{{{<<dice>>}}} for 3d6

{{{<<dice }}}//{{{specifier}}}//{{{ [}}}//{{{options}}}//{{{]>>}}} where specifier is something like 3d6, 1d4+1, 2d10-5

{{{<<dice fudge [}}}//{{{options}}}//{{{]>>}}} will roll 3 fudge dice (a fudge die gives -1, 0, or +1)

options can be zero or more of the following:

* show:eachface
** shows the face of each die rolled, then the total (not yet implemented)
* show:eachroll
** shows the number on each die rolled, then the total (default)
* show:result
** shows just the total result of the roll
* initialroll:yes
** do a roll when initially displayed
* initialroll:no
** don't roll until the user says so (default)
* rollby:click
** user clicks anywhere on the diceroller area to roll
* rollby:link
** user clicks an underlined link to roll (default)
* rollby:button
** user clicks a button to roll

eg:

{{{<<dice>>}}}
<<dice>>

{{{<<dice 3d6+2 rollby:button>>}}}
<<dice 3d6+2 rollby:button>>

{{{<<dice fudge initialroll:yes rollby:click>>}}}
<<dice fudge initialroll:yes rollby:click>>


!Notes
* much changing during this 0.5 version.

!Revision History
* 0.1
** first release
* 0.2
** changed the corners to slightly prettier ugly text chars
** finally got rid of the borders
** got rid of heading
** added 'Fudge' mode
* 0.3 (5 Oct 2005)
** fixed the problem with multiple dice rollers
* 0.31 (12 Oct 2005)
** worked out how to use a closure as a event handler, which means that the code added in 0.3 could be made a lot simpler.
* 0.5 (21 Oct 2005)
** aiming at getting a whole rewrite done. much progress!.

***/
/*{{{*/
// =======================================================================
version.extensions.dice = {major: 0, minor: 5, revision: 0};

config.macros.dice = {};

config.macros.dice.handler = function(place,macroName,params) {

    var rolldesc = params[0];
    if (rolldesc == undefined) rolldesc = '3d6';

	var options = '';
    if (params.length > 1) {
		params.shift();
    	options = params.join(' ');
	}

    var thisDiceRoller = new DiceRoller();
    createTiddlyElement(place, 'div', thisDiceRoller.id, null, 'If you see this, DiceRoller is broken.  Let Daniel know (DanielBaird at gmail dot com).');
    thisDiceRoller.newDice(rolldesc, options);
}
// =======================================================================
function DiceRoller() {
	this.idprefix =  'dice';
    this.version = '0.5 beta';
    this.id = this.idprefix + DiceRoller.prototype.nextid;
    DiceRoller.prototype.nextid++;
    return this;
}
// -----------------------------------------------------------------------
DiceRoller.prototype.nextid = 0;
// -----------------------------------------------------------------------
DiceRoller.prototype.newDice = function(rolldesc, options) {

	this.error = null;
	this.initialroll = false;
	this.display = 'eachroll';
	this.rolltag = 'roll';
	this.rollagaintag = 'roll again';
	this.rollby = 'link';
	this.parseDesc(rolldesc);
	this.parseOpts(options);
	if (this.initialroll) this.rollDice();
	this.drawRoller();
// ^^^^^^^^^^^^^ new stuff above.. ^^^^^^^^^^^^^
//    this.rolls = rolls;

//    this.resultDisplay = 'dice';
//    if (resultDisplay != null)	this.resultDisplay = resultDisplay;

//    this.resultSystem = 'sum';
//    if (resultSystem != null)	this.resultSystem = resultSystem;

//    this.sides = 6;
//    this.createDice();
//	this.roll();
}
// -----------------------------------------------------------------------
DiceRoller.prototype.parseDesc = function(desc) {
	this.rollstr = desc;
	desc = desc.toLowerCase();
	this.dicetype = 'standard';
	this.adjuster = null;
	if (desc == 'fudge') {
		// 'fudge' system: 3d3, where the d3 gives -1, 0 or +1
		this.dicetype = 'fudge';
		this.dicesides = 3;
		this.rollcount = 3;
	} else {
		// normal system: eg 3d6+2
		var reg = /(\d+)d(\d+)(\+(\d+)|-(\d+))?/;
		var info = desc.match(reg);
		this.rollcount = parseInt(info[1]);
		this.dicesides = parseInt(info[2]);
		this.adjuster = parseInt(info[3]);
		if ( isNaN(this.adjuster) ) this.adjuster = 0;
	}
}
// -----------------------------------------------------------------------
DiceRoller.prototype.parseOpts = function(options) {
	this.optstr = options;
	options = ' ' + options + ' ';
	if (options.indexOf(' show:eachface ') != -1) this.display = 'eachface';
	if (options.indexOf(' show:eachroll ') != -1) this.display = 'eachroll';
	if (options.indexOf(' show:result ') != -1) this.display = 'result';

	if (options.indexOf(' initialroll:yes ') != -1) this.initialroll = true;
	if (options.indexOf(' initialroll:no ') != -1) this.initialroll = false;

	if (options.indexOf(' rollby:click ') != -1) this.rollby = 'click';
	if (options.indexOf(' rollby:link ') != -1) this.rollby = 'link';
	if (options.indexOf(' rollby:button ') != -1) this.rollby = 'button';
}
// -----------------------------------------------------------------------
DiceRoller.prototype.createDice = function() {
    this.results = new Array(this.rolls);
    this.result = 0;
    this.showDice();
}
// -----------------------------------------------------------------------
DiceRoller.prototype.drawRoller = function() {
    var node = document.getElementById(this.id);
	if (this.display == 'eachface') node.innerHTML = this.drawRollerEachFace();
	if (this.display == 'eachroll') node.innerHTML = this.drawRollerEachRoll();
	if (this.display == 'result') node.innerHTML = this.drawRollerResult();

    // getClickHandler() is a function that returns a function.. JS is sweet huh
    if (this.rollby == 'click') {
		node.onclick = this.getClickHandler();
	} else {
		document.getElementById(this.id + '_roll').onclick = this.getClickHandler();
	}
	/*
    var html = '';

	if (this.display == 'eachface')

    html += '<table class="diceroller">';
    html += '<tr>';

	if (this.resultDisplay == 'text') {
		html.push('<td>You rolled ');
	}
	if (this.resultDisplay != 'textsummary') {
		var separator = '';
		for (var roll = 0; roll < this.rolls; roll++) {
			html.push( separator + this.drawDie(roll) );
			if (this.resultDisplay == 'text')	separator = ', ';
		}
		html.push('<td>');
	}
    if (this.resultSystem == 'fudge') {
	var resprefix = '';
	if (this.result > 0) resprefix = '+';
	html.push('Result is ' + resprefix + this.result + '.<br />Click to roll again.</td>');
    } else {
	html.push('<td>'+this.rolls+'d'+this.sides+': you rolled ' + this.result + '.<br />Click to roll again.</td>');
    }

    html += '</tr></table>';
    node.innerHTML = html;
	*/
}
// -----------------------------------------------------------------------
DiceRoller.prototype.drawRollerResult = function() {
	var str = '';
	str += 'Rolling';
	str += ((this.dicetype == 'fudge')?(':'):(' ' + this.rollstr + ':'));
	if (this.result != undefined) {
		str += 'You rolled <strong>';
		str += ((this.dicetype == 'fudge')?(this.addSign(this.result)):(this.result));
		str += '</strong>.';
	}
	str += this.makeRollTrigger();
	return str;
}
// -----------------------------------------------------------------------
DiceRoller.prototype.drawRollerEachRoll = function() {
	var str = '';
	str += 'Rolling';
	str += ((this.dicetype == 'fudge')?(':'):(' ' + this.rollstr + ':'));
	if (this.result != undefined) {
		str += ' You rolled ';
		var joiner = '';
		for (var r = 0; r < this.rollcount; r++) {
			str += joiner + ((this.dicetype == 'fudge')?(this.addSign(this.results[r])):(this.results[r]));
			joiner = ', ';
		}
		str += ' totalling <strong>';
		str += ((this.dicetype == 'fudge')?(this.addSign(this.result)):(this.result));
		str += '</strong>.';
	}
	str += this.makeRollTrigger();
	return str;
}
// -----------------------------------------------------------------------
DiceRoller.prototype.addSign = function(num) {
	return ( ((parseInt(num) > 0)?('+'):('')) + (num) );
}
// -----------------------------------------------------------------------
DiceRoller.prototype.makeRollTrigger = function() {
	var tag = ((this.result == undefined)?(this.rolltag):(this.rollagaintag));
	if (this.rollby == 'click')  return ' Click to ' + tag + '.';
	if (this.rollby == 'link')   return ' <a style="text-decoration: underline" href="#" id="' + this.id + '_roll">' + tag + '</a>';
	if (this.rollby == 'button') return ' <button id="' + this.id + '_roll">' + tag + '</button>';
}
// -----------------------------------------------------------------------
DiceRoller.prototype.drawDie = function(roll) {
    var html = new Array();

	if (this.resultDisplay == 'text') {
		if (this.resultSystem == 'fudge' && this.results[roll] > 0) html.push('+');
		html.push(this.results[roll]);
	} else {
		html.push('<td class="die">');

		//there are seven possible dot positions
		var dots = Array();
		for (var dot = 0; dot < 7; dot++) {
			dots.push('&nbsp;');
		}
		if ( this.results[roll] ) {
			if (this.results[roll] > 1) dots[0] = 'O';
			if (this.results[roll] > 3) dots[1] = 'O';
			if (this.results[roll] == 6) dots[2] = 'O';
			if (this.results[roll]%2 == 1) dots[3] = 'O';
			if (this.results[roll] == 6) dots[4] = 'O';
			if (this.results[roll] > 3) dots[5] = 'O';
			if (this.results[roll] > 1) dots[6] = 'O';
		}
		var pipe = '|';
		var space = '&nbsp;';
		if (this.resultDisplay == 'dice') {
			html.push(',-----.<br />');
			html.push(pipe + space + dots[0] + space + dots[1] + space + pipe + '<br />');
			html.push(pipe + space + dots[2] + dots[3] + dots[4] + space + pipe + '<br />');
			html.push(pipe + space + dots[5] + space + dots[6] + space + pipe + '<br />');
			html.push('`-----\'<br />');
		} else if (this.resultDisplay == 'compact') {
			html.push(dots[0] + space + dots[1] + '<br />');
			html.push(dots[2] + dots[3] + dots[4] + '<br />');
			html.push(dots[5] + space + dots[6] + '<br />');
		}
		html.push('</td>');
	}
    return html.join('');
}
// -------------------------------------------------------------------
DiceRoller.prototype.rollDice = function() {
	this.result = this.adjuster;
	this.results = new Array(this.rollcount);
	for (var roll = 0; roll < this.rollcount; roll++) {
		this.results[roll] = Math.floor((this.dicesides)*Math.random())+1;
		if (this.dicetype == 'fudge') {
			this.results[roll] -= 2;
		}
		this.result += this.results[roll];
	}
	this.drawRoller();
}
// -----------------------------------------------------------------------
DiceRoller.prototype.getClickHandler = function() {
	// trickey bit.. first make a local var that references the
	// current dice roller object, then return an anonymous function
	// that calls that object's roll() method.  woot for closures!
	var thisroller = this;
	return function(e) {
		thisroller.rollDice();
		return false;
	};
}
// =======================================================================
setStylesheet(
	".viewer table.diceroller, .viewer table.diceroller tr { "+
		"border: none;" +
	"} \n"+

	".viewer table.diceroller tr td { "+
		"border: none; " +
	"} \n"+

	".viewer table.diceroller td.die { "+
		"padding: 0.5em; " +
		"font-family: monospace; " +
		"line-height: 0.95em; " +
	"} \n"+

	"",
	"DiceRoller");

/*}}}*/
/%
|Name|DigitalClock|
|Source|http://www.TiddlyTools.com/#DigitalClock|
|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|display current time with automatic LIVE update|

Usage: <<tiddler DigitalClock with: format tick>>

where 'format' is any TiddlyWiki date/time formatting string
and 'tick' is the time in seconds between display updates (default=1sec)

For example, use:
   << ... "0hh:0mm" 60>>
to show hours and minutes only, updated once per minute

%/<script>
	window.DigitalClock_tick=function(id){
		var e=document.getElementById(id); if (!e) return;
		e.title='click to '+(e.paused?'RESUME':'PAUSE')+' clock display';
		if (e.paused) return;
		e.innerHTML=new Date().formatString(e.fmt);
		setTimeout('window.DigitalClock_tick('+id+')',e.tick*1000);
	}
	var e=createTiddlyElement(place,'a',new Date().getTime()+Math.random());
	e.onclick=function(){this.paused=!this.paused;window.DigitalClock_tick(this.id);}
	e.style.cursor='pointer';
	e.fmt=('$1'=='$'+'1')?'hh12:0mm:0ss am':'$1';
	e.tick=('$2'=='$'+'2')?'1':'$2';
	window.DigitalClock_tick(e.id);
</script>
|''Name''|DragonTheme|
|''Description''|Custom Theme Spawned from MPTW by MTP 11.08.08|
|''Last Revision''|MTP 12.31.08|

!Author Mode
|PageTemplate|ImgPageTemplate|
|ViewTemplate|CustomViewTemplate|
|EditTemplate|CustomEditTemplate|
|StyleSheet|##StyleSheet|
|ColorPalette|ColorPalette|


!StyleSheet
/*{{{*/
[[CustomStyleSheet]]
[[StyleSheetShortcuts]]
[[PluginStyles]]

/* Background Image */
body {
	background-image: url("theme/dragon1.jpeg") !important;
	background-repeat: repeat;
}
#topMenu, .header, .headerNow {
	background: transparent !important;
}
/*}}}*/
|<html><FORM action="file:///c:/" target="_blank"><INPUT type=submit value="c:\ drive" name="button" class="btn" name=submit2></FORM></html>|<html><FORM action="file:///d:/" target="_blank"><INPUT type=submit value="d:\ drive" name="button" class="btn" name=submit2></FORM></html>|<html><FORM action="file:///e:/" target="_blank"><INPUT type=submit value="e:\ drive" name="button" class="btn" name=submit2></FORM></html>||<html><FORM action="file:///f:/" target="_blank"><INPUT type=submit value="f:\ drive" name="button" class="btn" name=submit2></FORM></html>|
/***
|''Name:''|DropDownMenuPlugin|
|''Description:''|Create dropdown menus from unordered lists|
|''Author:''|Saq Imtiaz ( lewcid@gmail.com )|
|''Source:''|http://tw.lewcid.org/#DropDownMenuPlugin|
|''Code Repository:''|http://tw.lewcid.org/svn/plugins|
|''Version:''|2.1|
|''Date:''|11/04/2007|
|''License:''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|''~CoreVersion:''|2.2.5|

!!Usage:
* create a two-level unordered list using wiki syntax, and place {{{<<dropMenu>>}}} on the line after it.
* to create a vertical menu use {{{<<dropMenu vertical>>}}} instead.
* to assign custom classes to the list, just pass them as parameters to the macro {{{<<dropMenu className1 className2 className3>>}}}

!!Features:
*Supports just a single level of drop-downs, as anything more usually provides a poor experience for the user.
* Very light weight, about 1.5kb of JavaScript and 4kb of CSS.
* Comes with two built in css 'themes', the default horizontal and vertical. 

!!Customizing:
* to customize the appearance of the menu's, you can either add a custom class as described above or, you can edit the CSS via the StyleSheetDropDownMenu shadow tiddler.

!!Examples:
* [[DropDownMenuDemo]]

***/
// /%
//!BEGIN-PLUGIN-CODE
config.macros.dropMenu={

	dropdownchar: "\u25bc",

	handler : function(place,macroName,params,wikifier,paramString,tiddler){
		list = findRelated(place.lastChild,"UL","tagName","previousSibling");
		if (!list)
			return;
		addClass(list,"suckerfish");
		if (params.length){
			addClass(list,paramString);
		}
		this.fixLinks(list);
	},
	
	fixLinks : function(el){
		var els = el.getElementsByTagName("li");
		for(var i = 0; i < els.length; i++) {
			if(els[i].getElementsByTagName("ul").length>0){
				var link = findRelated(els[i].firstChild,"A","tagName","nextSibling");
				if(!link){
					var ih = els[i].firstChild.data;
					els[i].removeChild(els[i].firstChild);
					var d = createTiddlyElement(null,"a",null,null,ih+this.dropdownchar,{href:"javascript:;"});
					els[i].insertBefore(d,els[i].firstChild);
				}
				else{
					link.firstChild.data = link.firstChild.data + this.dropdownchar;
					removeClass(link,"tiddlyLinkNonExisting");
				}
			}
			els[i].onmouseover = function() {
				addClass(this, "sfhover");
			};
			els[i].onmouseout = function() {
				removeClass(this, "sfhover");
			};
		}
	}	
};

config.shadowTiddlers["StyleSheetDropDownMenuPlugin"] = 
	 "/*{{{*/\n"+
	 "/***** LAYOUT STYLES -  DO NOT EDIT! *****/\n"+
	 "ul.suckerfish, ul.suckerfish ul {\n"+
	 "	margin: 0;\n"+
	 "	padding: 0;\n"+
	 "	list-style: none;\n"+
	 "	line-height:1.4em;\n"+
	 "}\n\n"+
	 "ul.suckerfish  li {\n"+
	 "	display: inline-block; \n"+
	 "	display: block;\n"+
	 "	float: left; \n"+
	 "}\n\n"+
	 "ul.suckerfish li ul {\n"+
	 "	position: absolute;\n"+
	 "	left: -999em;\n"+
	 "}\n\n"+
	 "ul.suckerfish li:hover ul, ul.suckerfish li.sfhover ul {\n"+
	 "	left: auto;\n"+
	 "}\n\n"+
	 "ul.suckerfish ul li {\n"+
	 "	float: none;\n"+
	 "	border-right: 0;\n"+
	 "	border-left:0;\n"+
	 "}\n\n"+
	 "ul.suckerfish a, ul.suckerfish a:hover {\n"+
	 "	display: block;\n"+
	 "}\n\n"+
	 "ul.suckerfish li a.tiddlyLink, ul.suckerfish li a, #mainMenu ul.suckerfish li a {font-weight:bold;}\n"+
	 "/**** END LAYOUT STYLES *****/\n"+
	 "\n\n"+
	 "/**** COLORS AND APPEARANCE - DEFAULT *****/\n"+
	 "ul.suckerfish li a {\n"+
	 "	padding: 0.5em 1.5em;\n"+
	 "	color: #FFF;\n"+
	 "	background: #0066aa;\n"+
	 "	border-bottom: 0;\n"+
	 "	font-weight:bold;\n"+
	 "}\n\n"+
	 "ul.suckerfish li:hover a, ul.suckerfish li.sfhover a{\n"+
	 "	background: #00558F;\n"+
	 "}\n\n"+
	 "ul.suckerfish li:hover ul a, ul.suckerfish li.sfhover ul a{\n"+
	 "	color: #000;\n"+
	 "	background: #eff3fa;\n"+
	 "	border-top:1px solid #FFF;\n"+
	 "}\n\n"+
	 "ul.suckerfish ul li a:hover {\n"+
	 "	background: #e0e8f5;\n"+
	 "}\n\n"+
	 "ul.suckerfish li a{\n"+
	 "	width:9em;\n"+
	 "}\n\n"+
	 "ul.suckerfish ul li a, ul.suckerfish ul li a:hover{\n"+
	 "	display:inline-block;\n"+
	 "	width:9em;\n"+
	 "}\n\n"+
	 "ul.suckerfish li {\n"+
	 "	border-left: 1px solid #00558F;\n"+
	 "}\n"+
	 "/***** END COLORS AND APPEARANCE - DEFAULT *****/\n"+
	 "\n\n"+
	 "/***** LAYOUT AND APPEARANCE: VERTICAL *****/\n"+
	 "ul.suckerfish.vertical li{\n"+
	 "	width:10em;\n"+
	 "	border-left: 0px solid #00558f;\n"+
	 "}\n\n"+
	 "ul.suckerfish.vertical ul li, ul.suckerfish.vertical li a, ul.suckerfish.vertical li:hover a, ul.suckerfish.vertical li.sfhover a {\n"+
	 "	border-left: 0.8em solid #00558f;\n"+
	 "}\n\n"+
	 "ul.suckerfish.vertical li a, ul.suckerfish.vertical li:hover a, ul.suckerfish.vertical li.sfhover a,  ul.suckerfish.vertical li.sfhover a:hover{\n"+
	 "	width:8em;\n"+
	 "}\n\n"+
	 "ul.suckerfish.vertical {\n"+
	 "	width:10em; text-align:left;\n"+
	 "	float:left;\n"+
	 "}\n\n"+
	 "ul.suckerfish.vertical li a {\n"+
	 "	padding: 0.5em 1em 0.5em 1em;\n"+
	 "	border-top:1px solid  #fff;\n"+
	 "}\n\n"+
	 "ul.suckerfish.vertical, ul.suckerfish.vertical ul {\n"+
	 "	line-height:1.4em;\n"+
	 "}\n\n"+
	 "ul.suckerfish.vertical li:hover ul, ul.suckerfish.vertical li.sfhover ul { \n"+
	 "	margin: -2.4em 0 0 10.9em;\n"+
	 "}\n\n"+
	 "ul.suckerfish.vertical li:hover ul li a, ul.suckerfish.vertical li.sfhover ul li a {\n"+
	 "	border: 0px solid #FFF;\n"+
	 "}\n\n"+
	 "ul.suckerfish.vertical li:hover a, ul.suckerfish.vertical li.sfhover a{\n"+
	 "	padding-right:1.1em;\n"+
	 "}\n\n"+
	 "ul.suckerfish.vertical li:hover ul li, ul.suckerfish.vertical li.sfhover ul li {\n"+
	 "	border-bottom:1px solid  #fff;\n"+
	 "}\n\n"+
	 "/***** END LAYOUT AND APPEARANCE: VERTICAL *****/\n"+
	 "/*}}}*/";
store.addNotification("StyleSheetDropDownMenuPlugin",refreshStyles);
//!END-PLUGIN-CODE
// %/
[img(100%,auto)[Click for Full size (Eris Sig)|Images/erissigyb1.jpg][ES]]
file:\\D:\Staind\Dysfunction\Dysfunction_Home.mp3
+++[My Playlist]
<html>
<embed type="application/x-mplayer2" pluginspage="http://www.microsoft.com/Windows/MediaPlayer/" name="Player" autostart="false" ShowStatusBar="true" EnableContextMenu="true" width="300" height="40" loop="0" src="Dysfunction.m3u" />
</html>
===
+++[My Song]
<html>
<embed type="application/x-mplayer2" pluginspage="http://www.microsoft.com/Windows/MediaPlayer/" name="Player" autostart="false" ShowStatusBar="true" EnableContextMenu="true" width="300" height="40" loop="0" src="/music/Dysfunction.mp3" />
</html>
===
Name: Emerald
HeaderTop: #fff
HeaderMid: #50C878
HeaderBottom: #060
Background: #FFF
Foreground: #000
PrimaryPale: #fff
PrimaryLight: #50C878
PrimaryMid: #060
PrimaryDark: #50C878
SecondaryPale: #666
SecondaryLight: #ccc
SecondaryMid: #ccc
SecondaryDark: #ccc
TertiaryPale: #eee
TertiaryLight: #060
TertiaryMid: #ccc
TertiaryDark: #666
Error: #000
Test: #F00
Encrypted(31C436719C030BEC06E073B14DEFFE8917BB825D)
948cafa5de96608658653fd39bb023e331213133216105e07c2ab79e627124



{{menubox{
{{center{''__Encrypted data (passwords and sensitive information)__''+++[?]To Encrypt ANY tiddler use tag Encrypt(mynamehere) on save you will be asked for password for "mynamehere" see also: TiddlerEncryptionPlugin===}}}
{{centeredTable{
| <<tag [[Encrypted]]>> |
| <<newTiddler label:'New Encrypted Tiddler' title:'New Encrypted Tiddler' text:{{store.getTiddlerText('Template','')}} tag:'Encrypted]] [[Encrypt(Test)'>> |
}}}
}}}
{{{<<tiddler taggedRecent with:Reminders 7>>}}}
<<tiddler taggedRecent with:Reminders 7>>
<script show>
var ara1 = ['a','b','c','d','e','1','2','3','yellow car','blue car'];
var ara2 = ['c','e','f','2','4','blue car','purple car'];
var araDiff = ArraySubtract(ara1,ara2) ;

function ArraySubtract(ara1,ara2) {
  var aRes = new Array() ;
  for(var i=0;i<ara1.length;i++) {
    if( ! (ara2.contains(ara1[i]) )) {
      aRes.push(ara1[i]) ;
    }
  }
  return aRes ;

}

wikify(ara1+' (My Array 1)'+'\n' ,place);
wikify(ara2+' (My Array 2)' +'\n' ,place);
wikify(ArraySubtract(ara1,ara2)+' (aRes - perform the function here)' +'\n' ,place);
wikify(araDiff +' (Array Difference - return the var)' +'\n' ,place);
</script>

<script show>
var ara1 = ['a','b','c','d','e','1','2','3','yellow car','blue car'];
var ara2 = ['c','e','f','2','4','blue car','purple car'];
var araDiff = ArraySubtract(ara1,ara2) ;

//Using ArraySubtract Plugin

wikify(ara1+' (My Array 1)'+'\n' ,place);
wikify(ara2+' (My Array 2)' +'\n' ,place);
wikify(araDiff +' (Array Difference - [[ArraySubtract]] Plugin)' +'\n' ,place);
</script>

<script show>
var ara1 = store.getTaggedTiddlers("systemConfig");
var ara2 = store.getTaggedTiddlers("systemConfigDisable");
var araDiff = ArraySubtract(ara1,ara2);

//Using ArraySubtract Plugin

var l1 = ara1.length.toString();
var l2 = ara2.length.toString();
var l3 = araDiff.length.toString();

wikify(l1+' (Length of ara1 <<tag systemConfig>>)'+'\n' ,place);
wikify(l2+' (Length of ara2 <<tag systemConfigDisable>>)' +'\n' ,place);
wikify(l3+' (Length of araDiff <<tag systemConfig>> minus <<tag systemConfigDisable>>)' +'\n'+'!!!Results for araDiff'+'\n' ,place);

var out=[];
for (var t=0; t<araDiff.length; t++)
out.push('[['+araDiff[t].title+']]');
return out.join(' , ');

</script>
{{{<<tiddler taggedRecentList with:Reminders 7>>}}}
<<tiddler taggedRecentList with:Reminders 7>>
{{{<<tiddler taggedRecentList with:Tricks 7>>}}}
<<tiddler taggedRecentList with:Tricks 7>>
{{{<<tiddler taggedRecentList with:Tricks>>}}}
<<tiddler taggedRecentList with:Tricks>>
{{{<<tiddler taggedRecentList with:NoTag 7>>}}}
<<tiddler taggedRecentList with:NoTag 7>>
[[TagDB]]
<<forEachTiddler
	sortBy 
		'getSortedTagsText(tiddler)+"###"+tiddler.title'
    script '
        window.fetItemsPerPage = 20;

        function getHeader(context,count) {
            if (!window.fetStartIndex || window.fetStartIndex < 0) 
                window.fetStartIndex = 0;

            // ensure not to page behind the last page
            if (window.fetStartIndex >= count)
                window.fetStartIndex = Math.min(Math.max(window.fetStartIndex-window.fetItemsPerPage,0),count-1);

            createTiddlyButton(context.place,"<",null,
                    function(e) {
                        window.fetStartIndex -= window.fetItemsPerPage;
                        story.refreshTiddler(context.viewerTiddler.title,null,true);
                    });
            createTiddlyButton(context.place,">",null,
                    function(e) {
                        window.fetStartIndex += window.fetItemsPerPage;
                        story.refreshTiddler(context.viewerTiddler.title,null,true);
                    });

            var startNo = window.fetStartIndex+1;
            var endNo = Math.min(count,window.fetStartIndex+window.fetItemsPerPage);

            return "("+startNo+" - "+endNo+ " of "+ count + " items)\n";
        }
			function getSortedTagsText(tiddler) {
			var tags = tiddler.tags; 
			if (!tags || !tags.length) 
				return "{no tags}"; 
			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
            '(index >= window.fetStartIndex) && (index < window.fetStartIndex + 20) ? getGroupTitle(tiddler, context)+"** [["+tiddler.title+"]]\n" : ""'

        begin
            'getHeader(context,count)'

>>
{{left{<<photoGallery url:images/FamSlide-*.jpg first:1 last:11 height:300 time:4000 labels:SubTitles numbers >>}}}
<script label="FieldScriptCreator" show>
   var tids=store.getTiddlers("title");
   for (var t=0; t<tids.length; t++) {
      if (store.getValue(tids[t].title,"creator")!==undefined)
         store.setValue(tids[t].title,"creator","[[Mike Praeuner]]");
   }
</script>

<script label="FieldScriptCreator2" show>
   var tids=store.getTiddlers("title");
   for (var t=0; t<tids.length; t++) {
      if (store.getValue(tids[t].title,"creator")==undefined)
         store.setValue(tids[t].title,"creator","[[Mike Praeuner]]");
   }
</script>
/***
|''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);

//}}}
Name: Fire
HeaderTop: #f00
HeaderMid: #ff0
HeaderBottom: #ffa500
Background: #000
Foreground: #f30
PrimaryPale: #000
PrimaryLight: #f00
PrimaryMid: #ffa500
PrimaryDark: #f30
SecondaryPale: #ff0
SecondaryLight: #fc6
SecondaryMid: #F60
SecondaryDark: #ff0
TertiaryPale: #000
TertiaryLight: #ffa500
TertiaryMid: #555
TertiaryDark: #F90
Error: #F60
Test: #0F0
|''Name''|Fire1Theme|
|''Description''|Custom Theme Spawned from MPTW by MTP 11.08.08|
|''Last Revision''|MTP 12.31.08|

!Author Mode
|PageTemplate|ImgPageTemplate|
|ViewTemplate|CustomViewTemplate|
|EditTemplate|CustomEditTemplate|
|StyleSheet|##StyleSheet|
|ColorPalette|ColorPalette|


!StyleSheet
/*{{{*/
[[CustomStyleSheet]]
[[StyleSheetShortcuts]]
[[PluginStyles]]

/* Background Image */
body {
	background-image: url("theme/fire1.jpeg") !important;
	background-repeat: repeat;
}
#topMenu, .header, .headerNow {
	background: transparent !important;
}
/*}}}*/
|''Name''|Fire2Theme|
|''Description''|Custom Theme Spawned from MPTW by MTP 11.08.08|
|''Last Revision''|MTP 12.31.08|

!Author Mode
|PageTemplate|ImgPageTemplate|
|ViewTemplate|CustomViewTemplate|
|EditTemplate|CustomEditTemplate|
|StyleSheet|##StyleSheet|
|ColorPalette|ColorPalette|


!StyleSheet
/*{{{*/
[[CustomStyleSheet]]
[[StyleSheetShortcuts]]
[[PluginStyles]]

/* Background Image */
body {
	background-image: url("theme/fire2.jpeg") !important;
	background-repeat: repeat;
}
#topMenu, .header, .headerNow {
	background: transparent !important;
}
/*}}}*/
|''Name''|Fire3Theme|
|''Description''|Custom Theme Spawned from MPTW by MTP 11.08.08|
|''Last Revision''|MTP 12.31.08|

!Author Mode
|PageTemplate|ImgPageTemplate|
|ViewTemplate|CustomViewTemplate|
|EditTemplate|CustomEditTemplate|
|StyleSheet|##StyleSheet|
|ColorPalette|ColorPalette|


!StyleSheet
/*{{{*/
[[CustomStyleSheet]]
[[StyleSheetShortcuts]]
[[PluginStyles]]

/* Background Image */
body {
	background-image: url("theme/fire3.jpeg") !important;
	background-repeat: repeat;
}
#topMenu, .header, .headerNow {
	background: transparent !important;
}
/*}}}*/
|''Name''|Fire4Theme|
|''Description''|Custom Theme Spawned from MPTW by MTP 11.08.08|
|''Last Revision''|MTP 12.31.08|

!Author Mode
|PageTemplate|ImgPageTemplate|
|ViewTemplate|CustomViewTemplate|
|EditTemplate|CustomEditTemplate|
|StyleSheet|##StyleSheet|
|ColorPalette|ColorPalette|


!StyleSheet
/*{{{*/
[[CustomStyleSheet]]
[[StyleSheetShortcuts]]
[[PluginStyles]]

/* Background Image */
body {
	background-image: url("theme/fire4.jpeg") !important;
	background-repeat: repeat;
}
#topMenu, .header, .headerNow {
	background: transparent !important;
}
/*}}}*/
|''Name''|FireMindTheme|
|''Description''|Custom Theme Spawned from MPTW by MTP 11.08.08|
|''Last Revision''|MTP 12.31.08|

!Author Mode
|PageTemplate|ImgPageTemplate|
|ViewTemplate|CustomViewTemplate|
|EditTemplate|CustomEditTemplate|
|StyleSheet|##StyleSheet|
|ColorPalette|ColorPalette|


!StyleSheet
/*{{{*/
[[CustomStyleSheet]]
[[StyleSheetShortcuts]]
[[PluginStyles]]

/* Background Image */
body {
	background-image: url("theme/fw2.jpeg") !important;
	background-repeat: repeat;
}
#topMenu, .header, .headerNow {
	background: transparent !important;
}
/*}}}*/
/***
|''Name''|FirefoxPrivilegesPlugin|
|''Description''|Create a backstage tab to manage Firefox url privileges|
|''Author''|Xavier Vergés (xverges at gmail dot com)|
|''Version''|1.1.1 ($Rev: 4266 $)|
|''Date''|$Date: 2008-04-06 09:04:49 +0200 (dom, 06 abr 2008) $|
|''Status''|@@beta@@|
|''Source''|http://firefoxprivileges.tiddlyspot.com/|
|''CodeRepository''|http://trac.tiddlywiki.org/browser/Trunk/contributors/XavierVerges/plugins/FirefoxPrivilegesPlugin.js|
|''License''|BSD tbd|
|''CoreVersion''|2.2.4 (maybe 2.2+?)|
|''Feedback''|http://groups.google.com/group/TiddlyWiki|
|''BookmarkletReady''|http://icanhaz.com/firefoxprivileges|
|''Browser''|Mozilla. Tested under Firefox 2.0.0.12 and Firefox 3.0b4|
|''Documentation''|http://firefoxprivileges.tiddlyspot.com/#HowTo|
/%
!Description
!Notes
!Usage
!Revision History
!!v1.0 (2008-03-23)
* First public version
%/
!Usage
The wizard can be opened from the backstage or using the macro {{{<<firefoxPrivileges>>}}}
The step to show when opening the wizard can be set with the {{{txtPrivWizardDefaultStep}}} option: <<option txtPrivWizardDefaultStep>>
!Code
***/
//{{{
if(window.Components) {
config.macros.firefoxPrivileges = {};
config.macros.firefoxPrivileges.lingo = {};
/*
//}}}
!!! Strings to translate
//{{{
*/
merge(config.macros.firefoxPrivileges.lingo ,{
	wizardTitle: "Manage Firefox Privileges",
	learnStepTitle: "1. Learn about the risks of giving privileges to file: urls",
	learnStepHtml: "<h3>Local files</h3><p>Firefox can be configured to grant the same security privileges to every html document loaded from disk (those <i>file:</i> urls), or to grant different privileges on a per file basis. Local TiddyWikis need some high security privileges in order to let you save changes to disk, or to import tiddlers from remote servers. Unfortunately, these same privileges can potentially be used by the bad guys to launch programs, get files from your disk and upload them somewhere, access your browsing history...</p><p>While it is more convenient to let Firefox give all your local files the same security privileges, and I'm not aware of any malware attack that tries to take advantage of privileged <i>file:</i> urls, an ounce of prevention is worth a pound of cure.</p><p>You can learn more about this by reading <a href='http://www.mozilla.org/projects/security/components/per-file.html' class='externalLink'>Per-File Permissions</a> and <a href='http://www.mozilla.org/projects/security/components/signed-scripts.html#privs-list' class='externalLink'>JavaScript Security: Signed Script</a> at mozilla.org.</p><h3>Remote files</h3><p>When a remote document (<i>http:</i> urls) requests especial privileges, Firefox <ul><li>checks the value of <code>signed.applets.codebase_principal_support</code>, a preference that can be configured from the page that is loaded when you type <code>about:config</code> in the address bar</li><li>if the previous value is set to false, Firefox denies silently the request</li><li>if the previous value is set to true, Firefox looks for the document's domain in the list of privileges urls that can be configured from this wizard, and, if not there, asks the user to grant the privilege</li></ul><p>Note that, in this case, and unlike when dealing with local files, Firefox will only take into account the document's domain instead of performing an exact match of the url.</p><p>Take a look at <a href='http://messfromabove.tiddlyspot.com' class='externalLink'>http://messfromabove.tiddlyspot.com</a> to learn more about the nice and nasty possibilities that this setting provides.</p><h3>This Wizard</h3><p>This wizard will help you to grant the required privileges to your TiddlyWikis, local or remote, and warn you if you have enabled a dangerous default. To do so, Firefox will probably prompt you to grant it some special privileges in order to list and modify the list of privileged urls.</p><p>Please note that changing the privileges for an url may not have effect until you reload it in the browser.</p><input type='hidden' name='mark'></input>",
	learnStepButton: "1. Learn about the risks",
	learnStepButtonTooltip: "Learn why 'Remember this' is an unsafe choice in security prompts",
	grantStepTitle: "2. Grant privileges to individual local documents or remote domains",
	grantStepHtml: "Url: <input type='text' size=80 name='txtUrl'><br/><br/><input type='checkbox' checked='true' name='chkUniversalXPConnect'>Grant rights required to save to disk (Run or install software on your machine - UniversalXPConnect)</input><br/><input type='checkbox' checked='true' name='chkUniversalBrowserRead'>Grant rights required to import tiddlers from servers or access TiddlySpot (Read and upload local files - UniversalBrowserRead)</input><br/><input type='checkbox' name='chkUniversalBrowserWrite'>Modify any open window - UniversalBrowserWrite</input><br/><input type='checkbox' name='chkUniversalFileRead'>Read and upload local files - UniversalFileRead</input><br/><input type='checkbox' name='chkCapabilityPreferencesAccess'>By-pass core security settings - CapabilityPreferencesAccess</input><br/><input type='checkbox' name='chkUniversalPreferencesRead'>Read program settings - UniversalPreferencesRead</input><br/><input type='checkbox' name='chkUniversalPreferencesWrite'>Modify program settings - UniversalPreferencesWrite</input><br/><input type='button' class='button' name='btnGrant' value='Set privileges'/>",
	grantStepButton: "2. Set privileges",
	grantStepButtonTooltip: "Manage privileges for this or other docs",
	viewStepTitle: "3. Granted privileges",
	viewStepHtml: "<input type='hidden' name='mark'></input>",
	viewStepButton: "3. View privileges",
	viewStepButtonTooltip: "List granted privileges, and optionally reset them",
	viewStepEmptyMsg: "Asking for temporary privileges to list permanent privileges...",
	listViewTemplate: {
		columns: [
			{name: 'Selected', field: 'Selected', rowName: 'url', type: 'Selector'},
			{name: 'Url', field: 'url', title: "Url", type: 'LongLink'},
			{name: 'Granted', field: 'granted', title: "Granted", type: 'StringList'},
			{name: 'Denied', field: 'denied', title: "Denied", type: 'StringList'},
			{name: 'Handle', field: 'handle', title: "Handle", type: 'String'},
            {name: 'Notes', field: 'notes', title: "Notes", type: 'String'}
			],
		rowClasses: [
			{className: 'lowlight', field: 'highlight'},
			{className: 'error', field: 'warning'}
			]
		},
	listResetButton: "Reset the privileges of the selected urls",
	noteDangerous: "This is dangerous",
	noteNoEffect: "This has no effect",
	noteThisUrl: "This document's url",
	noteTheUrlYouUpdated: "The url you just updated",
	errNoUrl: "The url is required",
	errNotAuthorized: "Not enough privileges. Maybe you are trying this from a tiddlywiki loaded from a server?",
	msgUpdating: "Updating privileges for %0",
	msgSetting: "Setting privileges for %0",
	msgResetting: "Resetting privileges for %0"
});
merge(config.optionsDesc,{
	txtPrivWizardDefaultStep: "Step to show when opening the 'Manage Firefox Privileges' wizard"
});
merge(config.tasks,{
	firefoxPrivileges: {text: "security", tooltip: "Work with Firefox url privileges", content: '<<firefoxPrivileges>>'}
});
/*
//}}}
!!! Regular code
//{{{
*/
config.backstageTasks.pushUnique("firefoxPrivileges");
if (typeof(config.options.txtPrivWizardDefaultStep) === "undefined"){
	config.options.txtPrivWizardDefaultStep = "1";
}

(function(){

var plugin = config.macros.firefoxPrivileges;
var lingo = plugin.lingo;
plugin.privAccessCapabilities = "UniversalXPConnect CapabilityPreferencesAccess";
plugin.stepNames = ["learn", "grant", "view"];
plugin.lastUrl = document.location.toString();

plugin.handler = function(place,macroName,params,wikifier,paramString,tiddler)
{
	var wizard = new Wizard();
	wizard.createWizard(place,lingo.wizardTitle);
	var step = parseInt(config.options.txtPrivWizardDefaultStep);
	step = (isNaN(step)||(step<=0)||(step>3))? 0 : step-1;
	plugin.step(wizard, step);
};
plugin.buttons = (function(){
	var onclick = {};
	for (var ii=0; ii<plugin.stepNames.length; ii++) {
		onclick[plugin.stepNames[ii]] = 
			(function() {
				var index = ii;
				var handler = function(e) {
					plugin.step(new Wizard(resolveTarget(e)), index);
					return false;
				};
				return handler;})();
	}
	var getButtons = function(index) {
		var buttons = [];
		for (var ii= 0; ii<plugin.stepNames.length; ii++) {
			if (ii !== index) {
				var name = plugin.stepNames[ii];
				buttons.push({
					onClick: onclick[name],
					caption: lingo[name+"StepButton"],
					tooltip: lingo[name+"StepButtonTooltip"]
				});
			}
		}
		return buttons;
	};
	return getButtons;
})();
plugin.step = function(wizard, stepIndex, extraParams)
{
	var name = plugin.stepNames[stepIndex];
	var stepResult = {};
	wizard.addStep(lingo[name+"StepTitle"],lingo[name+"StepHtml"]);
	wizard.setButtons(plugin.buttons(stepIndex));
	if (plugin[name+"StepProcess"]) {
		plugin[name+"StepProcess"](wizard, extraParams);
	}
};
plugin.getMarkedDiv = function(wizard)
{
	var mark = wizard.getElement("mark");
	var div = document.createElement("div");
	mark.parentNode.insertBefore(div,mark);
	return div;
};
plugin.learnStepProcess = function(wizard)
{
	var src = config.optionsDesc.txtPrivWizardDefaultStep + ": <<option txtPrivWizardDefaultStep>>";
	wikify(src, plugin.getMarkedDiv(wizard));
}
plugin.grantStepProcess = function(wizard)
{
	wizard.getElement("btnGrant").onclick = plugin.btnSetPrivileges;
	wizard.getElement("txtUrl").value = plugin.lastUrl;
};
plugin.viewStepProcess = function(wizard, extraParams)
{
	var listWrapper = plugin.getMarkedDiv(wizard);
	listWrapper.innerHTML = lingo.viewStepEmptyMsg;

	var html = [];
	try {
		if (!extraParams || extraParams.reqAcccess) {
			netscape.security.PrivilegeManager.enablePrivilege(plugin.privAccessCapabilities);
		}

		var thisUrl = document.location.toString();
		var privs = plugin.getPrivilegedUrls(false);
		var listItems = [];
		for (var handle in privs) {
			if (privs.hasOwnProperty(handle)) {
				var priv = privs[handle];
				if ((priv.url === "file://") ||
					(priv.url.indexOf(" ") !== -1)) {
					priv.warning = true;
					priv.notes = (priv.url === "file://")? lingo.noteDangerous:lingo.noteNoEffect;
				} else if ((priv.url === thisUrl) || 
				           (priv.url === plugin.lastUrl)) {
					priv.highlight = true;
					priv.notes = (priv.url === thisUrl)? lingo.noteThisUrl:lingo.noteTheUrlYouUpdated;
				} 
				listItems.push(priv);
			}
		}
		var sortFunc = function(a,b) {
			if(a.url > b.url) {return 1;}
			if(a.url < b.url) {return -1;}
			return 0;
		};
		listItems.sort(sortFunc);
		listWrapper.innerHTML = "";
		var listView = ListView.create(listWrapper, listItems, lingo.listViewTemplate);
		wizard.setValue("listView",listView);

		createTiddlyButton(listWrapper, lingo.listResetButton, "", plugin.btnResetPrivileges);
	} catch (ex) {
		listWrapper.innerHTML = "Error: " + ex;
	}
};
plugin.btnSetPrivileges = function(ev)
{
	var wizard = new Wizard(this);
	var checkboxes = wizard.bodyElem.getElementsByTagName("input");
	var grant = [];
	for(var t=0; t<checkboxes.length; t++) {
		var cb = checkboxes[t];
		if((cb.getAttribute("type") === "checkbox")&&cb.checked) {
			grant.push(cb.name.substring(3));
		}
	}
	var url = wizard.getElement("txtUrl").value;
	if (!url) {
		alert(lingo.errNoUrl);
	} else {
		plugin.lastUrl = url;
		var viewStepExtraParams = {reqAcccess: false};
		var gotPrivileges = false;
		try {
			netscape.security.PrivilegeManager.enablePrivilege(config.macros.firefoxPrivileges.privAccessCapabilities);
			gotPrivileges = true;
		} catch(ex) {}
		if (gotPrivileges) {
			plugin.setUrlPrivilege(false, url, grant, false);
			plugin.step(wizard, 2, viewStepExtraParams);
		} else {
			alert(lingo.errNotAuthorized);
		}
	}
	return false;
};
plugin.btnResetPrivileges = function(ev)
{
	var wizard = new Wizard(this);
	var listView = wizard.getValue("listView");
	var urls = ListView.getSelectedRows(listView);
	if(urls.length === 0) {
		alert(config.messages.nothingSelected);
	} else {
		netscape.security.PrivilegeManager.enablePrivilege(config.macros.firefoxPrivileges.privAccessCapabilities);
		for (var ii=0; ii<urls.length; ii++) {
			plugin.setUrlPrivilege(false, urls[ii], [], true);
		}
		plugin.step(wizard, 2, {reqAcccess: false});
	}
	return false;
};
plugin.setUrlPrivilege = function(reqAccess, url, rights, reset)
{
	function getFreeHandle(dict, prefix) {
		var handle = prefix;
		var ii = 0;
		while("undefined" !== typeof(dict[handle])) {
			ii++;
			handle = prefix + ii;
		}
		return handle;
	}
	if (reqAccess) {
		netscape.security.PrivilegeManager.enablePrivilege(plugin.privAccessCapabilities);
	}
	var isUpdate = true;
	var urlHandle = "";
	var urls = plugin.getPrivilegedUrls(false);
	for (var handle in urls) {
		if (urls[handle].url === url) {
			urlHandle = handle;
			break;
		}
	}
	var denied = [];
	var granted = [];
	if (urlHandle) {
		if (!reset) {
			displayMessage(lingo.msgUpdating.format([url]), url);
			denied = urls[urlHandle].denied.slice();
			granted = urls[urlHandle].granted.slice();
		} else {
			displayMessage(lingo.msgResetting.format([url]), url);
		}
	} else {
		displayMessage(lingo.msgSetting.format([url]), url);
		urlHandle = getFreeHandle(urls, "FirefoxPrivilegesPlugin");
		isUpdate = false;
	}
	for (var ii=0; ii<rights.length; ii++) {
		denied.remove(rights[ii]);
		granted.pushUnique(rights[ii]);
	}
	var prefs = plugin.getPrefsBranch();
	var idStr = urlHandle + ".id";
	var deniedStr = urlHandle + ".denied";
	var grantedStr = urlHandle + ".granted";
	function clearPref(str) {
		if (prefs.prefHasUserValue(str)) {
			prefs.clearUserPref(str);
		}
	}
	function setOrClearPref(str, val) {
		if (val.length) {
			val = ("string" === typeof(val))? val : val.join(" ");
			prefs.setCharPref(str, val);
			// why oh why?!
			if (!prefs.prefHasUserValue(str)) {
				prefs.setCharPref(str, val);
			}
		} else {
			clearPref(str);
		}
	}
	if (!denied.length && !granted.length) {
		prefs.deleteBranch(urlHandle + ".");
	} else {
		setOrClearPref(idStr, url);
		setOrClearPref(deniedStr, denied);
		setOrClearPref(grantedStr , granted);
		setOrClearPref(idStr, url);
	}
	var prefService = plugin.getPrefsService();
	prefService.savePrefFile(null);

	return !isUpdate;
};
plugin.getPrivilegedUrls = function(reqAccess)
{
	function Privileged(url, granted, denied, handle) {
		this.url = url;
		this.granted = granted;
		this.denied = denied;
		this.handle = handle;
	}
	function getPermissions(branch, handle, type) {
		var permissions = [];
		var pref = handle + "." + type;
		if (branch.prefHasUserValue(pref)) {
			permissions = branch.getCharPref(pref).split(/\s+/);
			permissions.sort();
		}
		return permissions;
	}
	var privileged = {};
	if (reqAccess) {
		netscape.security.PrivilegeManager.enablePrivilege(plugin.privAccessCapabilities);
	}
	var prefs = plugin.getPrefsBranch(); 
	var capsEntries = prefs.getChildList("", { value: 0 }); 

	for (var ii=0; ii < capsEntries.length; ii++) 
	{ 
		var matches = capsEntries[ii].match(/([^\.]*)[\.]id/); 
		if (matches && (2 === matches.length)) 
		{ 
			var handle = matches[1];
			var url = prefs.prefHasUserValue(capsEntries[ii])? prefs.getCharPref(capsEntries[ii]) : "Error getting " + capsEntries[ii]; 
			var granted = getPermissions(prefs, handle, "granted");
			var denied = getPermissions(prefs, handle, "denied");
			privileged[handle] = new Privileged(url, granted, denied, handle);
		}
	}
	return privileged;
};
plugin.getPrefsService = function()
{
	return Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
};
plugin.getPrefsBranch = function()
{
	var prefsService = plugin.getPrefsService();
	return prefsService.getBranch("capability.principal.codebase."); 
};
/*
//}}}
!!! Bookmarklet interface
//{{{
*/
plugin.onload = function()
{
	var b=backstage;
	var bt=createTiddlyButton(b.toolbar, "security"+glyph("downTriangle"), "", b.onClickTab,"backstageTab");
	var fp="firefoxPrivileges";
	bt.setAttribute("task",fp);
	b.switchTab(fp);
};
/*
//}}}
!!! ListView tweak for long urls. http://trac.tiddlywiki.org/ticket/570
//{{{
*/
ListView.columnTypes.LongLink = {
	createHeader: ListView.columnTypes.String.createHeader,
	createItem: function(place,listObject,field,columnTemplate,col,row)
		{
			var v = listObject[field];
			var c = columnTemplate.text;
			if(v != undefined) {
				var link = createExternalLink(place,v);
				if(!c) {
					c = v.replace(/#|\.|\/|(\%..)|\?|\&/g, config.browser.isIE? "$&<wbr>": "$&&#8203;");
					link.innerHTML = c;
				} else {
					createTiddlyText(link, c);
				}
			}
		}
};


})();	// scope hiding

} // endif(window.Components)
//}}}
/***
|Name|FontSizePlugin|
|Created by|SaqImtiaz|
|Location|http://tw.lewcid.org/#FontSizePlugin|
|Version|1.0|
|Requires|~TW2.x|
!Description:
Resize tiddler text on the fly. The text size is remembered between sessions by use of a cookie.
You can customize the maximum and minimum allowed sizes.
(only affects tiddler content text, not any other text)

Also, you can load a TW file with a font-size specified in the url.
Eg: http://tw.lewcid.org/#font:110

!Demo:
Try using the font-size buttons in the sidebar, or in the MainMenu above.

!Installation:
Copy the contents of this tiddler to your TW, tag with systemConfig, save and reload your TW.
Then put {{{<<fontSize "font-size:">>}}} in your SideBarOptions tiddler, or anywhere else that you might like.

!Usage
{{{<<fontSize>>}}} results in <<fontSize>>
{{{<<fontSize font-size: >>}}} results in <<fontSize font-size:>>

!Customizing:
The buttons and prefix text are wrapped in a span with class fontResizer, for easy css styling.
To change the default font-size, and the maximum and minimum font-size allowed, edit the config.fontSize.settings section of the code below.

!Notes:
This plugin assumes that the initial font-size is 100% and then increases or decreases the size by 10%. This stepsize of 10% can also be customized.

!History:
*27-07-06, version 1.0 : prevented double clicks from triggering editing of containing tiddler.
*25-07-06,  version 0.9

!Code
***/

//{{{
config.fontSize={};

//configuration settings
config.fontSize.settings =
{
            defaultSize : 100,  // all sizes in %
            maxSize : 200,
            minSize : 40,
            stepSize : 10
};

//startup code
var fontSettings = config.fontSize.settings;

if (!config.options.txtFontSize)
            {config.options.txtFontSize = fontSettings.defaultSize;
            saveOptionCookie("txtFontSize");}
setStylesheet(".tiddler .viewer {font-size:"+config.options.txtFontSize+"%;}\n","fontResizerStyles");
setStylesheet("#contentWrapper .fontResizer .button {display:inline;font-size:105%; font-weight:bold; margin:0 1px; padding: 0 3px; text-align:center !important;}\n .fontResizer {margin:0 0.5em;}","fontResizerButtonStyles");

//macro
config.macros.fontSize={};
config.macros.fontSize.handler = function (place,macroName,params,wikifier,paramString,tiddler)
{

               var sp = createTiddlyElement(place,"span",null,"fontResizer");
               sp.ondblclick=this.onDblClick;
               if (params[0])
                           createTiddlyText(sp,params[0]);
               createTiddlyButton(sp,"+","increase font-size",this.incFont);
               createTiddlyButton(sp,"=","reset font-size",this.resetFont);
               createTiddlyButton(sp,"–","decrease font-size",this.decFont);
}

config.macros.fontSize.onDblClick = function (e)
{
             if (!e) var e = window.event;
             e.cancelBubble = true;
             if (e.stopPropagation) e.stopPropagation();
             return false;
}

config.macros.fontSize.setFont = function ()
{
               saveOptionCookie("txtFontSize");
               setStylesheet(".tiddler .viewer {font-size:"+config.options.txtFontSize+"%;}\n","fontResizerStyles");
}

config.macros.fontSize.incFont=function()
{
               if (config.options.txtFontSize < fontSettings.maxSize)
                  config.options.txtFontSize = (config.options.txtFontSize*1)+fontSettings.stepSize;
               config.macros.fontSize.setFont();
}

config.macros.fontSize.decFont=function()
{

               if (config.options.txtFontSize > fontSettings.minSize)
                  config.options.txtFontSize = (config.options.txtFontSize*1) - fontSettings.stepSize;
               config.macros.fontSize.setFont();
}

config.macros.fontSize.resetFont=function()
{

               config.options.txtFontSize=fontSettings.defaultSize;
               config.macros.fontSize.setFont();
}

config.paramifiers.font =
{
               onstart: function(v)
                  {
                   config.options.txtFontSize = v;
                   config.macros.fontSize.setFont();
                  }
};
//}}}
<!--{{{-->
<!-- http://mptw.tiddlyspot.com/#MptwPageTemplate ($Rev: 1829 $) -->
<!-- Modified for Quote & Footer div change PageTemplate link to use new template -->
<div class='header' macro='gradient vert  [[ColorPalette::PrimaryLight]] [[ColorPalette::HeaderMid]] [[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 class='qD' id='qD' refresh='content' tiddler='qD'></div>
	<div id='messageArea'></div>
	<div id='tiddlerDisplay'></div>
	<div class='fD' id='contentFooter' refresh='content' tiddler='contentFooter'></div>
</div>
<!--}}}-->
/*{{{*/
/* http://mptw.tiddlyspot.com/#MptwStyleSheet ($Rev: 2246 $) */
/* a contrasting background so I can see where one tiddler ends and the other begins */
/* Added stlye to change header height & qD style for quote & footer */
/* a little more room for hover menu floater */
/* Rounded a few corners for fun :) */
body {
	background: [[ColorPalette::TertiaryLight]];
}
/* experiment, making header phat */
.header {
	height: 75px;
}
/* experiment, new quote Div */
.qD {
	-moz-border-radius: 1em;
	align: center;
	text-align: center;
	background: [[ColorPalette::Background]];
	border-right: 2px [[ColorPalette::TertiaryMid]] solid;
	border-bottom: 2px [[ColorPalette::TertiaryMid]] solid;
	margin-left: 1em;
	margin-right: 1em;
	margin-top: 1em;
	margin-bottom: 1em;
}
/* experiment, new footer Div */
.fD {
	-moz-border-radius: 1em;
	align: center;
	text-align: center;
	background: [[ColorPalette::Background]];
	border-right: 2px [[ColorPalette::TertiaryMid]] solid;
	border-bottom: 2px [[ColorPalette::TertiaryMid]] solid;
	color: [[ColorPalette::Foreground]];
	margin-left: 1em;
	margin-right: 1em;
	margin-top: 1em;
	margin-bottom: 1em;
}
/* 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 {
	font-family: 'Consolas' monospace;
}

/* 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 {
	-moz-border-radius: 2em;
	background: [[ColorPalette::Background]];
	border-right: 2px [[ColorPalette::TertiaryMid]] solid;
	border-bottom: 2px [[ColorPalette::TertiaryMid]] solid;
	margin-bottom: 1em;
	padding-bottom: 1em;
	padding-top: 0.75em;
	margin-left: 1em;
	margin-right: 1em;
}

/* 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;
}
#hoverMenu  .button, #hoverMenu  .tiddlyLink {border:none; font-weight:bold; background:#fff; color:#000; padding:0 5px; float:right; margin-bottom:4px;
}
#hoverMenu .button:hover, #hoverMenu .tiddlyLink:hover {font-weight:bold; border:none; color:ffff; background:#000; padding:0 5px; float:right; margin-bottom:4px;
}
/* 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; }

/* for Tagger Plugin, thanks 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;
	}
}
/*}}}*/
/***
|''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.
***/
<html><nowiki><form>
<input name="title">
<input name="email">
<input name="foto">
<textarea name="perfil" rows="7" cols="60"></textarea>
<input type="button" value="Registra-se" onclick='
    var title=this.form.title.value;
    var email=this.form.email.value;
    var foto=this.form.foto.value;
    var perfil=this.form.perfil.value;
    var who=title;
    var when=new Date();
    var txt="[<img(200px,auto)["+foto+"]] (email:"+email+")\n"+perfil
 +"\n"+store.getTiddlerText("Registrarse##VideoText", "")
 +store.getTiddlerText("Registrarse##ePegadas", "");
    var tags="participant";
    var fields={};
    store.saveTiddler(title,title,txt,who,when,tags,fields);
    story.displayTiddler(null,title);
    return false;
'></form></html> 
/***
|Name|FullScreenPlugin|
|Created by|SaqImtiaz|
|Location|http://tw.lewcid.org/#FullScreenPlugin|
|Version|1.1|
|Requires|~TW2.x|
!Description:
Toggle between viewing tiddlers fullscreen and normally. Very handy for when you need more viewing space.

!Demo:
Click the ↕ button in the toolbar for this tiddler. Click it again to turn off fullscreen.

!Installation:
Copy the contents of this tiddler to your TW, tag with systemConfig, save and reload your TW.
Edit the ViewTemplate to add the fullscreen command to the toolbar.

!History:
*25-07-06: ver 1.1
*20-07-06: ver 1.0

!Code
***/
//{{{
var lewcidFullScreen = false;

config.commands.fullscreen =
{
            text:" ↕ ",
            tooltip:"Fullscreen mode"
};

config.commands.fullscreen.handler = function (event,src,title)
{
            if (lewcidFullScreen == false)
               {
                lewcidFullScreen = true;
                setStylesheet('#sidebar, .header, #mainMenu{display:none;} #displayArea{margin:0em 0 0 0 !important;}',"lewcidFullScreenStyle");
               }
            else
               {
                lewcidFullScreen = false;
                setStylesheet(' ',"lewcidFullScreenStyle");
               }
}

config.macros.fullscreen={};
config.macros.fullscreen.handler =  function(place,macroName,params,wikifier,paramString,tiddler)
{
        var label = params[0]||" ↕ ";
        var tooltip = params[1]||"Fullscreen mode";
        createTiddlyButton(place,label,tooltip,config.commands.fullscreen.handler);
}

var lewcid_fullscreen_closeTiddler = Story.prototype.closeTiddler;
Story.prototype.closeTiddler =function(title,animate,slowly)
{
           lewcid_fullscreen_closeTiddler.apply(this,arguments);
           if (story.isEmpty() && lewcidFullScreen == true)
              config.commands.fullscreen.handler();
}


Slider.prototype.lewcidStop = Slider.prototype.stop;
Slider.prototype.stop = function()
{
           this.lewcidStop();
           if (story.isEmpty() && lewcidFullScreen == true)
              config.commands.fullscreen.handler();
}
//}}}
<script>

/***
Requires InlineJavascriptPlugin. Use as a transclusion!
Put code into a tiddler, e.g. called "GetTaggedByField".
To get a sumary, call this tiddler using the tiddler macro like so:

<<tiddler getTaggedByField with: myTag myField>>
***/

//arr=results array, b=in results, g/i=control variables, out=output string, tid=tiddler, val=fieldvalue
var arr=[],b,g,i,out="",tid,val;
//tag and field to lookup
var theTag="$1";
var theField="$2";
//not tag or field --> no output
if(theTag=="$"+"1"||theField=="$"+"2")return;
//get all tids
var tids=store.getTiddlers('title','excludeLists');
//loop over all tids
for(i=0;i<tids.length;i++){
	//get tid
	tid=tids[i];
	//has tag?
	if(tid.tags.contains(theTag)){
		//get field
		val=store.getValue(tid,theField);
		//if defined
		if(val){
			//reset boolean
			b=false;
			//loop output (is there a builtin "contains" function for that?)
			for(g=0;g<arr.length;g++){
				//if fieldvalue already in array
				if(arr[g][0]==val){
					//remember that added
					b=true;
					//add to sublist
					arr[g][1][arr[g][1].length]=tid.title;
					//get out of the loop
					exit;
				}
			}
			//if no existing group
			if(!b){
				//get last
				g=arr.length;
				//add sublist
				arr[g]=[];
				//add fieldvalue and tiddlername as first element to sublist
				arr[g][0]=val;
				arr[g][1]=[];
				arr[g][1][0]=tid.title;
			}
		}
	}
}
//sort output alphabetically
arr.sort();
//loop over results array
for(g=0;g<arr.length;g++){
	//add group header as level one list
	out+="*[["+arr[g][0]+"]]\n";
	//get sublist and sort it
	l=arr[g][1]; l.sort;
	//loop over groupelements
	for(i=0;i<l.length;i++){
		//add element as second level listitem
		out+="**[["+l[i]+"]]\n";	
	}
}
//done
return out;
</script>
<<gradient horiz #bbbbbb #eeeeee #ffffff>>The new GradientMacro allows simple horizontal and vertical coloured gradients. They are constructed from coloured HTML elements, and don't require any images to work.>>
The GradientMacro is an ExtendedMacro that processes the text after it up until the next '>>' sequence. It looks like this:
{{{<<gradient vert #ffffff #ffdddd #ff8888>>gradient fill>>}}}
The first parameter can be ''vert'' or ''horiz'' to indicate the direction of the gradient. The following parameters are two or more colours (CSS RGB(r,g,b) format is also acceptable). The GradientMacro constructs a smooth linear gradient between each of the colours in turn.

| <<gradient vert #ffffff #ffdddd #ff8888>>No images were harmed in the making of this gradient fill>> | <<gradient vert #ffffff #ddffdd #88ff88>>No images were harmed in the making of this gradient fill>> | <<gradient vert #ffffff #ddddff #8888ff>>No images were harmed in the making of this gradient fill>> |

Inline CSS definitions can be added to gradient filles like this:

<<gradient vert #000000 #660000 #aa2222>>color:#ffffff;font-size:14pt;Darkness>>
{{{<<gradient vert #000000 #660000 #aa2222>>color:#ffffff;font-size:14pt;Darkness>>}}}
Name: Green2Green
HeaderTop: #efc
HeaderMid: #bc9
HeaderBottom: #453
Background: #efc
Foreground: #000
PrimaryPale: #bc9
PrimaryLight: #9ACD32
PrimaryMid: #453
PrimaryDark: #000
SecondaryPale: #ffc
SecondaryLight: #99dd55
SecondaryMid: #cccccc
SecondaryDark: #453
TertiaryPale: #bc9
TertiaryLight: #bc9
TertiaryMid: #ccc
TertiaryDark: #8B7355
<html>
           <div class="ContentArea">
      
          
          <span id="ctl00_altSelector"></span>
          
        
          <!--starting processing--><div class="topic" ><div class="majorTitle"><!----></div><div class="title">Additional Named Entities for HTML</div><!--Content type: SDKML. Transform: webcollection2mtps.xslt.--><div class="clsDocBody"><p>The following table contains additional named entities, their numeric character references (NCR), and a description of each. With the exception of the left and right-pointing brackets (&amp;#9001; and &amp;#9002;), the entities on this page are rendered using <code>Lucida sans Unicode</code>.</p>

<table class="clsStd">
<tr><th>Character</th><th>Named entity</th><th>NCR</th><th>Description</th></tr>

<tr><td colspan="4"><em>Latin Extended-B</em></td></tr>
<tr><td>ƒ</td><td>&amp;fnof;</td><td>&amp;#402;</td><td> Latin small f with hook, =function, =florin, U0192 ISOtech</td></tr>

<tr><td colspan="4"><em>Greek</em></td></tr>

<tr><td>Α</td><td>&amp;Alpha;</td><td>&amp;#913;</td><td> Greek capital letter alpha, U0391</td></tr>

<tr><td>Β</td><td>&amp;Beta;</td><td>&amp;#914;</td><td> Greek capital letter beta, U0392</td></tr>

<tr><td>Γ</td><td>&amp;Gamma;</td><td>&amp;#915;</td><td> Greek capital letter gamma, U0393 ISOgrk3</td></tr>

<tr><td>Δ</td><td>&amp;Delta;</td><td>&amp;#916;</td><td> Greek capital letter delta, U0394 ISOgrk3</td></tr>

<tr><td>Ε</td><td>&amp;Epsilon;</td><td>&amp;#917;</td><td> Greek capital letter epsilon, U0395</td></tr>

<tr><td>Ζ</td><td>&amp;Zeta;</td><td>&amp;#918;</td><td> Greek capital letter zeta, U0396</td></tr>

<tr><td>Η</td><td>&amp;Eta;</td><td>&amp;#919;</td><td> Greek capital letter eta, U0397</td></tr>

<tr><td>Θ</td><td>&amp;Theta;</td><td>&amp;#920;</td><td> Greek capital letter theta, U0398 ISOgrk3</td></tr>

<tr><td>Ι</td><td>&amp;Iota;</td><td>&amp;#921;</td><td> Greek capital letter iota, U0399</td></tr>

<tr><td>Κ</td><td>&amp;Kappa;</td><td>&amp;#922;</td><td> Greek capital letter kappa, U039A</td></tr>

<tr><td>Λ</td><td>&amp;Lambda;</td><td>&amp;#923;</td><td> Greek capital letter lambda, U039B ISOgrk3</td></tr>

<tr><td>Μ</td><td>&amp;Mu;</td><td>&amp;#924;</td><td> Greek capital letter mu, U039C</td></tr>

<tr><td>Ν</td><td>&amp;Nu;</td><td>&amp;#925;</td><td> Greek capital letter nu, U039D</td></tr>

<tr><td>Ξ</td><td>&amp;Xi;</td><td>&amp;#926;</td><td> Greek capital letter xi, U039E ISOgrk3</td></tr>

<tr><td>Ο</td><td>&amp;Omicron;</td><td>&amp;#927;</td><td> Greek capital letter omicron, U039F</td></tr>

<tr><td>Π</td><td>&amp;Pi;</td><td>&amp;#928;</td><td> Greek capital letter pi, U03A0 ISOgrk3</td></tr>

<tr><td>Ρ</td><td>&amp;Rho;</td><td>&amp;#929;</td><td> Greek capital letter rho, U03A1</td></tr>

<tr><td>Σ</td><td>&amp;Sigma;</td><td>&amp;#931;</td><td> Greek capital letter sigma, U03A3 ISOgrk3</td></tr>

<tr><td>Τ</td><td>&amp;Tau;</td><td>&amp;#932;</td><td> Greek capital letter tau, U03A4</td></tr>

<tr><td>Υ</td><td>&amp;Upsilon;</td><td>&amp;#933;</td><td> Greek capital letter upsilon, U03A5 ISOgrk3</td></tr>

<tr><td>Φ</td><td>&amp;Phi;</td><td>&amp;#934;</td><td> Greek capital letter phi, U03A6 ISOgrk3</td></tr>

<tr><td>Χ</td><td>&amp;Chi;</td><td>&amp;#935;</td><td> Greek capital letter chi, U03A7</td></tr>

<tr><td>Ψ</td><td>&amp;Psi;</td><td>&amp;#936;</td><td> Greek capital letter psi, U03A8 ISOgrk3</td></tr>

<tr><td>Ω</td><td>&amp;Omega;</td><td>&amp;#937;</td><td> Greek capital letter omega, U03A9 ISOgrk3</td></tr>

<tr><td>α</td><td>&amp;alpha;</td><td>&amp;#945;</td><td> Greek small letter alpha, U03B1 ISOgrk3</td></tr>

<tr><td>β</td><td>&amp;beta;</td><td>&amp;#946;</td><td> Greek small letter beta, U03B2 ISOgrk3</td></tr>

<tr><td>γ</td><td>&amp;gamma;</td><td>&amp;#947;</td><td> Greek small letter gamma, U03B3 ISOgrk3</td></tr>

<tr><td>δ</td><td>&amp;delta;</td><td>&amp;#948;</td><td> Greek small letter delta, U03B4 ISOgrk3</td></tr>

<tr><td>ε</td><td>&amp;epsilon;</td><td>&amp;#949;</td><td> Greek small letter epsilon, U03B5 ISOgrk3</td></tr>

<tr><td>ζ</td><td>&amp;zeta;</td><td>&amp;#950;</td><td> Greek small letter zeta, U03B6 ISOgrk3</td></tr>

<tr><td>η</td><td>&amp;eta;</td><td>&amp;#951;</td><td> Greek small letter eta, U03B7 ISOgrk3</td></tr>

<tr><td>θ</td><td>&amp;theta;</td><td>&amp;#952;</td><td> Greek small letter theta, U03B8 ISOgrk3</td></tr>

<tr><td>ι</td><td>&amp;iota;</td><td>&amp;#953;</td><td> Greek small letter iota, U03B9 ISOgrk3</td></tr>

<tr><td>κ</td><td>&amp;kappa;</td><td>&amp;#954;</td><td> Greek small letter kappa, U03BA ISOgrk3</td></tr>

<tr><td>λ</td><td>&amp;lambda;</td><td>&amp;#955;</td><td> Greek small letter lambda, U03BB ISOgrk3</td></tr>

<tr><td>μ</td><td>&amp;mu;</td><td>&amp;#956;</td><td> Greek small letter mu, U03BC ISOgrk3</td></tr>

<tr><td>ν</td><td>&amp;nu;</td><td>&amp;#957;</td><td> Greek small letter nu, U03BD ISOgrk3</td></tr>

<tr><td>ξ</td><td>&amp;xi;</td><td>&amp;#958;</td><td> Greek small letter xi, U03BE ISOgrk3</td></tr>

<tr><td>ο</td><td>&amp;omicron;</td><td>&amp;#959;</td><td> Greek small letter omicron, U03BF NEW</td></tr>

<tr><td>π</td><td>&amp;pi;</td><td>&amp;#960;</td><td> Greek small letter pi, U03C0 ISOgrk3</td></tr>

<tr><td>ρ</td><td>&amp;rho;</td><td>&amp;#961;</td><td> Greek small letter rho, U03C1 ISOgrk3</td></tr>

<tr><td>ς</td><td>&amp;sigmaf;</td><td>&amp;#962;</td><td> Greek small letter final sigma, U03C2 ISOgrk3</td></tr>

<tr><td>σ</td><td>&amp;sigma;</td><td>&amp;#963;</td><td> Greek small letter sigma, U03C3 ISOgrk3</td></tr>

<tr><td>τ</td><td>&amp;tau;</td><td>&amp;#964;</td><td> Greek small letter tau, U03C4 ISOgrk3</td></tr>

<tr><td>υ</td><td>&amp;upsilon;</td><td>&amp;#965;</td><td> Greek small letter upsilon, U03C5 ISOgrk3</td></tr>

<tr><td>φ</td><td>&amp;phi;</td><td>&amp;#966;</td><td> Greek small letter phi, U03C6 ISOgrk3</td></tr>

<tr><td>χ</td><td>&amp;chi;</td><td>&amp;#967;</td><td> Greek small letter chi, U03C7 ISOgrk3</td></tr>

<tr><td>ψ</td><td>&amp;psi;</td><td>&amp;#968;</td><td> Greek small letter psi, U03C8 ISOgrk3</td></tr>

<tr><td>ω</td><td>&amp;omega;</td><td>&amp;#969;</td><td> Greek small letter omega, U03C9 ISOgrk3</td></tr>

<tr><td>ϑ</td><td>&amp;thetasym;</td><td>&amp;#977;</td><td>Greek small letter theta symbol, U03D1 NEW</td></tr>

<tr><td>ϒ</td><td>&amp;upsih;</td><td>&amp;#978;</td><td> Greek upsilon with hook symbol, U03D2 NEW</td></tr>

<tr><td>ϖ</td><td>&amp;piv;</td><td>&amp;#982;</td><td> Greek pi symbol, U03D6 ISOgrk3</td></tr>

<tr><td colspan="4"><em>General Punctuation</em></td></tr>
<tr><td>•</td><td>&amp;bull;</td><td>&amp;#8226;</td><td> bullet, =black small circle, U2022 ISOpub</td></tr>

<tr><td>…</td><td>&amp;hellip;</td><td>&amp;#8230;</td><td> horizontal ellipsis, =three dot leader, U2026 ISOpub</td></tr>

<tr><td>′</td><td>&amp;prime;</td><td>&amp;#8242;</td><td> prime, =minutes, =feet, U2032 ISOtech</td></tr>

<tr><td>″</td><td>&amp;Prime;</td><td>&amp;#8243;</td><td> double prime, =seconds, =inches, U2033 ISOtech</td></tr>

<tr><td>‾</td><td>&amp;oline;</td><td>&amp;#8254;</td><td> overline, =spacing overscore, U203E NEW</td></tr>

<tr><td>⁄</td><td>&amp;frasl;</td><td>&amp;#8260;</td><td> fraction slash, U2044 NEW</td></tr>

<tr><td colspan="4"><em>Letterlike Symbols</em></td></tr>

<tr><td>℘</td><td>&amp;weierp;</td><td>&amp;#8472;</td><td> script capital P, =power set, =Weierstrass p, U2118 ISOamso</td></tr>

<tr><td>ℑ</td><td>&amp;image;</td><td>&amp;#8465;</td><td> blackletter capital I, =imaginary part, U2111 ISOamso</td></tr>

<tr><td>ℜ</td><td>&amp;real;</td><td>&amp;#8476;</td><td> blackletter capital R, =real part symbol, U211C ISOamso</td></tr>

<tr><td>™</td><td>&amp;trade;</td><td>&amp;#8482;</td><td> trade mark sign, U2122 ISOnum</td></tr>

<tr><td>ℵ</td><td>&amp;alefsym;</td><td>&amp;#8501;</td><td> alef symbol, =first transfinite cardinal, U2135 NEW</td></tr>

<tr><td colspan="4"><em>Arrows</em></td></tr>

<tr><td>←</td><td>&amp;larr;</td><td>&amp;#8592;</td><td> leftward arrow, U2190 ISOnum</td></tr>

<tr><td>↑</td><td>&amp;uarr;</td><td>&amp;#8593;</td><td> upward arrow, U2191 ISOnum</td></tr>

<tr><td>→</td><td>&amp;rarr;</td><td>&amp;#8594;</td><td> rightward arrow, U2192 ISOnum</td></tr>

<tr><td>↓</td><td>&amp;darr;</td><td>&amp;#8595;</td><td> downward arrow, U2193 ISOnum</td></tr>

<tr><td>↔</td><td>&amp;harr;</td><td>&amp;#8596;</td><td> left right arrow, U2194 ISOamsa</td></tr>

<tr><td>↵</td><td>&amp;crarr;</td><td>&amp;#8629;</td><td> downward arrow with corner leftward, =carriage return, U21B5 NEW</td></tr>

<tr><td>⇐</td><td>&amp;lArr;</td><td>&amp;#8656;</td><td> leftward double arrow, U21D0 ISOtech</td></tr>

<tr><td>⇑</td><td>&amp;uArr;</td><td>&amp;#8657;</td><td> upward double arrow, U21D1 ISOamsa</td></tr>

<tr><td>⇒</td><td>&amp;rArr;</td><td>&amp;#8658;</td><td> rightward double arrow, U21D2 ISOtech</td></tr>

<tr><td>⇓</td><td>&amp;dArr;</td><td>&amp;#8659;</td><td> downward double arrow, U21D3 ISOamsa</td></tr>

<tr><td>⇔</td><td>&amp;hArr;</td><td>&amp;#8660;</td><td> left right double arrow, U21D4 ISOamsa</td></tr>

<tr><td colspan="4"><em>Mathematical Operators</em></td></tr>

<tr><td>∀</td><td>&amp;forall;</td><td>&amp;#8704;</td><td> for all, U2200 ISOtech</td></tr>

<tr><td>∂</td><td>&amp;part;</td><td>&amp;#8706;</td><td> partial differential, U2202 ISOtech</td></tr>

<tr><td>∃</td><td>&amp;exist;</td><td>&amp;#8707;</td><td> there exists, U2203 ISOtech</td></tr>

<tr><td>∅</td><td>&amp;empty;</td><td>&amp;#8709;</td><td> empty set, =null set, =diameter, U2205 ISOamso</td></tr>

<tr><td>∇</td><td>&amp;nabla;</td><td>&amp;#8711;</td><td> nabla, =backward difference, U2207 ISOtech</td></tr>

<tr><td>∈</td><td>&amp;isin;</td><td>&amp;#8712;</td><td> element of, U2208 ISOtech</td></tr>

<tr><td>∉</td><td>&amp;notin;</td><td>&amp;#8713;</td><td> not an element of, U2209 ISOtech</td></tr>

<tr><td>∋</td><td>&amp;ni;</td><td>&amp;#8715;</td><td> contains as member, U220B ISOtech</td></tr>

<tr><td>∏</td><td>&amp;prod;</td><td>&amp;#8719;</td><td> n-ary product, =product sign, U220F ISOamsb</td></tr>

<tr><td>−</td><td>&amp;sum;</td><td>&amp;#8722;</td><td> n-ary sumation, U2211 ISOamsb</td></tr>

<tr><td>−</td><td>&amp;minus;</td><td>&amp;#8722;</td><td> minus sign, U2212 ISOtech</td></tr>

<tr><td>∗</td><td>&amp;lowast;</td><td>&amp;#8727;</td><td> asterisk operator, U2217 ISOtech</td></tr>

<tr><td>√</td><td>&amp;radic;</td><td>&amp;#8730;</td><td> square root, =radical sign, U221A ISOtech</td></tr>

<tr><td>∝</td><td>&amp;prop;</td><td>&amp;#8733;</td><td> proportional to, U221D ISOtech</td></tr>

<tr><td>∞</td><td>&amp;infin;</td><td>&amp;#8734;</td><td> infinity, U221E ISOtech</td></tr>

<tr><td>∠</td><td>&amp;ang;</td><td>&amp;#8736;</td><td> angle, U2220 ISOamso</td></tr>

<tr><td>⊥</td><td>&amp;and;</td><td>&amp;#8869;</td><td> logical and, =wedge, U2227 ISOtech</td></tr>

<tr><td>⊦</td><td>&amp;or;</td><td>&amp;#8870;</td><td> logical or, =vee, U2228 ISOtech</td></tr>

<tr><td>∩</td><td>&amp;cap;</td><td>&amp;#8745;</td><td> intersection, =cap, U2229 ISOtech</td></tr>

<tr><td>∪</td><td>&amp;cup;</td><td>&amp;#8746;</td><td> union, =cup, U222A ISOtech</td></tr>

<tr><td>∫</td><td>&amp;int;</td><td>&amp;#8747;</td><td> integral, U222B ISOtech</td></tr>

<tr><td>∴</td><td>&amp;there4;</td><td>&amp;#8756;</td><td> therefore, U2234 ISOtech</td></tr>

<tr><td>∼</td><td>&amp;sim;</td><td>&amp;#8764;</td><td> tilde operator, =varies with, =similar to, U223C ISOtech</td></tr>

<tr><td>≅</td><td>&amp;cong;</td><td>&amp;#8773;</td><td> approximately equal to, U2245 ISOtech</td></tr>

<tr><td>≅</td><td>&amp;asymp;</td><td>&amp;#8773;</td><td> almost equal to, =asymptotic to, U2248 ISOamsr</td></tr>

<tr><td>≠</td><td>&amp;ne;</td><td>&amp;#8800;</td><td> not equal to, U2260 ISOtech</td></tr>

<tr><td>≡</td><td>&amp;equiv;</td><td>&amp;#8801;</td><td> identical to, U2261 ISOtech</td></tr>

<tr><td>≤</td><td>&amp;le;</td><td>&amp;#8804;</td><td> less-than or equal to, U2264 ISOtech</td></tr>

<tr><td>≥</td><td>&amp;ge;</td><td>&amp;#8805;</td><td> greater-than or equal to, U2265 ISOtech</td></tr>

<tr><td>⊂</td><td>&amp;sub;</td><td>&amp;#8834;</td><td> subset of, U2282 ISOtech</td></tr>

<tr><td>⊃</td><td>&amp;sup;</td><td>&amp;#8835;</td><td> superset of, U2283 ISOtech</td></tr>

<tr><td>⊄</td><td>&amp;nsub;</td><td>&amp;#8836;</td><td> not a subset of, U2284 ISOamsn</td></tr>

<tr><td>⊆</td><td>&amp;sube;</td><td>&amp;#8838;</td><td> subset of or equal to, U2286 ISOtech</td></tr>

<tr><td>⊇</td><td>&amp;supe;</td><td>&amp;#8839;</td><td> superset of or equal to, U2287 ISOtech</td></tr>

<tr><td>⊕</td><td>&amp;oplus;</td><td>&amp;#8853;</td><td> circled plus, =direct sum, U2295 ISOamsb</td></tr>

<tr><td>⊗</td><td>&amp;otimes;</td><td>&amp;#8855;</td><td> circled times, =vector product, U2297 ISOamsb</td></tr>

<tr><td>⊥</td><td>&amp;perp;</td><td>&amp;#8869;</td><td> up tack, =orthogonal to, =perpendicular, U22A5 ISOtech</td></tr>

<tr><td>⋅</td><td>&amp;sdot;</td><td>&amp;#8901;</td><td> dot operator, U22C5 ISOamsb</td></tr>

<tr><td colspan="4"><em>Miscellaneous Technical</em></td></tr>

<tr><td>⌈</td><td>&amp;lceil;</td><td>&amp;#8968;</td><td> left ceiling, =apl upstile, U2308, ISOamsc</td></tr>

<tr><td>⌉</td><td>&amp;rceil;</td><td>&amp;#8969;</td><td> right ceiling, U2309, ISOamsc</td></tr>

<tr><td>⌊</td><td>&amp;lfloor;</td><td>&amp;#8970;</td><td> left floor, =apl downstile, U230A, ISOamsc</td></tr>

<tr><td>⌋</td><td>&amp;rfloor;</td><td>&amp;#8971;</td><td> right floor, U230B, ISOamsc</td></tr>

<tr><td>〈</td><td>&amp;lang;</td><td>&amp;#9001;</td><td> left-pointing angle bracket, =bra, U2329 ISOtech</td></tr>

<tr><td>〉</td><td>&amp;rang;</td><td>&amp;#9002;</td><td> right-pointing angle bracket, =ket, U232A ISOtech</td></tr>

<tr><td colspan="4"><em>Geometric Shapes</em></td></tr>
<tr><td>◊</td><td>&amp;loz;</td><td>&amp;#9674;</td><td> lozenge, U25CA ISOpub</td></tr>

<tr><td colspan="4"><em>Miscellaneous Symbols</em></td></tr>
<tr><td>♠</td><td>&amp;spades;</td><td>&amp;#9824;</td><td> black spade suit, U2660 ISOpub</td></tr>

<tr><td>♣</td><td>&amp;clubs;</td><td>&amp;#9827;</td><td> black club suit, =shamrock, U2663 ISOpub</td></tr>

<tr><td>♥</td><td>&amp;hearts;</td><td>&amp;#9829;</td><td> black heart suit, =valentine, U2665 ISOpub</td></tr>

<tr><td>♦</td><td>&amp;diams;</td><td>&amp;#9830;</td><td> black diamond suit, U2666 ISOpub</td></tr>

</table>
</div></div>
        
          
        </div>
      </div>
</html>

/***
|Name|HelloWorldMacro|
|Created by|SimonBaird|
|Location|http://mptw2.tiddlyspot.com/#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 = {};
config.macros.helloWorld.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);
}

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


//}}}

/***

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

<<shout Yeah>>

***/
/%
|Name|HideTiddlerBackground|
|Source|http://www.TiddlyTools.com/#HideTiddlerBackground|
|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|hide a tiddler's background and border (if any)|

Usage: <<tiddler HideTiddlerBackground>>

%/<script>
	var t=story.findContainingTiddler(place);
	if (!t || t.id=="HideTiddlerBackground") return;
	var nodes=t.getElementsByTagName("*");
	for (var i=0; i<nodes.length; i++) if (hasClass(nodes[i],"viewer")) {
		var s=nodes[i].style;
		s.backgroundImage="none";
		s.backgroundColor="transparent"
		s.borderColor="transparent";
		s.borderWidth=0;
		s.margin=0;
		s.padding=0;
		break;
	}
</script>
/***
|Name:|HideWhenPlugin|
|Description:|Allows conditional inclusion/exclusion in templates|
|Version:|3.1 ($Rev: 3919 $)|
|Date:|$Date: 2008-03-13 02:03:12 +1000 (Thu, 13 Mar 2008) $|
|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.hideWhenLastTest = false;

window.removeElementWhen = function(test,place) {
	window.hideWhenLastTest = test;
	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);
	}},

	hideWhenTitleIs: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( tiddler.title == params[0], place);
	}},

	showWhenTitleIs: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( tiddler.title != params[0], place);
	}},

	'else': { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( !window.hideWhenLastTest, place);
	}}

});

//}}}
/***
|''Name:''|HistoryPlugin|
|''Description:''|Limits to only one tiddler open. Manages an history stack and provides macro to navigate in this history (<<back>><<history>><<forward>>).|
|''Version:''|1.0.0|
|''Date:''|2008-03-23|
|''Source:''|http://tiddlywiki.bidix.info/#HistoryPlugin|
|''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.3.0|
***/
//{{{
	Story.prototype.tiddlerHistory = [];
	Story.prototype.historyCurrentPos = -1;
	Story.prototype.currentTiddler = null;
	Story.prototype.maxPos = 11;

	Story.prototype.old_history_displayTiddler = Story.prototype.displayTiddler;
	Story.prototype.displayTiddler = function(srcElement,title,template,animate,slowly)
	{
		title = ((typeof title === "string") ? title : title.title);
		//SinglePageMode
		if (this.currentTiddler) this.closeTiddler(this.currentTiddler);
		if (template == 2) {
			//switch to Edit mode : don't manage
			story.old_history_displayTiddler(null,title,template,animate,slowly);
			return; 
		}
		// if same tiddler no change
		if (this.tiddlerHistory[this.historyCurrentPos] == title) {
			this.currentTiddler = title;
			story.old_history_displayTiddler(null,title,template,animate,slowly);
			return;
		}
		if (this.historyCurrentPos == this.tiddlerHistory.length -1) {
			// bottom of stack
	    	this.tiddlerHistory.push(title);
		   	if (this.tiddlerHistory.length > 11) {
	                 this.tiddlerHistory.shift();
	       	} else {
		    this.historyCurrentPos += 1;
	            }

		} else {
			// middle of stack
		    this.historyCurrentPos += 1;
			if (this.tiddlerHistory[this.historyCurrentPos] != title) {
				// path change => cut history
				this.tiddlerHistory[this.historyCurrentPos] = title;
				var a = [];
				for(var i = 0; i <= this.historyCurrentPos;i++) {
					a[i] = this.tiddlerHistory[i];
				}
				this.tiddlerHistory = a;
			}
		}
		this.currentTiddler = title;
		story.old_history_displayTiddler(null,title,template,animate,true);
	        scrollTo(0, 1);
	}

	Story.prototype.old_history_closeTiddler = Story.prototype.closeTiddler;
	Story.prototype.closeTiddler = function(title,animate,slowly)
	{
		this.currentTiddler = null;
	    story.old_history_closeTiddler.apply(this,arguments);
	}

	config.macros.history = {};
	config.macros.history.action = function(event) {
	var popup = Popup.create(this);
		if(popup)
			{
	        if (!story.tiddlerHistory.length)
	            createTiddlyText(popup,"No history");
	        else
	           {
	           var c = story.tiddlerHistory.length;
			   for (i=0; i<c;i++ )
	               {
					var elmt = createTiddlyElement(popup,"li");
				   	var btn = createTiddlyButton(elmt,story.tiddlerHistory[i],story.tiddlerHistory[i],config.macros.history.onClick);
					btn.setAttribute("historyPos",i);
			       }
	           }
	        }
		Popup.show(popup,false);
		event.cancelBubble = true;
		if (event.stopPropagation) event.stopPropagation();
		return false;
	}
	config.macros.history.handler = function(place,macroName,params)
	{
		createTiddlyButton(place, 'history', 'history', config.macros.history.action);
	}

	config.macros.history.onClick = function(ev)
	{
		var e = ev ? ev : window.event;
		var historyPos = this.getAttribute("historyPos");
		story.historyCurrentPos = historyPos -1;
		story.displayTiddler(null,story.tiddlerHistory[historyPos]);
		return false;
	};

	config.macros.back = {};
	config.macros.back.action = function() {
	       if (story.historyCurrentPos > 0) {
				if (story.currentTiddler) story.closeTiddler(story.currentTiddler);
				story.historyCurrentPos = story.historyCurrentPos -2;
				story.displayTiddler(null,story.tiddlerHistory[story.historyCurrentPos+1]);
			} else {
				//if (story.currentTiddler) story.old_history_displayTiddler(null,story.currentTiddler);
				};
		return false;
	}
	config.macros.back.handler = function(place,macroName,params)
	{
		createTiddlyButton(place, '<<', 'back', config.macros.back.action,"backButton");
	}

	config.macros.forward = {};
	config.macros.forward.action = function() {
	       if (story.historyCurrentPos < story.tiddlerHistory.length -1) {
				if (story.currentTiddler) story.closeTiddler(story.currentTiddler);
				//story.historyCurrentPos = story.historyCurrentPos;
				story.displayTiddler(null,story.tiddlerHistory[story.historyCurrentPos+1]);
			} else {
				//if (story.currentTiddler) story.old_history_displayTiddler(null,story.currentTiddler);
			}
		return false;
	}
	config.macros.forward.handler = function(place,macroName,params)
	{
		createTiddlyButton(place, '>>', 'forward', config.macros.forward.action, "ibutton");
	}
//}}}
/***
|Name|HomeMacro|

!Demo:
{{{<<HomeMacro>>}}}<<HomeMacro>>

!Installation:
Copy the contents of this tiddler to your TW, tag with systemConfig, save and reload your TW.

!Code
***/
//{{{
config.macros.HomeMacro={};
config.macros.HomeMacro.handler= function(place,macroName,params,wikifier,paramString,tiddler)
{
        var label = params[0]||"Home";
        var tooltip = params[1]||"Home";
        createTiddlyButton(place,label,tooltip,this.onclick);
}
config.macros.HomeMacro.onclick= function()
{
	story.closeAllTiddlers();
	restart();
}
//}}}
<<top>>
<<toggleSideBar [[toggle sidebar]] [[toggle sidebar]] hide>><<renameButton '>' >>
<<jump j '' top>>
<<closeAll>><<renameButton x 'Close All'>>
<<collapseAll>><<renameButton c 'Collapse All'>>
<<saveAndReload>><<renameButton r 'Save & Reload'>>
<<saveChanges>><<renameButton s 'Save TiddlyWiki'>>
/***
|Name|HoverMenuPlugin|
|Created by|SaqImtiaz|
|Location|http://tw.lewcid.org/#HoverMenuPlugin|
|Version|1.11|
|Requires|~TW2.x|
!Description:
Provides a hovering menu on the edge of the screen for commonly used commands, that scrolls with the page.

!Demo:
Observe the hovering menu on the right edge of the screen.

!Installation:
Copy the contents of this tiddler to your TW, tag with systemConfig, save and reload your TW.
To customize your HoverMenu, edit the HoverMenu shadow tiddler.

To customize whether the menu sticks to the right or left edge of the screen, and its start position, edit the HoverMenu configuration settings part of the code below. It's well documented, so don't be scared!

The menu has an id of hoverMenu, in case you want to style the buttons in it using css.
*Changed StyleSheet to {{{[[HoverMenuStyleSheet]]}}} also spawned [[HoverMenuStyleSheet]] to change background color of hover bar to #aaa

!Notes:
Since the default HoverMenu contains buttons for toggling the side bar and jumping to the top of the screen and to open tiddlers, the ToggleSideBarMacro, JumpMacro and the JumpToTopMacro are included in this tiddler, so you dont need to install them separately. Having them installed separately as well could lead to complications.

If you dont intend to use these three macros at all, feel free to remove those sections of code in this tiddler.

!To Do:
* rework code to allow multiple hovering menus in different positions, horizontal etc.
* incorporate code for keyboard shortcuts that correspond to the buttons in the hovermenu

!History:
*03-08-06, ver 1.1.2: compatibility fix with SelectThemePlugin
*03-08-06,  ver 1.11: fixed error with button tooltips
*27-07-06, ver 1.1 : added JumpMacro to hoverMenu
*23-07-06

!Code
***/

/***
start HoverMenu plugin code
***/
//{{{
config.hoverMenu={};
//}}}

/***
HoverMenu configuration settings
***/
//{{{
config.hoverMenu.settings={
               align: 'right',    //align menu to right or left side of screen, possible values are 'right' and 'left'               
               x: 1,              // horizontal distance of menu from side of screen, increase to your liking.
               y: 158            //vertical distance of menu from top of screen at start, increase or decrease to your liking
               };
//}}}

//{{{
//continue HoverMenu plugin code
config.hoverMenu.handler=function()
{              
               if (!document.getElementById("hoverMenu"))
               {
               var theMenu = createTiddlyElement(document.getElementById("contentWrapper"), "div","hoverMenu");
               theMenu.setAttribute("refresh","content");
               theMenu.setAttribute("tiddler","HoverMenu");
               var menuContent = store.getTiddlerText("HoverMenu");
               wikify(menuContent,theMenu);
              }

	       var Xloc = this.settings.x;
	       Yloc =this.settings.y;
	       var ns = (navigator.appName.indexOf("Netscape") != -1);
	       function SetMenu(id)
                        {
		        var GetElements=document.getElementById?document.getElementById(id):document.all?document.all[id]:document.layers[id];
		        if(document.layers)GetElements.style=GetElements;
		        GetElements.sP=function(x,y){this.style[config.hoverMenu.settings.align]=x +"px";this.style.top=y +"px";};
		        GetElements.x = Xloc;
		        GetElements.y = findScrollY();
		        GetElements.y += Yloc;
		        return GetElements;
	                }
               window.LoCate_XY=function()
                        {
		        var pY =  findScrollY();
                        ftlObj.y += (pY + Yloc - ftlObj.y)/15;
		        ftlObj.sP(ftlObj.x, ftlObj.y);
		        setTimeout("LoCate_XY()", 10);
	                }
               ftlObj = SetMenu("hoverMenu");
	       LoCate_XY();
};

window.old_lewcid_hovermenu_restart = restart;
restart = function()
{
               window.old_lewcid_hovermenu_restart();
               config.hoverMenu.handler();
};

setStylesheet(
"#hoverMenu .imgLink, #hoverMenu .imgLink:hover {border:none; padding:0px; float:right; margin-bottom:2px; margin-top:0px;}\n"+
"#hoverMenu  .button, #hoverMenu  .tiddlyLink {border:none; font-weight:bold; background:#18f; color:#FFF; padding:0 5px; float:right; margin-bottom:4px;}\n"+
"#hoverMenu .button:hover, #hoverMenu .tiddlyLink:hover {font-weight:bold; border:none; color:#fff; background:#000; padding:0 5px; float:right; margin-bottom:4px;}\n"+
"#hoverMenu .button {width:100%; text-align:center}"+
"#hoverMenu { position:absolute; width:7px;}\n"+
"\n","hoverMenuStyles");


config.macros.renameButton={};
config.macros.renameButton.handler = function(place,macroName,params,wikifier,paramString,tiddler)
{

               if (place.lastChild.tagName!="BR")
                     {
                      place.lastChild.firstChild.data = params[0];
                      if (params[1]) {place.lastChild.title = params[1];}
                     }
};

config.shadowTiddlers["HoverMenu"]="<<top>>\n<<toggleSideBar>><<renameButton '>' >>\n<<jump j '' top>>\n<<saveChanges>><<renameButton s 'Save TiddlyWiki'>>\n<<newTiddler>><<renameButton n>>\n";
//}}}
//end HoverMenu plugin code

//Start ToggleSideBarMacro code
//{{{
config.macros.toggleSideBar={};

config.macros.toggleSideBar.settings={
         styleHide :  "#sidebar { display: none;}\n"+"#contentWrapper #displayArea { margin-right: 1em;}\n"+"",
         styleShow : " ",
         arrow1: "«",
         arrow2: "»"
};

config.macros.toggleSideBar.handler=function (place,macroName,params,wikifier,paramString,tiddler)
{
          var tooltip= params[1]||'toggle sidebar';
          var mode = (params[2] && params[2]=="hide")? "hide":"show";
          var arrow = (mode == "hide")? this.settings.arrow1:this.settings.arrow2;
          var label= (params[0]&&params[0]!='.')?params[0]+" "+arrow:arrow;
          var theBtn = createTiddlyButton(place,label,tooltip,this.onToggleSideBar,"button HideSideBarButton");
          if (mode == "hide")
             { 
             (document.getElementById("sidebar")).setAttribute("toggle","hide");
              setStylesheet(this.settings.styleHide,"ToggleSideBarStyles");
             }
};

config.macros.toggleSideBar.onToggleSideBar = function(){
          var sidebar = document.getElementById("sidebar");
          var settings = config.macros.toggleSideBar.settings;
          if (sidebar.getAttribute("toggle")=='hide')
             {
              setStylesheet(settings.styleShow,"ToggleSideBarStyles");
              sidebar.setAttribute("toggle","show");
              this.firstChild.data= (this.firstChild.data).replace(settings.arrow1,settings.arrow2);
              }
          else
              {    
               setStylesheet(settings.styleHide,"ToggleSideBarStyles");
               sidebar.setAttribute("toggle","hide");
               this.firstChild.data= (this.firstChild.data).replace(settings.arrow2,settings.arrow1);
              }

     return false;
}

setStylesheet(".HideSideBarButton .button {font-size:12px; font-weight:bold; padding: 0 5px;}\n","ToggleSideBarButtonStyles");
//}}}
//end ToggleSideBarMacro code

//start JumpToTopMacro code
//{{{
config.macros.top={};
config.macros.top.handler=function(place,macroName)
{
               createTiddlyButton(place,"^","jump to top",this.onclick);
}
config.macros.top.onclick=function()
{
               window.scrollTo(0,0);
};

config.commands.top =
{
               text:" ^ ",
               tooltip:"jump to top"
};

config.commands.top.handler = function(event,src,title)
{
               window.scrollTo(0,0);
}
//}}}
//end JumpToStartMacro code

//start JumpMacro code
//{{{
config.macros.jump= {};
config.macros.jump.handler = function (place,macroName,params,wikifier,paramString,tiddler)
{
        var label = (params[0] && params[0]!=".")? params[0]: 'jump';
        var tooltip = (params[1] && params[1]!=".")? params[1]: 'jump to an open tiddler';
        var top = (params[2] && params[2]=='top') ? true: false;        

        var btn =createTiddlyButton(place,label,tooltip,this.onclick);
        if (top==true)
              btn.setAttribute("top","true")
}

config.macros.jump.onclick = function(e)
{
        if (!e) var e = window.event;
        var theTarget = resolveTarget(e);
        var top = theTarget.getAttribute("top");
	var popup = Popup.create(this);
	if(popup)
		{
                 if(top=="true")
                                {createTiddlyButton(createTiddlyElement(popup,"li"),'Top ↑','Top of TW',config.macros.jump.top);
                                 createTiddlyElement(popup,"hr");}
		
		story.forEachTiddler(function(title,element) {
			createTiddlyLink(createTiddlyElement(popup,"li"),title,true);
			});
                }
	Popup.show(popup,false);
	e.cancelBubble = true;
	if (e.stopPropagation) e.stopPropagation();
	return false;
}

config.macros.jump.top = function()
{
       window.scrollTo(0,0);
}
//}}}
//end JumpMacro code

//utility functions
//{{{
Popup.show = function(unused,slowly)
{
	var curr = Popup.stack[Popup.stack.length-1];
	var rootLeft = findPosX(curr.root);
	var rootTop = findPosY(curr.root);
	var rootHeight = curr.root.offsetHeight;
	var popupLeft = rootLeft;
	var popupTop = rootTop + rootHeight;
	var popupWidth = curr.popup.offsetWidth;
	var winWidth = findWindowWidth();
        if (isChild(curr.root,'hoverMenu'))
              var x = config.hoverMenu.settings.x;
        else
              var x = 0;
	if(popupLeft + popupWidth+x > winWidth)
		popupLeft = winWidth - popupWidth -x;
        if (isChild(curr.root,'hoverMenu'))
  	        {curr.popup.style.right = x + "px";}
        else
                curr.popup.style.left = popupLeft + "px";
	curr.popup.style.top = popupTop + "px";
	curr.popup.style.display = "block";
	addClass(curr.root,"highlight");
	if(config.options.chkAnimate)
		anim.startAnimating(new Scroller(curr.popup,slowly));
	else
		window.scrollTo(0,ensureVisible(curr.popup));
}

window.isChild = function(e,parentId) {
        while (e != null) {
                var parent = document.getElementById(parentId);
                if (parent == e) return true;
                e = e.parentNode;
                }
        return false;
};
//}}}
/*{{{*/
/* http://mptw.tiddlyspot.com/#MptwStyleSheet ($Rev: 2246 $) */
/* a contrasting background so I can see where one tiddler ends and the other begins */
body {
	background: [[ColorPalette::TertiaryLight]];
}
/* experiment, making header phat */
.header {
	height: 75px;
}
/* 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 {
	font-family: 'Consolas' monospace;
}

/* 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-bottom: 1em;
	padding-top: 0.75em;
}

/* 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;
}
#hoverMenu  .button, #hoverMenu  .tiddlyLink {border:none; font-weight:bold; background:#fff; color:#000; padding:0 5px; float:right; margin-bottom:4px;
}
#hoverMenu .button:hover, #hoverMenu .tiddlyLink:hover {font-weight:bold; border:none; color:#fff; background:#000; padding:0 5px; float:right; margin-bottom:4px;
}
/* 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; }

/* for Tagger Plugin, thanks 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;
	}
}
/*}}}*/

<script>
   var myTag=prompt("enter tag");
   if (!myTag || !myTag.trim().length) return; /* cancelled by user */
   var tids=store.getTaggedTiddlers(myTag);
   if (!tids.length) return; /* no matches */
   var out="|sortable|k\n|Title|Notes|h\n";
   for (var t=0; t<tids.length; t++)
      out+="|[[%0]]|<<tiddler [[%0]]>>|\n".format([tids[t].title]);
   return out;
</script>
/***
|Name|ImageSizePlugin|
|Source|http://www.TiddlyTools.com/#ImageSizePlugin|
|Version|1.2.1|
|Author|Eric Shulman|
|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|adds support for resizing images|
This plugin adds optional syntax to scale an image to a specified width and height and/or interactively resize the image with the mouse.
!!!!!Usage
<<<
The extended image syntax is:
{{{
[img(w+,h+)[...][...]]
}}}
where ''(w,h)'' indicates the desired width and height (in CSS units, e.g., px, em, cm, in, or %). Use ''auto'' (or a blank value) for either dimension to scale that dimension proportionally (i.e., maintain the aspect ratio). You can also calculate a CSS value 'on-the-fly' by using a //javascript expression// enclosed between """{{""" and """}}""". Appending a plus sign (+) to a dimension enables interactive resizing in that dimension (by dragging the mouse inside the image). Use ~SHIFT-click to show the full-sized (un-scaled) image. Use ~CTRL-click to restore the starting size (either scaled or full-sized).
<<<
!!!!!Examples
<<<
{{{
[img(100px+,75px+)[images/meow2.jpg]]
}}}
[img(100px+,75px+)[images/meow2.jpg]]
{{{
[<img(34%+,+)[images/meow.gif]]
[<img(21% ,+)[images/meow.gif]]
[<img(13%+, )[images/meow.gif]]
[<img( 8%+, )[images/meow.gif]]
[<img( 5% , )[images/meow.gif]]
[<img( 3% , )[images/meow.gif]]
[<img( 2% , )[images/meow.gif]]
[img(  1%+,+)[images/meow.gif]]
}}}
[<img(34%+,+)[images/meow.gif]]
[<img(21% ,+)[images/meow.gif]]
[<img(13%+, )[images/meow.gif]]
[<img( 8%+, )[images/meow.gif]]
[<img( 5% , )[images/meow.gif]]
[<img( 3% , )[images/meow.gif]]
[<img( 2% , )[images/meow.gif]]
[img(  1%+,+)[images/meow.gif]]
{{tagClear{
}}}
<<<
!!!!!Revisions
<<<
2009.02.24 [1.2.1] cleanup width/height regexp, use '+' suffix for resizing
2009.02.22 [1.2.0] added stretchable images
2008.01.19 [1.1.0] added evaluated width/height values
2008.01.18 [1.0.1] regexp for "(width,height)" now passes all CSS values to browser for validation
2008.01.17 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.ImageSizePlugin= {major: 1, minor: 2, revision: 1, date: new Date(2009,2,24)};
//}}}
//{{{
var f=config.formatters[config.formatters.findByField("name","image")];
f.match="\\[[<>]?[Ii][Mm][Gg](?:\\([^,]*,[^\\)]*\\))?\\[";
f.lookaheadRegExp=/\[([<]?)(>?)[Ii][Mm][Gg](?:\(([^,]*),([^\)]*)\))?\[(?:([^\|\]]+)\|)?([^\[\]\|]+)\](?:\[([^\]]*)\])?\]/mg;
f.handler=function(w) {
	this.lookaheadRegExp.lastIndex = w.matchStart;
	var lookaheadMatch = this.lookaheadRegExp.exec(w.source)
	if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
		var floatLeft=lookaheadMatch[1];
		var floatRight=lookaheadMatch[2];
		var width=lookaheadMatch[3];
		var height=lookaheadMatch[4];
		var tooltip=lookaheadMatch[5];
		var src=lookaheadMatch[6];
		var link=lookaheadMatch[7];

		// Simple bracketted link
		var e = w.output;
		if(link) { // LINKED IMAGE
			if (config.formatterHelpers.isExternalLink(link)) {
				if (config.macros.attach && config.macros.attach.isAttachment(link)) {
					// see [[AttachFilePluginFormatters]]
					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(floatLeft) img.align="left"; else if(floatRight) img.align="right";
		if(width||height) {
			var x=width.trim(); var y=height.trim();
			var stretchW=(x.substr(x.length-1,1)=='+'); if (stretchW) x=x.substr(0,x.length-1);
			var stretchH=(y.substr(y.length-1,1)=='+'); if (stretchH) y=y.substr(0,y.length-1);
			if (x.substr(0,2)=="{{")
				{ try{x=eval(x.substr(2,x.length-4))} catch(e){displayMessage(e.description||e.toString())} }
			if (y.substr(0,2)=="{{")
				{ try{y=eval(y.substr(2,y.length-4))} catch(e){displayMessage(e.description||e.toString())} }
			img.style.width=x.trim(); img.style.height=y.trim();
			config.formatterHelpers.addStretchHandlers(img,stretchW,stretchH);
		}
		if(tooltip) img.title = tooltip;

		// GET IMAGE SOURCE
		if (config.macros.attach && config.macros.attach.isAttachment(src))
			src=config.macros.attach.getAttachment(src); // see [[AttachFilePluginFormatters]]
		else if (config.formatterHelpers.resolvePath) { // see [[ImagePathPlugin]]
			if (config.browser.isIE || config.browser.isSafari) {
				img.onerror=(function(){
					this.src=config.formatterHelpers.resolvePath(this.src,false);
					return false;
				});
			} else
				src=config.formatterHelpers.resolvePath(src,true);
		}
		img.src=src;
		w.nextMatch = this.lookaheadRegExp.lastIndex;
	}
}

config.formatterHelpers.addStretchHandlers=function(e,stretchW,stretchH) {
	e.title=((stretchW||stretchH)?'DRAG=stretch/shrink, ':'')
		+'SHIFT-CLICK=show full size, CTRL-CLICK=restore initial size';
	e.statusMsg='width=%0, height=%1';
	e.style.cursor='move';
	e.originalW=e.style.width;
	e.originalH=e.style.height;
	e.minW=Math.max(e.offsetWidth/20,10);
	e.minH=Math.max(e.offsetHeight/20,10);
	e.stretchW=stretchW;
	e.stretchH=stretchH;
	e.onmousedown=function(ev) { var ev=ev||window.event;
		this.sizing=true;
		this.startX=!config.browser.isIE?ev.pageX:(ev.clientX+findScrollX());
		this.startY=!config.browser.isIE?ev.pageY:(ev.clientY+findScrollY());
		this.startW=this.offsetWidth;
		this.startH=this.offsetHeight;
		return false;
	};
	e.onmousemove=function(ev) { var ev=ev||window.event;
		if (this.sizing) {
			var s=this.style;
			var currX=!config.browser.isIE?ev.pageX:(ev.clientX+findScrollX());
			var currY=!config.browser.isIE?ev.pageY:(ev.clientY+findScrollY());
			var newW=(currX-this.offsetLeft)/(this.startX-this.offsetLeft)*this.startW;
			var newH=(currY-this.offsetTop )/(this.startY-this.offsetTop )*this.startH;
			if (this.stretchW) s.width =Math.floor(Math.max(newW,this.minW))+'px';
			if (this.stretchH) s.height=Math.floor(Math.max(newH,this.minH))+'px';
			clearMessage(); displayMessage(this.statusMsg.format([s.width,s.height]));
		}
		return false;
	};
	e.onmouseup=function(ev) { var ev=ev||window.event;
		if (ev.shiftKey) { this.style.width=this.style.height=''; }
		if (ev.ctrlKey)  { this.style.width=this.originalW; this.style.height=this.originalH; }
		this.sizing=false;
		clearMessage();
		return false;
	};
	e.onmouseout=function(ev) { var ev=ev||window.event;
		this.sizing=false;
		clearMessage();
		return false;
	};
}
//}}}
(2) HTML versions
<html>
<A HREF="images/crew.jpg" TARGET=_BLANK><img src=images/crew.jpg style="width: 25%;" TITLE="The Crew" align=left hspace=”4″ vspace=”4″ /></A>

<A HREF="images/MLTrouble.jpg" TARGET=_BLANK><img src=images/MLTrouble.jpg style="width: 25%;" TITLE="Up to no Good" align=left hspace=”4″ vspace=”4″ /></A>
</html>














(2) ImageSizePlugin Versions
[<img(25%,auto)[images/crew.jpg]][<img(25%,auto)[images/MLTrouble.jpg]]
<!--{{{-->
<!-- Last Revision 11.20.08 -->
<!-- Modified for Quote & Footer div change PageTemplate link to use new template -->
<div class='header'>
	<div class='headerNow'>
		<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>
	<div class='hD' id='hD' refresh='content' tiddler='contentHeader'></div>
<div id='tiddlersBar' refresh='none' ondblclick='config.macros.tiddlersBar.onTiddlersBarAction(event)'></div>
	<div id='messageArea'></div>
	<div id='tiddlerDisplay'></div>
	<div class='fD' id='fD' refresh='content' tiddler='contentFooter'></div>
</div>
<!--}}}-->
#Click on the 'backstage' button (top right corner in the header) and select Import. (Or go to more>ImportTiddlers on the lower right-hand menu).
#Follow the instructions to find the file you want to Import from. Click on Open. A dialog box will open with a kind of warning in it and asking you to Allow or Deny (at least that's what I get).
#Choose Allow.
#Now another box opens, titled Import Tiddlers from Another File or Server. Give the workspace a name, or choose default, and click on Open.
#Next a box will open which lists all the tiddlers in the TiddlyWiki you are importing from. Tick the boxes of the ones you want to import. Then click on Import.
#Another dialog box will open listing those tiddlers you've selected and showing progress of Import. It will say the Import is finished once it's done.
#Click on Close (top right corner, where you found the backstage button). 

You should be able to see the tiddlers you've imported.
<<importTiddlers inline>>
/***
|Name|ImportTiddlersPlugin|
|Source|http://www.TiddlyTools.com/#ImportTiddlersPlugin|
|Documentation|http://www.TiddlyTools.com/#ImportTiddlersPluginInfo|
|Version|4.6.1|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Description|interactive controls for import/export with filtering.|
Combine tiddlers from any two TiddlyWiki documents.  Interactively select and copy tiddlers from another TiddlyWiki source document.  Includes prompting for skip, rename, merge or replace actions when importing tiddlers that match existing titles.  When done, a list of all imported tiddlers is written into [[ImportedTiddlers]].
!!!!!Documentation
<<<
see [[ImportTiddlersPluginInfo]] for details
<<<
!!!!!interactive control panel
<<<
<<importTiddlers inline>>
{{clear{
^^(see also: [[ImportTiddlers]] shadow tiddler)^^}}}
<<<
!!!!!Revisions
<<<
2009.10.10 4.6.1 in createImportPanel, Use {{{window.Components}}} instead of {{{config.browser.isGecko}}} to avoid applying FF3 'file browse' fixup in Chrome.
2009.10.06 4.6.0 added createTiddlerFromFile (import text files)
|please see [[ImportTiddlersPluginInfo]] for additional revision details|
2005.07.20 1.0.0 Initial Release
<<<
!!!!!Code
***/
//{{{
version.extensions.ImportTiddlersPlugin= {major: 4, minor: 6, revision: 1, date: new Date(2009,10,10)};

// IE needs explicit global scoping for functions/vars called from browser events
window.onClickImportButton=onClickImportButton;
window.refreshImportList=refreshImportList;

// default cookie/option values
if (!config.options.chkImportReport) config.options.chkImportReport=true;

// default shadow definition
config.shadowTiddlers.ImportTiddlers='<<importTiddlers inline>>';

// use shadow tiddler content in backstage panel
if (config.tasks) config.tasks.importTask.content='<<tiddler ImportTiddlers>>' // TW2.2 or above
//}}}
//{{{
// backward-compatiblity for TW2.0.x and TW1.2.x
if (config.macros.importTiddlers==undefined) config.macros.importTiddlers={};
if (typeof merge=='undefined') {
	function merge(dst,src,preserveExisting) {
		for(var i in src) { if(!preserveExisting || dst[i] === undefined) dst[i] = src[i]; }
		return dst;
	}
}
if (config.browser.isGecko===undefined)
	config.browser.isGecko=(config.userAgent.indexOf('gecko')!=-1);
//}}}
//{{{
merge(config.macros.importTiddlers,{
	$: function(id) { return document.getElementById(id); }, // abbreviation
	label: 'import tiddlers',
	prompt: 'Copy tiddlers from another document',
	openMsg: 'Opening %0',
	openErrMsg: 'Could not open %0 - error=%1',
	readMsg: 'Read %0 bytes from %1',
	foundMsg: 'Found %0 tiddlers in %1',
	filterMsg: "Filtered %0 tiddlers matching '%1'",
	summaryMsg: '%0 tiddler%1 in the list',
	summaryFilteredMsg: '%0 of %1 tiddler%2 in the list',
	plural: 's are',
	single: ' is',
	countMsg: '%0 tiddlers selected for import',
	processedMsg: 'Processed %0 tiddlers',
	importedMsg: 'Imported %0 of %1 tiddlers from %2',
	loadText: 'please load a document...',
	closeText: 'close',
	doneText: 'done',
	startText: 'import',
	stopText: 'stop',
	local: true,		// default to import from local file
	src: '',		// path/filename or URL of document to import (retrieved from SiteUrl)
	proxy: '',		// URL for remote proxy script (retrieved from SiteProxy)
	useProxy: false,	// use specific proxy script in front of remote URL
	inbound: null,		// hash-indexed array of tiddlers from other document
	newTags: '',		// text of tags added to imported tiddlers
	addTags: true,		// add new tags to imported tiddlers
	listsize: 10,		// # of lines to show in imported tiddler list
	importTags: true,	// include tags from remote source document when importing a tiddler
	keepTags: true,		// retain existing tags when replacing a tiddler
	sync: false,		// add 'server' fields to imported tiddlers (for sync function)
	lastFilter: '',		// most recent filter (URL hash) applied
	lastAction: null,	// most recent collision button performed
	index: 0,		// current processing index in import list
	sort: ''		// sort order for imported tiddler listbox
});
//}}}
//{{{
// hijack core macro handler
if (config.macros.importTiddlers.coreHandler==undefined)
	config.macros.importTiddlers.coreHandler=config.macros.importTiddlers.handler;

config.macros.importTiddlers.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
	if (!params[0] || params[0].toLowerCase()=='core') { // default to built in
		if (config.macros.importTiddlers.coreHandler)
			config.macros.importTiddlers.coreHandler.apply(this,arguments);
		else 
			createTiddlyButton(place,this.label,this.prompt,onClickImportMenu);
	} else if (params[0]=='link') { // show link to floating panel
		createTiddlyButton(place,params[1]||this.label,params[2]||this.prompt,onClickImportMenu);
	} else if (params[0]=='inline') {// show panel as INLINE tiddler content
		createImportPanel(place);
		this.$('importPanel').style.position='static';
		this.$('importPanel').style.display='block';
	} else if (config.macros.loadTiddlers)
		config.macros.loadTiddlers.handler(place,macroName,params); // any other params: loadtiddlers
}
//}}}
//{{{
// Handle link click to create/show/hide control panel
function onClickImportMenu(e) { var e=e||window.event;
	var parent=resolveTarget(e).parentNode;
	var panel=document.getElementById('importPanel');
	if (panel==undefined || panel.parentNode!=parent) panel=createImportPanel(parent);
	var isOpen=panel.style.display=='block';
	if(config.options.chkAnimate)
		anim.startAnimating(new Slider(panel,!isOpen,false,'none'));
	else
		panel.style.display=isOpen?'none':'block';
	e.cancelBubble = true; if (e.stopPropagation) e.stopPropagation(); return(false);
}
//}}}
//{{{
// Create control panel: HTML, CSS
function createImportPanel(place) {
	var cmi=config.macros.importTiddlers; // abbrev
	var panel=cmi.$('importPanel');
	if (panel) { panel.parentNode.removeChild(panel); }
	setStylesheet(store.getTiddlerText('ImportTiddlersPlugin##css'),'importTiddlers');
	panel=createTiddlyElement(place,'span','importPanel',null,null)
	panel.innerHTML=store.getTiddlerText('ImportTiddlersPlugin##html');
	refreshImportList();
	if (!cmi.src.length) cmi.src=store.getTiddlerText('SiteUrl')||'';
	cmi.$('importSourceURL').value=cmi.src;
	if (!cmi.proxy.length) cmi.proxy=store.getTiddlerText('SiteProxy')||'SiteProxy';
	cmi.$('importSiteProxy').value=cmi.proxy;
	if (window.Components) { // FF3 FIXUP
		cmi.$('fileImportSource').style.display='none';
		cmi.$('importLocalPanelFix').style.display='block';
	}
	cmi.$('chkSync').checked=cmi.sync;
	cmi.$('chkImportTags').checked=cmi.importTags;
	cmi.$('chkKeepTags').checked=cmi.keepTags;
	cmi.$('chkAddTags').checked=cmi.addTags;
	cmi.$('txtNewTags').value=cmi.newTags;
	cmi.$('txtNewTags').style.display=cmi.addTags?'block':'none';
	cmi.$('chkSync').checked=cmi.sync;
	cmi.$('chkImportReport').checked=config.options.chkImportReport;
	return panel;
}
//}}}
//{{{
// process control interactions
function onClickImportButton(which,event) {
	var cmi=config.macros.importTiddlers; // abbreviation
	var list=cmi.$('importList'); if (!list) return false;
	var thePanel=cmi.$('importPanel');
	var theCollisionPanel=cmi.$('importCollisionPanel');
	var theNewTitle=cmi.$('importNewTitle');
	var count=0;
	switch (which.id)
		{
		case 'importFromFile':	// show local panel
		case 'importFromWeb':	// show HTTP panel
			cmi.local=(which.id=='importFromFile');
			cmi.showPanel('importLocalPanel',cmi.local);
			cmi.showPanel('importHTTPPanel',!cmi.local);
			break;
		case 'importOptions':	// show/hide options panel
			cmi.showPanel('importOptionsPanel',cmi.$('importOptionsPanel').style.display=='none');
			break;
		case 'fileImportSource':
		case 'importLoad':		// load import source into hidden frame
			importReport();		// if an import was in progress, generate a report
			cmi.inbound=null;	// clear the imported tiddler buffer
			refreshImportList();	// reset/resize the listbox
			if (cmi.src=='') break;
			// Load document, read it's DOM and fill the list
			cmi.loadRemoteFile(cmi.src,cmi.filterTiddlerList);
			break;
		case 'importSelectFeed':	// select a pre-defined systemServer feed URL
			var p=Popup.create(which); if (!p) return false;
			var tids=store.getTaggedTiddlers('systemServer');
			if (!tids.length)
				createTiddlyText(createTiddlyElement(p,'li'),'no pre-defined server feeds');
			for (var t=0; t<tids.length; t++) {
				var u=store.getTiddlerSlice(tids[t].title,'URL');
				var d=store.getTiddlerSlice(tids[t].title,'Description');
				if (!d||!d.length) d=store.getTiddlerSlice(tids[t].title,'description');
				if (!d||!d.length) d=u;
				createTiddlyButton(createTiddlyElement(p,'li'),tids[t].title,d,
					function(){
						var u=this.getAttribute('url');
						document.getElementById('importSourceURL').value=u;
						config.macros.importTiddlers.src=u;
						document.getElementById('importLoad').onclick();
					},
					null,null,null,{url:u});
			}
			Popup.show();
			event.cancelBubble = true;
			if (event.stopPropagation) event.stopPropagation();
			return false;
			// create popup with feed list
			// onselect, insert feed URL into input field.
			break;
		case 'importSelectAll':		// select all tiddler list items (i.e., not headings)
			importReport();		// if an import was in progress, generate a report
			for (var t=0,count=0; t < list.options.length; t++) {
				if (list.options[t].value=='') continue;
				list.options[t].selected=true;
				count++;
			}
			clearMessage(); displayMessage(cmi.countMsg.format([count]));
			cmi.$('importStart').disabled=!count;
			break;
		case 'importSelectNew':		// select tiddlers not in current document
			importReport();		// if an import was in progress, generate a report
			for (var t=0,count=0; t < list.options.length; t++) {
				list.options[t].selected=false;
				if (list.options[t].value=='') continue;
				list.options[t].selected=!store.tiddlerExists(list.options[t].value);
				count+=list.options[t].selected?1:0;
			}
			clearMessage(); displayMessage(cmi.countMsg.format([count]));
			cmi.$('importStart').disabled=!count;
			break;
		case 'importSelectChanges':		// select tiddlers that are updated from existing tiddlers
			importReport();		// if an import was in progress, generate a report
			for (var t=0,count=0; t < list.options.length; t++) {
				list.options[t].selected=false;
				if (list.options[t].value==''||!store.tiddlerExists(list.options[t].value)) continue;
				for (var i=0; i<cmi.inbound.length; i++) // find matching inbound tiddler
					{ var inbound=cmi.inbound[i]; if (inbound.title==list.options[t].value) break; }
				list.options[t].selected=(inbound.modified-store.getTiddler(list.options[t].value).modified>0); // updated tiddler
				count+=list.options[t].selected?1:0;
			}
			clearMessage(); displayMessage(cmi.countMsg.format([count]));
			cmi.$('importStart').disabled=!count;
			break;
		case 'importSelectDifferences':		// select tiddlers that are new or different from existing tiddlers
			importReport();		// if an import was in progress, generate a report
			for (var t=0,count=0; t < list.options.length; t++) {
				list.options[t].selected=false;
				if (list.options[t].value=='') continue;
				if (!store.tiddlerExists(list.options[t].value)) { list.options[t].selected=true; count++; continue; }
				for (var i=0; i<cmi.inbound.length; i++) // find matching inbound tiddler
					{ var inbound=cmi.inbound[i]; if (inbound.title==list.options[t].value) break; }
				list.options[t].selected=(inbound.modified-store.getTiddler(list.options[t].value).modified!=0); // changed tiddler
				count+=list.options[t].selected?1:0;
			}
			clearMessage(); displayMessage(cmi.countMsg.format([count]));
			cmi.$('importStart').disabled=!count;
			break;
		case 'importApplyFilter':	// filter list to include only matching tiddlers
			importReport();		// if an import was in progress, generate a report
			clearMessage();
			if (!cmi.all) // no tiddlers loaded = '0 selected'
				{ displayMessage(cmi.countMsg.format([0])); return false; }
			var hash=cmi.$('importLastFilter').value;
			cmi.inbound=cmi.filterByHash('#'+hash,cmi.all);
			refreshImportList();	// reset/resize the listbox
			break;
		case 'importStart':		// initiate the import processing
			importReport();		// if an import was in progress, generate a report
			cmi.$('importApplyToAll').checked=false;
			cmi.$('importStart').value=cmi.stopText;
			if (cmi.index>0) cmi.index=-1; // stop processing
			else cmi.index=importTiddlers(0); // or begin processing
			importStopped();
			break;
		case 'importClose':		// unload imported tiddlers or hide the import control panel
			// if imported tiddlers not loaded, close the import control panel
			if (!cmi.inbound) { thePanel.style.display='none'; break; }
			importReport();		// if an import was in progress, generate a report
			cmi.inbound=null;	// clear the imported tiddler buffer
			refreshImportList();	// reset/resize the listbox
			break;
		case 'importSkip':	// don't import the tiddler
			cmi.lastAction=which;
			var theItem	= list.options[cmi.index];
			for (var j=0;j<cmi.inbound.length;j++)
			if (cmi.inbound[j].title==theItem.value) break;
			var theImported = cmi.inbound[j];
			theImported.status='skipped after asking';			// mark item as skipped
			theCollisionPanel.style.display='none';
			cmi.index=importTiddlers(cmi.index+1);	// resume with NEXT item
			importStopped();
			break;
		case 'importRename':		// change name of imported tiddler
			cmi.lastAction=which;
			var theItem		= list.options[cmi.index];
			for (var j=0;j<cmi.inbound.length;j++)
			if (cmi.inbound[j].title==theItem.value) break;
			var theImported		= cmi.inbound[j];
			theImported.status	= 'renamed from '+theImported.title;	// mark item as renamed
			theImported.set(theNewTitle.value,null,null,null,null);		// change the tiddler title
			theItem.value		= theNewTitle.value;			// change the listbox item text
			theItem.text		= theNewTitle.value;			// change the listbox item text
			theCollisionPanel.style.display='none';
			cmi.index=importTiddlers(cmi.index);	// resume with THIS item
			importStopped();
			break;
		case 'importMerge':	// join existing and imported tiddler content
			cmi.lastAction=which;
			var theItem	= list.options[cmi.index];
			for (var j=0;j<cmi.inbound.length;j++)
			if (cmi.inbound[j].title==theItem.value) break;
			var theImported	= cmi.inbound[j];
			var theExisting	= store.getTiddler(theItem.value);
			var theText	= theExisting.text+'\n----\n^^merged from: ';
			theText		+='[['+cmi.src+'#'+theItem.value+'|'+cmi.src+'#'+theItem.value+']]^^\n';
			theText		+='^^'+theImported.modified.toLocaleString()+' by '+theImported.modifier+'^^\n'+theImported.text;
			var theDate	= new Date();
			var theTags	= theExisting.getTags()+' '+theImported.getTags();
			theImported.set(null,theText,null,theDate,theTags);
			theImported.status   = 'merged with '+theExisting.title;	// mark item as merged
			theImported.status  += ' - '+theExisting.modified.formatString('MM/DD/YYYY 0hh:0mm:0ss');
			theImported.status  += ' by '+theExisting.modifier;
			theCollisionPanel.style.display='none';
			cmi.index=importTiddlers(cmi.index);	// resume with this item
			importStopped();
			break;
		case 'importReplace':		// substitute imported tiddler for existing tiddler
			cmi.lastAction=which;
			var theItem		  = list.options[cmi.index];
			for (var j=0;j<cmi.inbound.length;j++)
			if (cmi.inbound[j].title==theItem.value) break;
			var theImported     = cmi.inbound[j];
			var theExisting	  = store.getTiddler(theItem.value);
			theImported.status  = 'replaces '+theExisting.title;		// mark item for replace
			theImported.status += ' - '+theExisting.modified.formatString('MM/DD/YYYY 0hh:0mm:0ss');
			theImported.status += ' by '+theExisting.modifier;
			theCollisionPanel.style.display='none';
			cmi.index=importTiddlers(cmi.index);	// resume with THIS item
			importStopped();
			break;
		case 'importListSmaller':		// decrease current listbox size, minimum=5
			if (list.options.length==1) break;
			list.size-=(list.size>5)?1:0;
			cmi.listsize=list.size;
			break;
		case 'importListLarger':		// increase current listbox size, maximum=number of items in list
			if (list.options.length==1) break;
			list.size+=(list.size<list.options.length)?1:0;
			cmi.listsize=list.size;
			break;
		case 'importListMaximize':	// toggle listbox size between current and maximum
			if (list.options.length==1) break;
			list.size=(list.size==list.options.length)?cmi.listsize:list.options.length;
			break;
		}
}
//}}}
//{{{
config.macros.importTiddlers.showPanel=function(place,show,skipAnim) {
	if (typeof place=='string') var place=document.getElementById(place);
	if (!place||!place.style) return;
	if(!skipAnim && anim && config.options.chkAnimate) anim.startAnimating(new Slider(place,show,false,'none'));
	else place.style.display=show?'block':'none';
}
//}}}
//{{{
function refreshImportList(selectedIndex) {
	var cmi=config.macros.importTiddlers; // abbrev
	var list=cmi.$('importList'); if (!list) return;
	// if nothing to show, reset list content and size
	if (!cmi.inbound) {
		while (list.length > 0) { list.options[0] = null; }
		list.options[0]=new Option(cmi.loadText,'',false,false);
		list.size=cmi.listsize;
		cmi.$('importLoad').disabled=false;
		cmi.$('importLoad').style.display='inline';
		cmi.$('importStart').disabled=true;
		cmi.$('importOptions').disabled=true;
		cmi.$('importOptions').style.display='none';
		cmi.$('fileImportSource').disabled=false;
		cmi.$('importFromFile').disabled=false;
		cmi.$('importFromWeb').disabled=false;
		cmi.$('importStart').value=cmi.startText;
		cmi.$('importClose').value=cmi.doneText;
		cmi.$('importSelectPanel').style.display='none';
		cmi.$('importOptionsPanel').style.display='none';
		return;
	}
	// there are inbound tiddlers loaded...
	cmi.$('importLoad').disabled=true;
	cmi.$('importLoad').style.display='none';
	cmi.$('importOptions').style.display='inline';
	cmi.$('importOptions').disabled=false;
	cmi.$('fileImportSource').disabled=true;
	cmi.$('importFromFile').disabled=true;
	cmi.$('importFromWeb').disabled=true;
	cmi.$('importClose').value=cmi.closeText;
	if (cmi.$('importSelectPanel').style.display=='none')
		cmi.showPanel('importSelectPanel',true);

	// get the sort order
	if (!selectedIndex)   selectedIndex=0;
	if (selectedIndex==0) cmi.sort='title';		// heading
	if (selectedIndex==1) cmi.sort='title';
	if (selectedIndex==2) cmi.sort='modified';
	if (selectedIndex==3) cmi.sort='tags';
	if (selectedIndex>3) {
		// display selected tiddler count
		for (var t=0,count=0; t < list.options.length; t++) {
			if (!list.options[t].selected) continue;
			if (list.options[t].value!='')
				count+=1;
			else { // if heading is selected, deselect it, and then select and count all in section
				list.options[t].selected=false;
				for ( t++; t<list.options.length && list.options[t].value!=''; t++) {
					list.options[t].selected=true;
					count++;
				}
			}
		}
		clearMessage(); displayMessage(cmi.countMsg.format([count]));
	}
	cmi.$('importStart').disabled=!count;
	if (selectedIndex>3) return; // no refresh needed

	// get the alphasorted list of tiddlers
	var tiddlers=cmi.inbound;
	tiddlers.sort(function (a,b) {if(a['title'] == b['title']) return(0); else return (a['title'] < b['title']) ? -1 : +1; });
	// clear current list contents
	while (list.length > 0) { list.options[0] = null; }
	// add heading and control items to list
	var i=0;
	var indent=String.fromCharCode(160)+String.fromCharCode(160);
	if (cmi.all.length==tiddlers.length)
		var summary=cmi.summaryMsg.format([tiddlers.length,(tiddlers.length!=1)?cmi.plural:cmi.single]);
	else
		var summary=cmi.summaryFilteredMsg.format([tiddlers.length,cmi.all.length,(cmi.all.length!=1)?cmi.plural:cmi.single]);
	list.options[i++]=new Option(summary,'',false,false);
	list.options[i++]=new Option(((cmi.sort=='title'   )?'>':indent)+' [by title]','',false,false);
	list.options[i++]=new Option(((cmi.sort=='modified')?'>':indent)+' [by date]','',false,false);
	list.options[i++]=new Option(((cmi.sort=='tags')?'>':indent)+' [by tags]','',false,false);
	// output the tiddler list
	switch(cmi.sort) {
		case 'title':
			for(var t = 0; t < tiddlers.length; t++)
				list.options[i++] = new Option(tiddlers[t].title,tiddlers[t].title,false,false);
			break;
		case 'modified':
			// sort descending for newest date first
			tiddlers.sort(function (a,b) {if(a['modified'] == b['modified']) return(0); else return (a['modified'] > b['modified']) ? -1 : +1; });
			var lastSection = '';
			for(var t = 0; t < tiddlers.length; t++) {
				var tiddler = tiddlers[t];
				var theSection = tiddler.modified.toLocaleDateString();
				if (theSection != lastSection) {
					list.options[i++] = new Option(theSection,'',false,false);
					lastSection = theSection;
				}
				list.options[i++] = new Option(indent+indent+tiddler.title,tiddler.title,false,false);
			}
			break;
		case 'tags':
			var theTitles = {}; // all tiddler titles, hash indexed by tag value
			var theTags = new Array();
			for(var t=0; t<tiddlers.length; t++) {
				var title=tiddlers[t].title;
				var tags=tiddlers[t].tags;
				if (!tags || !tags.length) {
					if (theTitles['untagged']==undefined) { theTags.push('untagged'); theTitles['untagged']=new Array(); }
					theTitles['untagged'].push(title);
				}
				else for(var s=0; s<tags.length; s++) {
					if (theTitles[tags[s]]==undefined) { theTags.push(tags[s]); theTitles[tags[s]]=new Array(); }
					theTitles[tags[s]].push(title);
				}
			}
			theTags.sort();
			for(var tagindex=0; tagindex<theTags.length; tagindex++) {
				var theTag=theTags[tagindex];
				list.options[i++]=new Option(theTag,'',false,false);
				for(var t=0; t<theTitles[theTag].length; t++)
					list.options[i++]=new Option(indent+indent+theTitles[theTag][t],theTitles[theTag][t],false,false);
			}
			break;
		}
	list.selectedIndex=selectedIndex;		  // select current control item
	if (list.size<cmi.listsize) list.size=cmi.listsize;
	if (list.size>list.options.length) list.size=list.options.length;
}
//}}}
//{{{
// re-entrant processing for handling import with interactive collision prompting
function importTiddlers(startIndex) {
	var cmi=config.macros.importTiddlers; // abbrev
	if (!cmi.inbound) return -1;
	var list=cmi.$('importList'); if (!list) return;
	var t;
	// if starting new import, reset import status flags
	if (startIndex==0)
		for (var t=0;t<cmi.inbound.length;t++)
			cmi.inbound[t].status='';
	for (var i=startIndex; i<list.options.length; i++) {
		// if list item is not selected or is a heading (i.e., has no value), skip it
		if ((!list.options[i].selected) || ((t=list.options[i].value)==''))
			continue;
		for (var j=0;j<cmi.inbound.length;j++)
			if (cmi.inbound[j].title==t) break;
		var inbound = cmi.inbound[j];
		var theExisting = store.getTiddler(inbound.title);
		// avoid redundant import for tiddlers that are listed multiple times (when 'by tags')
		if (inbound.status=='added')
			continue;
		// don't import the 'ImportedTiddlers' history from the other document...
		if (inbound.title=='ImportedTiddlers')
			continue;
		// if tiddler exists and import not marked for replace or merge, stop importing
		if (theExisting && (inbound.status.substr(0,7)!='replace') && (inbound.status.substr(0,5)!='merge'))
			return i;
		// assemble tags (remote + existing + added)
		var newTags = '';
		if (cmi.importTags)
			newTags+=inbound.getTags()	// import remote tags
		if (cmi.keepTags && theExisting)
			newTags+=' '+theExisting.getTags(); // keep existing tags
		if (cmi.addTags && cmi.newTags.trim().length)
			newTags+=' '+cmi.newTags; // add new tags
		inbound.set(null,null,null,null,newTags.trim());
		// set the status to 'added' (if not already set by the 'ask the user' UI)
		inbound.status=(inbound.status=='')?'added':inbound.status;
		// set sync fields
		if (cmi.sync) {
			if (!inbound.fields) inbound.fields={}; // for TW2.1.x backward-compatibility
			inbound.fields['server.page.revision']=inbound.modified.convertToYYYYMMDDHHMM();
			inbound.fields['server.type']='file';
			inbound.fields['server.host']=(cmi.local&&!cmi.src.startsWith('file:')?'file:///':'')+cmi.src;
		}
		// do the import!
		store.suspendNotifications();
		store.saveTiddler(inbound.title, inbound.title, inbound.text, inbound.modifier, inbound.modified, inbound.tags, inbound.fields, true, inbound.created);
                store.fetchTiddler(inbound.title).created = inbound.created; // force creation date to imported value (needed for TW2.1.x and earlier)
		store.resumeNotifications();
		}
	return(-1);	// signals that we really finished the entire list
}
function importStopped() {
	var cmi=config.macros.importTiddlers; // abbrev
	var list=cmi.$('importList'); if (!list) return;
	var theNewTitle=cmi.$('importNewTitle');
	if (cmi.index==-1){ 
		cmi.$('importStart').value=cmi.startText;
		importReport();	// import finished... generate the report
	} else {
		// import collision...
		// show the collision panel and set the title edit field
		cmi.$('importStart').value=cmi.stopText;
		cmi.showPanel('importCollisionPanel',true);
		theNewTitle.value=list.options[cmi.index].value;
		if (cmi.$('importApplyToAll').checked && cmi.lastAction && cmi.lastAction.id!='importRename')
			onClickImportButton(cmi.lastAction);
	}
}
//}}}
//{{{
function importReport() {
	var cmi=config.macros.importTiddlers; // abbrev
	if (!cmi.inbound) return;
	// if import was not completed, the collision panel will still be open... close it now.
	var panel=cmi.$('importCollisionPanel'); if (panel) panel.style.display='none';
	// get the alphasorted list of tiddlers
	var tiddlers = cmi.inbound;
	// gather the statistics
	var count=0; var total=0;
	for (var t=0; t<tiddlers.length; t++) {
		if (!tiddlers[t].status || !tiddlers[t].status.trim().length) continue;
		if (tiddlers[t].status.substr(0,7)!='skipped') count++;
		total++;
	}
	// generate a report
	if (total) displayMessage(cmi.processedMsg.format([total]));
	if (count && config.options.chkImportReport) {
		// get/create the report tiddler
		var theReport = store.getTiddler('ImportedTiddlers');
		if (!theReport) { theReport=new Tiddler(); theReport.title='ImportedTiddlers'; theReport.text=''; }
		// format the report content
		var now = new Date();
		var newText = 'On '+now.toLocaleString()+', '+config.options.txtUserName
		newText +=' imported '+count+' tiddler'+(count==1?'':'s')+' from\n[['+cmi.src+'|'+cmi.src+']]:\n';
		if (cmi.addTags && cmi.newTags.trim().length)
			newText += 'imported tiddlers were tagged with: "'+cmi.newTags+'"\n';
		newText += '<<<\n';
		for (var t=0; t<tiddlers.length; t++) if (tiddlers[t].status)
			newText += '#[['+tiddlers[t].title+']] - '+tiddlers[t].status+'\n';
		newText += '<<<\n';
		// update the ImportedTiddlers content and show the tiddler
		theReport.text	 = newText+((theReport.text!='')?'\n----\n':'')+theReport.text;
		theReport.modifier = config.options.txtUserName;
		theReport.modified = new Date();
                store.saveTiddler(theReport.title, theReport.title, theReport.text, theReport.modifier, theReport.modified, theReport.tags, theReport.fields);
		story.displayTiddler(null,theReport.title,1,null,null,false);
		story.refreshTiddler(theReport.title,1,true);
	}
	// reset status flags
	for (var t=0; t<cmi.inbound.length; t++) cmi.inbound[t].status='';
	// mark document as dirty and let display update as needed
	if (count) { store.setDirty(true); store.notifyAll(); }
	// always show final message when tiddlers were actually loaded
	if (count) displayMessage(cmi.importedMsg.format([count,tiddlers.length,cmi.src.replace(/%20/g,' ')]));
}
//}}}
//{{{
// // File and XMLHttpRequest I/O
config.macros.importTiddlers.askForFilename=function(here) {
	var msg=here.title; // use tooltip as dialog box message
	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 file='';
	var result='';
	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.modeOpen);
			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 { // XPSP2 IE 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) {  // fallback
			var result=prompt(msg,path+file);
		}
	}
	return result;
}

config.macros.importTiddlers.loadRemoteFile = function(src,callback) {
	if (src==undefined || !src.length) return null; // filename is required
	var original=src; // URL as specified
	var hashpos=src.indexOf('#'); if (hashpos!=-1) src=src.substr(0,hashpos); // URL with #... suffix removed (needed for IE)
	clearMessage();
	displayMessage(this.openMsg.format([src.replace(/%20/g,' ')]));
	if (src.substr(0,5)!='http:' && src.substr(0,5)!='file:') { // if not a URL, read from local filesystem
		var txt=loadFile(src);
		if (!txt) { // file didn't load, might be relative path.. try fixup
			var pathPrefix=document.location.href;  // get current document path and trim off filename
			var slashpos=pathPrefix.lastIndexOf('/'); if (slashpos==-1) slashpos=pathPrefix.lastIndexOf('\\'); 
			if (slashpos!=-1 && slashpos!=pathPrefix.length-1) pathPrefix=pathPrefix.substr(0,slashpos+1);
			src=pathPrefix+src;
			if (pathPrefix.substr(0,5)!='http:') src=getLocalPath(src);
			var txt=loadFile(src);
		}
		if (!txt) { // file still didn't load, report error
			displayMessage(config.macros.importTiddlers.openErrMsg.format([src.replace(/%20/g,' '),'(filesystem error)']));
		} else {
			displayMessage(config.macros.importTiddlers.readMsg.format([txt.length,src.replace(/%20/g,' ')]));
			if (version.major+version.minor*.1+version.revision*.01!=2.52) txt=convertUTF8ToUnicode(txt);
			if (callback) callback(true,original,txt,src,null);
		}
	} else {
		doHttp('GET',src,null,null,config.options.txtRemoteUsername,config.options.txtRemotePassword,callback,original,null);
	}
}

config.macros.importTiddlers.readTiddlersFromHTML=function(html){
	var remoteStore=new TiddlyWiki();
	remoteStore.importTiddlyWiki(html);
	return remoteStore.getTiddlers('title');	
}

config.macros.importTiddlers.readTiddlersFromCSV=function(CSV){
	var remoteStore=new TiddlyWiki();
	// GET NAMES
	var lines=CSV.replace(/\r/g,'').split('\n');
	var names=lines.shift().replace(/"/g,'').split(',');
	CSV=lines.join('\n');
	// ENCODE commas and newlines within quoted values
	var comma='!~comma~!'; var commaRE=new RegExp(comma,'g');
	var newline='!~newline~!'; var newlineRE=new RegExp(newline,'g');
	CSV=CSV.replace(/"([^"]*?)"/g,
		function(x){ return x.replace(/\,/g,comma).replace(/\n/g,newline); });
	// PARSE lines
	var lines=CSV.split('\n');
	for (var i=0; i<lines.length; i++) { if (!lines[i].length) continue;
		var values=lines[i].split(',');
		// DECODE commas, newlines, and doubled-quotes, and remove enclosing quotes (if any)
		for (var v=0; v<values.length; v++)
			values[v]=values[v].replace(commaRE,',').replace(newlineRE,'\n')
				.replace(/^"|"$/g,'').replace(/""/g,'"');
		// EXTRACT tiddler values
		var title=''; var text=''; var tags=[]; var fields={};
		var created=null; var when=new Date(); var who=config.options.txtUserName;
		for (var v=0; v<values.length; v++) { var val=values[v];
			if (names[v]) switch(names[v].toLowerCase()) {
				case 'title':	title=val.replace(/\[\]\|/g,'_'); break;
				case 'created': created=new Date(val); break;
				case 'modified':when=new Date(val); break;
				case 'modifier':who=val; break;
				case 'text':	text=val; break;
				case 'tags':	tags=val.readBracketedList(); break;
				default:	fields[names[v].toLowerCase()]=val; break;
			}
		}
		// CREATE tiddler in temporary store
		if (title.length)
			remoteStore.saveTiddler(title,title,text,who,when,tags,fields,true,created||when);
	}
	return remoteStore.getTiddlers('title');
}

config.macros.importTiddlers.createTiddlerFromFile=function(src,txt) {
	var t=new Tiddler();
	var pos=src.lastIndexOf("/"); if (pos==-1) pos=src.lastIndexOf("\\");
	t.title=pos==-1?src:src.substr(pos+1);
	t.text=txt; 
	t.created=t.modified=new Date();
	t.modifier=config.options.txtUserName;
	if (src.substr(src.length-3,3)=='.js') t.tags=['systemConfig'];
	return [t];
}

config.macros.importTiddlers.filterTiddlerList=function(success,params,txt,src,xhr){
	var cmi=config.macros.importTiddlers; // abbreviation
	var src=src.replace(/%20/g,' ');
	if (!success) { displayMessage(cmi.openErrMsg.format([src,xhr.status])); return; }
	cmi.all=cmi.readTiddlersFromHTML(txt);
	if (!cmi.all||!cmi.all.length) cmi.all=cmi.readTiddlersFromCSV(txt)
	if (!cmi.all||!cmi.all.length) cmi.all=cmi.createTiddlerFromFile(src,txt)
	var count=cmi.all?cmi.all.length:0;
	var querypos=src.lastIndexOf('?'); if (querypos!=-1) src=src.substr(0,querypos);
	displayMessage(cmi.foundMsg.format([count,src]));
	cmi.inbound=cmi.filterByHash(params,cmi.all); // use full URL including hash (if any)
	cmi.$('importLastFilter').value=cmi.lastFilter;
	window.refreshImportList(0);
}

config.macros.importTiddlers.filterByHash=function(src,tiddlers){
	var hashpos=src.lastIndexOf('#'); if (hashpos==-1) return tiddlers;
	var hash=src.substr(hashpos+1); if (!hash.length) return tiddlers;
	var tids=[];
	var params=hash.parseParams('anon',null,true,false,false);
	for (var p=1; p<params.length; p++) {
		switch (params[p].name) {
			case 'anon':
			case 'open':
				tids.pushUnique(params[p].value);
				break;
			case 'tag':
				if (store.getMatchingTiddlers) { // for boolean expressions - see MatchTagsPlugin
					var r=store.getMatchingTiddlers(params[p].value,null,tiddlers);
					for (var t=0; t<r.length; t++) tids.pushUnique(r[t].title);
				} else for (var t=0; t<tiddlers.length; t++)
					if (tiddlers[t].isTagged(params[p].value))
						tids.pushUnique(tiddlers[t].title);
				break;
			case 'story':
				for (var t=0; t<tiddlers.length; t++)
					if (tiddlers[t].title==params[p].value) {
						tiddlers[t].changed();
						for (var s=0; s<tiddlers[t].links.length; s++)
							tids.pushUnique(tiddlers[t].links[s]);
						break;
					}
				break;
			case 'search':
				for (var t=0; t<tiddlers.length; t++)
					if (tiddlers[t].text.indexOf(params[p].value)!=-1)
						tids.pushUnique(tiddlers[t].title);
				break;
		}
	}
	var matches=[];
	for (var t=0; t<tiddlers.length; t++)
		if (tids.contains(tiddlers[t].title))
			matches.push(tiddlers[t]);
	displayMessage(config.macros.importTiddlers.filterMsg.format([matches.length,hash]));
	config.macros.importTiddlers.lastFilter=hash;
	return matches;
}
//}}}
/***
!!!Control panel CSS
//{{{
!css
#importPanel {
	display: none; position:absolute; z-index:11; width:35em; right:105%; top:3em;
	background-color: #eee; color:#000; font-size: 8pt; line-height:110%;
	border:1px solid black; border-bottom-width: 3px; border-right-width: 3px;
	padding: 0.5em; margin:0em; -moz-border-radius:1em;-webkit-border-radius:1em;
}
#importPanel a, #importPanel td a { color:#009; display:inline; margin:0px; padding:1px; }
#importPanel table { width:100%; border:0px; padding:0px; margin:0px; font-size:8pt; line-height:110%; background:transparent; }
#importPanel tr { border:0px;padding:0px;margin:0px; background:transparent; }
#importPanel td { color:#000; border:0px;padding:0px;margin:0px; background:transparent; }
#importPanel select { width:100%;margin:0px;font-size:8pt;line-height:110%;}
#importPanel input  { width:98%;padding:0px;margin:0px;font-size:8pt;line-height:110%}
#importPanel .box { border:1px solid #000; background-color:#eee; padding:3px 5px; margin-bottom:5px; -moz-border-radius:5px;-webkit-border-radius:5px;}
#importPanel .topline { border-top:1px solid #999; padding-top:2px; margin-top:2px; }
#importPanel .rad { width:auto; }
#importPanel .chk { width:auto; margin:1px;border:0; }
#importPanel .btn { width:auto; }
#importPanel .btn1 { width:98%; }
#importPanel .btn2 { width:48%; }
#importPanel .btn3 { width:32%; }
#importPanel .btn4 { width:23%; }
#importPanel .btn5 { width:19%; }
#importPanel .importButton { padding: 0em; margin: 0px; font-size:8pt; }
#importPanel .importListButton { padding:0em 0.25em 0em 0.25em; color: #000000; display:inline }
#backstagePanel #importPanel { left:10%; right:auto; }
!end
//}}}
!!!Control panel HTML
//{{{
!html
<!-- source and report -->
<table><tr><td align=left>
	import from
	<input type="radio" class="rad" name="importFrom" id="importFromFile" value="file" CHECKED
		onclick="onClickImportButton(this,event)" title="show file controls"> local file
	<input type="radio" class="rad" name="importFrom" id="importFromWeb"  value="http"
		onclick="onClickImportButton(this,event)" title="show web controls"> web server
</td><td align=right>
	<input type=checkbox class="chk" id="chkImportReport"
		onClick="config.options['chkImportReport']=this.checked;"> create report
</td></tr></table>

<div class="box" id="importSourcePanel" style="margin:.5em">
<div id="importLocalPanel" style="display:block;margin-bottom:2px;"><!-- import from local file  -->
enter or browse for source path/filename<br>
<input type="file" id="fileImportSource" size=57 style="width:100%"
	onKeyUp="config.macros.importTiddlers.src=this.value"
	onChange="config.macros.importTiddlers.src=this.value;document.getElementById('importLoad').onclick()">
<div id="importLocalPanelFix" style="display:none"><!-- FF3 FIXUP -->
	<input type="text" id="fileImportSourceFix" style="width:90%"
		title="Enter a path/file to import"
		onKeyUp="config.macros.importTiddlers.src=this.value"
		onChange="config.macros.importTiddlers.src=this.value;document.getElementById('importLoad').onclick()">
	<input type="button" id="fileImportSourceFixButton" style="width:7%" value="..."
		title="Select a path/file to import"
		onClick="var r=config.macros.importTiddlers.askForFilename(this); if (!r||!r.length) return;
			document.getElementById('fileImportSourceFix').value=r;
			config.macros.importTiddlers.src=r;
			document.getElementById('importLoad').onclick()">
</div><!--end FF3 FIXUP-->
</div><!--end local-->
<div id="importHTTPPanel" style="display:none;margin-bottom:2px;"><!-- import from http server -->
<table><tr><td align=left>
	enter a URL or <a href="javascript:;" id="importSelectFeed"
		onclick="return onClickImportButton(this,event)" title="select a pre-defined 'systemServer' URL">
		select a server</a><br>
</td><td align=right>
	<input type="checkbox" class="chk" id="importUsePassword"
		onClick="config.macros.importTiddlers.usePassword=this.checked;
			config.macros.importTiddlers.showPanel('importIDPWPanel',this.checked,true);">password
	<input type="checkbox" class="chk" id="importUseProxy"
		onClick="config.macros.importTiddlers.useProxy=this.checked;
			config.macros.importTiddlers.showPanel('importSiteProxy',this.checked,true);">proxy
</td></tr></table>
<input type="text" id="importSiteProxy" style="display:none;margin-bottom:1px" onfocus="this.select()" value="SiteProxy"
	onKeyUp="config.macros.importTiddlers.proxy=this.value"
	onChange="config.macros.importTiddlers.proxy=this.value;">
<input type="text" id="importSourceURL" onfocus="this.select()" value="SiteUrl"
	onKeyUp="config.macros.importTiddlers.src=this.value"
	onChange="config.macros.importTiddlers.src=this.value;">
<div id="importIDPWPanel" style="text-align:center;margin-top:2px;display:none";>
username: <input type=text id="txtImportID" style="width:25%" 
	onChange="config.options.txtRemoteUsername=this.value;">
 password: <input type=password id="txtImportPW" style="width:25%" 
	onChange="config.options.txtRemotePassword=this.value;">
</div><!--end idpw-->
</div><!--end http-->
</div><!--end source-->

<div class="box" id="importSelectPanel" style="display:none;margin:.5em;">
<table><tr><td align=left>
select:
<a href="javascript:;" id="importSelectAll"
	onclick="return onClickImportButton(this)" title="SELECT all tiddlers">
	all</a>
&nbsp;<a href="javascript:;" id="importSelectNew"
	onclick="return onClickImportButton(this)" title="SELECT tiddlers not already in destination document">
	added</a>
&nbsp;<a href="javascript:;" id="importSelectChanges"
	onclick="return onClickImportButton(this)" title="SELECT tiddlers that have been updated in source document">
	changes</a>
&nbsp;<a href="javascript:;" id="importSelectDifferences"
	onclick="return onClickImportButton(this)" title="SELECT tiddlers that have been added or are different from existing tiddlers">
	differences</a>
</td><td align=right>
<a href="javascript:;" id="importListSmaller"
	onclick="return onClickImportButton(this)" title="SHRINK list size">
	&nbsp;&#150;&nbsp;</a>
<a href="javascript:;" id="importListLarger"
	onclick="return onClickImportButton(this)" title="GROW list size">
	&nbsp;+&nbsp;</a>
<a href="javascript:;" id="importListMaximize"
	onclick="return onClickImportButton(this)" title="MAXIMIZE/RESTORE list size">
	&nbsp;=&nbsp;</a>
</td></tr></table>
<select id="importList" size=8 multiple
	onchange="setTimeout('refreshImportList('+this.selectedIndex+')',1)">
	<!-- NOTE: delay refresh so list is updated AFTER onchange event is handled -->
</select>
<div style="text-align:center">
	<a href="javascript:;"
		title="click for help using filters..."
		onclick="alert('A filter consists of one or more space-separated combinations of: tiddlertitle, tag:[[tagvalue]], tag:[[tag expression]] (requires MatchTagsPlugin), story:[[TiddlerName]], and/or search:[[searchtext]]. Use a blank filter to restore the list of all tiddlers.'); return false;"
	>filter</a>
	<input type="text" id="importLastFilter" style="margin-bottom:1px; width:65%"
		title="Enter a combination of one or more filters. Use a blank filter for all tiddlers."
		onfocus="this.select()" value=""
		onKeyUp="config.macros.importTiddlers.lastFilter=this.value"
		onChange="config.macros.importTiddlers.lastFilter=this.value;">
	<input type="button" id="importApplyFilter" style="width:20%" value="apply"
		title="filter list of tiddlers to include only those that match certain criteria"
		onclick="return onClickImportButton(this)">
	</div>
</div><!--end select-->

<div class="box" id="importOptionsPanel" style="text-align:center;margin:.5em;display:none;">
	apply tags: <input type=checkbox class="chk" id="chkImportTags" checked
		onClick="config.macros.importTiddlers.importTags=this.checked;">from source&nbsp;
	<input type=checkbox class="chk" id="chkKeepTags" checked
		onClick="config.macros.importTiddlers.keepTags=this.checked;">keep existing&nbsp;
	<input type=checkbox class="chk" id="chkAddTags" 
		onClick="config.macros.importTiddlers.addTags=this.checked;
			config.macros.importTiddlers.showPanel('txtNewTags',this.checked,false);
			if (this.checked) document.getElementById('txtNewTags').focus();">add tags<br>
	<input type=text id="txtNewTags" style="margin-top:4px;display:none;" size=15 onfocus="this.select()" 
		title="enter tags to be added to imported tiddlers" 
		onKeyUp="config.macros.importTiddlers.newTags=this.value;
		document.getElementById('chkAddTags').checked=this.value.length>0;" autocomplete=off>
	<nobr><input type=checkbox class="chk" id="chkSync" 
		onClick="config.macros.importTiddlers.sync=this.checked;">
		link tiddlers to source document (for sync later)</nobr>
</div><!--end options-->

<div id="importButtonPanel" style="text-align:center">
	<input type=button id="importLoad"	class="importButton btn3" value="open"
		title="load listbox with tiddlers from source document"
		onclick="onClickImportButton(this)">
	<input type=button id="importOptions"	class="importButton btn3" value="options..."
		title="set options for tags, sync, etc."
		onclick="onClickImportButton(this)">
	<input type=button id="importStart"	class="importButton btn3" value="import"
		title="start/stop import of selected source tiddlers into current document"
		onclick="onClickImportButton(this)">
	<input type=button id="importClose"	class="importButton btn3" value="done"
		title="clear listbox or hide control panel"
		onclick="onClickImportButton(this)">
</div>

<div class="none" id="importCollisionPanel" style="display:none;margin:.5em 0 .5em .5em;">
	<table><tr><td style="width:65%" align="left">
		<table><tr><td align=left>
			tiddler already exists:
		</td><td align=right>
			<input type=checkbox class="chk" id="importApplyToAll" 
			onclick="document.getElementById('importRename').disabled=this.checked;"
			checked>apply to all
		</td></tr></table>
		<input type=text id="importNewTitle" size=15 autocomplete=off">
	</td><td style="width:34%" align="center">
		<input type=button id="importMerge"
			class="importButton" style="width:47%" value="merge"
			title="append the incoming tiddler to the existing tiddler"
			onclick="onClickImportButton(this)"><!--
		--><input type=button id="importSkip"
			class="importButton" style="width:47%" value="skip"
			title="do not import this tiddler"
			onclick="onClickImportButton(this)"><!--
		--><br><input type=button id="importRename"
			class="importButton" style="width:47%" value="rename"
			title="rename the incoming tiddler"
			onclick="onClickImportButton(this)"><!--
		--><input type=button id="importReplace"
			class="importButton" style="width:47%" value="replace"
			title="discard the existing tiddler"
			onclick="onClickImportButton(this)">
	</td></tr></table>
</div><!--end collision-->
!end
//}}}
***/
 
!!!Important Dates
<<reminder month:9 day:20 title:"TiddlyWiki's First Release Anniversary" firstyear:2004>>
<<reminder month:1 day:15 title:"Firearm Authorization Expires" >>
<<reminder month:6 day:15 title:"Firearm Authorization Expires" >>

!!!Holidays
*<<reminder month:1 day:1 title:"New Year's Day" >>
*<<reminder month:2 day:2 title:"Groundhog Day" >>
*<<reminder month:2 day:15 offsetdayofweek:1 title:"President's Day">>
*<<reminder month:5 day:8 offsetdayofweek:0 title:"Mother's Day">>
*<<reminder month:5 day:31 offsetdayofweek:-1 title:"Memorial Day">>
*<<reminder month:2 day:14 title:"Valentine's Day" >>
*<<reminder month:4 day:1 title:"April Fool's Day" >>
*<<reminder month:4 day:15  title:"Tax day">>
*<<reminder month:4 day:22 title:"Earth Day">>
*<<reminder month:6 day:14 title:"Flag Day" >>
*<<reminder month:6 day:15 offsetdayofweek:0 title:"Father's Day">>
*<<reminder month:7 day:4 title:"Independence Day" >>
*<<reminder month:9 day:1 offsetdayofweek:1 title:"Labor Day">>
*<<reminder month:10 day:8 offsetdayofweek:1 title:"Columbus Day">>
*<<reminder month:10 day:31 title:"Halloween" >>
*<<reminder month:11 day:11 title:"Veteran's Day" >>
*<<reminder month:11 day:22 offsetdayofweek:4 title:"Thanksgiving (US)">>
*<<reminder month:12 day:25 title:"Christmas Day" >>

<<newReminder>>
On Tuesday, June 22, 2010 12:22:35 AM, Mike imported 1 tiddler from
[[http://www.tiddlytools.com|http://www.tiddlytools.com]]:
<<<
#[[ShowSimilarTiddlers]] - added
<<<

----
On Tuesday, June 22, 2010 12:22:22 AM, Mike imported 3 tiddlers from
[[http://www.tiddlytools.com|http://www.tiddlytools.com]]:
<<<
#[[MultiSelectSampleScript]] - added
#[[ShowAllByTags]] - replaces ShowAllByTags - 12/22/2009 08:12:00 by Mike
#[[ShowAllPermalinks]] - added
<<<

----
On Tuesday, June 22, 2010 12:21:21 AM, Mike imported 19 tiddlers from
[[http://www.tiddlytools.com|http://www.tiddlytools.com]]:
<<<
#[[QuickEditPackage]] - replaces QuickEditPackage - 3/27/2008 00:28:00 by ELSDesignStudios
#[[QuickEditPlugin]] - replaces QuickEditPlugin - 5/18/2008 22:45:00 by ELSDesignStudios
#[[QuickEditToolbar]] - replaces QuickEditToolbar - 6/22/2010 00:13:25 by Mike
#[[QuickEdit_align]] - replaces QuickEdit_align - 4/3/2008 18:19:00 by ELSDesignStudios
#[[QuickEdit_color]] - replaces QuickEdit_color - 2/28/2008 07:55:00 by ELSDesignStudios
#[[QuickEdit_convert]] - added
#[[QuickEdit_custom]] - added
#[[QuickEdit_customList]] - added
#[[QuickEdit_font]] - replaces QuickEdit_font - 3/22/2008 14:20:00 by ELSDesignStudios
#[[QuickEdit_fontList]] - replaces QuickEdit_fontList - 3/22/2008 14:01:00 by ELSDesignStudios
#[[QuickEdit_format]] - replaces QuickEdit_format - 4/3/2008 18:23:00 by ELSDesignStudios
#[[QuickEdit_image]] - replaces QuickEdit_image - 2/28/2008 08:00:00 by ELSDesignStudios
#[[QuickEdit_insert]] - added
#[[QuickEdit_link]] - replaces QuickEdit_link - 3/27/2008 00:27:00 by ELSDesignStudios
#[[QuickEdit_macro]] - replaces QuickEdit_macro - 2/28/2008 07:56:00 by ELSDesignStudios
#[[QuickEdit_replace]] - replaces QuickEdit_replace - 2/28/2008 07:56:00 by ELSDesignStudios
#[[QuickEdit_sort]] - replaces QuickEdit_sort - 2/28/2008 07:56:00 by ELSDesignStudios
#[[QuickEdit_split]] - replaces QuickEdit_split - 3/8/2008 03:08:00 by ELSDesignStudios
#[[StyleSheetShortcuts]] - replaces StyleSheetShortcuts - 1/5/2008 21:43:00 by ELSDesignStudios
<<<

----
On Tuesday, June 22, 2010 12:17:59 AM, Mike imported 1 tiddler from
[[http://www.tiddlytools.com|http://www.tiddlytools.com]]:
<<<
#[[ImportTiddlersPlugin]] - replaces ImportTiddlersPlugin - 6/3/2009 16:46:00 by YourName
<<<

----
On Wednesday, February 10, 2010 4:09:32 PM, Mike imported 9 tiddlers from
[[E:\Documents\tw\testwiki.htm|E:\Documents\tw\testwiki.htm]]:
<<<
#[[All Open Tiddlers]] - added
#[[GetTaggedByField]] - added
#[[HelloWorldMacro]] - added
#[[ListTags]] - added
#[[ShowAllByTags]] - added
#[[ShowAllByTagsB]] - added
#[[Tag List from prefix]] - added
#[[allTagsExcept]] - added
#[[simple for / next loop]] - added
<<<

----
On Wednesday, February 10, 2010 4:06:30 PM, Mike imported 10 tiddlers from
[[E:\Documents\tw\testwiki.htm|E:\Documents\tw\testwiki.htm]]:
<<<
#[[CoreTweaks]] - replaces CoreTweaks - 1/28/2009 17:04:00 by Mike
#[[CustomViewTemplate]] - replaces CustomViewTemplate - 12/20/2008 13:50:00 by Mike
#[[DefaultTiddlers]] - replaces DefaultTiddlers - 11/24/2009 14:23:00 by Mike
#[[SandBox]] - replaces SandBox - 8/18/2009 08:58:00 by Mike
#[[Script]] - replaces Script - 5/21/2009 07:25:00 by Mike
#[[Slideshow]] - replaces Slideshow - 6/4/2009 09:13:00 by Mike
#[[TagDB]] - replaces TagDB - 8/4/2009 12:26:00 by Mike
#[[Thumbs]] - replaces Thumbs - 6/5/2009 14:20:00 by Mike
#[[Thumbs align right]] - replaces Thumbs align right - 6/5/2009 16:43:00 by Mike
#[[Tiddler transclude right]] - replaces Tiddler transclude right - 6/5/2009 17:21:00 by Mike
<<<

----
On Wednesday, June 03, 2009 4:47:18 PM, YourName imported 297 tiddlers from
[[E:\Private\Documents\TidlyWiki\TestWiki.htm|E:\Private\Documents\TidlyWiki\TestWiki.htm]]:
<<<
#[[(Default) MD]] - added
#[[041209 JS tag to table]] - added
#[[042409 Count Tiddlers]] - added
#[[042809 Auto / Silent Create]] - added
#[[All Tiddlers]] - added
#[[AllThumbs]] - added
#[[Apples]] - added
#[[Auto Test 042809]] - added
#[[BackstageSR]] - added
#[[Black n Blue]] - added
#[[Black2Khaki]] - added
#[[Blood1Theme]] - added
#[[Blood2Theme]] - added
#[[Blood3Theme]] - added
#[[Blood6Theme]] - added
#[[Blood7Theme]] - added
#[[Bloody]] - added
#[[Bloody2]] - added
#[[Blue2Blue]] - added
#[[Blue2Theme]] - added
#[[Blue3Theme]] - added
#[[Blue4Theme]] - added
#[[Blue6Theme]] - added
#[[Blue7Theme]] - added
#[[Blueberry]] - added
#[[Brown]] - added
#[[Brown2Black]] - added
#[[BrownnBlack]] - added
#[[Calendar]] - added
#[[CalendarPlugin]] - added
#[[CheckboxPlugin]] - added
#[[CheckboxPluginInfo]] - added
#[[CheckboxToggleTag]] - added
#[[ChecklistScript]] - added
#[[Chrome]] - added
#[[ClickifyPlugin]] - added
#[[CloseOnCancelPlugin]] - added
#[[CollapseTemplate]] - added
#[[CollapseTiddlersPlugin]] - added
#[[CollapsedTemplate]] - added
#[[ColorChart SH]] - added
#[[ColorPalette]] - added
#[[ColorPaletteColors]] - added
#[[ConfigTweaksPlugin]] - added
#[[CoreTweaks]] - added
#[[CustomEditTemplate]] - added
#[[CustomPageTemplate]] - added
#[[CustomStyleSheet]] - added
#[[CustomTheme]] - added
#[[CustomViewTemplate]] - added
#[[DatePlugin]] - added
#[[DatePluginConfig]] - added
#[[DateTime]] - added
#[[Decrypt(Home)]] - added
#[[Decrypt(Test)]] - added
#[[Decrypt(Work)]] - added
#[[DefaultTiddlers]] - added
#[[DeleteAllTaggedPlugin]] - added
#[[DeleteCompletedPlugin]] - added
#[[DeprecatedFunctionsPlugin]] - added
#[[DevilTheme]] - added
#[[Dice]] - added
#[[DigitalClock]] - added
#[[DragonTheme]] - added
#[[Drives]] - added
#[[DropDownMenuPlugin]] - added
#[[Embed Media Player]] - added
#[[Emerald]] - added
#[[EmptyTest]] - added
#[[Encrypt(Home)]] - added
#[[Encrypt(Test)]] - added
#[[Encrypt(Work)]] - added
#[[Encrypted]] - added
#[[ExcludeFromTagList]] - added
#[[FET Tiddler List (with Paging)]] - added
#[[Fire]] - added
#[[Fire1Theme]] - added
#[[Fire2Theme]] - added
#[[Fire3Theme]] - added
#[[Fire4Theme]] - added
#[[FireMindTheme]] - added
#[[FirefoxPrivilegesPlugin]] - added
#[[FontSizePlugin]] - added
#[[FooterPageTemplate]] - added
#[[FooterStyleSheet]] - added
#[[ForEachTiddlerPlugin]] - added
#[[FullScreenPlugin]] - added
#[[GradientMacro]] - added
#[[Green2Green]] - added
#[[Header&Footer]] - added
#[[HideTiddlerBackground]] - added
#[[HideWhenPlugin]] - added
#[[HistoryPlugin]] - added
#[[HomeMacro]] - added
#[[HoverMenu]] - added
#[[HoverMenuPlugin]] - added
#[[HoverMenuStyleSheet]] - added
#[[Html]] - added
#[[ILJS Table Example]] - added
#[[ImageSizePlugin]] - added
#[[Images HTML Linked & Plugin]] - added
#[[ImgPageTemplate]] - added
#[[Import Tiddlers]] - added
#[[ImportTiddlers]] - added
#[[ImportTiddlersPlugin]] - skipped after asking
#[[Important Dates]] - added
#[[InlineJavascriptPlugin]] - added
#[[InlineJavascriptPluginInfo]] - added
#[[Java Date Examples]] - added
#[[Khaki2Black]] - added
#[[Khaki2Grey]] - added
#[[KhakiBlack]] - added
#[[KhakinBlack2]] - added
#[[LessBackupsPlugin]] - added
#[[LimitOpenTiddlersPlugin]] - added
#[[LoadTiddlersPlugin]] - added
#[[LoadTiddlersPluginInfo]] - added
#[[MGTDBlue]] - added
#[[MGTDGreen]] - added
#[[MGTDRed]] - added
#[[MGTDSmoke]] - added
#[[MGTDTeal]] - added
#[[MONEY]] - added
#[[MainMenu]] - added
#[[MatchTagsPlugin]] - added
#[[Mauve]] - added
#[[Menu]] - added
#[[Mocha]] - added
#[[Movable Panel Trick]] - added
#[[MovablePanelPlugin]] - added
#[[MoveablePanelPluginInfo]] - added
#[[MptwBlack]] - added
#[[MptwRounded]] - added
#[[MptwStyleSheet]] - added
#[[MptwTheme]] - added
#[[NestedSlidersPlugin]] - added
#[[NestedSlidersPluginInfo]] - added
#[[New Here Button Plugin]] - added
#[[NewHerePlugin]] - added
#[[NewMeansNewPlugin]] - added
#[[NewTiddlerwithData]] - added
#[[No Tags]] - added
#[[OptionsPanel]] - added
#[[Orange2Black]] - added
#[[OrangenBlack]] - added
#[[PaletteViewMacro]] - added
#[[PartTiddlerPlugin]] - added
#[[PhotoGalleryPlugin]] - added
#[[PluginStyles]] - added
#[[Pretty Tags]] - added
#[[PrettyDatesPlugin]] - added
#[[Quick Countdown v2.1]] - added
#[[QuickEdit]] - added
#[[QuickEditPackage]] - added
#[[QuickEditPlugin]] - added
#[[QuickEditTemplate]] - added
#[[QuickEditToolbar]] - added
#[[QuickEdit_align]] - added
#[[QuickEdit_color]] - added
#[[QuickEdit_css]] - added
#[[QuickEdit_file]] - added
#[[QuickEdit_font]] - added
#[[QuickEdit_fontList]] - added
#[[QuickEdit_format]] - added
#[[QuickEdit_image]] - added
#[[QuickEdit_link]] - added
#[[QuickEdit_macro]] - added
#[[QuickEdit_replace]] - added
#[[QuickEdit_sort]] - added
#[[QuickEdit_split]] - added
#[[QuickEdit_tiddler]] - added
#[[QuickOpenTagPlugin]] - added
#[[Quotations]] - added
#[[QuoteOfTheDayPlugin]] - added
#[[QuoteOfTheDayPluginInfo]] - added
#[[REDD]] - added
#[[RearrangeTiddlersPlugin]] - added
#[[Red3Theme]] - added
#[[Red7Theme]] - added
#[[RednBlack]] - added
#[[Reference]] - added
#[[RefreshTiddler]] - added
#[[ReminderExamples]] - added
#[[ReminderPlugin]] - added
#[[ReminderSyntax]] - added
#[[Reminders]] - added
#[[RenameTagsPlugin]] - added
#[[RunMacroIfTaggedPlugin]] - added
#[[STRM Blue 1]] - added
#[[STRM Blue 2]] - added
#[[STRM Blue 3]] - added
#[[SandBox]] - added
#[[SaveAndReloadMacro]] - added
#[[SaveAsPlugin]] - added
#[[SaveCloseTiddlerPlugin]] - added
#[[Script]] - added
#[[SearchMenu]] - added
#[[Sections n Slices]] - added
#[[SelectPalettePlugin]] - added
#[[SetTiddlerBackground]] - added
#[[SetUserNamePlugin]] - added
#[[ShowClockMacro]] - added
#[[ShowCookies]] - added
#[[ShowLocalDirectory]] - added
#[[ShowPopup]] - added
#[[ShowTabsForTags]] - added
#[[ShowTiddlerStatistics]] - added
#[[ShowUserName]] - added
#[[SideBarOptions]] - added
#[[SideBarTabs]] - added
#[[SideBarWG]] - added
#[[SiteSubtitle]] - added
#[[SiteTitle]] - added
#[[Skull3Theme]] - added
#[[Skull5bTheme]] - added
#[[Skull8Theme]] - added
#[[SliceGridPlugin]] - added
#[[SliceGridPluginInfo]] - added
#[[Slices to table (ELS)]] - added
#[[Slider]] - added
#[[SliderHelp]] - added
#[[SmileyPlugin]] - added
#[[Smileys]] - added
#[[SourceTiddler]] - added
#[[StyleSheetAdjustments]] - added
#[[StyleSheetPrint]] - added
#[[StyleSheetShortcuts]] - added
#[[StyleSheetTiddlersBar]] - added
#[[SwitchThemePlugin]] - added
#[[SwitchThemePluginInfo]] - added
#[[Tab for Tag (using Match Tiddlers)]] - added
#[[TabContents]] - added
#[[TabMore]] - added
#[[TableAggregatePlugin]] - added
#[[TableAggregateSample]] - added
#[[TableSortingPlugin]] - added
#[[Tabs]] - added
#[[TagCloudPlugin]] - added
#[[TagDB]] - added
#[[TaggedTemplateTweak]] - added
#[[TaggedTemplateTweakInfo]] - added
#[[TaggerPlugin]] - added
#[[TaggerPluginDocumentation]] - added
#[[Tagging]] - added
#[[TagglyTaggingPlugin]] - added
#[[TagsTreePlugin]] - added
#[[TaskOrganizerPlugin]] - added
#[[TaskOrganizerPluginDoc]] - added
#[[TaskOrganizerPluginDoc:Test]] - added
#[[TaskOrganizerPluginDoc:Test2]] - added
#[[Test]] - added
#[[Test.Test]] - added
#[[Test.Test2]] - added
#[[Test1.1]] - added
#[[Test1.2]] - added
#[[Test2.1]] - added
#[[Test2.2]] - added
#[[TestPalette]] - added
#[[TextAreaPlugin]] - added
#[[TextAreaPluginInfo]] - added
#[[ThumbThing]] - added
#[[Thumbs]] - added
#[[Tiddler by Who]] - added
#[[TiddlerEncryptionPlugin]] - added
#[[TiddlerTweakerPlugin]] - added
#[[TiddlersBarPlugin]] - added
#[[TiddlyWiki]] - added
#[[ToggleScrollingSidebars]] - added
#[[ToggleTagPlugin]] - added
#[[ToolbarCommands]] - added
#[[Trash]] - added
#[[TrashPlugin]] - added
#[[Tricks]] - added
#[[UnTagged]] - added
#[[User Name from Options]] - added
#[[ViewPalettePlugin]] - added
#[[Wiki Formatting]] - added
#[[WiltedRose]] - added
#[[WordCount]] - added
#[[YourSearch Help]] - added
#[[YourSearchPlugin]] - added
#[[completed]] - added
#[[contentFooter]] - added
#[[contentHeader]] - added
#[[encrypt(home)]] - added
#[[excludeLists]] - added
#[[extendTagButton.Tweak]] - added
#[[extendTagButtonPlugin]] - added
#[[greenishgray]] - added
#[[noRandom]] - added
#[[palette]] - added
#[[skull5Theme]] - added
#[[systemConfig]] - added
#[[systemConfigDisable]] - added
#[[systemTheme]] - added
#[[tagged tiddlers in a table]] - added
#[[tasks]] - added
#[[zConfig]] - added
<<<
/***
|Name|InlineJavascriptPlugin|
|Source|http://www.TiddlyTools.com/#InlineJavascriptPlugin|
|Documentation|http://www.TiddlyTools.com/#InlineJavascriptPluginInfo|
|Version|1.9.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|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.
!!!!!Documentation
>see [[InlineJavascriptPluginInfo]]
!!!!!Revisions
<<<
2008.06.11 [1.9.3] added $(...) function as 'shorthand' convenience syntax for document.getElementById()
2008.03.03 [1.9.2] corrected declaration of wikifyPlainText() for 'TW 2.1.x compatibility fallback' (fixes Safari "parse error")
2008.02.23 [1.9.1] in onclick function, use string instead of array for 'bufferedHTML' attribute on link element (fixes IE errors)
2008.02.21 [1.9.0] 'onclick' scripts now allow returned text (or document.write() calls) to be wikified into a span that immediately follows the onclick link.  Also, added default 'return false' handling if no return value provided (prevents HREF from being triggered -- return TRUE to allow HREF to be processed).  Thanks to Xavier Verges for suggestion and preliminary code.
|please see [[InlineJavascriptPluginInfo]] for additional revision details|
2005.11.08 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.inlineJavascript= {major: 1, minor: 9, revision: 3, date: new Date(2008,6,11)};

config.formatters.push( {
	name: "inlineJavascript",
	match: "\\<script",
	lookahead: "\\<script(?: src=\\\"((?:.|\\n)*?)\\\")?(?: label=\\\"((?:.|\\n)*?)\\\")?(?: title=\\\"((?:.|\\n)*?)\\\")?(?: key=\\\"((?:.|\\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) {
			var src=lookaheadMatch[1];
			var label=lookaheadMatch[2];
			var tip=lookaheadMatch[3];
			var key=lookaheadMatch[4];
			var show=lookaheadMatch[5];
			var code=lookaheadMatch[6];
			if (src) { // 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 = src;
				document.body.appendChild(script); document.body.removeChild(script);
			}
			if (code) { // there is script code
				if (show) // show inline script code in tiddler output
					wikify("{{{\n"+lookaheadMatch[0]+"\n}}}\n",w.output);
				if (label) { // 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",wikifyPlainText(label));
					var fixup=code.replace(/document.write\s*\(/gi,'place.bufferedHTML+=(');
					link.code="function _out(place){"+fixup+"\n};_out(this);"
					link.tiddler=w.tiddler;
					link.onclick=function(){
						this.bufferedHTML="";
						try{ var r=eval(this.code);
							if(this.bufferedHTML.length || (typeof(r)==="string")&&r.length)
								var s=this.parentNode.insertBefore(document.createElement("span"),this.nextSibling);
							if(this.bufferedHTML.length)
								s.innerHTML=this.bufferedHTML;
							if((typeof(r)==="string")&&r.length) {
								wikify(r,s,null,this.tiddler);
								return false;
							} else return r!==undefined?r:false;
						} catch(e){alert(e.description||e.toString());return false;}
					};
					link.setAttribute("title",tip||"");
					var URIcode='javascript:void(eval(decodeURIComponent(%22(function(){try{';
					URIcode+=encodeURIComponent(encodeURIComponent(code.replace(/\n/g,' ')));
					URIcode+='}catch(e){alert(e.description||e.toString())}})()%22)))';
					link.setAttribute("href",URIcode);
					link.style.cursor="pointer";
					if (key) link.accessKey=key.substr(0,1); // single character only
				}
				else { // run inline script code
					var fixup=code.replace(/document.write\s*\(/gi,'place.innerHTML+=(');
					var code="function _out(place){"+fixup+"\n};_out(w.output);"
					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;
		}
	}
} )
//}}}

// // Backward-compatibility for TW2.1.x and earlier
//{{{
if (typeof(wikifyPlainText)=="undefined") window.wikifyPlainText=function(text,limit,tiddler) {
	if(limit > 0) text = text.substr(0,limit);
	var wikifier = new Wikifier(text,formatter,null,tiddler);
	return wikifier.wikifyPlain();
}
//}}}

// // $(...) function: 'shorthand' convenience syntax for document.getElementById()
//{{{
if (typeof($)=="undefined") { // avoid redefinition
function $() {
	var elements=new Array();
	for (var i=0; i<arguments.length; i++) {
		var element=arguments[i];
		if (typeof element=='string') element=document.getElementById(element);
		if (arguments.length==1) return element;
		elements.push(element);
	}
	return elements;
}
}
//}}}
/***
|Name|InlineJavascriptPluginInfo|
|Source|http://www.TiddlyTools.com/#InlineJavascriptPlugin|
|Documentation|http://www.TiddlyTools.com/#InlineJavascriptPluginInfo|
|Version|1.9.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|documentation|
|Requires||
|Overrides||
|Description|Documentation for InlineJavascriptPlugin|
''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
<<<
This plugin adds wiki syntax for surrounding tiddler content with {{{<script>}}} and {{{</script>}}} markers, so that it can be recognized as embedded javascript code.
<script show>
	/* javascript code goes here... */
</script>Every time the tiddler content is rendered, the javascript code is automatically evaluated, allowing you to invoke 'side-effect' processing and/or produce dynamically-generated content that is then inserted into the tiddler content, immediately following the script (see below).  By including the optional ''show'' keyword as the final parameter in a {{{<script>}}} marker, the plugin will also include the script source code in the output that it displays in the tiddler.  This is helpful when creating examples for documentation purposes (such as used in this tiddler!)

__''Deferred execution from an 'onClick' link''__
<script label="click here" title="mouseover tooltip text" key="X" show>
	/* javascript code goes here... */
	alert('you clicked on the link!');
</script>
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, and a {{{key="X"}}} parameter to specify an //access key// (which must be a //single// letter or numeric digit only).

__''Loading scripts from external source files''__
<script src="URL" show>
	/* optional javascript code goes here... */
</script>You can also load javascript directly 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.

In addition to loading the javascript from the external file, you can also use this feature to invoke javascript code contained within the {{{<script>...</script>}}} markers.  This code is invoked //after// the external script file has been processed, and can make immediate use of the functions and/or global variables defined by the external script file.
>Note: To ensure that your javascript functions are always available when needed, you should load the libraries from a tiddler that is rendered as soon as your TiddlyWiki document is opened, such as MainMenu.  For example: put your {{{<script src="..."></script>}}} syntax into a separate 'library' tiddler (e.g., LoadScripts), and then add {{{<<tiddler LoadScripts>>}}} to MainMenu so that the library is loaded before any other tiddlers that rely upon the functions it defines. 
>
>Normally, loading external javascript in this way does not produce any direct output, and should not have any impact on the appearance of your MainMenu.  However, if your LoadScripts tiddler contains notes or other visible content, you can suppress this output by using 'inline CSS' in the MainMenu, like this: {{{@@display:none;<<tiddler LoadScripts>>@@}}}
<<<
!!!!!Creating dynamic tiddler content and accessing the ~TiddlyWiki DOM
<<<
An important difference between TiddlyWiki inline 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()}}} (or {{{document.writeln()}}}) 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 instead will //completely replace the entire ~TiddlyWiki document in your browser window (which is clearly not a good thing!)//.  In order to allow scripts to use {{{document.write()}}}, the plugin automatically converts and buffers all HTML output so it can be safely inserted into your tiddler content, immediately following the script.

''Note that {{{document.write()}}} can only be used to output "pure HTML" syntax.  To produce //wiki-formatted// output, your script should instead return a text value containing the desired wiki-syntax content'', which will then be automatically rendered immediately following the script.  If returning a text value is not sufficient for your needs, the plugin also provides an automatically-defined variable, 'place', that gives the script code ''direct access to the //containing DOM element//'' into which the tiddler output is being rendered.  You can use this variable to ''perform direct DOM manipulations'' that can, for example:
* generate wiki-formatted output using {{{wikify("...content...",place)}}}
* vary the script's actions based upon the DOM element in which it is embedded
* access 'tiddler-relative' DOM information using {{{story.findContainingTiddler(place)}}}
Note:
''When using an 'onclick' script, the 'place' element actually refers to the onclick //link text// itself, instead of the containing DOM element.''  This permits you to directly reference or modify the link text to reflect any 'stateful' conditions that might set by the script.  To refer to the containing DOM element from within an 'onclick' script, you can use "place.parentNode" instead.
<<<
!!!!!Instant "bookmarklets"
<<<
You can also use an 'onclick' link to define a "bookmarklet": a small piece of javascript that can be ''invoked directly from the browser without having to be defined within the current document.''  This allows you to create 'stand-alone' commands that can be applied to virtually ANY TiddlyWiki document... even remotely-hosted documents that have been written by others!!  To create a bookmarklet, simply define an 'onclick' script and then grab the resulting link text and drag-and-drop it onto your browser's toolbar (or right-click and use the 'bookmark this link' command to add it to the browser's menu).

Notes:
*When writing scripts intended for use as bookmarklets, due to the ~URI-encoding required by the browser, ''you cannot not use ANY double-quotes (") within the bookmarklet script code.''
*All comments embedded in the bookmarklet script must ''use the fully-delimited {{{/* ... */}}} comment syntax,'' rather than the shorter {{{//}}} comment syntax.
*Most importantly, because bookmarklets are invoked directly from the browser interface and are not embedded within the TiddlyWiki document, there is NO containing 'place' DOM element surrounding the script.  As a result, ''you cannot use a bookmarklet to generate dynamic output in your document,''  and using {{{document.write()}}} or returning wiki-syntax text or making reference to the 'place' DOM element will halt the script and report a "Reference Error" when that bookmarklet is invoked.  
Please see [[InstantBookmarklets]] for many examples of 'onclick' scripts that can also be used as bookmarklets.
<<<
!!!!!Special reserved function name
<<<
The plugin 'wraps' all inline javascript code 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.
<<<
!!!!!$(...) 'shorthand' function
<<<
As described by Dustin Diaz [[here|http://www.dustindiaz.com/top-ten-javascript/]], the plugin defines a 'shorthand' function that allows you to write:
{{{
$(id)
}}}
in place of the normal standard javascript syntax:
{{{
document.getElementById(id)
}}}
This function is provided merely as a convenience for javascript coders that may be familiar with this abbreviation, in order to allow them to save a few bytes when writing their own inline script code.
<<<
!!!!!Examples
<<<
simple dynamic output:
><script show>
	document.write("The current date/time is: "+(new Date())+"<br>");
	return "link to current user: [["+config.options.txtUserName+"]]\n";
</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).getAttribute("tiddler");
	var size=store.getTiddlerText(title).length;
	return title+" is using "+size+" bytes";
</script>
dynamic output from an 'onclick' script, using {{{document.write()}}} and/or {{{return "..."}}}
><script label="click here" show>
	document.write("<br>The current date/time is: "+(new Date())+"<br>");
	return "link to current user: [["+config.options.txtUserName+"]]\n";
</script>
creating an 'onclick' button/link that accesses the link text AND the containing tiddler:
><script label="click here" title="clicking this link will show an 'alert' box" key="H" show>
	if (!window.story) window.story=window;
	var txt=place.firstChild.data;
	var tid=story.findContainingTiddler(place).getAttribute('tiddler');
	alert('Hello World!\nlinktext='+txt+'\ntiddler='+tid);
</script>
dynamically setting onclick link text based on stateful information:
>{{block{
{{{
<script label="click here">
	/* toggle "txtSomething" value */
	var on=(config.txtSomething=="ON");
	place.innerHTML=on?"enable":"disable";
	config.txtSomething=on?"OFF":"ON";
	return "\nThe current value is: "+config.txtSomething;
</script><script>
	/* initialize onclick link text based on current "txtSomething" value */
	var on=(config.txtSomething=="ON");
	place.lastChild.previousSibling.innerHTML=on?"disable":"enable";
</script>
}}}
<script label="click here">
	/* toggle "txtSomething" value */
	var on=(config.txtSomething=="ON");
	place.innerHTML=on?"enable":"disable";
	config.txtSomething=on?"OFF":"ON";
	return "\nThe current value is: "+config.txtSomething;
</script><script>
	/* initialize onclick link text based on current "txtSomething" value */
	var on=(config.txtSomething=="ON");
	place.lastChild.innerHTML=on?"enable":"disable";
</script>
}}}
loading a script from a source url:
>http://www.TiddlyTools.com/demo.js contains:
>>{{{function inlineJavascriptDemo() { alert('Hello from demo.js!!') } }}}
>>{{{displayMessage('InlineJavascriptPlugin: demo.js has been loaded');}}}
>note: When using this example on your local system, you will need to download the external script file from the above URL and install it into the same directory as your document.
>
><script src="demo.js" show>
	return "inlineJavascriptDemo() function has been defined"
</script>
><script label="click to invoke inlineJavascriptDemo()" key="D" show>
	inlineJavascriptDemo();
</script>
<<<
!!!!!Revisions
<<<
2008.06.11 [1.9.3] added $(...) function as 'shorthand' convenience syntax for document.getElementById()
2008.03.03 [1.9.2] corrected declaration of wikifyPlainText() for 'TW 2.1.x compatibility fallback' (fixes Safari "parse error")
2008.02.23 [1.9.1] in onclick function, use string instead of array for 'bufferedHTML' attribute on link element (fixes IE errors)
2008.02.21 [1.9.0] 'onclick' scripts now allow returned text (or document.write() calls) to be wikified into a span that immediately follows the onclick link.  Also, added default 'return false' handling if no return value provided (prevents HREF from being triggered -- return TRUE to allow HREF to be processed).  Thanks to Xavier Verges for suggestion and preliminary code.
2008.02.14 [1.8.1] added backward-compatibility for use of wikifyPlainText() in TW2.1.3 and earlier
2008.01.08 [*.*.*] plugin size reduction: documentation moved to ...Info tiddler
2007.12.28 [1.8.0] added support for key="X" syntax to specify custom access key definitions
2007.12.15 [1.7.0] autogenerate URI encoded HREF on links for onclick scripts.  Drag links to browser toolbar to create bookmarklets.  IMPORTANT NOTE: place is NOT defined when scripts are used as bookmarklets.  In addition, double-quotes will cause syntax errors.  Thanks to PaulReiber for debugging and brainstorming.
2007.11.26 [1.6.2] when converting "document.write()" function calls in inline code, allow whitespace between "write" and "(" so that "document.write ( foobar )" is properly converted.
2007.11.16 [1.6.1] when rendering "onclick scripts", pass label text through wikifyPlainText() to parse any embedded wiki-syntax to enable use of HTML entities or even TW macros to generate dynamic label text.
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
<<<
<script show>
	var randomImages = ['bg1','bg2'];
	var rndNum = Math.ceil(Math.random() * randomImages.length);

</script>
<script>

//Set the two dates
today=new Date()
var christmas=new Date(today.getFullYear(), 11, 25) //Month is 0-11 in JavaScript
//Set 1 day in milliseconds
var one_day=1000*60*60*24

//Calculate difference btw the two dates, and convert to days
document.write(Math.ceil((christmas.getTime()-today.getTime())/(one_day))+
" days left until Christmas!")

</script> 

<script>

//Set the two dates
var startingdate=new Date(2003,03,26,14,15,00) //Month is 0-11 in JavaScript
var today=new Date()
//Get 1 day in milliseconds
var one_day=1000*60*60*24

//Calculate difference btw the two dates, and convert to days
document.write(Math.ceil((today.getTime()-startingdate.getTime())/(one_day))+
" days have gone by since started work at XOM!" + "<br><br>")

//Calculate difference btw the two dates, and convert to years
document.write(Math.ceil((today.getTime()-startingdate.getTime())/(one_day)/(365))+
" years have gone by since started work at XOM!" + "<br><br>")

</script>
Name: Khaki2Black
HeaderTop: #dc9
HeaderMid: #b83
HeaderBottom: #111
Background: #FFF
Foreground: #000
PrimaryPale: #dc9
PrimaryLight: #b83
PrimaryMid: #111
PrimaryDark: #b83
SecondaryPale: #666
SecondaryLight: #dc9
SecondaryMid: #db4
SecondaryDark: #841
TertiaryPale: #eee
TertiaryLight: #000
TertiaryMid: #dc9
TertiaryDark: #666
Error: #000
Test: #F00
Name: Khaki2Grey
HeaderTop: #841
HeaderMid: #dc9
HeaderBottom: #000
Background: #FFF
Foreground: #666
PrimaryPale: #999
PrimaryLight: #CC9
PrimaryMid: #000
PrimaryDark: #000
SecondaryPale: #666
SecondaryLight: #EEE
SecondaryMid: #CC9
SecondaryDark: #CC9
TertiaryPale: #CCC
TertiaryLight: #999
TertiaryMid: #CCC
TertiaryDark: #CC9
Error: #CC9
Test: #F6F
Name: KhakinBlack
HeaderTop: #300
HeaderMid: #dc9
HeaderBottom: #300
Background: #FFF
Foreground: #666
PrimaryPale: #999
PrimaryLight: #CC9
PrimaryMid: #000
PrimaryDark: #ccc
SecondaryPale: #666
SecondaryLight: #EEE
SecondaryMid: #CC9
SecondaryDark: #CC9
TertiaryPale: #CCC
TertiaryLight: #000
TertiaryMid: #CCC
TertiaryDark: #CC9
Error: #CC9
Test: #F6F
Name: KhakinBlack2
HeaderTop: #000
HeaderMid: #cc9
HeaderBottom: #000
Background: #FFF
Foreground: #000
PrimaryPale: #aaa
PrimaryLight: #CC9
PrimaryMid: #111
PrimaryDark: #000
SecondaryPale: #666
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #841
TertiaryPale: #eee
TertiaryLight: #999
TertiaryMid: #CCC
TertiaryDark: #666
Error: #000
Test: #F6F
/***
|''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.4.0|
|''~CoreVersion:''|2.3.0|
|''Requires:''| |
|''Overrides:''| |
|''Description:''|Launch an application from within TiddlyWiki using a button|
!!!!!Usage
<<<
{{{<<LaunchApplication "buttonLabel" "tooltip" "application" ["arguments" ...]>>}}}
{{{<<LaunchApplicationButton "buttonLabel" "tooltip" "application" ["arguments" ...]>>}}}
{{{<<LaunchApplicationLink "buttonLabel" "tooltip" "application" ["arguments" ...]>>}}}
* buttonLabel is anything you like
* tooltip is anything you like
* application is a path to the executable (which is Operating System dependant)
* 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

{{{<<LaunchApplication...>>}}} functions the same as {{{<<LaunchApplicationButton...>>}}}

eg.

{{{
<<LaunchApplicationButton "Emacs" "Linux Emacs" "file:///usr/bin/emacs">>
}}}
<<LaunchApplicationButton "Emacs" "Linux Emacs" "file:///usr/bin/emacs">>

{{{
<<LaunchApplicationLink "LocalProgram" "Program relative to Tiddly html file" "localDir/bin/emacs">>
}}}
<<LaunchApplicationLink "LocalProgram" "Program relative to Tiddly html file" "localDir/bin/emacs">>
					     
{{{
<<LaunchApplicationButton "Open Notepad" "Text Editing" "file:///e:/Windows/notepad.exe">>
}}}
<<LaunchApplicationButton "Open Notepad" "Text Editing" "file:///e:/Windows/notepad.exe">>

{{{
<<LaunchApplicationLink "C Drive" "Folder" "file:///c:/">>
}}}
<<LaunchApplicationLink "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.
* 1.4.0 - updated core version and fixed empty tooltip and added launch link capability

<<<
***/
//{{{
version.extensions.LaunchApplication = {major: 1, minor: 4, revision: 0, date: new Date(2007,12,29)};
config.macros.LaunchApplication = {};
config.macros.LaunchApplicationButton = {};
config.macros.LaunchApplicationLink = {};

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[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;
    }
}
config.macros.LaunchApplicationButton.handler = function (place,macroName,params,wikifier,paramString,tiddler) {
    config.macros.LaunchApplication.handler (place,macroName,params,wikifier,paramString,tiddler);
}

config.macros.LaunchApplicationLink.handler = function (place,macroName,params,wikifier,paramString,tiddler) {
    // 0=ButtonText, 1=toolTip, 2=AppToLaunch, 3...AppParameters
    if (params[0] && (params[1] || params[1] == "") && params[2]) {
        //var theLink = createExternalLink(place, getParam(params,"buttonText",params[0]));
        var theLink = createTiddlyButton(place, getParam(params,"buttonText",params[0]), getParam(params,"toolTip",params[1]), onClickLaunchApplication,"link");
        theLink.setAttribute("appToLaunch", getParam(params,"appToLaunch",params[2]));
        params.splice(0,3);
        theLink.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));
}

//}}}
//{{{
Story.prototype.tiddlerHistory= [];
Story.prototype.maxTiddlers = 5;
Story.prototype.closedHistory=[];
Story.prototype.closedHistoryMax = 20;

Array.prototype.moveToEnd = function(item)
{
    this.remove(item);
    this.push(item);
}

Story.prototype.old_history_displayTiddler = Story.prototype.displayTiddler;
Story.prototype.displayTiddler = function(srcElement,title,template,animate,slowly)
{
    this.tiddlerHistory.moveToEnd(title);
    this.closedHistory.remove(title);
    var closeCount = this.tiddlerHistory.length - this.maxTiddlers;
    if (closeCount > 0)
        {
        var count = this.tiddlerHistory.splice (0,closeCount);
        for (var i=0; i<count.length;i++)
            {
            story.closeTiddler(count[i],false);
            }
        }
    story.old_history_displayTiddler(null,title,template,animate,slowly);
}

Story.prototype.old_history_closeTiddler = Story.prototype.closeTiddler;
Story.prototype.closeTiddler = function(title,animate,slowly)
{
    this.tiddlerHistory.remove(title);
    this.closedHistory.remove(title);
    this.closedHistory.unshift(title);
    story.old_history_closeTiddler.apply(this,arguments);
}

Story.prototype.displayTiddlers = function(srcElement,titles,template,animate,slowly)
{
	for(var t = titles.length-1;t>=0;t--)
	    {
        this.tiddlerHistory.moveToEnd(titles[t]);
        this.closedHistory.remove(titles[t]);
		this.old_history_displayTiddler(srcElement,titles[t],template,animate,slowly);
        }
}

config.commands.history={
	text: "history",
	tooltip: "re-open a closed tiddler"};

config.commands.history.handler = function(event,src,title)
{
	var popup = Popup.create(src);
	if(popup)
		{
        if (!story.closedHistory.length)
            createTiddlyText(popup,"No history");
        else
           {
           var c = Math.min(story.closedHistory.length,story.closedHistoryMax);
		   for (i=0; i<c;i++ )
               {
			   createTiddlyLink(createTiddlyElement(popup,"li"),story.closedHistory[i],true);
		       }
           }
        }
	Popup.show(popup,false);
	event.cancelBubble = true;
	if (event.stopPropagation) event.stopPropagation();
	return false;
}
//}}}
/%
For: List tiddler tags in body of tiddler
Usage: <<tiddler [[ListTags]] with: {{tiddler.title}}>> 
%/<script>
var tag = "$1" ; 
var tags = store.getTiddler(tag).tags ;
var out = "" ;
for(var i=0;i<tags.length;i++) {out += tags[i] + ", " ;}
return out ;
</script>
<script src="images/work/array_work.js"></script>
<script src="images/home/array_home.js"></script>
<script src="images/array_root.js"></script>
/***
|Name|LoadTiddlersPlugin|
|Source|http://www.TiddlyTools.com/#LoadTiddlersPlugin|
|Documentation|http://www.TiddlyTools.com/#LoadTiddlersPluginInfo|
|Version|3.6.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||
|Options|##Configuration|
|Description|macro for automated updates or one-click installations of tiddlers from remote sources|
!!!!!Documentation
>see [[LoadTiddlersPluginInfo]]
!!!!!Configuration
<<<
__password-protected server settings //(optional, if needed)//:__
>username: <<option txtRemoteUsername>> password: <<option txtRemotePassword>>
>{{{usage: <<option txtRemoteUsername>> <<option txtRemotePassword>>}}}
>''note: these settings are also used by [[ExternalTiddlersPlugin]] and [[ImportTiddlersPlugin]]''
<<<
!!!!!Revisions
<<<
2008.08.05 [3.6.2] rewrote loadFile() to eliminate use of platform-specific fileExists() test
|please see [[LoadTiddlersPluginInfo]] for additional revision details|
2005.07.20 [1.0.0] Initial Release
<<<
!!!!!Code
***/
//{{{
version.extensions.loadTiddlers = {major: 3, minor: 6, revision: 2, date: new Date(2008,8,5)};

config.macros.loadTiddlers = {
	label: "",
	tip: "add/update tiddlers from '%0'",
	lockedTag: "noReload",	// if existing tiddler has this tag value, don't overwrite it, even if inbound tiddler is newer
	askMsg: "Please enter a local path/filename or a remote URL",
	openMsg: "Opening %0",
	openErrMsg: "Could not open %0 - error=%1",
	readMsg: "Read %0 bytes from %1",
	foundMsg: "Found %0 tiddlers in %1",
	nochangeMsg: "'%0' is up-to-date... skipped.",
	lockedMsg: "'%0' is tagged '%1'... skipped.",
	skippedMsg: "skipped (cancelled by user)",
	loadedMsg: "Loaded %0 of %1 tiddlers from %2",
	reportTitle: "ImportedTiddlers",
	warning: "Warning!!  Processing '%0' as a systemConfig (plugin) tiddler may produce unexpected results! Are you sure you want to proceed?",
	handler: function(place,macroName,params) {
		var label=(params[0] && params[0].substr(0,6)=='label:')?params.shift().substr(6):this.label;
		var tip=(params[0] && params[0].substr(0,7)=='prompt:')?params.shift().substr(7):this.tip;
		var filter="updates";
		if (params[0] && (params[0]=='all' || params[0]=='new' || params[0]=='changes' || params[0]=='updates'
			|| params[0].substr(0,8)=='tiddler:' || params[0].substr(0,4)=='tag:'))
			filter=params.shift();
		var src=params.shift(); if (!src || !src.length) return; // filename is required
		var quiet=(params[0]=="quiet"); if (quiet) params.shift();
		var ask=(params[0]=="confirm"); if (ask) params.shift();
		var force=(params[0]=="force"); if (force) params.shift();
		var init=(params[0]=="init"); if (init) params.shift();
		var noreport=(params[0]=="noreport"); if (noreport) params.shift();
		this.newTags=[]; if (params[0]) this.newTags=params; // any remaining params are used as "autotags"
		if (label.trim().length) {
			// link triggers load tiddlers from another file/URL and then applies filtering rules to add/replace tiddlers in the store
			createTiddlyButton(place,label.format([src.replace(/%20/g," ")]),tip.format([src.replace(/%20/g," ")]), function() {
				if (src=="ask") src=prompt(this.askMsg);
				config.macros.loadTiddlers.loadFile(src,config.macros.loadTiddlers.doImport,{quiet:quiet,ask:ask,filter:filter,force:force,init:init,noreport:noreport});
			})
		}
		else {
			// load tiddlers from another file/URL and then apply filtering rules to add/replace tiddlers in the store
			if (src=="ask") src=prompt(this.askMsg);
			config.macros.loadTiddlers.loadFile(src,config.macros.loadTiddlers.doImport,{quiet:quiet,ask:ask,filter:filter,force:force,init:init,noreport:noreport});
		}
	},
	loadFile: function(src,callback,params) {
		var quiet=params.quiet;
		if (src==undefined || !src.length) return null; // filename is required
		if (!quiet) clearMessage();
		if (!quiet) displayMessage(this.openMsg.format([src.replace(/%20/g," ")]));
		if (src.substr(0,5)!="http:" && src.substr(0,5)!="file:") { // if not a URL, read from local filesystem
			var txt=loadFile(src);
			if (!txt) { // file didn't load, might be relative path.. try fixup
				var pathPrefix=document.location.href;  // get current document path and trim off filename
				var slashpos=pathPrefix.lastIndexOf("/"); if (slashpos==-1) slashpos=pathPrefix.lastIndexOf("\\"); 
				if (slashpos!=-1 && slashpos!=pathPrefix.length-1) pathPrefix=pathPrefix.substr(0,slashpos+1);
				src=pathPrefix+src;
				if (pathPrefix.substr(0,5)!="http:") src=getLocalPath(src);
				var txt=loadFile(src);
			}
			if (!txt) { // file still didn't load, report error
				if (!quiet) displayMessage(this.openErrMsg.format([src.replace(/%20/g," "),"(unknown)"]));
			} else {
				if (!quiet) displayMessage(this.readMsg.format([txt.length,src.replace(/%20/g," ")]));
				if (callback) callback(true,params,convertUTF8ToUnicode(txt),src,null);
			}
		} else {
			var name=config.options.txtRemoteUsername; var pass=config.options.txtRemotePassword;
			var x=doHttp("GET",src,null,null,name,pass,callback,params,null);
		}
	},
	readTiddlersFromHTML: function(html) {
		// for TW2.2+
		if (TiddlyWiki.prototype.importTiddlyWiki!=undefined) {
			var remoteStore=new TiddlyWiki();
			remoteStore.importTiddlyWiki(html);
			return remoteStore.getTiddlers("title");	
		}
	},
	doImport: function(status,params,html,src,xhr) {
		var quiet=params.quiet;
		var ask=params.ask;
		var filter=params.filter;
		var force=params.force;
		var init=params.init;
		var noreport=params.noreport;
		var tiddlers = config.macros.loadTiddlers.readTiddlersFromHTML(html);
		var count=tiddlers?tiddlers.length:0;
		var querypos=src.lastIndexOf("?"); if (querypos!=-1) src=src.substr(0,querypos);
		if (!quiet) displayMessage(config.macros.loadTiddlers.foundMsg.format([count,src.replace(/%20/g," ")]));
		store.suspendNotifications();
		var count=0;
		if (tiddlers) for (var t=0;t<tiddlers.length;t++) {
			var inbound = tiddlers[t];
			var theExisting = store.getTiddler(inbound.title);
			if (inbound.title==config.macros.loadTiddlers.reportTitle)
				continue; // skip "ImportedTiddlers" history from the other document...
			if (theExisting && theExisting.tags.contains(config.macros.loadTiddlers.lockedTag)) {
				if (!quiet) displayMessage(config.macros.loadTiddlers.lockedMsg.format([theExisting.title,config.macros.loadTiddlers.lockedTag]));
				continue; // skip existing tiddler if tagged with 'noReload'
			}
			// apply the all/new/changes/updates filter (if any)
			if (filter && filter!="all") {
				if ((filter=="new") && theExisting) // skip existing tiddlers
					continue;
				if ((filter=="changes") && !theExisting) // skip new tiddlers
					continue;
				if ((filter.substr(0,4)=="tag:") && inbound.tags.indexOf(filter.substr(4))==-1) // must match specific tag value
					continue;
				if ((filter.substr(0,8)=="tiddler:") && inbound.title!=filter.substr(8)) // must match specific tiddler name
					continue;
				if (!force && store.tiddlerExists(inbound.title) && ((theExisting.modified.getTime()-inbound.modified.getTime())>=0))
					{ if (!quiet) displayMessage(config.macros.loadTiddlers.nochangeMsg.format([inbound.title])); continue; }
			}
			// get confirmation if required
			if (ask && !confirm((theExisting?"Update":"Add")+" tiddler '"+inbound.title+"'\nfrom "+src.replace(/%20/g," ")))
				{ tiddlers[t].status=config.macros.loadTiddlers.skippedMsg; continue; }
			// DO IT!
			var tags=Array.concat(inbound.tags,config.macros.loadTiddlers.newTags);
	                store.saveTiddler(inbound.title, inbound.title, inbound.text, inbound.modifier, inbound.modified, tags, inbound.fields, true, inbound.created);
	                store.fetchTiddler(inbound.title).created = inbound.created; // force creation date to imported value - needed for TW2.1.3 or earlier
			tiddlers[t].status=theExisting?"updated":"added"
			if (init && tags.contains("systemConfig") && !tags.contains("systemConfigDisable")) {
				var ok=true;
				if (ask||!quiet) ok=confirm(config.macros.loadTiddlers.warning.format([inbound.title]))
				if (ok) { // run the plugin
					try { window.eval(inbound); tiddlers[t].status+=" (plugin initialized)"; }
					catch(ex) { displayMessage(config.messages.pluginError.format([exceptionText(ex)])); }
				}
			}
			count++;
		}
		store.resumeNotifications();
		if (count) {
			// refresh display
			store.setDirty(true); store.notifyAll();
			// generate a report
			if (!noreport) config.macros.loadTiddlers.report(src,tiddlers,count,quiet);
		}
		// always show final message when tiddlers were actually loaded
		if (!quiet||count) displayMessage(config.macros.loadTiddlers.loadedMsg.format([count,tiddlers.length,src.replace(/%20/g," ")]));
	},
	report: function(src,tiddlers,count,quiet) {
		// format the new report content
		var newText = "On "+(new Date()).toLocaleString()+", ";
		newText += config.options.txtUserName+" loaded "+count+" tiddlers ";
		newText += "from\n[["+src+"|"+src+"]]:\n";
		newText += "<<<\n";
		for (var t=0; t<tiddlers.length; t++)
			if (tiddlers[t].status)
				newText += "#[["+tiddlers[t].title+"]] - "+tiddlers[t].status+"\n";
		newText += "<<<\n";
		// get current report (if any)
		var title=config.macros.loadTiddlers.reportTitle;
		var currText="";
		var theReport = store.getTiddler(title);
		if (theReport) currText=((theReport.text!="")?'\n----\n':"")+theReport.text;
		// update the ImportedTiddlers content and show the tiddler
		store.saveTiddler(title, title, newText+currText, config.options.txtUserName, new Date(), theReport?theReport.tags:null, theReport?theReport.fields:null);
		if (!quiet) { story.displayTiddler(null,title,1,null,null,false); story.refreshTiddler(title,1,true); }
	}
}
//}}}
/***
|Name|LoadTiddlersPluginInfo|
|Source|http://www.TiddlyTools.com/#LoadTiddlersPlugin|
|Documentation|http://www.TiddlyTools.com/#LoadTiddlersPluginInfo|
|Version|3.6.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|documentation|
|Requires||
|Overrides||
|Description|documentation for LoadTiddlersPlugin|
!!!!!Usage
<<<
Syntax:
{{{<<loadTiddlers label:text prompt:text filter source quiet confirm force init noreport tag tag tag...>>}}}

Example:
{{{<<loadTiddlers "label:load tiddlers from %0" example.html confirm temporary>>}}}
<<loadTiddlers "label:load tiddlers from %0" example.html confirm temporary>>

Example2:
{{{<<loadTiddlers label:UpgradeTestWiki prompt:Click2Upgrade new TestWiki.htm>>}}}
<<loadTiddlers label:UpgradeTestWiki prompt:Click2Upgrade new TestWiki.htm>>

Where:
''"""label:text"""'' and ''"""prompt:text"""''
>defines link text and tooltip (prompt) that can be clicked to trigger the load tiddler processing.  If a label is NOT provided, then no link is created and the loadTiddlers function is performed whenever the containing tiddler is rendered.
''filter'' (optional) determines which tiddlers will be automatically selected for importing.  Use one of the following keywords:
>''"all"'' retrieves ALL tiddlers from the import source document, even if they have not been changed.
>''"new"'' retrieves only tiddlers that are found in the import source document, but do not yet exist in the destination document
>''"changes"'' retrieves only tiddlers that exist in both documents for which the import source tiddler is newer than the existing tiddler
>''"updates"'' retrieves both ''new'' and ''changed'' tiddlers (this is the default action when none is specified)
>''""""tiddler:TiddlerName""""'' retrieves only the specific tiddler named in the parameter.
>''""""tag:text""""'' retrieves only the tiddlers tagged with the indicated text.
>> Note: ''if an existing tiddler is tagged with 'noReload', then it will not be overwritten'', even if the inbound tiddler has been selected by the filtering process.  This allows you to make local changes to imported tiddlers while ensuring that those changes won't be lost due to automatic tiddler updates retrieved from the import source document.
''source'' (required) is the location of the imported document.  It can be either a local document path/filename in whatever format your system requires, or a remote web location (starting with "http://" or "https://")
>use the keyword ''ask'' to prompt for a source location whenever the macro is invoked
''"quiet"'' (optional)
>supresses all status message during the import processing (e.g., "opening local file...", "found NN tiddlers..." etc).  Note that if ANY tiddlers are actualy imported, a final information message will still be displayed (along with the ImportedTiddlers report), even when 'quiet' is specified.  This ensures that changes to your document cannot occur without any visible indication at all.
''"confirm"'' (optional)
>adds interactive confirmation.  A browser message box (OK/Cancel) is displayed for each tiddler that will be imported, so that you can manually bypass any tiddlers that you do not want to import.
''"init"'' (optional)
>invoke tiddlers tagged with <<tag systemConfig>> as plugins as soon as they are imported, without requiring a save-and-reload action first.  For safety, a browser message box (OK/Cancel) is displayed for each imported plugin, so that you can manually bypass any plugins that you do not want to invoke.  Note, however, that those tiddlers are still //imported// into your document and therefore will still take effect the next time you save-and-reload the document.
''"force"'' (optional)
>import all matching tiddlers, even if unchanged
''"noreport"'' (optional)
>suppress generation of [[ImportedTiddlers]] report
''"tag tag tag..."'' (optional)
>any remaining parameters are used as tag values to be added to each imported tiddler (i.e., "tag-on-import")
<<<
!!!!!Configuration
<<<
__password-protected server settings //(optional, if needed)//:__
>username: <<option txtRemoteUsername>> password: <<option txtRemotePassword>>
>{{{usage: <<option txtRemoteUsername>> <<option txtRemotePassword>>}}}
>''note: these settings are also used by [[ExternalTiddlersPlugin]] and [[ImportTiddlersPlugin]]''
<<<
!!!!!Revisions
<<<
2008.08.05 [3.6.2] rewrote loadFile() to eliminate use of platform-specific fileExists() test
2008.08.03 [3.6.1] in handler(), changed variable 'prompt' to 'tip' to avoid conflict with prompt() function
2008.01.07 [3.6.0] added 'init' option to automatically invoke plugin tiddlers as soon as they are loaded (without needing save/reload)
2008.01.03 [3.5.0] in loadFile(), use lower-level doHttp() instead of loadRemoteFile() in order to support username/password access to remote server
2007.12.04 [*.*.*] update for TW2.3.0: replaced deprecated core functions, regexps, and macros
2007.06.27 [3.4.8] added missing 'fields' params to saveTiddler() call. Fixes problem where importing tiddlers would lose the custom fields.
2007.06.25 [3.4.7] add calls to store.suspendNotifications() and store.resumeNotifications() to eliminate redisplay overhead DURING import activities.
2007.05.27 [3.4.6] in handler(),  loadRemoteFile() and doImport(), added 'noreport' flag to suppress generation of ImportedTiddlers
2007.05.27 [3.4.5] in handler(),  initialize 'newTags' to [] (empty array) instead of null... fixes fatal error when loading tiddler without autotagging.
2007.04.22 [3.4.4] in readTiddlersFromHTML(), for TW2.2 and above, use importTiddlyWiki() (new core functionality) to get tiddlers from remote file content.  Also, copied updated TW21Loader.prototype.internalizeTiddler() definition from TW2.2b5 so plugin can read tiddlers from TW2.2+ even when running under TW2.1.x
2007.04.05 [3.4.3] in doImport(), changed this.readTiddlersFromHTML(html) to config.macros.loadTiddlers.readTiddlersFromHTML(html).  Fixes error caused when ImportTiddlersPlugin has NOT been installed along side this plugin.
2007.03.26 [3.4.2] renamed import() to doImport() to fix IE load-time error ("identifier expected").  This may also cause a problem with FF1.5.0.x.... Apparently, "import" is a reserved word in some browsers...
2007.03.22 [3.4.1] code cleanup: moved all functions inside object def'n, re-wrote report function
2007.03.21 [3.4.0] split ImportTiddlersPlugin and LoadTiddlersPlugin functionality into separate plugins
|please see [[ImportTiddlersPluginInfo]] for additional revision details|
2005.07.20 [1.0.0] Initial Release
<<<
Name: Blue
HeaderTop: #fff
HeaderMid: #fff
HeaderBottom: #114
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
HeaderTop: #fff
HeaderMid: #9b9
HeaderBottom: #031
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
HeaderTop: #fff
HeaderMid: #fff
HeaderBottom: #711
Background: #fff
Foreground: #000
PrimaryPale: #c30
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
HeaderTop: #fff
HeaderMid: #fff
HeaderBottom: #111
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
HeaderTop: #fff
HeaderMid: #fff
HeaderBottom: #1a3844
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
HeaderMid: #cff
Name: MONEY
HeaderTop: #ffc
HeaderMid: #efc
HeaderBottom: #bc9
Background: #efc
Foreground: #000
PrimaryPale: #453
PrimaryLight: #453
PrimaryMid: #bc9
PrimaryDark: #efc
SecondaryPale: #453
SecondaryLight: #9c5
SecondaryMid: #ccc
SecondaryDark: #453
TertiaryPale: #453
TertiaryLight: #bc9
TertiaryMid: #453
TertiaryDark: #bc9
<<tag Tricks>>
<<tag Script>>
[[Explore|ShowLocalDirectory]]
[[Reminders]]
''<<tiddler ShowPopup with: Calendar Calendar Calendar buttonClass 150px popupClass>>''
<<search>>
@@display:none;<<tiddler LoadScripts>>@@
/***
|Name|MatchTagsPlugin|
|Source|http://www.TiddlyTools.com/#MatchTagsPlugin|
|Documentation|http://www.TiddlyTools.com/#MatchTagsPluginInfo|
|Version|2.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|'tag matching' with full boolean expressions (AND, OR, NOT, and nested parentheses)|
!!!!!Documentation
> see [[MatchTagsPluginInfo]]
!!!!!Revisions
<<<
2008.09.04 [2.0.0] added "report" and "panel" options to generate formatted results and store in a tiddler.  Also, added config.macros.matchTags.formatList(place,fmt,sep) API to return formatted output for use with other plugins/scripts
| please see [[MatchTagsPluginInfo]] for additional revision details |
2008.02.28 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.MatchTagsPlugin= {major: 2, minor: 0, revision: 0, date: new Date(2008,9,4)};

// store.getMatchingTiddlers() processes boolean expressions for tag matching
//    sortfield (optional) sets sort order for tiddlers - default=title
//    tiddlers (optional) use alternative set of tiddlers (instead of current store)
TiddlyWiki.prototype.getMatchingTiddlers = function(tagexpr,sortfield,tiddlers) {

	var debug=config.options.chkDebug; // abbreviation
	var cmm=config.macros.matchTags; // abbreviation
	var r=[]; // results are an array of tiddlers
	var tids=tiddlers||store.getTiddlers(sortfield||"title");
	if (tiddlers && sortfield) store.sortTiddlers(tids,sortfield);
	if (debug) displayMessage(cmm.msg1.format([tids.length]));

	// try simple lookup to quickly find single tags or tags that
	// contain boolean operators as literals, e.g. "foo and bar"
	for (var t=0; t<tids.length; t++)
		if (tids[t].isTagged(tagexpr)) r.pushUnique(tids[t]);
	if (r.length) {
		if (debug) displayMessage(cmm.msg4.format([r.length,tagexpr]));
		return r;
	}
	
	// convert expression into javascript code with regexp tests,
	// so that "tag1 AND ( tag2 OR NOT tag3 )" becomes
	// "/\~tag1\~/.test(...) && ( /\~tag2\~/.test(...) || ! /\~tag3\~/.test(...) )"

	// normalize whitespace, tokenize operators, delimit with "~"
	var c=tagexpr.trim(); // remove leading/trailing spaces
	c = c.replace(/\s+/ig," "); // reduce multiple spaces to single spaces
	c = c.replace(/\(\s?/ig,"~(~"); // open parens
	c = c.replace(/\s?\)/ig,"~)~"); // close parens
	c = c.replace(/(\s|~)?&&(\s|~)?/ig,"~&&~"); // &&
	c = c.replace(/(\s|~)AND(\s|~)/ig,"~&&~"); // AND
	c = c.replace(/(\s|~)?\|\|(\s|~)?/ig,"~||~"); // ||
	c = c.replace(/(\s|~)OR(\s|~)/ig,"~||~"); // OR
	c = c.replace(/(\s|~)?!(\s|~)?/ig,"~!~"); // !
	c = c.replace(/(^|~|\s)NOT(\s|~)/ig,"~!~"); // NOT
	c = c.replace(/(^|~|\s)NOT~\(/ig,"~!~("); // NOT(
	// change tag terms to regexp tests
	var terms=c.split("~"); for (var i=0; i<terms.length; i++) { var t=terms[i];
		if (/(&&)|(\|\|)|[!\(\)]/.test(t) || t=="") continue; // skip operators/parens/spaces
		if (t==config.macros.matchTags.untaggedKeyword)
			terms[i]="tiddlertags=='~~'"; // 'untagged' tiddlers
		else
			terms[i]="/\\~"+t+"\\~/.test(tiddlertags)";
	}
	c=terms.join(" ");
	if (debug) { displayMessage(cmm.msg2.format([tagexpr])); displayMessage(cmm.msg3.format([c])); }

	// scan tiddlers for matches
	for (var t=0; t<tids.length; t++) {
	 	// assemble tags from tiddler into string "~tag1~tag2~tag3~"
		var tiddlertags = "~"+tids[t].tags.join("~")+"~";
		try { if(eval(c)) r.push(tids[t]); } // test tags
		catch(e) { // error in test
			displayMessage(cmm.msg2.format([tagexpr]));
			displayMessage(cmm.msg3.format([c]));
			displayMessage(e.toString());
			break; // skip remaining tiddlers
		}
	}
	if (debug) displayMessage(cmm.msg4.format([r.length,tagexpr]));
	return r;
}
//}}}
//{{{
config.macros.matchTags = {
	msg1: "scanning %0 input tiddlers",
	msg2: "looking for '%0'",
	msg3: "using expression: '%0'",
	msg4: "found %0 tiddlers matching '%1'",
	noMatch: "no matching tiddlers",
	untaggedKeyword: "-",



	untaggedLabel: "no tags",
	untaggedPrompt: "show tiddlers with no tags",
	defTiddler: "MatchingTiddlers",
	defFormat: "%0",
	defSeparator: "\n",
	reportHeading: "Found %0 tiddlers tagged with: '{{{%1}}}'\n----\n",
	handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		var mode=params[0]?params[0].toLowerCase():'';
		if (mode=="inline")
			params.shift();
		if (mode=="report" || mode=="panel") {
			params.shift();
			var target=params.shift()||this.defTiddler;
		}
		if (mode=="popup") {
			params.shift();
			if (params[0]&&params[0].substr(0,6)=="label:") var label=params.shift().substr(6);
			if (params[0]&&params[0].substr(0,7)=="prompt:") var prompt=params.shift().substr(7);
		} else {
			var fmt=(params.shift()||this.defFormat).unescapeLineBreaks();
			var sep=(params.shift()||this.defSeparator).unescapeLineBreaks();
		}
		var sortBy="+title";
		if (params[0]&&params[0].substr(0,5)=="sort:") sortBy=params.shift().substr(5);
		var expr = params.join(" ");
		if (mode!="panel" && (!expr||!expr.trim().length)) return;
		if (expr==this.untaggedKeyword)
			{ var label=this.untaggedLabel; var prompt=this.untaggedPrompt };
		switch (mode) {
			case "popup": this.createPopup(place,label,expr,prompt,sortBy); break;
			case "panel": this.createPanel(place,expr,fmt,sep,sortBy,target); break;
			case "report": this.createReport(target,expr,fmt,sep,sortBy); break;
			case "inline": default: this.createInline(place,expr,fmt,sep,sortBy); break;
		}
	},
	formatList: function(tids,fmt,sep) {
		var out=[];
		for (var t=0; t<tids.length; t++) {
			var title="[["+tids[t].title+"]]";
			var who=tids[t].modifier;
			var when=tids[t].modified.toLocaleString();
			var text=tids[t].text;
			var first=tids[t].text.split("\n")[0];
			var desc=store.getTiddlerSlice(tids[t].title,"description");
			desc=desc||store.getTiddlerSlice(tids[t].title,"Description");
			desc=desc||store.getTiddlerText(tids[t].title+"##description");
			desc=desc||store.getTiddlerText(tids[t].title+"##Description");
			out.push(fmt.format([title,who,when,text,first,desc]));
		}
		return out.join(sep);
	},
	createInline: function(place,expr,fmt,sep,sortBy) {
		wikify(this.formatList(store.sortTiddlers(store.getMatchingTiddlers(expr),sortBy),fmt,sep),place);
	},
	createPopup: function(place,label,expr,prompt,sortBy) {
		var btn=createTiddlyButton(place,
			(label||expr).format([expr]),
			(prompt||config.views.wikified.tag.tooltip).format([expr]),
			function(ev){ return config.macros.matchTags.showPopup(this,ev||window.event); });
		btn.setAttribute("sortBy",sortBy);
		btn.setAttribute("expr",expr);
	},
	showPopup: function(here,ev) {
		var p=Popup.create(here); if (!p) return false;
		var tids=store.getMatchingTiddlers(here.getAttribute("expr"));
		store.sortTiddlers(tids,here.getAttribute("sortBy"));
		var list=[]; for (var t=0; t<tids.length; t++) list.push(tids[t].title);
		if (!list.length) createTiddlyText(p,this.noMatch);
		else {
			var b=createTiddlyButton(createTiddlyElement(p,"li"),
				config.views.wikified.tag.openAllText,
				config.views.wikified.tag.openAllTooltip,
				function() {
					var list=this.getAttribute("list").readBracketedList();
					story.displayTiddlers(null,tids);
				});
			b.setAttribute("list","[["+list.join("]] [[")+"]]");
			createTiddlyElement(p,"hr");
		}
		var out=this.formatList(tids," &nbsp;%0&nbsp; ","\n"); wikify(out,p);
		Popup.show(p,false);
		ev.cancelBubble=true;
		if(ev.stopPropagation) ev.stopPropagation();
		return false;
	},
	createReport: function(target,expr,fmt,sep,sortBy) {
		var tids=store.sortTiddlers(store.getMatchingTiddlers(expr),sortBy);
		if (!tids.length) { displayMessage('no matches for: '+expr); return false; }
		var msg=config.messages.overwriteWarning.format([target]);
		if (store.tiddlerExists(target) && !confirm(msg)) return false;
		var out=this.reportHeading.format([tids.length,expr])
		out+=this.formatList(tids,fmt,sep);
		store.saveTiddler(target,target,out,config.options.txtUserName,new Date(),[],{});
		story.closeTiddler(target); story.displayTiddler(null,target);
	},
	createPanel: function(place,expr,fmt,sep,sortBy,tid) {
		var html="<form style='display:inline'><!-- \
			--><input type='text'    name='expr' style='width:55%' title='tag expression'><!-- \
			--><input type='text'    name='fmt'  style='width:10%' title='list item format'><!-- \
			--><input type='text'    name='sep'  style='width:5%'  title='list item separator'><!-- \
			--><input type='text'    name='tid'  style='width:20%' title='target tiddler title'><!-- \
			--><input type='button'  name='go'   style='width:8%'  value='go' onclick=\" \
				var expr=this.form.expr.value; \
				if (!expr.length) { alert('Enter a boolean tag expression'); return false; } \
				var fmt=this.form.fmt.value; \
				if (!fmt.length) { alert('Enter the list item output format'); return false; } \
				var sep=this.form.sep.value.unescapeLineBreaks(); \
				var tid=this.form.tid.value; \
				if (!tid.length) { alert('Enter a target tiddler title'); return false; } \
				config.macros.matchTags.createReport(tid,expr,fmt,sep,'title'); \
				return false;\"> \
			</form>";
		var s=createTiddlyElement(place,"span"); s.innerHTML=html;
		var f=s.getElementsByTagName("form")[0];
		f.expr.value=expr; f.fmt.value=fmt; f.sep.value=sep.escapeLineBreaks(); f.tid.value=tid;
	}
};
//}}}
//{{{
// SHADOW TIDDLER for displaying default panel input form
config.shadowTiddlers.MatchTags="{{smallform{<<matchTags panel>>}}}";
//}}}
//{{{
// TWEAK core filterTiddlers() for enhanced boolean matching in [tag[...]] syntax:
// use getMatchingTiddlers instead getTaggedTiddlers
var fn=TiddlyWiki.prototype.filterTiddlers;
fn=fn.toString().replace(/getTaggedTiddlers/g,"getMatchingTiddlers");
eval("TiddlyWiki.prototype.filterTiddlers="+fn);
//}}}
//{{{
// REDEFINE core handler for enhanced boolean matching in tag:"..." paramifier
// use filterTiddlers() instead of getTaggedTiddlers() to get list of tiddlers.
config.paramifiers.tag = {
	onstart: function(v) {
		var tagged = store.filterTiddlers("[tag["+v+"]]");
		story.displayTiddlers(null,tagged,null,false,null);
	}
};
//}}}
Name: Mauve
HeaderTop: #fff
HeaderMid: #fff
HeaderBottom: #552233
Background: #ffeedd
Foreground: #000
PrimaryPale: #ddaa99
PrimaryLight: #cc9999
PrimaryMid: #552233
PrimaryDark: #000
SecondaryPale: #ffc
SecondaryLight: #fff
SecondaryMid: #cccccc
SecondaryDark: #fff
TertiaryPale: #da9
TertiaryLight: #E9C2A6
TertiaryMid: #666
TertiaryDark: #8B7355

Name: Mocha
HeaderTop: #553322
HeaderMid: #ffc
HeaderBottom: #553322
Background: #eeddaa
Foreground: #000
PrimaryPale: #ddcc99
PrimaryLight: #bb8833
PrimaryMid: #553322
PrimaryDark: #000
SecondaryPale: #ffc
SecondaryLight: #fe8
SecondaryMid: #cccccc
SecondaryDark: #553322
TertiaryPale: #ddcc99
TertiaryLight: #AC7F24
TertiaryMid: #ffc
TertiaryDark: #8B7355
+++^30em^[panel]<<moveablePanel>>this is a headline for the panel
----
 this is a moveable floating panel
 with a few lines of text
 as an example for you to try...
 //note: this line is really long so you can see what happens to word wrapping when you re-size this panel//
===


When the mouse is just inside the edges of the tiddler/panel, the cursor will change to a "crossed-arrows" symbol, indicating that the panel is "moveable". Grab (click-hold) the panel anywhere in the edge area and then drag the mouse to reposition the panel.

To resize the panel, hold the ''shift'' key and then grab the panel: the cursor will change to a "double-arrow" symbol. Drag a side edge of the panel to stretch horizontally or vertically, or drag a corner of the panel to stretch in both dimensions at once.

Double-clicking anywhere in the edge area of a panel will 'maximize' it to fit the current browser window.

When the mouse is anywhere over a panel (not just near the edge), a 'toolbar menu' appears in the ''upper right corner'', with the following command items:
*fold/unfold: ''fold'' temporarily reduces the panel height to show just one line of text. ''unfold'' restores the panel height.
*hover/scroll: when you scroll the browser window, the moveable panels scroll with it. ''hover'' lets you keep a panel in view, while the rest of the page content moves in the window. ''scroll'' restores the default scrolling behavior for the panel. //Note: Due to browser limitations, this feature is not currently available when using Internet Explorer (v6 or lower)... sorry.//
*close: ''close'' hides a panel from the page display. If you have moved/resized a panel, closing it restores its default position and size.
*dock: unlike a floating panel, a moveable //tiddler// does not "float" on the page until it has actually been moved from its default position. When moving a tiddler, the ''close'' command is replaced with ''dock'', which restores the tiddler to its default //non-floating// location on the page.
<<<
/***
|Name|MoveablePanelPlugin|
|Source|http://www.TiddlyTools.com/#MoveablePanelPlugin|
|Documentation|http://www.TiddlyTools.com/#MoveablePanelPluginInfo|
|Version|2.1.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|NestedSlidersPlugin|
|Overrides||
|Description|drag/stretch 'floating sliders' and other page elements|
Adds move and size mouse event handling and fold/unfold, and close/dock toolbar command items to any floating slider panel or tiddler element
!!!!!Documentation
>see [[MoveablePanelPluginInfo]]
!!!!!Revisions
<<<
2008.09.11 [2.1.2] corrected caching of transient attribute (use =="true" to convert string to boolean)
|please see [[MoveablePanelPluginInfo]] for additional revision details|
''2006.03.04 [1.0.0]'' Initial public release
<<<
!!!!!Code
***/
//{{{
version.extensions.MoveablePanelPlugin= {major: 2, minor: 1, revision: 2, date: new Date(2008,9,11)};
//}}}
//{{{
config.macros.moveablePanel= { 
	handler: function(place,macroName,params) {
		var p=this.getPanel(place); if (!p) return;
		var showfold=true; var showclose=true; var showhover=true;
		var noedges=false; var param=null;
		while (param=params.shift()) { param=param.toLowerCase();
			if (param=="noclose") showclose=false;
			if (param=="nofold") showfold=false;
			if (param=="nohover") showhover=false;
			if (param=="noedges") noedges=true;
		}
		if (!p.saved) p.saved= { // remember original panel event handlers, size, location, border
			mouseover: p.onmouseover, mouseout: p.onmouseout, dblclick: p.ondblclick,
			top: p.style.top, left: p.style.left, width: p.style.width, height: p.style.height,
			position: p.style.position, border: p.style.border, title: p.title,
			transient: p.getAttribute("transient")=="true"
		};
		// create control menu items
		var html='<div class="toolbar" style="display:none;position:absolute;';
		html+=(hasClass(p,"floatingPanel")?'right:1em;top:1em;':'right:.5em;top:-1em;')+'">';
		var s='border:1px solid #666;background:#ccc;color:#666 !important;padding:0px .25em;-moz-border-radius:0px';
		if (showfold)
			html+='<a href="javascript:;" title="FOLD: reduce panel size" style="'+s+'"'
				+' onclick="return config.macros.moveablePanel.foldPanel(this,event)">&minus;</a>';
		if (showhover)
			html+='<a href="javascript:;" title="SCROLLING: panel moves with page" style="'+s+'"'
				+' onclick="return config.macros.moveablePanel.hoverPanel(this,event)">=</a>';
		if (showclose) {
			if (hasClass(p,"floatingPanel"))
				html+='<a href="javascript:;" title="CLOSE: hide panel and reset size/position" style="'+s+'"'
					+' onclick="return config.macros.moveablePanel.closePanel(this,event)">X</a>';
			else
				html+='<a href="javascript:;" title="DOCK: reset panel size/position" style="'+s+'"'
					+' onclick="return config.macros.moveablePanel.dockPanel(this,event)">&radic;</a>';
		}
		html+='</div>';
		p.menudiv=createTiddlyElement(place,"span");
		p.menudiv.innerHTML=html;

		// init mouse handling and tooltip
		p.setAttribute("noedges",noedges?"true":"false"); // for alternative mouseover/drag handling
		p.onmousemove=function(event) { return config.macros.moveablePanel.setCursorPanel(this,event); };
		p.onmousedown=function(event) { return config.macros.moveablePanel.moveOrSizePanel(this,event); };
		p.ondblclick=function(event) { // DOUBLE-CLICK = DOCK
			if (p.getAttribute("noedges")=="true" && !((isTop&&!isLeft&&!isRight)||(isBottom&&isRight))) // not over grab handles
				return p.saved.dblclick?p.saved.dblclick.apply(this,arguments):true;
			if (!config.macros.moveablePanel.isEdge(this,event)) // not over edge
				return p.saved.dblclick?p.saved.dblclick.apply(this,arguments):true;
			if (config.macros.moveablePanel.dockPanel(this,event)) // not docking
				return p.saved.dblclick?p.saved.dblclick.apply(this,arguments):true;
			else return false; // docked... done.
		};
		p.onmouseover=function(event) { // MOUSEOVER = SHOW MENU ITEMS
			if(addClass instanceof Function)
				addClass(this,"selected"); // so toolbar-classed items will display
			if (this.getAttribute("undocked")=="true"||hasClass(this,"floatingPanel"))
				this.menudiv.firstChild.style.display="inline";
			if (this.saved.mouseover) return this.saved.mouseover.apply(this,arguments);
		};
		p.onmouseout=function(event) { // MOUSEOUT = HIDE MENU ITEMS
			if(removeClass instanceof Function)
				removeClass(this,"selected"); // so toolbar-classed items are hidden again
			if (this.menudiv) this.menudiv.firstChild.style.display="none";
			if (this.saved.mouseout) return this.saved.mouseout.apply(this,arguments);
		};

		// FIXUP for "floating sliders" (see NestedSlidersPlugin)
		// prevent automatic trigger of adjustSliderPos() for mouse events on floating slider panel/button
		// and make sure that slider button causes moveable panel to be close AND docked (if needed)
		if (hasClass(p,"floatingPanel") && p.button) {
			p.saved.mouseover=null; // discard previous mouse event handlers to prevent
			p.saved.mouseout=null; // automatic triggering of adjustSliderPos() for mouseovers
			p.button.onmouseover=null; // on slider panel and slider button
			if(!p.button.saved_onclick) p.button.saved_onclick=p.button.onclick; // HIJACK SLIDER BUTTON
			p.button.onclick=function(ev){
				config.macros.moveablePanel.dockPanel(this.sliderPanel,ev); // DOCK PANEL FIRST...
				return this.saved_onclick.apply(this,arguments); // ...THEN CLOSE IT
			}
		}
	},
	processed: function(event) {
		event.cancelBubble=true; if (event.stopPropagation) event.stopPropagation(); return false;
	},
	getPanel: function(place) {
		// find a floating panel or use containing element
		var p=place; while (p && !(hasClass(p,"floatingPanel")||p.saved)) p=p.parentNode;
		return p||place;
	},
	isEdge: function(place,event) {
		if (!event) var event=window.event;
		var p=this.getPanel(place); if (!p) return false;
		var left=findPosX(p); var top=findPosY(p);
		var width=p.offsetWidth; var height=p.offsetHeight;
		var x=!config.browser.isIE?event.pageX:event.clientX;
		var y=!config.browser.isIE?event.pageY:event.clientY;
		if (x<left||x>=left+width||y<top||y>=top+height) return false;
		var edgeWidth=10; var edgeHeight=10;
		var isTop=(y-top<edgeHeight); var isLeft=(x-left<edgeWidth);
		var isBottom=(top+height-y<edgeHeight); var isRight=(left+width-x<edgeWidth);
		return isTop||isLeft||isBottom||isRight;
	},
	dockPanel: function(place,event) {
		if (!event) var event=window.event;
		var p=this.getPanel(place); if (!p) return true;
		if (p.folded) this.foldPanel(p.foldButton,event); 
		if (p.hover) this.hoverPanel(p.hoverButton,event); 
		if (p.saved) {
			p.style.top=p.saved.top; p.style.left=p.saved.left;
			p.style.width=p.saved.width; p.style.height=p.saved.height;
			p.style.position=p.saved.position;
			if (p.saved.transient) p.setAttribute("transient","true");
			p.setAttribute("undocked","");
		}
		if (hasClass(p,"floatingPanel") && window.adjustSliderPos) // see NestedSlidersPlugin
			window.adjustSliderPos(p.parentNode,p.button,p);
		return this.processed(event);
	},
	closePanel: function(place,event) {
		var p=this.getPanel(place); if (!p) return true;
		// if a slider button exists close the panel by calling slider button handler
		if (p.button) { p.button.focus(); onClickNestedSlider({target:p.button}); }
		return this.dockPanel(place,event); // and then reset panel state
	},
	foldPanel: function(place,event) {
		if (!event) var event=window.event;
		var p=this.getPanel(place); if (!p) return true;
		if (!p.foldButton) p.foldButton=place;
		if (p.folded) {
			p.style.height=p.folded_savedheight;
			p.style.overflow=p.folded_savedoverflow;
			if (!hasClass(p,"floatingPanel")) p.menudiv.firstChild.style.top="-1em";
		} else {
			p.folded_savedheight=p.style.height; p.style.height="1em"; 
			p.folded_savedoverflow=p.style.overflow; p.style.overflow="hidden";
			if (!hasClass(p,"floatingPanel")) p.menudiv.firstChild.style.top="1em";
		}
		p.folded=!p.folded;
		place.innerHTML=p.folded?"+":"&minus;";
		place.title=p.folded?"UNFOLD: restore panel size":"FOLD: reduce panel size";
		return this.processed(event);
	},
	hoverPanel: function(place,event) {
		if (!event) var event=window.event;
		var p=this.getPanel(place); if (!p) return true;
		if (!p.hoverButton) p.hoverButton=place;
		if (p.hover) {
			p.style.position=p.hover_savedposition;
			if (p.getAttribute("undocked")!="true" && p.saved && p.saved.transient)
				p.setAttribute("transient","true"); // see NestedSlidersPlugin
		} else {
			p.hover_savedposition=p.style.position; p.style.position="fixed";
			if (p.saved.transient) p.setAttribute("transient","false");
		}
		p.hover=!p.hover;
		place.innerHTML=p.hover?"^":"=";
		place.title=p.hover?"HOVERING: panel stays in view when scrolling page":"SCROLLING: panel moves with page";
		return this.processed(event);
	},
	setCursorPanel: function(place,event) {
		if (!event) var event=window.event;
		var p=this.getPanel(place); if (!p) return true;
		var left=findPosX(p); var top=findPosY(p);
		var width=p.offsetWidth; var height=p.offsetHeight;
		var x=!config.browser.isIE?event.pageX:event.clientX;
		var y=!config.browser.isIE?event.pageY:event.clientY;
		if (x<left||x>=left+width||y<top||y>=top+height) return true; // not inside panel, let mousedown bubble through
		var edgeWidth=10; var edgeHeight=10;
		var isTop=(y-top<edgeHeight); var isLeft=(x-left<edgeWidth);
		var isBottom=(top+height-y<edgeHeight); var isRight=(left+width-x<edgeWidth);
		p.style.cursor="auto";
		p.title=p.saved?p.saved.title:"";
		if (!(isTop||isLeft||isBottom||isRight)) return true;
		if (p.getAttribute("noedges")=="true") {
			if (isTop&&!isLeft&&!isRight) {
				p.style.cursor="move";
				p.title="MOVE: drag top panel edge"
					+(p.getAttribute("undocked")=="true"?", DOCK: double-click":"");
			} else if (isBottom && isRight) {
				p.style.cursor="se-resize";
				p.title="RESIZE: drag lower right corner"
					+(p.getAttribute("undocked")=="true"?", DOCK: double-click":"");
			}
		} else {
			p.style.cursor=!event.shiftKey?"move":((isTop?'n':(isBottom?'s':''))+(isLeft?'w':(isRight?'e':''))+'-resize');
			p.title="MOVE: drag panel edge, RESIZE: hold shift key"
				+(p.getAttribute("undocked")=="true"?", DOCK: double-click":"");
		}
		return true; // let mouseover event bubble through
	},
	moveOrSizePanel: function(place,event) {
		if (!event) var event=window.event;
		var p=this.getPanel(place); if (!p) return true;
		if (!this.isEdge(place,event)) return true;
		if (!p.saved) p.saved= { // remember original panel event handlers, size, location, border
			mouseover: p.onmouseover, mouseout: p.onmouseout, dblclick: p.ondblclick,
			top: p.style.top, left: p.style.left, width: p.style.width, height: p.style.height,
			position: p.style.position, border: p.style.border,
			transient: p.getAttribute("transient")=="true"
		};
		var left=findPosX(p); var top=findPosY(p);
		var width=p.offsetWidth; var height=p.offsetHeight;
		var x=!config.browser.isIE?event.pageX:event.clientX;
		var y=!config.browser.isIE?event.pageY:event.clientY;
		var edgeWidth=10; var edgeHeight=10;
		var isTop=(y-top<edgeHeight); var isLeft=(x-left<edgeWidth);
		var isBottom=(top+height-y<edgeHeight); var isRight=(left+width-x<edgeWidth);
		var sizing=event.shiftKey; // remember this for use during mousemove tracking
		if (p.getAttribute("noedges")=="true") {
			if (!((isTop&&!isLeft&&!isRight)||(isBottom&&isRight))) return true; // not over grab handle
			var sizing=isBottom&&isRight;
		}
		var adjustLeft=0; var adjustTop=0;
		// adjustment for relative container
		var pp=p.parentNode; while (pp && !(pp.style&&pp.style.position=='relative')) pp=pp.parentNode;
		if (pp) { adjustLeft+=findPosX(pp); adjustTop+=findPosY(pp); }
		// adjustment for floating slider container
		var pp=p.parentNode; while (pp && !hasClass(pp,"floatingPanel")) pp=pp.parentNode;
		if (pp) { adjustLeft+=findPosX(pp); adjustTop+=findPosY(pp); }
	
		// start tracking mousemove events
		this.activepanel=p;
		var target=p; // if 'capture' handling not supported, track within panel only
		if (document.body.setCapture) { document.body.setCapture(); var target=document.body; } // IE
		if (window.captureEvents) { window.captureEvents(Event.MouseMove|Event.MouseUp,true); var target=window; } // moz
		if (target.onmousemove!=undefined) target.saved_mousemove=target.onmousemove;
		target.onmousemove=function(e){
			if (!e) var e=window.event;
			var p=config.macros.moveablePanel.activepanel;
			if (!p) { this.onmousemove=this.saved_mousemove?this.saved_mousemove:null; return; }
	
			// PROBLEM: p.offsetWidth and p.offsetHeight do not seem to account for padding or borders
			// WORKAROUND: subtract padding and border (in px) when calculating new panel width and height
			// TBD: get these values from p.style... convert to px as needed.
			var paddingWidth=10.6667; var paddingHeight=10.6667;
			var borderWidth=1; var borderHeight=1;
			var adjustWidth=-(paddingWidth*2+borderWidth*2);
			var adjustHeight=-(paddingHeight*2+borderHeight*2);
	
			if (p.style.position!="absolute"&&p.style.position!="fixed") {
				// convert static/relative panel to movable absolute panel
				p.style.position="absolute";
				p.style.left=left+"px"; p.style.top=top+"px";
				p.style.width=(width+adjustWidth)+"px"; p.style.top=(height+adjustHeight)+"px";
			}
			var newX=!config.browser.isIE?e.pageX:e.clientX;
			var newY=!config.browser.isIE?e.pageY:e.clientY;
			if (sizing) { // resize panel
				// don't let panel get smaller than edge "grab" zones
				var minWidth=edgeWidth*2-adjustWidth;
				var minHeight=edgeHeight*2-adjustHeight;
				if (p.folded) this.foldPanel(p.foldButton,e); // make sure panel is unfolded
				if (isBottom) var newHeight=height+newY-y+1;
				if (isTop) var newHeight=height-newY+y+1;
				if (isLeft) var newWidth=width-newX+x+1;
				if (isRight) var newWidth=width+newX-x+1;
				if (isLeft||isRight) p.style.width=(newWidth>minWidth?newWidth:minWidth)+adjustWidth+"px";
				if (isLeft) p.style.left=left-adjustLeft+newX-x+1+"px";
				if (isTop||isBottom) p.style.height=(newHeight>minHeight?newHeight:minHeight)+adjustHeight+"px";
				if (isTop) p.style.top=top-adjustTop+newY-y+1+"px";
				p.setAttribute("undocked","true");
			} else { // move panel
				p.style.top=top-adjustTop+newY-y+1+"px";
				p.style.left=left-adjustLeft+newX-x+1+"px";
				if (p.saved && p.saved.transient) p.setAttribute("transient","false");
				p.setAttribute("undocked","true");
			}
			var status=sizing?("size: "+p.style.width+","+p.style.height):("pos: "+p.style.left+","+p.style.top);
			window.status=status.replace(/(\.[0-9]+)|px/g,""); // remove decimals and "px"
			return config.macros.moveablePanel.processed(e);
		};
		// stop tracking mousemove events
		if (target.onmouseup!=undefined) target.saved_mouseup=target.onmouseup;
		target.onmouseup=function(e){
			if (!e) var e=window.event;
			if (this.releaseCapture) this.releaseCapture(); // IE
			if (this.releaseEvents) this.releaseEvents(Event.MouseMove|Event.MouseUp); // moz
			this.onmousemove=this.saved_mousemove?this.saved_mousemove:null;
			this.onmouseup=this.saved_mouseup?this.saved_mouseup:null;
			config.macros.moveablePanel.activepanel=null;
			window.status="";
			return config.macros.moveablePanel.processed(e);
		};
		return this.processed(event); // mousedown handled
	}
};
//}}}
/***
|Name|MoveablePanelPlugin|
|Source|http://www.TiddlyTools.com/#MoveablePanelPlugin|
|Documentation|http://www.TiddlyTools.com/#MoveablePanelPluginInfo|
|Version|2.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|NestedSlidersPlugin|
|Overrides||
|Description|documentation for MoveablePanelPlugin|
Adds move and size mouse event handling and fold/unfold, and close/dock toolbar command items to any floating slider panel or tiddler element
!!!!!Usage
<<<
syntax: {{{<<moveablePanel nofold nohover noclose noedges>>}}}

where ''nofold'', ''nohover'' and ''noclose'' are optional flags to suppress display of selected commands in the moveable panel "toolbar" and ''noedges'' uses alternative 'grab handle' hot zones: top edge for moving and lower-right corner for sizing.

When the mouse is just inside the edges of the panel, the cursor will change to a "crossed-arrows" symbol, indicating that it is "moveable".  Grab (click-hold) the panel anywhere in the edge area and then drag the mouse to reposition it.  To resize the panel, hold the ''shift'' key before grabbing the panel: the cursor will change to a "double-arrow" symbol.  Drag a side edge of the panel to stretch horizontally or vertically, or drag a corner of the panel to stretch in both dimensions at once.  Double-clicking in the edge area of a panel will reset the panel to its original size and location.

When the mouse is anywhere over a panel (not just near the edge), a 'toolbar menu' appears in the ''upper right corner'', with the following command buttons:
*fold/unfold: ''fold'' temporarily reduces the panel height to show just one line of text.  ''unfold'' restores the panel height.
*hover/scroll: ''hover'' causes the panel to remain in view (i.e., "fixed position") even when scrolling the rest of the page content.  ''scroll'' allows the panel to revert to scrolling with the page content.
*close: ''close'' hides a panel from the page display.  If you have moved/resized a panel, closing it restores its default position and size.
*dock: unlike a "floating slider" panel (see [[NestedSlidersPlugin]], a simple moveable panel does not "float" on the page until it has actually been moved from its default position.  When moving a simple panel, the ''close'' command is replaced with ''dock'', which restores the tiddler to its default //non-floating// location on the page.
<<<
!!!!!Example
<<<
//using NestedSlidersPlugin 'floating panel' syntax//
//{{{
+++^30em^[panel]<<moveablePanel>>this is a headline for the panel
----
	this is a moveable floating panel
	with a few lines of text
	as an example for you to try...
	//note: this line is really long so you can see what happens to word wrapping when you re-size this panel//
===
//}}}
Try it: +++^30em^[panel]<<moveablePanel>>this is a headline for the panel
----
	this is a moveable floating panel
	with a few lines of text
	as an example for you to try...
	//note: this line is really long so you can see what happens to word wrapping when you re-size this panel//
===
<<<
!!!!!Revisions
<<<
2008.01.08 [*.*.*] plugin size reduction: documentation moved to ...Info tiddler
2007.12.30 [2.1.0] added 'noedges' option for alternative 'grab handles' (top=move, bottom-right=resize)
2007.12.17 [2.0.0] code reduction and feature cleanup: in getPanel(), removed handling for returning a tiddler element.  Instead, when the macro is not in a floating panel, it will make it's containing element moveable.  Removed "maximize" functionality (which was badly broken), and replaced it with "double-click=DOCK" (resets size/position without hiding panel). Changed "float/close" menu style to use absolute positioned elements instead of using "float:right" so panels don't suddenly stretch when the menu items are displayed.  Also, throughout code, replaced direct comparison for className=="floatingPanel" with hasClass() test function.  This allows additional classes to be used with moveable floating panels to apply custom CSS styles.
2007.06.10 [1.3.7] in handler(), mouse event handlers now use apply() to correctly invoke any previous mouse handler functions.  This allows *moveable tiddlers* to still process the TW standard handlers for mouseover/out that toggle the 'selected' class used to highlight the toolbar items when the mouse is over a tiddler.  Also, when setting up a moveable "floatingPanel", clear the existing "snap panel back to button location" mouseover/out event handlers (defined by NestedSlidersPlugin when the panels are created).  This extends the fix from v1.3.5 (see below). 
2007.06.08 [1.3.6] in getPanel(), remove unneeded check for "moveable" tag.  Also, added support for "noclose" macro param, and updated documentation accordingly.
2007.06.02 [1.3.5] in handler(), if floating panel has a corresponding button element (i.e., a NestedSlider), then remove onmouseover handler from that button element, to prevent automatic "snap to original location" behavior.  This allows *moveable* floating panels to maintain their placement when they have been manually re-positioned.  This change is made for compatibility with [[NestedSlidersPlugin]] use of onmouseover (see entry for version 2.0.4)
2006.10.17 [1.3.4] when moving panel, adjust position for relative containing DIV
2006.05.25 [1.3.3] in closePanel(), use p.button.onclick() so that normal processing (updating slider button tooltip, access key, etc.) is performed
2006.05.11 [1.3.2] doc update
2006.05.11 [1.3.1] re-define all functions within moveablePanel object (eliminate global window.* function definitions (and some "leaky closures" in IE)
2006.05.11 [1.3.0] converted from inline javascript to true plugin
2006.05.09 [1.2.3] in closePanel(), set focus to sliderpanel button (if any)
2006.05.02 [1.2.2] in MoveOrSizePanel(), calculate adjustments for top and left when inside nested floating panels
2006.04.06 [1.2.1] in getPanel(), allow redefinition or bypass of "moveable" tag (changed from hard-coded "tearoff")
2006.03.29 [1.2.0] in getPanel(), require "tearoff" tag to enable floating tiddlers
2006.03.13 [1.1.0] added handling for floating tiddlers and conditional menu display
2006.03.06 [1.0.2] set move or resize cursor during mousetracking
2006.03.05 [1.0.1] use "window" vs "document.body" so mousetracking in FF doesn't drop the panel when moving too quickly
2006.03.04 [1.0.0] Initial public release
<<<
Name: MptwBlack
HeaderTop: #000
HeaderMid: #555
HeaderBottom: #888
Background:#000
Foreground: #fff
PrimaryPale: #333
PrimaryLight: #555
PrimaryMid: #888
PrimaryDark: #aaa
SecondaryPale: #111
SecondaryLight: #222
SecondaryMid: #555
SecondaryDark: #888
TertiaryPale: #222
TertiaryLight: #666
TertiaryMid: 888
TertiaryDark: #aaa
Error: #f00
Test: #0F0
|Name|MptwRounded|
|Description|Mptw Theme with some rounded corners (Firefox only)|
|ViewTemplate|CustomViewTemplate|
|EditTemplate|CustomEditTemplate|
|PageTemplate|MptwTheme##PageTemplate|
|StyleSheet|##StyleSheet|

!StyleSheet
/*{{{*/

[[MptwTheme##StyleSheet]]

.tiddler,
.sliderPanel,
.button,
.tiddlyLink,
.tabContents
{ -moz-border-radius: 1em; }

.tab {
	-moz-border-radius-topleft: 0.5em;
	-moz-border-radius-topright: 0.5em;
}
#topMenu {
	-moz-border-radius-bottomleft: 2em;
	-moz-border-radius-bottomright: 2em;
}

/* get user styles specified in StyleSheet */
[[StyleSheetShortcuts]]
[[PluginStyles]]

/*}}}*/
[[StyleSheetShortcuts]]
[[PluginStyles]]
/*{{{*/
/* http://mptw.tiddlyspot.com/#MptwStyleSheet ($Rev: 2246 $) */

/* 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 {
	font-family: 'Consolas' monospace;
}

/* 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-bottom: 1em;
	padding-top: 0.75em;
}

/* 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; }

/* for Tagger Plugin, thanks sb56637 */
.popup li a {
   display:inline;
}
/*}}}*/
|Name|MptwTheme|
|Description|Mptw Theme including custom PageLayout|
|PageTemplate|##PageTemplate|
|ViewTemplate|CustomViewTemplate|
|EditTemplate|CustomEditTemplate|
|StyleSheet|##StyleSheet|

http://mptw.tiddlyspot.com/#MptwTheme ($Rev: 1829 $)

!PageTemplate
<!--{{{-->
<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>
<!--}}}-->

!StyleSheet
/*{{{*/

/* 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:1em;
	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-color: transparent;
	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; }

/* fix for TaggerPlugin. from sb56637. improved by FND */
.popup li .tagger a {
   display:inline;
}

/* makes theme selector look a little better */
#sidebarOptions .sliderPanel .select .button {
  padding:0.5em;
  display:block;
}
#sidebarOptions .sliderPanel .select br {
	display:none;
}

/* 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;
	}
}

/* get user styles specified in StyleSheet */
[[StyleSheetShortcuts]]
[[PluginStyles]]

/*}}}*/
/%
|Name|MultiSelectSampleScript|
|Source|http://www.TiddlyTools.com/#MultiSelectSampleScript|
|Version|0.0.0|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|script|
|Description|demonstrates handling for multi-select listboxes|

This sample script demonstrates how to display and populate a multi-select listbox of tiddler titles, and then act on the selection programmatically (via onclick handler for "go" button).  This is only an example.  Adapt it for your own use.  Good Luck!

%/<html><form action="javascript:;" style="display:inline"><!--
	--><select multiple name=list size=6 style="width:100%"></select><br><!--
	--><div style="text-align:center"><!--
	--> list size:<input type=text size=1 value=6 
		onchange="this.form.list.size=this.value; this.form.list.multiple=(this.value>1);"><!--
	--> <input type=button name=refresh value='refresh' 
		onclick="var list=this.form.list; while (list.options[0]) list.options[0]=null; var tids=store.getTiddlers('title','excludeLists'); for (i=0; i<tids.length; i++) list.options[list.length]=new Option(tids[i].title,tids[i].title,false,false);"><!--
	--> <input type=button name=go value='go' 
		onclick="var list=this.form.list;
			var tids=[]; for (i=0;i<list.length;i++)
				if (list.options[i].selected)
					tids.push(list.options[i].value);
			for (t=0;t<tids.length;t++) {
				var title=tids[t];
				displayMessage(title); /* ACT ON TIDDLER */
			}
		"><!--
	--></div><!--
--></form><hide linebreaks></html><script>
	var form=place.lastChild.firstChild;
	var tids=store.getTiddlers('title','excludeLists');
	while (form.list.options[0]) form.list.options[0]=null; 
	for (i=0; i<tids.length; i++)
		form.list.options[form.list.length]=new Option(tids[i].title,tids[i].title,false,false);
</script><<tiddler HideTiddlerTags>>
/***
|Name|NestedSlidersPlugin|
|Source|http://www.TiddlyTools.com/#NestedSlidersPlugin|
|Documentation|http://www.TiddlyTools.com/#NestedSlidersPluginInfo|
|Version|2.4.6|
|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||
|Options|##Configuration|
|Description|show content in nest-able sliding/floating panels, without creating separate tiddlers for each panel's content|
!!!!!Documentation
>see [[NestedSlidersPluginInfo]]
!!!!!Configuration
<<<
<<option chkFloatingSlidersAnimate>> allow floating sliders to animate when opening/closing
>Note: This setting can cause 'clipping' problems in some versions of InternetExplorer.
>In addition, for floating slider animation to occur you must also allow animation in general (see [[AdvancedOptions]]).
<<<
!!!!!Revisions
<<<
2008.09.07 - 2.4.6 added removeOptionCookie() function for compatibility with [[CookieManagerPlugin]]
2008.06.07 - 2.4.5 in 'onmouseover' handler for 'open on hover' slider buttons,<br>use call() method when invoking document.onclick function (avoids error in IE)
|please see [[NestedSlidersPluginInfo]] for additional revision details|
2005.11.03 - 1.0.0 initial public release.  Thanks to RodneyGomes, GeoffSlocock, and PaulPetterson for suggestions and experiments.
<<<
!!!!!Code
***/
//{{{
version.extensions.NestedSlidersPlugin= {major: 2, minor: 4, revision: 6, date: new Date(2008,9,7)};

// options for deferred rendering of sliders that are not initially displayed
if (config.options.chkFloatingSlidersAnimate===undefined)
	config.options.chkFloatingSlidersAnimate=false; // avoid clipping problems in IE

// 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");

// if removeOptionCookie() function is not defined by TW core, define it here.
if (window.removeOptionCookie===undefined) {
window.removeOptionCookie=function(cookie) {
	var ex=new Date(); ex.setTime(ex.getTime()-1000);  // immediately expire cookie
	document.cookie = cookie+"=novalue; path=/; expires="+ex.toGMTString();
}
}

config.formatters.push( {
	name: "nestedSliders",
	match: "\\n?\\+{3}",
	terminator: "\\s*\\={3}\\n?",
	lookahead: "\\n?\\+{3}(\\+)?(\\([^\\)]*\\))?(\\!*)?(\\^(?:[^\\^\\*\\@\\[\\>]*\\^)?)?(\\*)?(\\@)?(?:\\{\\{([\\w]+[\\s\\w]*)\\{)?(\\[[^\\]]*\\])?(\\[[^\\]]*\\])?(?:\\}{3})?(\\#[^:]*\\:)?(\\>)?(\\.\\.\\.)?\\s*",
	handler: function(w)
		{
			lookaheadRegExp = new RegExp(this.lookahead,"mg");
			lookaheadRegExp.lastIndex = w.matchStart;
			var lookaheadMatch = lookaheadRegExp.exec(w.source)
			if(lookaheadMatch && lookaheadMatch.index == w.matchStart)
			{
				var defopen=lookaheadMatch[1];
				var cookiename=lookaheadMatch[2];
				var header=lookaheadMatch[3];
				var panelwidth=lookaheadMatch[4];
				var transient=lookaheadMatch[5];
				var hover=lookaheadMatch[6];
				var buttonClass=lookaheadMatch[7];
				var label=lookaheadMatch[8];
				var openlabel=lookaheadMatch[9];
				var panelID=lookaheadMatch[10];
				var blockquote=lookaheadMatch[11];
				var deferred=lookaheadMatch[12];

				// location for rendering button and panel
				var place=w.output;

				// default to closed, no cookie, no accesskey, no alternate text/tip
				var show="none"; var cookie=""; var key="";
				var closedtext=">"; var closedtip="";
				var openedtext="<"; var openedtip="";

				// extra "+", default to open
				if (defopen) show="block";

				// cookie, use saved open/closed state
				if (cookiename) {
					cookie=cookiename.trim().slice(1,-1);
					cookie="chkSlider"+cookie;
					if (config.options[cookie]==undefined)
						{ config.options[cookie] = (show=="block") }
					show=config.options[cookie]?"block":"none";
				}

				// parse label/tooltip/accesskey: [label=X|tooltip]
				if (label) {
					var parts=label.trim().slice(1,-1).split("|");
					closedtext=parts.shift();
					if (closedtext.substr(closedtext.length-2,1)=="=")	
						{ key=closedtext.substr(closedtext.length-1,1); closedtext=closedtext.slice(0,-2); }
					openedtext=closedtext;
					if (parts.length) closedtip=openedtip=parts.join("|");
					else { closedtip="show "+closedtext; openedtip="hide "+closedtext; }
				}

				// parse alternate label/tooltip: [label|tooltip]
				if (openlabel) {
					var parts=openlabel.trim().slice(1,-1).split("|");
					openedtext=parts.shift();
					if (parts.length) openedtip=parts.join("|");
					else openedtip="hide "+openedtext;
				}

				var title=show=='block'?openedtext:closedtext;
				var tooltip=show=='block'?openedtip:closedtip;

				// create the button
				if (header) { // use "Hn" header format instead of button/link
					var lvl=(header.length>5)?5:header.length;
					var btn = createTiddlyElement(createTiddlyElement(place,"h"+lvl,null,null,null),"a",null,buttonClass,title);
					btn.onclick=onClickNestedSlider;
					btn.setAttribute("href","javascript:;");
					btn.setAttribute("title",tooltip);
				}
				else
					var btn = createTiddlyButton(place,title,tooltip,onClickNestedSlider,buttonClass);
				btn.innerHTML=title; // enables use of HTML entities in label

				// set extra button attributes
				btn.setAttribute("closedtext",closedtext);
				btn.setAttribute("closedtip",closedtip);
				btn.setAttribute("openedtext",openedtext);
				btn.setAttribute("openedtip",openedtip);
				btn.sliderCookie = cookie; // save the cookiename (if any) in the button object
				btn.defOpen=defopen!=null; // save default open/closed state (boolean)
				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
				}
				btn.setAttribute("hover",hover?"true":"false");
				btn.onmouseover=function(ev) {
					// optional 'open on hover' handling
					if (this.getAttribute("hover")=="true" && this.sliderPanel.style.display=='none') {
						document.onclick.call(document,ev); // close transients
						onClickNestedSlider(ev); // open this slider
					}
					// mouseover on button aligns floater position with button
					if (window.adjustSliderPos) window.adjustSliderPos(this.parentNode,this,this.sliderPanel);
				}

				// create slider panel
				var panelClass=panelwidth?"floatingPanel":"sliderPanel";
				if (panelID) panelID=panelID.slice(1,-1); // trim off delimiters
				var panel=createTiddlyElement(place,"div",panelID,panelClass,null);
				panel.button = btn; // so the slider panel know which button it belongs to
				btn.sliderPanel=panel; // so the button knows which slider panel it belongs to
				panel.defaultPanelWidth=(panelwidth && panelwidth.length>2)?panelwidth.slice(1,-1):"";
				panel.setAttribute("transient",transient=="*"?"true":"false");
				panel.style.display = show;
				panel.style.width=panel.defaultPanelWidth;
				panel.onmouseover=function(event) // mouseover on panel aligns floater position with button
					{ if (window.adjustSliderPos) window.adjustSliderPos(this.parentNode,this.button,this); }

				// render slider (or defer until shown) 
				w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
				if ((show=="block")||!deferred) {
					// render now if panel is supposed to be shown or NOT deferred rendering
					w.subWikify(blockquote?createTiddlyElement(panel,"blockquote"):panel,this.terminator);
					// align floater position with button
					if (window.adjustSliderPos) window.adjustSliderPos(place,btn,panel);
				}
				else {
					var src = w.source.substr(w.nextMatch);
					var endpos=findMatchingDelimiter(src,"+++","===");
					panel.setAttribute("raw",src.substr(0,endpos));
					panel.setAttribute("blockquote",blockquote?"true":"false");
					panel.setAttribute("rendered","false");
					w.nextMatch += endpos+3;
					if (w.source.substr(w.nextMatch,1)=="\n") w.nextMatch++;
				}
			}
		}
	}
)

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);
	while (theTarget && theTarget.sliderPanel==undefined) theTarget=theTarget.parentNode;
	if (!theTarget) return false;
	var theSlider = theTarget.sliderPanel;
	var isOpen = theSlider.style.display!="none";

	// toggle label
	theTarget.innerHTML=isOpen?theTarget.getAttribute("closedText"):theTarget.getAttribute("openedText");
	// toggle tooltip
	theTarget.setAttribute("title",isOpen?theTarget.getAttribute("closedTip"):theTarget.getAttribute("openedTip"));

	// deferred rendering (if needed)
	if (theSlider.getAttribute("rendered")=="false") {
		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 && (!hasClass(theSlider,'floatingPanel') || config.options.chkFloatingSlidersAnimate))
		anim.startAnimating(new Slider(theSlider,!isOpen,e.shiftKey || e.altKey,"none"));
	else
		theSlider.style.display = isOpen ? "none" : "block";
	// reset to default width (might have been changed via plugin code)
	theSlider.style.width=theSlider.defaultPanelWidth;
	// align floater panel position with target button
	if (!isOpen && window.adjustSliderPos) window.adjustSliderPos(theSlider.parentNode,theTarget,theSlider);
	// 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" && ctrls[c].type!="hidden") || t=="textarea" || t=="select")
				{ ctrls[c].focus(); break; }
		}
	}
	var cookie=theTarget.sliderCookie;
	if (cookie && cookie.length) {
		config.options[cookie]=!isOpen;
		if (config.options[cookie]!=theTarget.defOpen) window.saveOptionCookie(cookie);
		else window.removeOptionCookie(cookie); // remove cookie if slider is in default display state
	}

	// prevent SHIFT-CLICK from being processed by browser (opens blank window... yuck!)
	// prevent clicks *within* a slider button from being processed by browser
	// but allow plain click to bubble up to page background (to close transients, if any)
	if (e.shiftKey || theTarget!=resolveTarget(e))
		{ e.cancelBubble=true; if (e.stopPropagation) e.stopPropagation(); }
	Popup.remove(); // close open popup (if any)
	return false;
}
//}}}
//{{{
// click in document background closes transient panels 
document.nestedSliders_savedOnClick=document.onclick;
document.onclick=function(ev) { if (!ev) var ev=window.event; var target=resolveTarget(ev);

	if (document.nestedSliders_savedOnClick)
		var retval=document.nestedSliders_savedOnClick.apply(this,arguments);
	// if click was inside a popup... leave transient panels alone
	var p=target; while (p) if (hasClass(p,"popup")) break; else p=p.parentNode;
	if (p) return retval;
	// if click was inside transient panel (or something contained by a transient panel), leave it alone
	var p=target; while (p) {
		if ((hasClass(p,"floatingPanel")||hasClass(p,"sliderPanel"))&&p.getAttribute("transient")=="true") break;
		p=p.parentNode;
	}
	if (p) return retval;
	// otherwise, find and close all transient panels...
	var all=document.all?document.all:document.getElementsByTagName("DIV");
	for (var i=0; i<all.length; i++) {
		 // if it is not a transient panel, or the click was on the button that opened this panel, don't close it.
		if (all[i].getAttribute("transient")!="true" || all[i].button==target) continue;
		// otherwise, if the panel is currently visible, close it by clicking it's button
		if (all[i].style.display!="none") window.onClickNestedSlider({target:all[i].button}) 
	}
	return retval;
};
//}}}
//{{{
// adjust floating panel position based on button position
if (window.adjustSliderPos==undefined) window.adjustSliderPos=function(place,btn,panel) {
	if (hasClass(panel,"floatingPanel")) {
		var rightEdge=document.body.offsetWidth-1;
		var panelWidth=panel.offsetWidth;
		var left=0;
		var top=btn.offsetHeight; 
		if (place.style.position=="relative" && findPosX(btn)+panelWidth>rightEdge) {
			left-=findPosX(btn)+panelWidth-rightEdge; // shift panel relative to button
			if (findPosX(btn)+left<0) left=-findPosX(btn); // stay within left edge
		}
		if (place.style.position!="relative") {
			var left=findPosX(btn);
			var top=findPosY(btn)+btn.offsetHeight;
			var p=place; while (p && !hasClass(p,'floatingPanel')) p=p.parentNode;
			if (p) { left-=findPosX(p); top-=findPosY(p); }
			if (left+panelWidth>rightEdge) left=rightEdge-panelWidth;
			if (left<0) left=0;
		}
		panel.style.left=left+"px"; panel.style.top=top+"px";
	}
}
//}}}
//{{{
// TW2.1 and earlier:
// hijack Slider stop handler so overflow is visible after animation has completed
Slider.prototype.coreStop = Slider.prototype.stop;
Slider.prototype.stop = function()
	{ this.coreStop.apply(this,arguments); this.element.style.overflow = "visible"; }

// TW2.2+
// hijack Morpher stop handler so sliderPanel/floatingPanel overflow is visible after animation has completed
if (version.major+.1*version.minor+.01*version.revision>=2.2) {
	Morpher.prototype.coreStop = Morpher.prototype.stop;
	Morpher.prototype.stop = function() {
		this.coreStop.apply(this,arguments);
		var e=this.element;
		if (hasClass(e,"sliderPanel")||hasClass(e,"floatingPanel")) {
			// adjust panel overflow and position after animation
			e.style.overflow = "visible";
			if (window.adjustSliderPos) window.adjustSliderPos(e.parentNode,e.button,e);
		}
	};
}
//}}}
/***
|Name|NestedSlidersPluginInfo|
|Source|http://www.TiddlyTools.com/#NestedSlidersPlugin|
|Documentation|http://www.TiddlyTools.com/#NestedSlidersPluginInfo|
|Version|2.4.5|
|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 NestedSlidersPlugin|
This plugin adds new wiki syntax for embedding 'slider' panels directly into tiddler content.
!!!!!Usage
<<<
Use {{{+++}}} and {{{===}}} to delimit the slider content.  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.

Additional optional syntax elements let you specify
*default to open
*cookiename
*heading level
*floater (with optional CSS width value)
*transient display (clicking elsewhere closes panel)
*open on hover (without needing to click)
*custom class/label/tooltip/accesskey
*alternate label/tooltip (displayed when panel is open)
*panelID (for later use with {{{<<DOM>>}}} macro.  See [[DOMTweaksPlugin]])
*automatic blockquote style on panel
*deferred rendering of panel content
The complete syntax, using all options, is:
//{{{
++++(cookiename)!!!!!^width^*@{{class{[label=key|tooltip][altlabel|alttooltip]}}}#panelID:>...
content goes here
===
//}}}
where:
* ''"""+++""" (or """++++""") and """==="""''<br>marks the start and end of the slider definition, respectively.  When the extra {{{+}}} is used, the slider will be open when initially displayed.
* ''"""(cookiename)"""''<br>saves the slider opened/closed state, and restores this state whenever the slider is re-rendered.
* ''"""! through !!!!!"""''<br>displays the slider label using a formatted headline (Hn) style instead of a button/link style
* ''"""^width^ (or just ^)"""''<br>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)
* ''"""*"""''<br>denotes "transient display": when a click occurs elsewhere in the document, the slider/floating panel will be automatically closed.  This is useful for creating 'pulldown menus' that automatically go away after they are used.  //Note: using SHIFT-click on a slider label will open/close that slider without triggering the automatic closing of any transient slider panels that are currently displayed, permitting ''temporary'' display of several transient panels at once.//
* ''"""@"""''<br>denotes "open on hover": the slider/floating panel will be automatically opened as soon as the mouse moves over the slider label, without requiring a click.
* ''"""{{class{[label=key|tooltip][altlabel|alttooltip]}}}"""''<br>uses label/tooltip/accesskey.  """{{class{...}}}""", """=key""", """|tooltip""" and """[altlabel|alttooltip]""" are optional.  'class' is any valid CSS class name, used to style the slider label text.  'key' must be a ''single letter only''.  altlabel/alttooltip specify alternative label/tooltip for use when slider/floating panel is displayed.  //Note: you can use HTML syntax within the label text to include HTML entities (e.g., {{{&raquo;}}} (&raquo;) or {{{&#x25ba;}}} (&#x25ba;), or even embedded images (e.g., {{{<img src="images/eric3.gif">}}}).//
* ''"""#panelID:"""''<br>defines a unique DOM element ID that is assigned to the panel element used to display the slider content.  This ID can then be used later to reposition the panel using the {{{<<DOM move id>>}}} macro (see [[DOMTweaksPlugin]]), or to access/modify the panel element through use of {{{document.getElementById(...)}}}) javascript code in a plugin or inline script.
* ''""">"""''<br>automatically adds blockquote formatting to slider content
* ''"""..."""''<br>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 (except cookie) //(default open, heading, sized floater, transient, open on hover, class, label/tooltip/key, blockquoted, deferred)//
{{{
++++!!!^30em^*@{{big{[label=Z|click or press Alt-Z to open]}}}>...
   content
===
}}}
++++!!!^30em^*@{{big{[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 panel with more specific info:
	+++^10em^[view details...|click for details]
		put some detail here, which could in turn contain a transient panel,
		perhaps 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 panel with more specific info:
	+++^10em^[view details...|click for details]
		put some detail here, which could in turn contain a transient panel,
		perhaps with a +++^25em^*[glossary definition]explaining technical terms===
	===
===
----
embedded image as slider button
{{{
+++[<img src=images/eric3.gif>|click me!]>
	{{big{OUCH!}}}
===
}}}
+++[<img src=images/eric3.gif>|click me!]>
	{{big{OUCH!}}}
===
<<<
!!!!!Revisions
<<<
2008.06.07 - 2.4.5 in 'onmouseover' handler for 'open on hover' slider buttons, use call() method when invoking document.onclick function (avoids error in IE)
2008.06.07 - 2.4.4 changed default for chkFloatingSlidersAnimate to FALSE to avoid clipping problem on some browsers (IE).  Updated Morpher hijack (again) to adjust regular sliderPanel styles as well as floatingPanel styles.
2008.05.07 - 2.4.3 updated Morpher hijack to adjust floatingPanel styles after animation without affecting other animated elements (i.e. popups).  Also, updated adjustSliderPos() to account for scrollwidth and use core findWindowWidth().
2008.04.02 - 2.4.2 in onClickNestedSlider, handle clicks on elements contained //within// slider buttons (e.g., when using HTML to display an image as a slider button).
2008.04.01 - 2.4.1 open on hover also triggers document.onclick to close other transient sliders
2008.04.01 - 2.4.0 re-introduced 'open on hover' feature using "@" symbol
2008.03.26 - 2.3.5 in document.onclick(), if click is in popup, don't dismiss transient panel (if any)
2008.01.08 - [*.*.*] plugin size reduction: documentation moved to ...Info tiddler
2007.12.28 - 2.3.4 added hijack for Animator.prototype.startAnimating().  Previously, the plugin code simply set the overflow to "visible" after animation.  This code tweak corrects handling of elements that were styled with overflow=hidden/auto/scroll before animation by saving the overflow style and then restoring it after animation has completed.
2007.12.17 - 2.3.3 use hasClass() instead of direct comparison to test for "floatingPanel" class.  Allows floating panels to have additional classes assigned to them (i.e., by AnimationEffectsPlugin).
2007.11.14 - 2.3.2 in onClickNestedSlider(), prevent SHIFT-click events from opening a new, empty browser window by setting "cancelBubble=true" and calling "stopPropagation()".  Note: SHIFT-click is still processed as a normal click (i.e., it toggles the slider panel display).  Also, using SHIFT-click will prevent 'transient' sliders from being automatically closed when another slider is opened, allowing you to *temporarily* display several transient sliders at once.
2007.07.26 - 2.3.1 in document.onclick(), propagate return value from hijacked core click handler to consume OR bubble up click as needed.  Fixes "IE click disease", whereby nearly every mouse click causes a page transition.
2007.07.20 - 2.3.0 added syntax for setting panel ID (#panelID:).  This allows individual slider panels to be repositioned within tiddler content simply by giving them a unique ID and then moving them to the desired location using the {{{<<DOM move id>>}}} macro.
2007.07.19 - 2.2.0 added syntax for alttext and alttip (button label and tooltip to be displayed when panel is open)
2007.07.14 - 2.1.2 corrected use of 'transient' attribute in IE to prevent (non-recursive) infinite loop
2007.07.12 - 2.1.0 replaced use of "*" for 'open/close on rollover' (which didn't work too well).  "*" now indicates 'transient' panels that are automatically closed if a click occurs somewhere else in the document.  This permits use of nested sliders to create nested "pulldown menus" that automatically disappear after interaction with them has been completed.  Also, in onClickNestedSlider(), use "theTarget.sliderCookie", instead of "this.sliderCookie" to correct cookie state tracking when automatically dismissing transient panels.
2007.06.10 - 2.0.5 add check to ensure that window.adjustSliderPanel() is defined before calling it (prevents error on shutdown when mouse event handlers are still defined)
2007.05.31 - 2.0.4 add handling to invoke adjustSliderPanel() for onmouseover events on slider button and panel.  This allows the panel position to be re-synced when the button position shifts due to changes in unrelated content above it on the page.  (thanks to Harsha for bug report)
2007.03.30 - 2.0.3 added chkFloatingSlidersAnimate (default to FALSE), so that slider animation can be disabled independent of the overall document animation setting (avoids strange rendering and focus problems in floating panels)
2007.03.01 - 2.0.2 for TW2.2+, hijack Morpher.prototype.stop so that "overflow:hidden" can be reset to "overflow:visible" after animation ends
2007.03.01 - 2.0.1 in hijack for Slider.prototype.stop, use apply() to pass params to core function
2006.07.28 - 2.0.0 added custom class syntax around label/tip/key syntax: {{{{{classname{[label=key|tip]}}}}}}
2006.07.25 - 1.9.3 when parsing slider, save default open/closed state in button element, then in onClickNestedSlider(), if slider state matches saved default, instead of saving cookie, delete it.  Significantly reduces the 'cookie overhead' when default slider states are used.
2006.06.29 - 1.9.2 in onClickNestedSlider(), when setting focus to first control, skip over type="hidden"
2006.06.22 - 1.9.1 added panel.defaultPanelWidth to save requested panel width, even after resizing has changed the style value
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
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
<<<
window.onClickToolbarNewHere = function(e) {
	if (!e) var e = window.event;
	clearMessage();
	if(this.parentNode.id) {
		displayTiddler(this.parentNode,"New Tiddler",2,null,null,false,false);
		tagBox = document.getElementById("editorTagsNew Tiddler"); 
		tagBox.value = this.parentNode.id.substring(7);
	}
	e.cancelBubble = true;
	if (e.stopPropagation) e.stopPropagation();
	return(false);
}

config.views.wikified.toolbarNewHere = {text: "new here", tooltip: "Create a new tiddler with tagged as this tiddler"};

window.createTiddlerToolbar_orig_mptw_newhere = window.createTiddlerToolbar;
window.createTiddlerToolbar = function(title,isEditor) {
	createTiddlerToolbar_orig_mptw_newhere(title,isEditor);
	var theToolbar = document.getElementById("toolbar" + title);
	var lingo = config.views.wikified;
	if(!isEditor) {
		createTiddlyButton(theToolbar, lingo.toolbarNewHere.text, lingo.toolbarNewHere.tooltip, onClickToolbarNewHere);
		insertSpacer(theToolbar);
	}
}
/***
|Name:|NewHerePlugin|
|Description:|Creates the new here and new journal macros|
|Version:|3.0 ($Rev: 3861 $)|
|Date:|$Date: 2008-03-08 10:53:09 +1000 (Sat, 08 Mar 2008) $|
|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 label:'New Notification' title:'New Notification' text:{{store.getTiddlerText('NotificationTemplate','')}} tag:'Notification'>>
}}}
<<newTiddler label:'New Notification' title:'New Notification' text:{{store.getTiddlerText('NotificationTemplate','')}} tag:'Notification'>>
/***
|''Name:''| NiceTaggingPlugin|
|''Description:''| creates a nicer interface for adding and removing TiddlyWiki. Ideal for tiddly novices. |
|''Version:''|0.51|
|''Date:''|April 2010|
|''Source:''|http://www.jonrobson.me.uk/development/niceTagging|
|''Author:''|Jon Robson|
|''License:''|[[BSD open source license]]|
|''CoreVersion:''|2.3|
|''Dependencies:''||
***/

if(store){
  config.shadowTiddlers.NiceTaggingStyle = "/*{{{*/\n" +
  ".tip {font-style:italic;font-weight:bold;}\n"+
  ".dp-popup {position:absolute;background-color:white;} a.dp-choose-date {  float: left;  width: 16px;  height: 16px;  padding: 0;  margin: 5px 3px 0;  display: block;  text-indent: -2000px;  overflow: hidden;  background: url(calendar.png) no-repeat; }a.dp-choose-date.dp-disabled {  background-position: 0 -20px;  cursor: default;}input.dp-applied {  width: 140px;  float: left;}\n"+
  ".niceTagger input {width:200px; float:left;}\n"+
  ".deleter {color:red; font-weight:bold; padding:2px; cursor:pointer;}\n"+
  ".ac_results {padding: 0px;border: 1px solid black;background-color: white;overflow: hidden;z-index: 99999;}\n"+
  ".ac_results ul {width: 100%;list-style-position: outside;list-style: none;padding: 0;margin: 0;}\n"+
  ".ac_results li {margin: 0px;padding: 2px 5px;cursor: default;display: block;font: menu;font-size: 12px;line-height: 16px;overflow: hidden;}\n"+
  ".ac_loading {background: white url('indicator.gif') right center no-repeat;}\n"+
  ".ac_odd {background-color: #eee;}\n"+
  ".ac_over {background-color: #0A246A;color: white;}\n"+
  "/*}}}*/";
store.addNotification("NiceTaggingStyle", refreshStyles);
}

String.prototype.toJSON = function(){var namedprms = this.parseParams(null, null, true);var options ={};for(var i=0; i < namedprms.length;i++){var nameval = namedprms[i];if(nameval.name)options[nameval.name] = nameval.value;}return options;};

config.macros.niceTagger = {
  lingo:{
    add: "add"
  }
  ,twtags: {}
  ,initialised:{}
  ,init: function(field){
    if(!field)field = 'tags';
    if(this.initialised[field]){
        if(field =='tags'){
            var numTags= store.getTags();
            if(numTags.length == this.twtags[field].length) return;
        }
        else{
            return;
        }
    }
    var tiddlers= store.getTiddlers();
    config.macros.niceTagger.twtags[field] = [];
    var uniqueSuggestions = [];
    for(var i=0; i < tiddlers.length; i++){
      
      var tid = tiddlers[i];
      var values;
      if(field=='tags')values = tid.tags;
      else {
        values=tid.fields[field]
        if(!values)values="";
        values = values.readBracketedList();
      }
      for(var j=0; j < values.length; j++){
        uniqueSuggestions.pushUnique(values[j]);
      }
      
    }
    config.macros.niceTagger.twtags[field] = uniqueSuggestions;
    this.initialised[field] =true;
  }
  ,save: function(title,field,listvalues,place,autosavechanges){
    //console.log("save",title,field,list);
    var tiddler =  store.getTiddler(title);
    if(!tiddler) { //doesnt work when tiddler is brand spanking new
      var dummytiddler ={title:title,tags:[],fields:{}};
      var tagTempPlace = jQuery("input[edit="+field+"]",place);

      if(!tagTempPlace[0]){
        jQuery(place).append('<input style="display:none;" type="text" edit="'+field+'"/>')
      }
      tagTempPlace = jQuery("input[edit="+field+"]",place);
      
      var tags = [];
      if(field=='tags'){
          tags = listvalues;
          dummytiddler.tags = listvalues;
      }
      else{
          dummytiddler.fields[field] = listvalues;
      }
      tagTempPlace.val(String.encodeTiddlyLinkList(listvalues))
      return dummytiddler;
      //store.saveTiddler(title,title,null,true,null,tags,fields,null);
      //tiddler =  store.getTiddler(title);
    } 
    var strVal;
    if(typeof(listvalues) =='string'){
        strVal = listvalues;
    }
    else{
        strVal= String.encodeTiddlyLinkList(listvalues);
    } 
    //tiddler.fields[field] = strVal
    //store.saveTiddler(tiddler.title,tiddler.title,tiddler.text,null,null,tiddler.tags,tiddler.fields,null);
    store.setValue(tiddler.title,field,strVal);
    store.saveTiddler(tiddler.title, tiddler.title, tiddler.text, tiddler.modifier, tiddler.modified, tiddler.tags, tiddler.fields, false, tiddler.created)
    if(autosavechanges)autoSaveChanges()      
    //story.setDirty(title,true);
    return tiddler;
        //console.log("finished save tags",tiddler.tags,"field",tiddler.fields[field]);
  }
  ,refreshFieldDisplay: function(place,tiddler,field){
    //console.log("refresh tasgs",field,tiddler.fields[field]);
    jQuery(place).html("");
    var tags;
    if(!field ||field=='tags'){
      tags = tiddler.tags;
    }
    else{
      var val= tiddler.fields[field];
      if(!val)val="";
      tags = val.readBracketedList();
    }
    for(var t=0; t < tags.length; t++){
      var tag = tags[t];
      jQuery(place).append(" <span class='tag'>"+tag+"</span> <span class='deleter' deletes='"+escape(tag)+"'>x</span>");
    }
      
    jQuery(".deleter",place).click(function(e){
      //console.log("gonna delete");
      var todelete = jQuery(this).attr("deletes");
      var newtags = [];
      //console.log("delete",todelete);
      for(var i=0; i < tags.length; i++){
          if(escape(tags[i]) != todelete){
             newtags.push(tags[i]);
          }
      }
      //console.log("Save",tiddler.title,field,newtags);
      tiddler = config.macros.niceTagger.save(tiddler.title,field,newtags,place,tiddler.autosavechanges);
      //console.log("Refresh",tiddler,field);
      config.macros.niceTagger.refreshFieldDisplay(place,tiddler,field);
      //console.log("done refresh")
    });
  }
  ,saveNewTag: function(tiddler,field,value,place,splitChar){
    var saveThis = [];
    var adder = jQuery("input",place)[0];
    if(field=='tags'){
        saveThis = tiddler.tags;
    }
    else{
      var val = tiddler.fields[field];
      if(!val)val= "";
      saveThis = val.readBracketedList();
    }
    //console.log(value,"is value");
    if(value && value.replace(" ","").length == 0) return;
    var savedVals;
    if(splitChar && value.indexOf(splitChar) !=-1){
      savedVals= value.split(splitChar);
    }
    else{
      savedVals = [value];
    }            
    for(var i=0; i < savedVals.length;i++){
      var svalue = savedVals[i];
      if(saveThis.indexOf(svalue) == -1) saveThis.push(svalue);
    }            
    tiddler= config.macros.niceTagger.save(tiddler.title,field,saveThis,place,tiddler.autosavechanges);
    
    var tagplace = jQuery(".niceTagger",place)[0];
    if(tagplace)config.macros.niceTagger.refreshFieldDisplay(tagplace,tiddler,field);
    if(adder)adder.value = "";
  }
  ,getSuggestionsFromTiddler: function(srcTiddler,textcase){
    var suggestions = [];
    if(srcTiddler){
      var src = store.getTiddler(srcTiddler);
      var text = src.text;
      var tempdiv = document.createElement("div");
      wikify(text,tempdiv,null,src);
      var html = jQuery(tempdiv).html();
      suggestions = html.split(/<br\/?>/gi);
    }
    var finalSuggestions = [];
    for(var i=0; i < suggestions.length; i++){
      var val = suggestions[i].trim();
      if(textcase && textcase == "lower")val = val.toLowerCase();
      finalSuggestions.pushUnique(val);
    }
    return finalSuggestions;
  }
  ,removeFromList: function(list,removeList){
    var uniqueSuggestions = [];
    for(var i=0; i < list.length; i++){
      var s =list[i];
      if(s && typeof(s) =='string'){
        if(uniqueSuggestions.indexOf(s) ==-1 && removeList.indexOf(s) ==-1){
          uniqueSuggestions.push(s);
        }
      }
    }
    return uniqueSuggestions;
  }
  ,handler: function(place,macroName,paramlist,wikifier,paramString,tiddler){
    var macro =config.macros.niceTagger;
    var options = paramString.toJSON();
    if(options.autoSaveChanges)tiddler.autosavechanges = true;
    if(!options.field)options.field = "tags";        
    this.init(options.field);
    var displayer = document.createElement("div");
    displayer.className = "niceTagger";
    place.appendChild(displayer);
    config.macros.niceTagger.refreshFieldDisplay(displayer,tiddler,options.field);
    var tagplace = document.createElement("div");
    tagplace.className ="niceTaggerAdder"
    place.appendChild(tagplace);
        
    var splitChar = options.splitOn;
    var saveNewTag= config.macros.niceTagger.saveNewTag;
    var adder;
    

    if(jQuery().autocomplete){
      var params = paramString.parseParams("anon",null,true,false,false);
      var textcase = getParam(params,"case");
      var srcTiddler = getParam(params,"valuesSource");
      var suggestions;
      if(srcTiddler)suggestions = macro.getSuggestionsFromTiddler(srcTiddler,textcase);
      else suggestions = [];
      var tagsoff = getParam(params,"nostoretags");
      if(!tagsoff) suggestions = suggestions.concat(config.macros.niceTagger.twtags[options.field]);
      
      
      var ignoreList = paramString.parseParams("exclude",null,true,false,true);
      if(ignoreList && ignoreList[0] && ignoreList[0]["exclude"]) ignoreList =  ignoreList[0]["exclude"];
      else ignoreList = ["excludeList"];
      suggestions = macro.removeFromList(suggestions,ignoreList);
    
      var addtaghandler = function(v){saveNewTag(tiddler,options.field,v,place,splitChar);jQuery("input",tagplace).val("");}
      jQuery("<input type='text' name=\""+options.field+"\" value=\"\"/>").autocomplete(suggestions,{matchContains: true,selectFirst:false}).result(addtaghandler).appendTo(tagplace);
      adder = jQuery("input",tagplace)[0];
      
    }
    else{
      adder = document.createElement("input");
      tagplace.appendChild(adder);
    }
    jQuery(adder).keypress(function (e) {
      if(e.which == 13){
        var results = jQuery(".ac_over",".ac_results"); //is anything highlighted in autocomplete plugin
        if(results.length ==0)saveNewTag(tiddler,options.field,adder.value,place,splitChar);
      }
    });
    var addbutton = document.createElement("input");
    addbutton.type = "button";
    addbutton.value = config.macros.niceTagger.lingo.add;
    addbutton.className = "adder";
    tagplace.appendChild(addbutton);
    jQuery(addbutton).click(function(e){
      var val = adder.value;
      saveNewTag(tiddler,options.field,val,place,splitChar);
    }); 
    jQuery(place).attr("dirty","true");
        
  }  
};
config.macros.niceTagger.init();
(function($) { 
/* The following code is optional and adds search suggestions */
/*
 * Autocomplete - jQuery plugin 1.0.2
 *
 * Copyright (c) 2007 Dylan Verheul, Dan G. Switzer, Anjesh Tuladhar, Jörn Zaefferer
 *
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 *
 * Revision: $Id: jquery.autocomplete.js 5747 2008-06-25 18:30:55Z joern.zaefferer $
 *
 */
 /* Copyright (c) 2006 Brandon Aaron (http://brandonaaron.net)
  * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) 
  * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
  *
  * $LastChangedDate: 2007-07-22 01:45:56 +0200 (Son, 22 Jul 2007) $
  * $Rev: 2447 $
  *
  * Version 2.1.1
  */
 (function($){$.fn.bgIframe=$.fn.bgiframe=function(s){if($.browser.msie&&/6.0/.test(navigator.userAgent)){s=$.extend({top:'auto',left:'auto',width:'auto',height:'auto',opacity:true,src:'javascript:false;'},s||{});var prop=function(n){return n&&n.constructor==Number?n+'px':n;},html='<iframe class="bgiframe"frameborder="0"tabindex="-1"src="'+s.src+'"'+'style="display:block;position:absolute;z-index:-1;'+(s.opacity!==false?'filter:Alpha(Opacity=\'0\');':'')+'top:'+(s.top=='auto'?'expression(((parseInt(this.parentNode.currentStyle.borderTopWidth)||0)*-1)+\'px\')':prop(s.top))+';'+'left:'+(s.left=='auto'?'expression(((parseInt(this.parentNode.currentStyle.borderLeftWidth)||0)*-1)+\'px\')':prop(s.left))+';'+'width:'+(s.width=='auto'?'expression(this.parentNode.offsetWidth+\'px\')':prop(s.width))+';'+'height:'+(s.height=='auto'?'expression(this.parentNode.offsetHeight+\'px\')':prop(s.height))+';'+'"/>';return this.each(function(){if($('> iframe.bgiframe',this).length==0)this.insertBefore(document.createElement(html),this.firstChild);});}return this;};})(jQuery);
  
eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}(';(3($){$.31.1o({12:3(b,d){5 c=Y b=="1w";d=$.1o({},$.D.1L,{11:c?b:14,w:c?14:b,1D:c?$.D.1L.1D:10,Z:d&&!d.1x?10:3U},d);d.1t=d.1t||3(a){6 a};d.1q=d.1q||d.1K;6 I.K(3(){1E $.D(I,d)})},M:3(a){6 I.X("M",a)},1y:3(a){6 I.15("1y",[a])},20:3(){6 I.15("20")},1Y:3(a){6 I.15("1Y",[a])},1X:3(){6 I.15("1X")}});$.D=3(o,r){5 t={2N:38,2I:40,2D:46,2x:9,2v:13,2q:27,2d:3x,2j:33,2o:34,2e:8};5 u=$(o).3f("12","3c").P(r.24);5 p;5 m="";5 n=$.D.2W(r);5 s=0;5 k;5 h={1z:B};5 l=$.D.2Q(r,o,1U,h);5 j;$.1T.2L&&$(o.2K).X("3S.12",3(){4(j){j=B;6 B}});u.X(($.1T.2L?"3Q":"3N")+".12",3(a){k=a.2F;3L(a.2F){Q t.2N:a.1d();4(l.L()){l.2y()}A{W(0,C)}N;Q t.2I:a.1d();4(l.L()){l.2u()}A{W(0,C)}N;Q t.2j:a.1d();4(l.L()){l.2t()}A{W(0,C)}N;Q t.2o:a.1d();4(l.L()){l.2s()}A{W(0,C)}N;Q r.19&&$.1p(r.R)==","&&t.2d:Q t.2x:Q t.2v:4(1U()){a.1d();j=C;6 B}N;Q t.2q:l.U();N;3A:1I(p);p=1H(W,r.1D);N}}).1G(3(){s++}).3v(3(){s=0;4(!h.1z){2k()}}).2i(3(){4(s++>1&&!l.L()){W(0,C)}}).X("1y",3(){5 c=(1n.7>1)?1n[1]:14;3 23(q,a){5 b;4(a&&a.7){16(5 i=0;i<a.7;i++){4(a[i].M.O()==q.O()){b=a[i];N}}}4(Y c=="3")c(b);A u.15("M",b&&[b.w,b.H])}$.K(1g(u.J()),3(i,a){1R(a,23,23)})}).X("20",3(){n.18()}).X("1Y",3(){$.1o(r,1n[1]);4("w"2G 1n[1])n.1f()}).X("1X",3(){l.1u();u.1u();$(o.2K).1u(".12")});3 1U(){5 b=l.26();4(!b)6 B;5 v=b.M;m=v;4(r.19){5 a=1g(u.J());4(a.7>1){v=a.17(0,a.7-1).2Z(r.R)+r.R+v}v+=r.R}u.J(v);1l();u.15("M",[b.w,b.H]);6 C}3 W(b,c){4(k==t.2D){l.U();6}5 a=u.J();4(!c&&a==m)6;m=a;a=1k(a);4(a.7>=r.22){u.P(r.21);4(!r.1C)a=a.O();1R(a,2V,1l)}A{1B();l.U()}};3 1g(b){4(!b){6[""]}5 d=b.1Z(r.R);5 c=[];$.K(d,3(i,a){4($.1p(a))c[i]=$.1p(a)});6 c}3 1k(a){4(!r.19)6 a;5 b=1g(a);6 b[b.7-1]}3 1A(q,a){4(r.1A&&(1k(u.J()).O()==q.O())&&k!=t.2e){u.J(u.J()+a.48(1k(m).7));$.D.1N(o,m.7,m.7+a.7)}};3 2k(){1I(p);p=1H(1l,47)};3 1l(){5 c=l.L();l.U();1I(p);1B();4(r.2U){u.1y(3(a){4(!a){4(r.19){5 b=1g(u.J()).17(0,-1);u.J(b.2Z(r.R)+(b.7?r.R:""))}A u.J("")}})}4(c)$.D.1N(o,o.H.7,o.H.7)};3 2V(q,a){4(a&&a.7&&s){1B();l.2T(a,q);1A(q,a[0].H);l.1W()}A{1l()}};3 1R(f,d,g){4(!r.1C)f=f.O();5 e=n.2S(f);4(e&&e.7){d(f,e)}A 4((Y r.11=="1w")&&(r.11.7>0)){5 c={45:+1E 44()};$.K(r.2R,3(a,b){c[a]=Y b=="3"?b():b});$.43({42:"41",3Z:"12"+o.3Y,2M:r.2M,11:r.11,w:$.1o({q:1k(f),3X:r.Z},c),3W:3(a){5 b=r.1r&&r.1r(a)||1r(a);n.1h(f,b);d(f,b)}})}A{l.2J();g(f)}};3 1r(c){5 d=[];5 b=c.1Z("\\n");16(5 i=0;i<b.7;i++){5 a=$.1p(b[i]);4(a){a=a.1Z("|");d[d.7]={w:a,H:a[0],M:r.1v&&r.1v(a,a[0])||a[0]}}}6 d};3 1B(){u.1e(r.21)}};$.D.1L={24:"3R",2H:"3P",21:"3O",22:1,1D:3M,1C:B,1a:C,1V:B,1j:10,Z:3K,2U:B,2R:{},1S:C,1K:3(a){6 a[0]},1q:14,1A:B,E:0,19:B,R:", ",1t:3(b,a){6 b.2C(1E 3J("(?![^&;]+;)(?!<[^<>]*)("+a.2C(/([\\^\\$\\(\\)\\[\\]\\{\\}\\*\\.\\+\\?\\|\\\\])/2A,"\\\\$1")+")(?![^<>]*>)(?![^&;]+;)","2A"),"<2z>$1</2z>")},1x:C,1s:3I};$.D.2W=3(g){5 h={};5 j=0;3 1a(s,a){4(!g.1C)s=s.O();5 i=s.3H(a);4(i==-1)6 B;6 i==0||g.1V};3 1h(q,a){4(j>g.1j){18()}4(!h[q]){j++}h[q]=a}3 1f(){4(!g.w)6 B;5 f={},2w=0;4(!g.11)g.1j=1;f[""]=[];16(5 i=0,30=g.w.7;i<30;i++){5 c=g.w[i];c=(Y c=="1w")?[c]:c;5 d=g.1q(c,i+1,g.w.7);4(d===B)1P;5 e=d.3G(0).O();4(!f[e])f[e]=[];5 b={H:d,w:c,M:g.1v&&g.1v(c)||d};f[e].1O(b);4(2w++<g.Z){f[""].1O(b)}};$.K(f,3(i,a){g.1j++;1h(i,a)})}1H(1f,25);3 18(){h={};j=0}6{18:18,1h:1h,1f:1f,2S:3(q){4(!g.1j||!j)6 14;4(!g.11&&g.1V){5 a=[];16(5 k 2G h){4(k.7>0){5 c=h[k];$.K(c,3(i,x){4(1a(x.H,q)){a.1O(x)}})}}6 a}A 4(h[q]){6 h[q]}A 4(g.1a){16(5 i=q.7-1;i>=g.22;i--){5 c=h[q.3F(0,i)];4(c){5 a=[];$.K(c,3(i,x){4(1a(x.H,q)){a[a.7]=x}});6 a}}}6 14}}};$.D.2Q=3(e,g,f,k){5 h={G:"3E"};5 j,y=-1,w,1m="",1M=C,F,z;3 2r(){4(!1M)6;F=$("<3D/>").U().P(e.2H).T("3C","3B").1J(2p.2n);z=$("<3z/>").1J(F).3y(3(a){4(V(a).2m&&V(a).2m.3w()==\'2l\'){y=$("1F",z).1e(h.G).3u(V(a));$(V(a)).P(h.G)}}).2i(3(a){$(V(a)).P(h.G);f();g.1G();6 B}).3t(3(){k.1z=C}).3s(3(){k.1z=B});4(e.E>0)F.T("E",e.E);1M=B}3 V(a){5 b=a.V;3r(b&&b.3q!="2l")b=b.3p;4(!b)6[];6 b}3 S(b){j.17(y,y+1).1e(h.G);2h(b);5 a=j.17(y,y+1).P(h.G);4(e.1x){5 c=0;j.17(0,y).K(3(){c+=I.1i});4((c+a[0].1i-z.1c())>z[0].3o){z.1c(c+a[0].1i-z.3n())}A 4(c<z.1c()){z.1c(c)}}};3 2h(a){y+=a;4(y<0){y=j.1b()-1}A 4(y>=j.1b()){y=0}}3 2g(a){6 e.Z&&e.Z<a?e.Z:a}3 2f(){z.2B();5 b=2g(w.7);16(5 i=0;i<b;i++){4(!w[i])1P;5 a=e.1K(w[i].w,i+1,b,w[i].H,1m);4(a===B)1P;5 c=$("<1F/>").3m(e.1t(a,1m)).P(i%2==0?"3l":"3k").1J(z)[0];$.w(c,"2c",w[i])}j=z.3j("1F");4(e.1S){j.17(0,1).P(h.G);y=0}4($.31.2b)z.2b()}6{2T:3(d,q){2r();w=d;1m=q;2f()},2u:3(){S(1)},2y:3(){S(-1)},2t:3(){4(y!=0&&y-8<0){S(-y)}A{S(-8)}},2s:3(){4(y!=j.1b()-1&&y+8>j.1b()){S(j.1b()-1-y)}A{S(8)}},U:3(){F&&F.U();j&&j.1e(h.G);y=-1},L:3(){6 F&&F.3i(":L")},3h:3(){6 I.L()&&(j.2a("."+h.G)[0]||e.1S&&j[0])},1W:3(){5 a=$(g).3g();F.T({E:Y e.E=="1w"||e.E>0?e.E:$(g).E(),2E:a.2E+g.1i,1Q:a.1Q}).1W();4(e.1x){z.1c(0);z.T({29:e.1s,3e:\'3d\'});4($.1T.3b&&Y 2p.2n.3T.29==="3a"){5 c=0;j.K(3(){c+=I.1i});5 b=c>e.1s;z.T(\'3V\',b?e.1s:c);4(!b){j.E(z.E()-28(j.T("32-1Q"))-28(j.T("32-39")))}}}},26:3(){5 a=j&&j.2a("."+h.G).1e(h.G);6 a&&a.7&&$.w(a[0],"2c")},2J:3(){z&&z.2B()},1u:3(){F&&F.37()}}};$.D.1N=3(b,a,c){4(b.2O){5 d=b.2O();d.36(C);d.35("2P",a);d.4c("2P",c);d.4b()}A 4(b.2Y){b.2Y(a,c)}A{4(b.2X){b.2X=a;b.4a=c}}b.1G()}})(49);',62,261,'|||function|if|var|return|length|||||||||||||||||||||||||data||active|list|else|false|true|Autocompleter|width|element|ACTIVE|value|this|val|each|visible|result|break|toLowerCase|addClass|case|multipleSeparator|moveSelect|css|hide|target|onChange|bind|typeof|max||url|autocomplete||null|trigger|for|slice|flush|multiple|matchSubset|size|scrollTop|preventDefault|removeClass|populate|trimWords|add|offsetHeight|cacheLength|lastWord|hideResultsNow|term|arguments|extend|trim|formatMatch|parse|scrollHeight|highlight|unbind|formatResult|string|scroll|search|mouseDownOnSelect|autoFill|stopLoading|matchCase|delay|new|li|focus|setTimeout|clearTimeout|appendTo|formatItem|defaults|needsInit|Selection|push|continue|left|request|selectFirst|browser|selectCurrent|matchContains|show|unautocomplete|setOptions|split|flushCache|loadingClass|minChars|findValueCallback|inputClass||selected||parseInt|maxHeight|filter|bgiframe|ac_data|COMMA|BACKSPACE|fillList|limitNumberOfItems|movePosition|click|PAGEUP|hideResults|LI|nodeName|body|PAGEDOWN|document|ESC|init|pageDown|pageUp|next|RETURN|nullData|TAB|prev|strong|gi|empty|replace|DEL|top|keyCode|in|resultsClass|DOWN|emptyList|form|opera|dataType|UP|createTextRange|character|Select|extraParams|load|display|mustMatch|receiveData|Cache|selectionStart|setSelectionRange|join|ol|fn|padding|||moveStart|collapse|remove||right|undefined|msie|off|auto|overflow|attr|offset|current|is|find|ac_odd|ac_even|html|innerHeight|clientHeight|parentNode|tagName|while|mouseup|mousedown|index|blur|toUpperCase|188|mouseover|ul|default|absolute|position|div|ac_over|substr|charAt|indexOf|180|RegExp|100|switch|400|keydown|ac_loading|ac_results|keypress|ac_input|submit|style|150|height|success|limit|name|port||abort|mode|ajax|Date|timestamp||200|substring|jQuery|selectionEnd|select|moveEnd'.split('|'),0,{}))


})(jQuery); //end alias

Tagging in TiddlyWiki is fun isn't it, but lets me honest it could be more fun. That's why I created niceTagging!
It makes tagging... well... nicer.

NiceTaggingPlugin takes out the complicated bits and even makes some suggestions for you.
So now no need to know TiddlyWiki tagging syntax. No longer being expected to know that to tag two words you have to create a tag {{{[two words]]}}} and if you want tags two words and three words you have to write {{{[[two words]] [[three words]] }}} rather than {{{two words, three words}}}.

Click edit and see for yourself.
or try it out here:
<<niceTagger>>

If you prefer you can allow users to use commas to separate tags eg. "Alice In Wonderland,Mad Hatter,rabbit" - just use {{{splitOn:,}}}
<<niceTagger splitOn:,>>

Usage:
*{{{<<niceTagger>>}}} creates a nice tagging interface with all the tags currently living in the TiddlyWiki document.
* If you want to exclude a tag simply use the exclude named parameter like so:
{{{<<niceTagger exclude:foo exclude:systemConfig>>}}}
*If you want to add your own suggested tags along with all the tags in the document you can create a tiddler called [[Suggestions]] and reference it from the macro like so: 
{{{<<niceTagger valuesSource:Suggestions>>}}}
* You can also use macros in the Suggestions tiddler as it will be wikified before generating suggestions. Try adding {{{<<message options txtUserName>>}}} to [[Suggestions]] on a new line.
<script>
  var out=[];
  var tids=store.getTiddlers('title','excludeLists');
  for (var t=0; t<tids.length; t++)
     if (tids[t].tags.length==0) out.push('[['+tids[t].title+']]');
  return out.join('\n');
</script> 
/***
|Name|''OpenHereMacro'' |h
|Author |[[Robert Pollard]] |
|Version |1.0 |
|Date|2009.08.26 - Wednesday, 26 August 2009 |
|Description |Creates an internal link that opens the tiddler immediately below the link, building on Eric Shulman's NestedSlidersPlugin  |
|Source |http://www.climatechange3.net/#OpenHereMacro |
|Requires |[[NestedSlidersPlugin]] - http://www.TiddlyTools.com/#NestedSlidersPlugin |
***/
/***
!!!Example
{{{<<oh "OpenHereMacro">>}}}
<<oh "OpenHereMacro">>
!!!Installation
Import (or copy/paste) this tiddler into your document: and tag it with "systemConfig"
!!!Note
This macro generates the following syntax:
<<<
{{{
+++[TiddlerName]
<<tiddler "TiddlerName">>

===
}}}
<<<
!!!Code
***/
//{{{
config.macros.oh = {};
config.macros.oh.handler= function(place,macroName,params) {
   var key=params[0];
   wikify('+++['+key+']\n\n<'+'<tiddler "'+key+'">'+'>\n\n===\n',place)
}
//}}}
<script label="Open My Tiddlers" show>
story.displayTiddlers(null,store.filterTiddlers(store.getTiddlerText("OpenListedTiddlers##YourList")));
</script>
!!!YourList
[tag[Reference]]
[[SandBox]]
[[DefaultTiddlers]] 
!!!End
<<tiddler OpenTiddlersByTag##script with: yourtag>>
/%
!script
<script label="OpenTiddlerByTheTag">
var msg=store.getTaggedTiddlers('$1');
var list=msg;
story.closeAllTiddlers();
story.displayTiddlers(msg,list);
</script>
!end
%/ 
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
<<option chkDisableTabsBar>> ~DisableTabsBar
<<option chkRandomTheme>> ~RandomTheme
----
Also see AdvancedOptions
Name: Orange2Black
HeaderTop: #fc3
HeaderMid: #f60
HeaderBottom: #000
Background: #fff
Foreground: #000
PrimaryPale: #ffa500
PrimaryLight: #F60
PrimaryMid: #000
PrimaryDark: #F60
SecondaryPale: #f90
SecondaryLight: #fc6
SecondaryMid: #F60
SecondaryDark: #000
TertiaryPale: #fff
TertiaryLight: #000
TertiaryMid: #ed9121
TertiaryDark: #F90
Error: #F60
Test: #F00
Name: OrangenBlack
HeaderTop: #ff0
HeaderMid: #f60
HeaderBottom: #000
Background: #fff
Foreground: #000
PrimaryPale: #ffa500
PrimaryLight: #F60
PrimaryMid: #000
PrimaryDark: #F60
SecondaryPale: #f90
SecondaryLight: #fc6
SecondaryMid: #F60
SecondaryDark: #000
TertiaryPale: #fff
TertiaryLight: #000
TertiaryMid: #ed9121
TertiaryDark: #F90
Error: #F60
Test: #F00
<script show>
(function($) {
config.macros.photoGallery.handler= function(place,macroName,params,wikifier,paramString,tiddler) {
  var i, args = paramString.parseParams(null,null,true);
  var url = getParam(args,"url",null);
  this.first = parseInt(getParam(args,"first",null));
  this.last = parseInt(getParam(args,"last",null));
  if(!url || !this.first || !this.last) return false;
  var height = getParam(args,"height",null);
  var width = getParam(args,"width",null);
  this.time = parseFloat(getParam(args,"time",0));
  this.labels = getParam(args,"labels",null);
  if(!store.tiddlerExists(this.labels)) this.labels = null;
  var argsArray = paramString.readMacroParams();
  this.numbers = ($.inArray('numbers',argsArray) > -1);
  var pictureHolder = document.createElement('CENTER');
  this.current = this.first;
  var pos = url.indexOf('*');
  var prefix = url.substring(0,pos);
  var postfix = url.substring(pos+1);
  var image;
  if(this.labels) this.labelsArray = store.getTiddlerText(this.labels).split("\n");
  for(i=this.first; i<=this.last; i++){
    image=pictureHolder.appendChild(document.createElement('IMG'));
    image.src = prefix+i+postfix;
    image.id = 'pgObject'+i;
    image.style.display='none';
    image.style.marginTop="0.5em";
    image.style.marginBottom="0.5em";
    if(height) image.height = height;
    if(width) image.width = width;
    place.appendChild(pictureHolder);
  }
  $('#pgObject'+this.current).toggle();
  var navBar = createTiddlyElement(pictureHolder,"DIV");
  navBar.style.marginBottom="0.5em";
  createTiddlyButton(navBar,"«","",this.firstImage);
  createTiddlyButton(navBar,"‹","",this.previousImage);
  if(this.time>0) {
    createTiddlyButton(navBar,"►",null,this.auto,null,"pgPlay");
  }
  createTiddlyButton(navBar,"›","",this.nextImage);
  createTiddlyButton(navBar,"»","",this.lastImage);
  if(this.labels) createTiddlyElement(pictureHolder,"DIV","pgLabel","",this.labelsArray[0]);
  if(this.numbers){
    this.nImages=this.last-this.first+1;
    createTiddlyElement(navBar,"SPAN","pgCounter","","1/"+this.nImages);
  }
}
})(jQuery)

</script>
/***
|''Name''|PaletteViewMacro|
|''Version''|0.2|
|''Author''|FND|
|''Source''|[[FND's DevPad|http://devpad.tiddlyspot.com/#PaletteViewMacro]]|
|''License''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|''~CoreVersion''|2.1|
|''Type''|macro|
|''Requires''|N/A|
|''Overrides''|N/A|
|''Description''|Displays color palettes.|
!Notes
There is also [[ViewPalettePlugin|http://simon.tiddlyspot.com/#ViewPalettePlugin]], which currently does not work with TiddlyWiki v2.2 though.
!Usage
{{{
<<paletteView [tiddler name]>>
}}}
!!Example
<<paletteView [[ColorPalette]]>>
!Revision History
!!v0.1 (2007-11-18)
* initial release
!!v0.2 (2007-11-20)
* limited processing to slices containing [[actual color values|http://www.w3.org/TR/CSS21/syndata.html#color-units]]
* changed fallback value to the tiddler the macro is called from (instead of using [[ColorPalette]])
!To Do
* selection list for all available palettes (tag-based)
* parameter for custom table class
* customizable column order
* documentation (e.g. using from within [[ViewTemplate]])
!Code
***/
//{{{
config.macros.paletteView = {};

config.macros.paletteView.handler = function(place, macroName, params, wikifier, paramString, tiddler) {
	var title = params[0] || tiddler.title;
	//var palettes = store.getTaggedTiddlers(params[0]); // DEBUG: yet to be implemented
	var colors = store.calcAllSlices(title);
	var labels = [];
	for(var c in colors) {
		if(this.isColor(colors[c])) {
			labels.push(c);
		}
	}
	if(labels.length > 0) {
		var output = "|!Sample|!Value|!Name|h\n";
		for(var i = 0; i < labels.length; i++) {
			output += "|padding:0 4em;background-color:" + colors[labels[i]] + ";&nbsp;|"
				+ "{{{" + colors[labels[i]] + "}}}|"
				+ "[[" + labels[i] + "|" + title + "]]|\n";
		}
		wikify(output, place);
	}
};

config.macros.paletteView.isColor = function(s) {
	var colors = ["Black", "Green", "Silver", "Lime", "Gray", "Olive", "White", "Yellow",
		"Maroon", "Navy", "Red", "Blue", "Purple", "Teal", "Fuchsia", "Aqua", "Orange"];
	var match = s.match(/^#[0-9A-F]{3}$|^#[0-9A-F]{6}$|^RGB\([\d,\s]{5,}\)$/i);
	if(match) return true;
	if(colors.contains(s)) return true;
	return false;
};
//}}}
/***
|<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>
***/
/***
|''Name:''|PhotoGalleryPlugin|
|''Description:''|A photo gallery with optional subtitles|
|''Author:''|Paulo Soares|
|''Version:''|1.1.0|
|''Date:''|2009-03-13|
|''Source:''|http://www.math.ist.utl.pt/~psoares/addons.html|
|''Documentation:''|Example: {{{<<photoGallery url:photos/lisboa-*.jpg first:1 last:4 height:200 time:2000 labels:SubTitles numbers>>}}}|
|''License:''|[[Creative Commons Attribution-Share Alike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|''~CoreVersion:''|2.5.0|
***/
//{{{
if(!version.extensions.photoGalleryPlugin) { //# ensure that the plugin is only installed once
version.extensions.photoGalleryPlugin = {installed: true};

(function($) {
config.macros.photoGallery = {};

config.macros.photoGallery.handler= function(place,macroName,params,wikifier,paramString,tiddler) {
  var i, args = paramString.parseParams(null,null,true);
  var url = getParam(args,"url",null);
  this.first = parseInt(getParam(args,"first",null));
  this.last = parseInt(getParam(args,"last",null));
  if(!url || !this.first || !this.last) return false;
  var height = getParam(args,"height",null);
  var width = getParam(args,"width",null);
  this.time = parseFloat(getParam(args,"time",0));
  this.labels = getParam(args,"labels",null);
  if(!store.tiddlerExists(this.labels)) this.labels = null;
  var argsArray = paramString.readMacroParams();
  this.numbers = ($.inArray('numbers',argsArray) > -1);
  var pictureHolder = document.createElement('CENTER');
  this.current = this.first;
  var pos = url.indexOf('*');
  var prefix = url.substring(0,pos);
  var postfix = url.substring(pos+1);
  var image;
  if(this.labels) this.labelsArray = store.getTiddlerText(this.labels).split("\n");
  for(i=this.first; i<=this.last; i++){
    image=pictureHolder.appendChild(document.createElement('IMG'));
    image.src = prefix+i+postfix;
    image.id = 'pgObject'+i;
    image.style.display='none';
    image.style.marginTop="0.5em";
    image.style.marginBottom="0.5em";
    if(height) image.height = height;
    if(width) image.width = width;
    place.appendChild(pictureHolder);
  }
  $('#pgObject'+this.current).toggle();
  var navBar = createTiddlyElement(pictureHolder,"DIV");
  navBar.style.marginBottom="0.5em";
  createTiddlyButton(navBar,"«","",this.firstImage);
  createTiddlyButton(navBar,"‹","",this.previousImage);
  if(this.time>0) {
    createTiddlyButton(navBar,"►",null,this.auto,null,"pgPlay");
  }
  createTiddlyButton(navBar,"›","",this.nextImage);
  createTiddlyButton(navBar,"»","",this.lastImage);
  if(this.labels) createTiddlyElement(pictureHolder,"DIV","pgLabel","",this.labelsArray[0]);
  if(this.numbers){
    this.nImages=this.last-this.first+1;
    createTiddlyElement(navBar,"SPAN","pgCounter","","1/"+this.nImages);
  }
}

config.macros.photoGallery.auto = function() {
  var cm = config.macros.photoGallery;
  if(this.autoAdvance) {
    clearInterval(this.autoAdvance);
    this.autoAdvance = null;
    $("#pgPlay").text('►');
  } else {
    if(cm.time>0) {
      this.autoAdvance = setInterval(config.macros.photoGallery.nextImage, cm.time);
      $("#pgPlay").text('▣');
    }
  }
}

config.macros.photoGallery.jump = function(step) {
  var target;
  switch (step) {
  case "f":
    target=this.first;
    break;
  case "l":
    target=this.last;
    break;
  case "n":
    target = ((this.current+1)>this.last) ? this.first : this.current+1; 
    break;
  case "p":
    target = ((this.current-1)<this.first) ? this.last : this.current-1; 
  }
  $('#pgObject'+this.current).toggle();
  this.current = target;
  $('#pgObject'+this.current).toggle();
  if(this.numbers) $("#pgCounter").text((target-this.first+1) + '/'+ this.nImages);
  if(this.labels) $("#pgLabel").text(this.labelsArray[target-this.first]);
}

config.macros.photoGallery.nextImage = function(){config.macros.photoGallery.jump('n');}
config.macros.photoGallery.previousImage = function(){config.macros.photoGallery.jump('p');}
config.macros.photoGallery.lastImage = function(){config.macros.photoGallery.jump('l');}
config.macros.photoGallery.firstImage = function(){config.macros.photoGallery.jump('f');}
})(jQuery)
}
//}}}
/***
Last Revision 12.04.08
***/
/***
!~TagCloud Styles
***/
/*{{{*/
/*tagCloud Styles*/
.tagCloud span{height: 3.5em; margin: 20px; padding: 20px; width: 250px;}
.tagCloud1{font-size: 120%; font-weight: bold; padding: 10px; color: brown;}
.tagCloud2{font-size: 160%; font-weight: bold; padding: 10px; color: orange;}
.tagCloud3{font-size: 200%; font-weight: bold; padding: 10px; color: purple;}
.tagCloud4{font-size: 240%; font-weight: bold; padding: 10px; color: green;}
.tagCloud5{font-size: 280%; font-weight: bold; padding: 10px; color: blue;}
.tagCloud6{font-size: 320%; font-weight: bold; padding: 10px; color: red;}
/*}}}*/

/***
!Table Sorting Style
***/
/*{{{*/
table.sortable td.sortedCol {background: [[ColorPalette::HeaderMid]];}
/*}}}*/

/***
!Encryption Password Box Style
***/
/*{{{*/
#passwordPromptBox {background-color: [[ColorPalette::Background]];}
/*}}}*/

/***
!Tagger Styles
***/
/*{{{*/
.popup {
	background: [[ColorPalette::SecondaryPale]];
	border: 1px solid #ccc;
	font-size: 80%;
	font-family: 'Trebuchet MS' sans-serif;
}
#nestedtagger {
	background: [[ColorPalette::Background]];
	border: 1px solid #ccc;
	font-size: 80%;
	font-family: 'Trebuchet MS' sans-serif;
}
/*}}}*/

/***
!Calendar Styles
***/
/*{{{*/
.calendar {
	background:#999;
	color: black;
}
.calendar a {
	color: #000;
}
/*}}}*/

/***
!Center Table Style
***/
/*{{{*/
.viewer div.centeredTable {
	text-align: center;
}
.viewer div.centeredTable table {
	margin: 0 auto;
	text-align: left;
}
/*}}}*/

/***
!Hover Menu Style
***/
/*{{{*/
#hoverMenu .button, #hoverMenu .tiddlyLink {
	border:none;
	font-weight:bold;
	background:#fff;
	color:#000;
	padding:0 5px;	
	float:right;
	margin-bottom:4px;
}
#hoverMenu .button:hover, #hoverMenu .tiddlyLink:hover {
	font-weight:bold;
	border:none; color:ffff;
	background:#000;
	padding:0 5px;
	float:right;
}
/* Modify Tiddler margin/paddin to fit Hover Menu better */
.tiddler {
	margin-bottom:4px;
	margin-bottom: 1em;
	padding-bottom: 1em;
	padding-top: 0.75em;
	margin-left: 1em;
	margin-right: 1em;
}
/*}}}*/

/***
!Header & Footer Div Style
***/
/*{{{*/
.hD {
	-moz-border-radius: 1em;
	align: center;
	text-align: center;
	background: [[ColorPalette::Background]];
	border-right: 2px [[ColorPalette::TertiaryMid]] solid;
	border-bottom: 2px [[ColorPalette::TertiaryMid]] solid;
	margin-left: 1em;
	margin-right: 1em;
	margin-top: 1em;
	margin-bottom: 1em;
}
.fD {
	-moz-border-radius: 1em;
	align: center;
	text-align: center;
	background: [[ColorPalette::Background]];
	border-right: 2px [[ColorPalette::TertiaryMid]] solid;
	border-bottom: 2px [[ColorPalette::TertiaryMid]] solid;
	color: [[ColorPalette::Foreground]];
	margin-left: 1em;
	margin-right: 1em;
	margin-top: 1em;
	margin-bottom: 1em;
}
/*}}}*/

/***
!QuickEdit Menu Style
***/
/*{{{*/
.quickEdit a:hover {
	color: #a00;
	background: #fff;
}
/*}}}*/

/***
!
***/
/*{{{*/

/*}}}*/
Only works if QuickOpenTagPlugin is disabled.

{{{<<tag systemConfig Plugins System+Config>>}}}
<<tag systemConfig Plugins System+Config>>

Only works if QuickOpenTagPlugin is enabled.
{{{<<tag Plugins|systemConfig>>}}}
<<tag Plugins|systemConfig>>
/***
|Name:|PrettyDatesPlugin|
|Description:|Provides a new date format ('pppp') that displays times such as '2 days ago'|
|Version:|1.0 ($Rev: 3646 $)|
|Date:|$Date: 2008-02-27 02:34:38 +1000 (Wed, 27 Feb 2008) $|
|Source:|http://mptw.tiddlyspot.com/#PrettyDatesPlugin|
|Author:|Simon Baird <simon.baird@gmail.com>|
|License:|http://mptw.tiddlyspot.com/#TheBSDLicense|
!!Notes
* If you want to you can rename this plugin. :) Some suggestions: LastUpdatedPlugin, RelativeDatesPlugin, SmartDatesPlugin, SexyDatesPlugin.
* Inspired by http://ejohn.org/files/pretty.js
***/
//{{{
Date.prototype.prettyDate = function() {
	var diff = (((new Date()).getTime() - this.getTime()) / 1000);
	var day_diff = Math.floor(diff / 86400);

	if (isNaN(day_diff))      return "";
	else if (diff < 0)        return "in the future";
	else if (diff < 60)       return "just now";
	else if (diff < 120)      return "1 minute ago";
	else if (diff < 3600)     return Math.floor(diff/60) + " minutes ago";
	else if (diff < 7200)     return "1 hour ago";
	else if (diff < 86400)    return Math.floor(diff/3600) + " hours ago";
	else if (day_diff == 1)   return "Yesterday";
	else if (day_diff < 7)    return day_diff + " days ago";
	else if (day_diff < 14)   return  "a week ago";
	else if (day_diff < 31)   return Math.ceil(day_diff/7) + " weeks ago";
	else if (day_diff < 62)   return "a month ago";
	else if (day_diff < 365)  return "about " + Math.ceil(day_diff/31) + " months ago";
	else if (day_diff < 730)  return "a year ago";
	else                      return Math.ceil(day_diff/365) + " years ago";
}

Date.prototype.formatString_orig_mptw = Date.prototype.formatString;

Date.prototype.formatString = function(template) {
	return this.formatString_orig_mptw(template).replace(/pppp/,this.prettyDate());
}

// for MPTW. otherwise edit your ViewTemplate as required.
// config.mptwDateFormat = 'pppp (DD/MM/YY)'; 
config.mptwDateFormat = 'pppp'; 

//}}}
{{center{<script>

var now = new Date();
// Change Date inside ( ) to desired date and time of event / countdown
var FutureDate = new Date('November 15, 2008 6:00:00 pm');
var diff=FutureDate-now;
// date is still good
if(diff < 0)
{
document.write(" I am Home !! !! !! )"+ "<br>");
}
// date is still good
else{
var milliseconds=Math.floor(diff % 1000);   
    diff=diff/1000;            
var seconds=Math.floor(diff % 60);
    diff=diff/60;
var minutes=Math.floor(diff % 60);
    diff=diff/60;
var hours=Math.floor(diff % 24);
    diff=diff/24;
var days=Math.floor(diff);
//Below for Troubleshooting
//document.write((FutureDate)+ " Future"+ "<br>");
//document.write((now)+ " Today"+ "<br>");
//document.write((diff)+" = diff comment out"+ "<br>")
//build a display string
document.write("<br>" + "Countdown Untill I am Home: " + days + " Day(s) " + hours + " Hour(s) " + minutes + " Minute(s) " + seconds + " Second(s) " + "<br>");
}
</script>}}}

This package provides a toolbar of interactive 'power tools' that you can use while editing a tiddler to quickly insert TiddlyWiki tiddler links, images, macros, etc. or common formatting sequences directly into tiddler content, as well as perform other functions (such as find/replace, sort, split, convert, etc.) that can be used to modify the current tiddler's source content in a variety of ways.

<<tiddler QuickEditToolbar with: show>>
!!!!!Installation:
<<<
Individual ~QuickEdit buttons are defined in separate tiddlers (e.g., [[QuickEdit_replace]]) that have also been //transcluded// into a single toolbar definition named [[QuickEditToolbar]].  You can edit this definition to add, remove, or rearrange the toolbar buttons to best suit your needs, and then embed the [[QuickEditToolbar]] tiddler into your document's [[EditTemplate]], like this:
{{{
<div macro='tiddler QuickEditToolbar'></div>
}}}
Next, in order to support some of the formatting 'shortcuts' provided by the toolbar, add a reference to the shortcuts CSS class definitions in your [[StyleSheet]]:
{{{
[[StyleSheetShortcuts]]
}}}
By default, the QuickEdit toolbar is hidden until you enable it by using the ''toggleQuickEdit'' command, which you can add to the ~EditToolbar definition in [[ToolbarCommands]]:
{{{
|EditToolbar|... toggleQuickEdit ...|
}}}
You can also toggle the ~QuickEdit toolbar display via a single checkbox option that can be added to [[SideBarOptions]] (or any other desired location):
{{{
<<option chkShowQuickEdit>> show QuickEdit toolbar
}}}
Note: You can 'hard-code' the ''chkShowQuickEdit'' setting, so that the toolbar will be //initially// displayed, by creating a tiddler (e.g., ConfigTweaks), tagged with <<tag systemConfig>>, containing:
{{{
config.options.chkShowQuickEdit=true;
}}}
Alternatively, if you want the toolbar to //always// be displayed, regardless of the option setting, you can add a special keyword, ''show'', to the [[EditTemplate]] syntax, like this:
{{{
<div macro='tiddler QuickEditToolbar with: show'></div>
}}}
<<<
/***
|Name|QuickEditPlugin|
|Source|http://www.TiddlyTools.com/#QuickEditPlugin|
|Documentation|http://www.TiddlyTools.com/#QuickEditPlugin|
|Version|2.4.3|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Description|Support functions for ~QuickEdit package: styles, utility functions, and 'toggleQuickEdit' command|
!!!!!Revisions
<<<
2009.06.11 [2.4.3] added keyup() function to abbreviate listbox handling for CR and ESC
2009.05.07 [2.4.2] added processed() function to abbreviate event handler code
2008.09.07 [2.4.1] added removeCookie() function for compatibility with [[CookieManagerPlugin]]
2008.05.17 [2.4.0] copied code from StickyPopupPlugin to remove dependency
2008.05.12 [2.3.0] added "toggleQuickEdit" command handler (replaces inline script command)
2008.01.11 [2.2.0] converted from inline script
2007.03.29 [1.0.0] initial release (as inline script)
<<<
!!!!!Code
***/
//{{{
version.extensions.QuickEditPlugin= {major: 2, minor: 4, revision: 3, date: new Date(2009,6,11)};

// SET STYLESHEET
setStylesheet("\
.quickEdit a { border:2px outset ButtonFace; padding:0px 3px !important; \
	-moz-border-radius:.5em; -webkit-border-radius:.5em; \
	-moz-appearance:button !important; -webkit-appearance:push-button !important; \
	background-color:ButtonFace; color:ButtonText !important;  \
	line-height:200%; font-weight:normal; } \
.quickEdit a:hover { border: 2px inset ButtonFace; background-color:ButtonFace; }\
", "quickEditStyles");

// REMOVE COOKIE
if (window.removeCookie===undefined) {
	window.removeCookie=function(name) {
		document.cookie = name+'=; expires=Thu, 01-Jan-1970 00:00:01 UTC; path=/;'; 
	}
}

// UTILITY FUNCTIONS
config.quickEdit = {
	processed: function(ev) { ev=ev||window.event;
		ev.cancelBubble=true;
		if(ev.stopPropagation) ev.stopPropagation();
		return false;
	},
	keyup: function(ev){ var k=(ev||window.event).keyCode;
		if (k==13) this.onclick();
		if (k==27) Popup.remove();
	},
	getField: function(where) {
		var here=story.findContainingTiddler(where); if (!here) return null;
		var e=story.getTiddlerField(here.getAttribute("tiddler"),"text");
		if (e&&e.getAttribute("edit")=="text") return e;
		return null;
	},
	setSelection: function(where,newtext) {
		var e=this.getField(where); if (!e) return false;
		e.focus(); replaceSelection(e,newtext);
		return false;
	},
	wrapSelection: function(where,before,after) {
		var e=this.getField(where); if (!e) return false;
		e.focus(); replaceSelection(e,before+config.quickEdit.getSelection(e)+after);
		return false;
	},
	getSelection: function(e) {
		var seltext="";
		if (e&&e.setSelectionRange)
			seltext=e.value.substr(e.selectionStart,e.selectionEnd-e.selectionStart);
		else if (document.selection) {
			var range = document.selection.createRange();
			if (range.parentElement()==e) seltext=range.text
		}
		return seltext;
	},
	promptForFilename: function(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.modeOpen);
				var thispath = Components.classes['@mozilla.org/file/local;1'].createInstance(Components.interfaces.nsILocalFile);
				thispath.initWithPath(path);
				picker.displayDirectory=thispath;
				picker.defaultExtension='jpg';
				picker.defaultString=file;
				picker.appendFilters(nsIFilePicker.filterAll|nsIFilePicker.filterImages);
				if (picker.show()!=nsIFilePicker.returnCancel)
					var result="file:///"+picker.file.persistentDescriptor.replace(/\\/g,'/');
			}
			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|*.*|JPG files|*.jpg|GIF files|*.gif|PNG files|*.png|';
				s.FilterIndex=1; // default to JPG
				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;
	}
}
//}}}

//{{{
if (config.options.chkShowQuickEdit===undefined) config.options.chkShowQuickEdit=false;
config.commands.toggleQuickEdit = {
	hideReadOnly: true,
	getText: function() { return config.options.chkShowQuickEdit?'\u221Aquickedit':'quickedit'; },

	tooltip: 'show QuickEdit toolbar buttons',
	handler: function(event,src,title) {
		var opt='chkShowQuickEdit';
		config.options[opt]=!config.options[opt];
		config.macros.option.propagateOption(opt,"checked", config.options[opt],"input");
		if (config.options[opt]) saveOptionCookie(opt);	else removeCookie(opt);
		src.innerHTML=config.commands.toggleQuickEdit.getText();
		story.forEachTiddler(function(t,e){if (story.isDirty(t)) refreshElements(e);});
		return false;
	}
};
//}}}

// // COPIED FROM [[StickyPopupPlugin]] TO ELIMINATE PLUGIN DEPENDENCY
//{{{
if (config.options.chkStickyPopups==undefined) config.options.chkStickyPopups=false;
Popup.stickyPopup_onDocumentClick = function(ev)
{
	// if click is in a sticky popup, ignore it so popup will remain visible
	var e = ev ? ev : window.event; var target = resolveTarget(e);
	var p=target; while (p) {
		if (hasClass(p,"popup") && (hasClass(p,"sticky")||config.options.chkStickyPopups)) break;
		else p=p.parentNode;
	}
	if (!p) // not in sticky popup (or sticky popups disabled)... use normal click handling
		Popup.onDocumentClick(ev);
	return true;
};
try{removeEvent(document,"click",Popup.onDocumentClick);}catch(e){};
try{addEvent(document,"click",Popup.stickyPopup_onDocumentClick);}catch(e){};
//}}}
<!--{{{-->
<!--- http://mptw.tiddlyspot.com/#MptwEditTemplate ($Rev: 1829 $) --->
<!--- moved toolbar to ToolbarCommands MTP 10.23.08 --->
<div class='toolbar' macro='toolbar [[ToolbarCommands::EditToolbar]]'></div>
<div class="title" macro="view title"></div>
<div class="editLabel">Title</div><div class="editor" macro="edit title"></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>
<div macro='tiddler QuickEditToolbar'></div>
<div macro="showWhenExists EditPanelTemplate">[[EditPanelTemplate]]</div>
<div class="editor" macro="edit text"></div>
<!--}}}-->
/%
|Name|QuickEditToolbar|
|Source|http://www.TiddlyTools.com/#QuickEditToolbar|
|Version|2.4.3|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.2|
|Type|transclusion|
|Requires|QuickEditPlugin|
|Optional|QuickEdit_*|
|Description|format/insert TiddlyWiki content using toolbar buttons|

Usage:
* install [[QuickEditPlugin]] (runtime support functions)

* add the toolbar to [[EditTemplate]]:
	<div macro='tiddler QuickEditToolbar with: show'></div>

* 'show' (optional) forces the toolbar to always be displayed or,
  omit keyword and use <<option chkShowQuickEdit>> setting

* selected QuickEdit buttons can also be added individually to the
  regular tiddler toolbar by adding references directly in [[EditTemplate]]:
	<span class='toolbar' macro='tiddler QuickEdit_...'></span>

* see [[QuickEditPackage]] for additional installation options

%/{{hidden fine center quickEdit{
<<tiddler {{ // show/hide toolbar
	var here=story.findContainingTiddler(place); if (here) var tid=here.getAttribute('tiddler');
	var show='$1'!='$'+'1'||config.options.chkShowQuickEdit||tid=='QuickEditToolbar'; 
	place.style.display=show?'block':'none';
'';}}>>/%

TOOLBAR DEFINITION - add, remove, or re-order items as desired:
= = = = = = = = = =
%/<<tiddler QuickEdit_replace>>/%
%/<<tiddler QuickEdit_split>>/%
%/<<tiddler QuickEdit_sort>>/%
%/<<tiddler QuickEdit_convert>>/%
%/ &nbsp;/% (SPACER)
%/<<tiddler QuickEdit_link>>/%
%/<<tiddler QuickEdit_insert>>/%
%/<<tiddler QuickEdit_macro>>/%
%/<<tiddler QuickEdit_image>>/%
%/ &nbsp;/% (SPACER)
%/<<tiddler QuickEdit_format>>/%
%/<<tiddler QuickEdit_align>>/%
%/<<tiddler QuickEdit_color>>/%
%/<<tiddler QuickEdit_font>>/%
%/ &nbsp;/% (SPACER)
%/<<tiddler QuickEdit_custom>>/%
%/}}}
/%
|Name|QuickEdit_align|
|Source|http://www.TiddlyTools.com/#QuickEdit_align|
|Version|2.4.3|
|Author|Eric Shulman|
|License|see http://www.TiddlyTools.com/#QuickEditPlugin|
|Type|html|
|Requires|QuickEditPlugin|
|Description|quickedit - text alignment|

Usage: see  http://www.TiddlyTools.com/#QuickEditToolbar

%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink" tabindex="-1" 
title="align text"
onclick="var p=Popup.create(this); if (!p) return false; p.className+=' sticky smallform';
	var s=createTiddlyElement(p,'select'); s.button=this;
	s.options[0]=new Option('select text alignment...','');
	s.options[s.length]=new Option('left','left');
	s.options[s.length-1].title='{{left{...}}}';
	s.options[s.length]=new Option('center','center');
	s.options[s.length-1].title='{{center{...}}}';
	s.options[s.length]=new Option('right','right');
	s.options[s.length-1].title='{{right{...}}}';
	s.options[s.length]=new Option('justify','justify');
	s.options[s.length-1].title='{{justify{...}}}';
	s.options[s.length]=new Option('float left','floatleft');
	s.options[s.length-1].title='{{floatleft{...}}}';
	s.options[s.length]=new Option('float right','floatright');
	s.options[s.length-1].title='{{floatright{...}}}';
	s.size=s.length;
	s.onclick=function(){ if (!this.value.length) return;
		config.quickEdit.wrapSelection(this.button,'{{'+this.value+'{','}}}');
		Popup.remove(); return false;
	};
	s.onkeyup=config.quickEdit.keyup;
	Popup.show();
	s.focus();
	return config.quickEdit.processed(event);"
>align</a></html>
/%
|Name|QuickEdit_color|
|Source|http://www.TiddlyTools.com/#QuickEdit_color|
|Version|2.4.3|
|Author|Eric Shulman|
|License|see http://www.TiddlyTools.com/#QuickEditPlugin|
|Type|html|
|Requires|QuickEditPlugin|
|Description|quickedit - text/background color|

Usage: see  http://www.TiddlyTools.com/#QuickEditToolbar

%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink" tabindex="-1" 
title="text/background color - @@color:#RGB;background-color:#RGB;...@@"
onclick="var p=Popup.create(this,null,'popup sticky smallform'); if (!p) return false;
 	p.style.padding='2px';
	function hex(d) { return '0123456789ABCDEF'.substr(d,1); }
	var fg=createTiddlyElement(p,'select'); fg.button=this;
	fg.style.width='12em';
	fg.options[0]=new Option('text color...','');
	fg.options[1]=new Option('\xa0 or enter a value','_ask');
	fg.options[2]=new Option('\xa0 or use default color','');
	for (var r=0;r<16;r+=3) for (var g=0;g<16;g+=3) for (var b=0;b<16;b+=3) {
		var label=hex(r)+hex(g)+hex(b);
		fg.options[fg.length]=new Option(label,'#'+label);
		fg.options[fg.length-1].style.color='#'+label;
	}
	fg.onchange=function(){ var val=this.value;
		if (val=='_ask') { val=prompt('Enter a CSS color value');
		if (!val||!val.length) return false; }
		this.options[0].value=val; this.options[0].text=val.length?'text: '+val:'text color...';
		var bg=this.nextSibling;
		for (var i=3;i<bg.options.length;i++) bg.options[i].style.color=val;
		var preview=this.nextSibling.nextSibling.nextSibling;
		var t=config.quickEdit.getSelection(config.quickEdit.getField(this.button));
		t=t.replace(/^@@(color\:.+;)?(background-color\:.+;)?/,'').replace(/@@$/,'');
		if (!t.length) t='~AaBbCcDdEeFfGgHhIiJj 1234567890';
		var fg=this.value; if (fg.length) fg='color:'+fg+';';
		var bg=this.nextSibling.value; if (bg.length) bg='background-color:'+bg+';';
		if (fg.length||bg.length) t='@@'+fg+bg+t+'@@';
		removeChildren(preview); wikify(t,preview);
		this.selectedIndex=0; return false;
	};
	var bg=createTiddlyElement(p,'select'); bg.button=this;
	bg.style.width='12em';
	bg.options[0]=new Option('background color...','');
	bg.options[1]=new Option('\xa0 or enter a value','_ask');
	bg.options[2]=new Option('\xa0 or use default color','');
	for (var r=0;r<16;r+=3) for (var g=0;g<16;g+=3) for (var b=0;b<16;b+=3) {
		var label=hex(15-r)+hex(15-g)+hex(15-b);
		bg.options[bg.length]=new Option(label,'#'+label);
		bg.options[bg.length-1].style.backgroundColor='#'+label;
	}
	bg.onchange=function(){ var val=this.value;
		if (val=='_ask') { val=prompt('Enter a CSS color value');
		if (!val||!val.length) return false; }
		this.options[0].value=val;
		this.options[0].text=val.length?'background: '+val:'background color...';
		var fg=this.previousSibling;
		for (var i=3;i<fg.options.length;i++) fg.options[i].style.backgroundColor=val;
		var preview=this.nextSibling.nextSibling;
		var t=config.quickEdit.getSelection(config.quickEdit.getField(this.button));
		t=t.replace(/^@@(color\:.+;)?(background-color\:.+;)?/,'').replace(/@@$/,'');
		if (!t.length) t='~AaBbCcDdEeFfGgHhIiJj 1234567890';
		var fg=this.previousSibling.value; if (fg.length) fg='color:'+fg+';';
		var bg=this.value; if (bg.length) bg='background-color:'+bg+';';
		if (fg.length||bg.length) t='@@'+fg+bg+t+'@@';
		removeChildren(preview); wikify(t,preview);
		this.selectedIndex=0; return false;
	};
	var b=createTiddlyElement(p,'input',null,null,null,{type:'button'}); b.button=this;
	b.value='ok'; b.style.width='4em';
	b.onclick=function() {
		var fg=this.previousSibling.previousSibling.value; if (fg.length) fg='color:'+fg+';';
		var bg=this.previousSibling.value; if (bg.length) bg='background-color:'+bg+';';
		var t=config.quickEdit.getSelection(config.quickEdit.getField(this.button));
		t=t.replace(/^@@(color\:.+;)?(background-color\:.+;)?/,'').replace(/@@$/,'');
		if (fg.length||bg.length) config.quickEdit.setSelection(this.button,'@@'+fg+bg+t+'@@');
		Popup.remove(); return false;
	};
	var preview=createTiddlyElement(p,'div',null,'viewer'); var s=preview.style;
	s.border='1px solid'; s.margin='2px'; s.width='24em'; s.padding='3px'; s.MozBorderRadius='3px';
	s.overflow='hidden'; s.textAlign='center'; s.whiteSpace='normal';
	var t=config.quickEdit.getSelection(config.quickEdit.getField(this));
	wikify(t.length?t:'~AaBbCcDdEeFfGgHhIiJj 1234567890',preview);
	Popup.show();
	event.cancelBubble=true;if(event.stopPropagation)event.stopPropagation();return false;"
>color</a></html>
/%
|Name|QuickEdit_convert|
|Source|http://www.TiddlyTools.com/#QuickEdit_convert|
|Version|2.4.3|
|Author|Eric Shulman|
|License|see http://www.TiddlyTools.com/#QuickEditPlugin|
|Type|html|
|Requires|QuickEditPlugin|
|Description|quickedit - convert between comma/tab-separated and TW table format|

Usage: see  http://www.TiddlyTools.com/#QuickEditToolbar

%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink" tabindex="-1" 
title="convert between comma/tab-separated and TW table format"
onclick="var e=config.quickEdit.getField(this);
	if (e) e.focus(); var txt=config.quickEdit.getSelection(e);
	if (txt.indexOf(',')+txt.indexOf('\t')+txt.indexOf('|')==-3) {
		alert('Please select text containing tabs, commas, or TiddlyWiki table syntax.');
		return false;
	}
	var p=Popup.create(this); if (!p) return false; p.className+=' sticky smallform';
	var s=createTiddlyElement(p,'select'); s.button=this;
	s.options[0]=new Option('select a converter...','');
	if (txt.indexOf(',')!=-1) {
		s.options[s.length]=new Option('commas -> table','commasToTable');
		s.options[s.length]=new Option('commas -> tabs','commasToTabs');
	}
	if (txt.indexOf('\t')!=-1) {
		s.options[s.length]=new Option('tabs -> table','tabsToTable');
		s.options[s.length]=new Option('tabs -> commas','tabsToCommas');
	}
	if (txt.indexOf('|')!=-1) {
		s.options[s.length]=new Option('table -> tabs','tableToTabs');
		s.options[s.length]=new Option('table -> commas','tableToCommas');
	}
	s.size=s.length;
	s.onclick=function(){ if (!this.value.length) return;
	        var e=config.quickEdit.getField(this.button); if (!e) return false;
		e.focus(); var txt=config.quickEdit.getSelection(e);
		switch(this.value) {
			case 'tabsToTable':
				txt=txt.replace(/\t/g,'|').replace(/^|$/g,'|');
				txt=txt.replace(/\n/g,'|\n|').replace(/^\|$/g,'');
				break;
			case 'tableToTabs':
				txt=txt.replace(/\t/g,' ').replace(/\|/g,'\t');
				txt=txt.replace(/^\t/g,'').replace(/\t$/g,'');
				txt=txt.replace(/\n\t/g,'\n').replace(/\t\n/g,'\n');
				break;
			case 'commasToTable':
				txt=txt.replace(/,/g,'|').replace(/^|$/g,'|');
				txt=txt.replace(/\n/g,'|\n|').replace(/^\|$/g,''); 
				break;
			case 'tableToCommas':
				txt=txt.replace(/,/g,' ').replace(/\|/g,',');
				txt=txt.replace(/^,/g,'').replace(/,$/g,''); 
				txt=txt.replace(/\n,/g,'\n').replace(/,\n/g,'\n'); 
				break;
			case 'tabsToCommas':
				txt=txt.replace(/\t/g,',');
				break;
			case 'commasToTabs':
				txt=txt.replace(/,/g,'\t');
				break;
		}
		replaceSelection(e,txt);
		Popup.remove(); return false;
	};
	s.onkeyup=config.quickEdit.keyup;
	Popup.show();
	s.focus();
	return config.quickEdit.processed(event);"
>convert</a></html>
/%
|Name|QuickEdit_css|
|Source|http://www.TiddlyTools.com/#QuickEdit_css|
|Version|2.2.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.2|
|Type|script|
|Requires|QuickEditPlugin|
|Overrides||
|Description|definition for toolbar button for inline css and css class wrappers|

Usage:
QuickEditToolbar: <<tiddler QuickEdit_css>>
OR
EditTemplate: <span class='toolbar' macro='tiddler QuickEdit_css'></span>

%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink"
	title="inline CSS styles - @@attr:value;attr:value;...@@"
	onclick="var css=prompt('Enter CSS attribute/value pairs (attr:val;attr:val;...;)','');
		if (!css) return false; /* cancelled by user */
		return config.quickEdit.wrapSelection(this,'@@'+css+';','@@');"
>style</a></html>/%

%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink"
	title="CSS class wrapper - {{classname classname etc{...}}}"
	onclick="var c=prompt('Enter a CSS classname','');
		if (!c) return false; /* cancelled by user */
		return config.quickEdit.wrapSelection(this,'{{'+c+'{','}}}');"
>class</a></html>
/%
|Name|QuickEdit_custom|
|Source|http://www.TiddlyTools.com/#QuickEdit_custom|
|Version|2.4.3|
|Author|Eric Shulman|
|License|see http://www.TiddlyTools.com/#QuickEditPlugin|
|Type|html|
|Requires|QuickEditPlugin|
|Description|quickedit - custom defined formats|

Usage: see  http://www.TiddlyTools.com/#QuickEditToolbar

!help
Reminders:

Custom formats are stored as an "HR-separated list" in [[QuickEdit_customList]], where the first line of each list item is the text 'label' to show in the droplist, followed by one or more lines of wiki content to be inserted into the tiddler source.

Substitution markers can be used to dynamically insert values into the formatted output: $1 inserts the tiddler editor's current selected text. $[[message|default value]] interactively prompts for a value to be inserted. $[[message|$1]] uses the selected text as the default value. $[[message|{{javascript}}]] calculates the default value using javascript code.
!end help

%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink" tabindex="-1" title="custom defined formats"
onclick="var p=Popup.create(this); if (!p) return false; p.className+=' sticky smallform';
	var s=createTiddlyElement(p,'select'); s.button=this;
	s.options[0]=new Option('select a custom format...','');
	var items=store.getTiddlerText('QuickEdit_customList','').split('\n----\n');
	for (var i=0; i<items.length; i++) {
		if (!items[i].length) continue; var lines=items[i].split('\n');
		var label=lines.shift(); var val=lines.join('\n');
		s.options[s.length]=new Option(label,val); s.options[s.length-1].title=val;
	}
	s.options[s.length]=new Option('[Edit custom formats...]','_edit');
	s.options[s.length-1].title='add/change custom format definitions...';
	s.size=Math.min(s.length,15);
	s.onclick=function(){ if (!this.value.length) return;
		if (this.value=='_edit') {
			alert(store.getTiddlerText('QuickEdit_custom##help'));
			story.displayTiddler(story.findContainingTiddler(this.button),
				'QuickEdit_customList',DEFAULT_EDIT_TEMPLATE);
		} else {
		        var e=config.quickEdit.getField(this.button); if (!e) return false;
			e.focus(); var txt=config.quickEdit.getSelection(e);
			replaceSelection(e, this.value.replace(/\$\x31/g,txt)
				.replace(/\$\[\[[^\]]+\]\]/g, function(t){
					x=t.substr(3,t.length-5).split('|');
					var msg=x[0]; var def=x[1]||'';
					if (def.startsWith('{{')) {
						try{def=eval(def.substr(2,def.length-4))} catch(ex){showException(ex)}
					}
					return prompt(msg,def)||'';
				})
			);
		}
		Popup.remove(); return false;
	};
	s.onkeyup=config.quickEdit.keyup;
	Popup.show();
	s.focus();
	return config.quickEdit.processed(event);"
>custom</a></html>
timestamp
$[[enter a date|{{new Date().formatString('DDD, MMM DDth, YYYY hh12:0mm:0ssam')}}]]
----
scrollbox
@@display:block;height:10em;overflow:auto;$[[enter scrolling content|$1]]@@@@display:block;text-align:right;^^scroll for more...^^@@
----
nested slider
+++[$1]<<tiddler $1>>===
----
big red
@@font-size:36pt;color:red;$1@@
----
/%
|Name|QuickEdit_file|
|Source|http://www.TiddlyTools.com/#QuickEdit_file|
|Version|2.2.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.2|
|Type|script|
|Requires|QuickEditPlugin|
|Overrides||
|Description|definition for toolbar buttons that insert content from external files|

Usage:
QuickEditToolbar: <<tiddler QuickEdit_file>>
OR
EditTemplate: <span class='toolbar' macro='tiddler QuickEdit_file'></span>

**** INSERT FILE ****
%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink"
	title="insert content from an external text file"
	onclick="var fn=config.quickEdit.promptForFilename('Enter/select a text file',getLocalPath(document.location.href),'');
	if (!fn) return false; /* cancelled by user */
	var text=loadFile(getLocalPath(fn)); if (!text) { alert('Error: unable to read contents from \0027'+fn+'\0027'); return; }
	return config.quickEdit.setSelection(place,text);"
>file</a></html>
/%
|Name|QuickEdit_font|
|Source|http://www.TiddlyTools.com/#QuickEdit_font|
|Version|2.4.3|
|Author|Eric Shulman|
|License|see http://www.TiddlyTools.com/#QuickEditPlugin|
|Type|html|
|Requires|QuickEditPlugin|
|Description|quickedit - select font family|

Usage: see  http://www.TiddlyTools.com/#QuickEditToolbar

%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink" tabindex="-1" 
title="set font-family CSS attribute - @@font-family:facename;...@@"
onclick="var p=Popup.create(this); if (!p) return false; p.className+=' sticky smallform';
	var s=createTiddlyElement(p,'select'); s.button=this;
	s.options[0]=new Option('select a font family...','');
	var fonts=store.getTiddlerText('QuickEdit_fontList','').split('\n');
	for (var i=0; i<fonts.length; i++) {
		if (!fonts[i].length) continue;
		s.options[s.length]=new Option(fonts[i],fonts[i]);
		s.options[s.length-1].style.fontFamily=fonts[i];
	}
	s.options[s.length]=new Option('[Edit font list...]','_edit');
	s.options[s.length-1].title='enter fonts, one per line...';
	s.size=Math.min(s.length,15);
	s.onclick=function(){
		if (this.value=='_edit')
			story.displayTiddler(story.findContainingTiddler(this.button),'QuickEdit_fontList',DEFAULT_EDIT_TEMPLATE);			
		else
			config.quickEdit.wrapSelection(this.button,'@@font-family:\x22'+this.value+'\x22;','@@');
		Popup.remove(); return false;
	};
	s.onkeyup=config.quickEdit.keyup;
	Popup.show();
	s.focus();
	return config.quickEdit.processed(event);"
>font</a></html>
Arial,helvetica,sans-serif
Times New Roman,times,serif
Courier,monospaced
/%
|Name|QuickEdit_format|
|Source|http://www.TiddlyTools.com/#QuickEdit_format|
|Version|2.4.3|
|Author|Eric Shulman|
|License|see http://www.TiddlyTools.com/#QuickEditPlugin|
|Type|html|
|Requires|QuickEditPlugin|
|Description|quickedit - basic text formats, headings, blockquotes, etc.|

Usage: see  http://www.TiddlyTools.com/#QuickEditToolbar

%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink" tabindex="-1" 
title="plain text (remove ALL formatting)" accesskey="P" 
onclick="var e=config.quickEdit.getField(this); if (e) e.focus(); var txt=config.quickEdit.getSelection(e);
	config.quickEdit.setSelection(e,wikifyPlainText(txt)); return false;"
>&nbsp;~&nbsp;</a></html>/%

%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink" tabindex="-1" 
title="''bold''" accesskey="B"
onclick="config.quickEdit.wrapSelection(this,'\x27\x27','\x27\x27'); return false;"
>&nbsp;B&nbsp;</a></html>/%

%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink" tabindex="-1" 
title="//italics//" accesskey="I" 
onclick="config.quickEdit.wrapSelection(this,'//','//'); return false;"
>&nbsp;I&nbsp;</a></html>/%

%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink" tabindex="-1" 
title="__underline__" accesskey="U" 
onclick="config.quickEdit.wrapSelection(this,'__','__'); return false;"
>&nbsp;U&nbsp;</a></html>/%

%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink" tabindex="-1" 
title="--strikethrough--" accesskey="S" 
onclick="config.quickEdit.wrapSelection(this,'--','--'); return false;"
>&nbsp;S&nbsp;</a></html>/%

%/ &nbsp;/%  SPACER

%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink" tabindex="-1" 
title="format text"
onclick="var p=Popup.create(this); if (!p) return false; p.className+=' sticky smallform';
	var s=createTiddlyElement(p,'select'); s.button=this;
	s.options[0]=new Option('select text format...','');
	s.options[s.length]=new Option('CSS class wrapper','{{$1{,}}},Enter a CSS classname');
	s.options[s.length-1].title='CSS class wrapper - {{classname classname etc{...}}}';
	s.options[s.length]=new Option('inline CSS styles','@@$1,@@,Enter CSS (attribute:value;attribute:value;...;)');
	s.options[s.length-1].title='inline CSS styles - @@attr:value;attr:value;...@@';
	s.options[s.length]=new Option('heading 1','\n!,\n');
	s.options[s.length-1].title='H1 heading - !';
	s.options[s.length]=new Option('heading 2','\n!!,\n');
	s.options[s.length-1].title='H2 heading - !!';
	s.options[s.length]=new Option('heading 3','\n!!!,\n');
	s.options[s.length-1].title='H3 heading - !!!';
	s.options[s.length]=new Option('heading 4','\n!!!!,\n');
	s.options[s.length-1].title='H4 heading - !!!!';
	s.options[s.length]=new Option('heading 5','\n!!!!!,\n');
	s.options[s.length-1].title='H5 heading - !!!!!';
	s.options[s.length]=new Option('blockquote','\n\<\<\<\n,\n\<\<\<\n');
	s.options[s.length-1].title='indented blockquote - \<\<\<';
	s.options[s.length]=new Option('monospaced','{{{,}}}');
	s.options[s.length-1].title='inline monospaced text - {{{...}}}';
	s.options[s.length]=new Option('plain text','\n{{{\n,\n}}}\n');
	s.options[s.length-1].title='multi-line monospaced text box - {{{...}}}';
	s.options[s.length]=new Option('superscript','^^,^^');
	s.options[s.length-1].title='^^superscript^^';
	s.options[s.length]=new Option('subscript','~~,~~');
	s.options[s.length-1].title='~~subscript~~';
	s.options[s.length]=new Option('HTML','<html>,<\x2fhtml>');
	s.options[s.length-1].title='HTML syntax - <html>...<\x2fhtml>';
	s.options[s.length]=new Option('comment','/%,%/');
	s.options[s.length-1].title='comment (hidden content) - /%...%/';
	s.size=s.length;
	s.onclick=function(){ if (!this.value.length) return;
		var parts=this.value.split(',');
		var prefix=parts[0]; var suffix=parts[1]; var ask=parts[2];
		if (ask) {
			var val=prompt(ask); if (!val) { Popup.remove(); return false; }
			prefix=prefix.replace(/\$1/g,val); suffix=suffix.replace(/\$1/g,val);
		}
		config.quickEdit.wrapSelection(this.button,prefix,suffix);
		Popup.remove(); return false;
	};
	s.onkeyup=config.quickEdit.keyup;
	Popup.show();
	s.focus();
	return config.quickEdit.processed(event);"
>format</a></html>
/%
|Name|QuickEdit_image|
|Source|http://www.TiddlyTools.com/#QuickEdit_image|
|Version|2.4.3|
|Author|Eric Shulman|
|License|see http://www.TiddlyTools.com/#QuickEditPlugin|
|Type|html|
|Requires|QuickEditPlugin|
|Description|quickedit - embed an image|

Usage: see  http://www.TiddlyTools.com/#QuickEditToolbar

%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink" tabindex="-1" 
	title="embed an image (jpg/gif/png) - [img[tooltip|URL]] or [img[tooltip|path/to/file.ext]]"
	onclick="var fn=config.quickEdit.promptForFilename(
		'Enter/select an image file',getLocalPath(document.location.href),'');
	if (!fn) return false;  /* cancelled by user */
	var h=document.location.href; var p=decodeURIComponent(h.substr(0,h.lastIndexOf('/')+1));
	if (fn.startsWith(p)) fn=fn.substr(p.length); /* use RELATIVE path/filename.ext */
	var tip=prompt('Enter a tooltip for this image',''); if (!tip) tip=''; else tip+='|';
	return config.quickEdit.setSelection(this,'[img['+tip+fn+']]');"
>image</a></html>
/%
|Name|QuickEdit_insert|
|Source|http://www.TiddlyTools.com/#QuickEdit_insert|
|Version|2.4.3|
|Author|Eric Shulman|
|License|see http://www.TiddlyTools.com/#QuickEditPlugin|
|Type|html|
|Requires|QuickEditPlugin|
|Description|quickedit - insert content from another tiddler or external file|

Usage: see  http://www.TiddlyTools.com/#QuickEditToolbar

%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink" tabindex="-1" 
title="insert content from another tiddler or external file"
onclick="var p=Popup.create(this); if (!p) return false; p.className+=' sticky smallform';

	var s2=createTiddlyElement(p,'select'); s2.title='filter by tag';
	s2.options[0]=new Option('filter by tag...','');
	s2.options[s2.length]=new Option('[all tiddlers]','');
	var tags=store.getTags();
	for (var t=0; t<tags.length; t++) s2.options[s2.length]=new Option(tags[t][0],tags[t][0]);
	s2.onchange=function(){
		var tag=this.value;
		var tids=tag.length?store.reverseLookup('tags',tag,true):store.reverseLookup('tags','excludeLists');
		var list=this.nextSibling.nextSibling;
		while (list.length) list.options[0]=null;
		var prompt='select a tiddler or file...';
		if (tag.length) prompt='select a tagged tiddler ['+tids.length+' matches]...';
		list.options[0]=new Option(prompt,'');
		if (!tag.length) list.options[list.length]=new Option('[browse for file...]','_file');
		for (var t=0; t<tids.length; t++) {
			list.options[list.length]=new Option(tids[t].title,tids[t].title);
			list.options[list.length-1].title=tids[t].getSubtitle();
		}
		list.size=Math.min(list.length,10);
		list.selectedIndex=0; list.focus();
		this.style.width=list.offsetWidth+'px';
		if (!tag.length) this.selectedIndex=0;
	};
	createTiddlyElement(p,'br');

	var s=createTiddlyElement(p,'select'); s.button=this;
	s.title='select a tiddler or file';
	s.options[0]=new Option('select a tiddler or file...','');
	s.options[s.length]=new Option('[browse for file...]','_file');
	var tids=store.reverseLookup('tags','excludeLists');
	for (var t=0; t<tids.length; t++) {
		s.options[s.length]=new Option(tids[t].title,tids[t].title);
		s.options[s.length-1].title=tids[t].getSubtitle();
	}
	s.size=Math.min(s.length,10);
	s.onclick=function(){ if (!this.value.length) return false;
		if (this.value=='_file') {
			var fn=config.quickEdit.promptForFilename(
				'Enter/select a text file',getLocalPath(document.location.href),'');
			if (!fn) return false; /* cancelled by user */
			var txt=loadFile(getLocalPath(fn));
			if (!txt) { alert('Error: unable to read contents from \0027'+fn+'\0027'); return; }
		}
		else var txt=store.getTiddlerText(this.value);
		if (!txt) {
			displayMessage(this.value+' not found');
			this.selectedIndex=0; this.focus();
			return false;
		}
		config.quickEdit.setSelection(this.button,txt);
		Popup.remove(); return false;
	};
	s.onkeyup=config.quickEdit.keyup;
	Popup.show();
	s2.style.width=s.offsetWidth+'px';
	s.focus();
	return config.quickEdit.processed(event);"
>insert</a></html>
/%
|Name|QuickEdit_link|
|Source|http://www.TiddlyTools.com/#QuickEdit_link|
|Version|2.4.3|
|Author|Eric Shulman|
|License|see http://www.TiddlyTools.com/#QuickEditPlugin|
|Type|html|
|Requires|QuickEditPlugin|
|Description|quickedit - link to tiddler or external file|

Usage: see  http://www.TiddlyTools.com/#QuickEditToolbar

%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink" tabindex="-1" 
title="add a link to a tiddler or external file - [[link text|TiddlerName]]"
onclick="var p=Popup.create(this); if (!p) return false; p.className+=' sticky smallform';

	var s2=createTiddlyElement(p,'select'); s2.title='filter by tag';
	s2.options[0]=new Option('filter by tag...','');
	s2.options[s2.length]=new Option('[all tiddlers]','');
	var tags=store.getTags();
	for (var t=0; t<tags.length; t++) s2.options[s2.length]=new Option(tags[t][0],tags[t][0]);
	s2.onchange=function(){
		var tag=this.value;
		var tids=tag.length?store.reverseLookup('tags',tag,true):store.reverseLookup('tags','excludeLists');
		var list=this.nextSibling.nextSibling;
		while (list.length) list.options[0]=null;
		var prompt='select a tiddler or file...';
		if (tag.length) prompt='select a tagged tiddler ['+tids.length+' matches]...';
		list.options[0]=new Option(prompt,'');
		if (!tag.length) list.options[list.length]=new Option('[browse for file...]','_file');
		for (var t=0; t<tids.length; t++) {
			list.options[list.length]=new Option(tids[t].title,tids[t].title);
			list.options[list.length-1].title=tids[t].getSubtitle();
		}
		list.size=Math.min(list.length,10);
		list.selectedIndex=0; list.focus();
		this.style.width=list.offsetWidth+'px';
		if (!tag.length) this.selectedIndex=0;
	};
	createTiddlyElement(p,'br');

	var s=createTiddlyElement(p,'select'); s.button=this;
	s.title='select a tiddler or file';
	s.options[0]=new Option('select a tiddler or file...','');
	s.options[s.length]=new Option('[browse for file...]','_file');
	var tids=store.reverseLookup('tags','excludeLists');
	for (var t=0; t<tids.length; t++) {
		s.options[s.length]=new Option(tids[t].title,tids[t].title);
		s.options[s.length-1].title=tids[t].getSubtitle();
	}
	s.size=Math.min(s.length,10);
	s.onclick=function(){ if (!this.value.length) return false;
		var title=this.value; var txt=title;
		if (title=='_file') {
			title=config.quickEdit.promptForFilename('Select a file',
				getLocalPath(document.location.href),'');
			if (!title) { this.selectedIndex=0; this.focus(); return false; }
			var txt=title.substr(title.lastIndexOf('/')+1);
		}
		var txt=prompt('Enter the text to display for this link',txt);
		if (!txt) { this.selectedIndex=0; this.focus(); return false; }
		config.quickEdit.setSelection(this.button,'[['+txt+'|'+title+']]');
		Popup.remove(); return false;
	};
	s.onkeyup=config.quickEdit.keyup;
	Popup.show();
	s2.style.width=s.offsetWidth+'px';
	s.focus();
	return config.quickEdit.processed(event);"
>link</a></html>
/%
|Name|QuickEdit_macro|
|Source|http://www.TiddlyTools.com/#QuickEdit_macro|
|Version|2.4.3|
|Author|Eric Shulman|
|License|see http://www.TiddlyTools.com/#QuickEditPlugin|
|Type|html|
|Requires|QuickEditPlugin|
|Description|quickedit - embed a macro with 'guide text'|

Usage: see  http://www.TiddlyTools.com/#QuickEditToolbar

Note:
Optional 'guideText' can be used to add suggested defaults/placeholders for specific macro parameters.
Add guideText to your own plugin-defined macros using:
	config.macros.macroName.guideText='guide text goes here';

%/<<tiddler {{
	/* define guide text for a few common TW core macros */
	config.macros.edit.guideText='fieldname #rows';
	config.macros.view.guideText='fieldname (link,wikified,date) format';
	config.macros.slider.guideText='cookie TiddlerName label tooltip';
	config.macros.option.guideText='(txtCookieName,chkCookieName)';
	config.macros.tiddler.guideText='TiddlerName with: params...';
	''; /* must return blank to suppress output */ }}>>/%

%/<html><hide linebreaks><a href='javascript:;' class='tiddlyLink' tabindex='-1' 
title='add a macro - \<\<macroName ...\>\>'
onclick="var p=Popup.create(this); if (!p) return false; p.className+=' sticky smallform';
	var s=createTiddlyElement(p,'select'); s.button=this;
	s.options[0]=new Option('select a macro...','');
	var macros=[]; for (var m in config.macros) if (config.macros[m].handler) macros.push(m); macros.sort();
	for (var i=0; i<macros.length; i++) { var m=macros[i];
		var help=config.macros[m].guideText; if (!help) help=''; else help=' '+help;
		s.options[s.length]=new Option(m,m+help);
		s.options[s.length-1].title='\<\<'+m+help+'\>\>';
	}
	s.size=Math.min(s.length,15);
	s.onclick=function(){ if (!this.value.length) return;
		config.quickEdit.setSelection(this.button,'\<\<'+this.value+'\>\>');
		Popup.remove(); return false;
	};
	s.onkeyup=config.quickEdit.keyup;
	Popup.show();
	s.focus();
	return config.quickEdit.processed(event);"
>macro</a></html>
/%
|Name|QuickEdit_replace|
|Source|http://www.TiddlyTools.com/#QuickEdit_replace|
|Version|2.4.4|
|Author|Eric Shulman|
|License|see http://www.TiddlyTools.com/#QuickEditPlugin|
|Type|html|
|Requires|QuickEditPlugin|
|Description|quickedit - find/replace selected text with replacement text|

Usage: see  http://www.TiddlyTools.com/#QuickEditToolbar

%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink" tabindex="-1" 
title="find/replace selected text with replacement text"
onclick="var here=story.findContainingTiddler(this); if (!here) return false;
	var e=config.quickEdit.getField(here);
	var s=config.quickEdit.getSelection(e); 
	var p=Popup.create(this,null,'popup sticky smallform'); if (!p) return false;
	var t=createTiddlyElement(p,'input'); t.onfocus=function(){this.select()};
	t.value=s.length?s:'enter target text';
	var r=createTiddlyElement(p,'input'); r.onfocus=function(){this.select()};
	r.value='enter replacement text';
	var tid=here.getAttribute('tiddler');
	var b=createTiddlyElement(p,'button',null,null,'?',{tid:tid});
	b.style.width='2em';
	b.title='FIND/FIND NEXT target text';
	b.onclick=function(ev) { /* FIND */
		var e=story.getTiddlerField(this.getAttribute('tid'),'text');
		if (!e||e.getAttribute('edit')!='text') return;
		var t=this.previousSibling.previousSibling;
		var tv=t.value.replace(/\\t/mg,'\t').unescapeLineBreaks();
		e.focus();
		if (e.setSelectionRange) { /* MOZ */
			var newstart=e.value.indexOf(tv,e.selectionStart+1);
			if (newstart==-1) newstart=e.value.indexOf(tv); /* wrap around */
			if (newstart==-1) { alert('\u0022'+t.value+'\u0022 not found'); t.focus(); return; }
			e.setSelectionRange(newstart,newstart+tv.length);
			var linecount=e.value.split('\n').length;
			var thisline=e.value.substr(0,e.selectionStart).split('\n').length;
			e.scrollTop=Math.floor((thisline-1-e.rows/2)*e.scrollHeight/linecount);
		} else if (document.selection) { /* IE */
			var range=document.selection.createRange();
			if(range.parentElement()==e) {
				range.collapse(false);
				var found=false; try{found=range.findText(v,e.value.length,4)}catch(e){}
				if (found) range.select();
				else { alert('\u0022'+t.value+'\u0022 not found'); t.focus(); }
			}
		}
	};
	b=createTiddlyElement(p,'button',null,null,'=',{tid:tid});
	b.style.width='2em';
	b.title='REPLACE selected text';
	b.onclick=function(ev) { /* REPLACE */
		var e=story.getTiddlerField(this.getAttribute('tid'),'text');
		if (!e||e.getAttribute('edit')!='text') return;
		var t=this.previousSibling.previousSibling.previousSibling;
		var r=this.previousSibling.previousSibling;
		var rv=r.value.replace(/\\t/mg,'\t').unescapeLineBreaks();
		if (   (e.selectionStart!==undefined && e.selectionEnd==e.selectionStart)
		    || (document.selection && document.selection.createRange().text==''))
			this.previousSibling.click(); /* no selection... do FIND first */
		if (   (e.selectionStart!==undefined && e.selectionEnd==e.selectionStart)
		    || (document.selection && document.selection.createRange().text==''))
			{ t.focus(); return; } /* still no selection... goto target input */
		e.focus(); replaceSelection(e,rv);
	};
	b=createTiddlyElement(p,'button',null,null,'+',{tid:tid});
	b.style.width='2em';
	b.title='REPLACE selected text AND FIND NEXT target text';
	b.onclick=function(ev) { /* REPLACE and FIND NEXT */
		this.previousSibling.click();
		this.previousSibling.previousSibling.click();
	};
	b=createTiddlyElement(p,'button',null,null,'!',{tid:tid});
	b.style.width='2em';
	b.title='REPLACE ALL occurrences of target text';
	b.onclick=function(ev) { /* REPLACE ALL */
		var e=story.getTiddlerField(this.getAttribute('tid'),'text');
		if (!e||e.getAttribute('edit')!='text') return;
		var t=this.previousSibling.previousSibling.previousSibling.previousSibling.previousSibling;
		var r=this.previousSibling.previousSibling.previousSibling.previousSibling;
		var tv=t.value.replace(/\\t/mg,'\t').unescapeLineBreaks();
		var rv=r.value.replace(/\\t/mg,'\t').unescapeLineBreaks();
		if (!tv.length) { alert('Please enter the target text'); t.focus(); return; }
		var m='This will replace all occurrences of:\n\n'+tv+'\n\nwith:\n\n'+rv+'\n\nAre you sure?';
		if (!confirm(m)) { r.focus(); r.select(); return; }
		e.value=e.value.replace(new RegExp(tv.escapeRegExp(),'gm'),rv);
		e.focus(); e.select(); Popup.remove();
	};
	Popup.show();
	if (!s.length) {t.focus();t.select()} else {r.focus();r.select()}
	event.cancelBubble=true;if(event.stopPropagation)event.stopPropagation();return false;"
>replace</a></html>
/%
|Name|QuickEdit_sort|
|Source|http://www.TiddlyTools.com/#QuickEdit_sort|
|Version|2.4.3|
|Author|Eric Shulman|
|License|see http://www.TiddlyTools.com/#QuickEditPlugin|
|Type|html|
|Requires|QuickEditPlugin|
|Description|quickedit - sort lines of text|

Usage: see  http://www.TiddlyTools.com/#QuickEditToolbar

%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink" tabindex="-1" 
title="sort lines of text"
onclick="var p=Popup.create(this); if (!p) return false; p.className+=' sticky smallform';
	var s=createTiddlyElement(p,'select'); s.button=this;
	s.options[0]=new Option('select sort order...','');
	s.options[s.length]=new Option('ascending','A');
	s.options[s.length-1].title='ascending';
	s.options[s.length]=new Option('descending','D');
	s.options[s.length-1].title='descending';
	s.size=s.length;
	s.onclick=function(){ if (!this.value.length) return;
		var e=config.quickEdit.getField(this.button); if (!e) return false;
		var lines=config.quickEdit.getSelection(e).split('\n').sort();
		if (this.value=='D') lines=lines.reverse();
		replaceSelection(e,lines.join('\n'));
		e.focus();
		Popup.remove(); return false;
	};
	s.onkeyup=config.quickEdit.keyup;
	Popup.show();
	s.focus();
	return config.quickEdit.processed(event);"
>sort</a></html>
/%
|Name|QuickEdit_split|
|Source|http://www.TiddlyTools.com/#QuickEdit_split|
|Version|2.4.3|
|Author|Eric Shulman|
|License|see http://www.TiddlyTools.com/#QuickEditPlugin|
|Type|html|
|Requires|QuickEditPlugin|
|Description|quickedit - move selection to new tiddler and insert link, embedded tiddler, or slider|

Usage: see  http://www.TiddlyTools.com/#QuickEditToolbar

Based on ideas originally developed by YannPerrin
(http://yann.perrin.googlepages.com/twkd.html#easySlicer)

%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink" tabindex="-1" 
title="move selection to new tiddler and insert link, embedded tiddler, or slider"
onclick="var p=Popup.create(this); if (!p) return false; p.className+=' sticky smallform';
	p.style.whiteSpace='nowrap';
	var i=createTiddlyElement(p,'input');
	i.defaultValue='Enter a new tiddler title';
	i.onfocus=function(){this.select()};
	var s=createTiddlyElement(p,'select'); s.button=this;
	s.options[0]=new Option('select type...','');
	s.options[0].title='select split type';
	s.options[1]=new Option('link','link');
	s.options[1].title='replace with [[TiddlerName]]';
	s.options[2]=new Option('embed','embed');
	s.options[2].title='replace with \<\<tiddler TiddlerName\>\>';
	s.options[3]=new Option('slider','slider');
	s.options[3].title='replace with \<\<slider \u0022\u0022 [[TiddlerName]] [[label]] [[tooltip]]\>\>';
	s.onchange=function(){
		if (s.previousSibling.value==s.previousSibling.defaultValue)
			{ alert('A tiddler title is required'); s.selectedIndex=0; s.previousSibling.focus(); return false; }
		var tid=s.previousSibling.value;
		if (store.tiddlerExists(tid) && !confirm(config.messages.overwriteWarning.format([tid])))
			{ s.previousSibling.focus(); return false; }
		switch(s.value) {
			case 'link':
				var newtxt='[['+tid+']]';
				break;
			case 'embed':
				var newtxt='\<\<tiddler [['+tid+']]\>\>';
				break;
			case 'slider':
				var label=prompt('Enter a slider label',tid);
				if (!label) { Popup.remove(); return false; }
				var tip=prompt('Enter a slider tooltip',label);
				if (!tip) { Popup.remove(); return false; }
				var newtxt='\<\<slider \u0022\u0022 [['+tid+']] [['+label+']] [['+tip+']]\>\>';
				break;
		}
		var txt=config.quickEdit.getSelection(config.quickEdit.getField(this.button));
		store.saveTiddler(tid,tid,txt,config.options.txtUserName,new Date(),[],{});
		story.displayTiddler(story.findContainingTiddler(this.button),tid);
		config.quickEdit.setSelection(this.button,newtxt);
		Popup.remove(); return false;
	};
	Popup.show();
	event.cancelBubble=true;if(event.stopPropagation)event.stopPropagation();return false;"
>split</a></html>
/%
|Name|QuickEdit_tiddler|
|Source|http://www.TiddlyTools.com/#QuickEdit_tiddler|
|Version|2.2.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.2|
|Type|script|
|Requires|QuickEditPlugin|
|Overrides||
|Description|definition for toolbar button that inserts content from another tiddler|

Usage:
QuickEditToolbar: <<tiddler QuickEdit_tiddler>>
OR
EditTemplate: <span class='toolbar' macro='tiddler QuickEdit_tiddler'></span>

**** INSERT TIDDLER ****
%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink"
title="copy content from another tiddler"
onclick="var p=Popup.create(this); if (!p) return false; p.className+=' sticky smallform';
	var s=createTiddlyElement(p,'select'); s.button=this;
	s.options[0]=new Option('select a tiddler...','');
	s.onchange=function(){
		var txt=store.getTiddlerText(this.value);
		if (!txt) { displayMessage(this.value+' not found'); this.selectedIndex=0; this.focus(); return false; }
		config.quickEdit.setSelection(this.button,txt);
		Popup.remove(); return false;
	};
	var tids=store.getTiddlers('title');
	for (var t=0; t<tids.length; t++) {
		s.options[s.length]=new Option(tids[t].title,tids[t].title);
		s.options[s.length-1].title=tids[t].getSubtitle();
	}
	var s=createTiddlyElement(p,'select');
	s.options[0]=new Option('match tag...','');
	s.onchange=function(){
		var tag=this.value;
		var tids=tag.length?store.getTaggedTiddlers(tag,'title'):store.getTiddlers('title');
		var list=this.previousSibling;
		while (list.length) list.options[0]=null;
		var prompt='select a '+(tag.length?'tagged ':'')+'tiddler'+(tag.length?(' ['+tids.length+' matches]'):'')+'...';
		list.options[0]=new Option(prompt,'');
		for (var t=0; t<tids.length; t++) {
			list.options[list.length]=new Option(tids[t].title,tids[t].title);
			list.options[list.length-1].title=tids[t].getSubtitle();
		}
	};
	var tags=store.getTags();
	for (var t=0; t<tags.length; t++) s.options[s.length]=new Option(tags[t][0],tags[t][0]);
	Popup.show(p,false);
	event.cancelBubble=true;if(event.stopPropagation)event.stopPropagation();return false;"
>tiddler</a></html>
/***
|Name:|QuickOpenTagHack|
|Description:|Changes tag links to make it easier to open tags as tiddlers|
|Version:|1.2 hacked from v3.0.1 ($Rev: 3861 $)|
|Date:|03.16.2010|
|Reason for Hack:|change from custom pretty tag style to core pretty tag style|
|OriginalSource:|http://mptw.tiddlyspot.com/#QuickOpenTagPlugin|
***/
//{{{
config.quickOpenTag = {

	dropdownChar: (document.all ? "\u25bc" : "\u25be"), // the little one doesn't work in IE?

	createTagButton: function(place,tag,excludeTiddler,title,tooltip) {
		var sp = createTiddlyElement(place,"span",null,"quickopentag"); //combined container
//http://groups.google.com/group/tiddlywiki/browse_thread/thread/65a470a0bac00a9c/47d51ba41e5a554a?show_docid=47d51ba41e5a554a
		createTiddlyText(createTiddlyLink(sp,tag||title,false),(title?title:tag) );  //Mark S.

		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);
	},


	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();

//}}}
/***
|Name:|QuickOpenTagPlugin|
|Description:|Changes tag links to make it easier to open tags as tiddlers|
|Version:|3.0.1 ($Rev: 3861 $)|
|Date:|$Date: 2008-03-08 10:53:09 +1000 (Sat, 08 Mar 2008) $|
|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 do this: <<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();

//}}}
The way to learn to use TiddlyWiki is to forget that you don't know how to use TiddlyWiki...
----
If you have 2P and I have 2P, then one of us has 2Q2P!
----
"Knock, Knock"...  "Who's there?"... "Oh! I guess you know that one..."
----
In theory, there is no difference between theory and practice. But, in practice, there is.
----
Sometimes when reading Goethe I have the paralyzing suspicion that he is trying to be funny.
----
Before I got married I had six theories about bringing up children; now I have six children and no theories.
----
A witty saying proves nothing.
----
The problem with some people is that when they aren't drunk, they're sober.
----
The great thing about television is that if something important happens anywhere in the world, day or night, you can always change the channel.
----
Don't be so humble - you are not that great.
----
The combination "ough" can be pronounced in nine different ways. The following sentence contains them all: "A rough-coated, dough-faced, thoughtful ploughman strode through the streets of Scarborough; after falling into a slough, he coughed and hiccoughed." 
----
If you lived here, you'd be home by now...
----
I love my dust. It shows I had something better to do.
----
Time flies like an arrow... Fruit flies like a banana [Groucho Marx]
----
If you don't know where you're going, you'll probably end up somewhere else.
----
Weebles wobble... but they don't fall down!
----
It's all very simple... or else it's all very complex... or perhaps it's neither... or both.
----
Accepting reality is the first step to insanity
----
Oops!  Sorry. My karma ran over your dogma.
----
If it looks like a duck, walks like a duck and sounds like a duck, it's probably something else.
----
Some times you feel like a nut, some times you bolt.
----
Santaclaustrophobia... The feeling that Christmas is closing in all around you.
----
Don't touch that! You don't know where it's been...
----
Why is abbreviation such a long word?
----
Life's a trip, not a destination.  So watch out for the cows.
----
Diplomacy is the art of saying 'Nice doggie!'... until you can find a rock.
----
Scientists working on cloning technology have done what the american educational system has been doing for years - producing identical sheep.
----
Umm... What's another word for thesaurus?
----
Give me ambiguity or give me something else
----
Don't anthropomorphize your computer, it doesn't like it.
----
Ninth Law of Cartoon Physics: Everything falls faster than an anvil.
----
New clinical studies show there aren't any answers.  So just enjoy the questions...
----
Oh yeah?  Far out!
----
Boycott Shampoo - Demand the REAL poo!
----
On Blintze! On Bagel! On Spaetzle! On Strudel! On Matzo! On Latke! On Kuchen! On Kugel!...   Merry Chanukah!
----
Remember: Don't sweat the petty things... and don't pet the sweaty things.
----
Sign in lunch room: Shoes are required to eat in the cafeteria... socks can eat anywhere they want.
----
Don't be irreplaceable, if you can't be replaced, you can't be promoted.
----
5 out of 4 people have problems with fractions...
----
Osborne's Law of Mathematics: Variables won't; constants aren't.
----
Always remember you're unique, just like everyone else.
----
Something to ponder: What was the best thing *before* sliced bread?   Hmmm...
----
Physics Joke #27: Two hydrogen atoms bump into each other while walking down the street: 'Are you alright?'... 'No, I lost an electron!'... 'Are you sure?'... 'Yeah, I'm Positive!'
----
The one thing I can't stand is intolerant people!
----
Old programmers never die. . . they just can't C as well.
----
World Shortest 'Bar' joke: A guy walks into a bar...   OUCH! he says...
----
Who are you going to believe, me or your own eyes? 
----
Never judge a man 'til you have walked a mile in his shoes, because by then, he's a mile away, you've got his shoes, and you can say whatever the hell you want to.
----
The problem with troubleshooting is that real trouble shoots back.
----
How much wood would a woochuck chuck if a woodchuck could chuck wood?
----
These are the roots of rhythm: boom, de boom, de-boom, ding-dong, ooh! [Leila ~Gallagher-Breen]
----
These are the roots of music: boom-chicky-chicky boom, meow, meow, baddom, baddom,  ding-aling-a-long, chicky-boom! [Leila ~Gallagher-Breen]
----
Classified ad (in Physics Quarterly): Got Mole problems?  Call Avagadro Exterminators: 602-1023
----
He who laughs last thinks slowest
----
Would a fly without wings be called a walk?
----
The winner of the World's Worst Analogy contest: 'The little boat glided across the water in exactly the way a bowling ball wouldn't.'
----
From the 'say what?!?' files: We are ready for any unforeseen event that may or may not occur. [Dan Quayle 9/22/90]
----
I believe you should live each day as if it is your last, which is why I don't have any clean laundry because, come on, who wants to wash clothes on the last day of their life? [Jack Handy]
----
PRINTER - A device consisting of three main parts: the case, the jammed paper tray, and the blinking red light.
----
Dilbert's Laws of Work: The more crap you put up with, the more crap you are going to get.
----
Q: Why'd the electron cross the road? A: 'Cause he was already on the other side...
----
When the going gets tough, remember STRESSED spelled backwards is DESSERTS.
----
Foobar... baz. Mumble: frotz, gronk, snork. Snerfle? Natter and gromish!
----
Pentiums melt in your PC, not in your hand.
----
everyone is cute... even me.  But in purple... I'm STUNNING!! [Londo Mollari] 
----
I always wanted to be somebody, but I should have been more specific. [Lily Tomlin] 
----
It's OK to change horses in mid-stream, especially if the first horse can't swim! [Laura Shulman] 
----
Work is the curse of the drinking classes. [Oscar Wilde] 
----
We have only two things to worry about:  That things will never get back to normal, and that they already have.
----
Intelligence is a funny thing: those who don't have it think they do, and those who do are smart enough to know better.
----
Life is hard, Love is strange.  Nothing lasts, people change.   Dream of a long and wonderful future, but live now.
----
'Can you prove any of the stuff you believe in?', my friend asked. When I said that's not how belief works, he nodded and said that's what he thought but he was just checking to make sure he hadn't missed a key point.
----
Life ... It's a good place to be!
----
Do not follow where the path may lead.  Go, instead, where there is no path, and leave a trail.
----
History is made at night... character is what you are in the dark. [Dr. Emilio Lizardo, aka Lord John Worfin] 
----
You can't always get what you want... but if you try sometimes, you just may find, that you get what you need. [The Rolling Stones] 
----
The only man who behaved sensibly was my tailor; he took my measurement anew every time he saw me, while all the rest went on with their old measurements and expected them to fit me. [George Bernard Shaw] 
----
In matters of style, swim with the current: in matters of principle, stand like a rock. [Thomas Jefferson] 
----
Great things are not done by impulse, but by a series of small things brought together. [Vincent van Gogh] 
----
'I think there is a world market for maybe five computers.' [Thomas Watson, chairman of IBM, 1943] 
----
We have to live today by what truth we can get today, and be ready tomorrow to call it falsehood. [William James] 
----
There are two ways of spreading light: to be the candle or the mirror that reflects it. [Edith Wharton] 
----
Talent develops in tranquility, character in the full current of human life. [Johann Wolfgang von Goethe (1749-1832)] 
----
Our firmest convictions are apt to be the most suspect; they mark our limitations and our bounds.  Life is a petty thing unless it is moved by the indomitable urge to extend its boundaries. [Jose Ortega y Gasset] 
----
It takes courage to grow up and turn out to be who you really are. [e e cummings (1894-1962)] 
----
If we knew what it was we were doing, it would not be called research, would it? [Albert Einstein] 
----
To invent, you need a good imagination and a pile of junk. [Thomas Edison] 
----
Dare to be naive. [R. Buckminster Fuller] 
----
Quiet minds cannot be perplexed or frightened, but go on in fortune or misfortune at their own private pace, like a clock during a thunderstorm. [Robert Louis Stevenson] 
----
In the struggle between yourself and the world, second the world. [Franz Kafka] 
----
Every man's condition is a solution in hieroglyph to those inquiries he would put.  He acts it as life before he apprehends it as truth. [Ralph Waldo Emerson] 
----
One can remain alive...if one is unafraid of change, insatiable in intellectual curiosity, interested in big things, and happy in small ways. [Edith Wharton] 
----
a rock is like space because it doesnt move; and space is like a rock because it is empty.  words are buddhas. [Jack Kerouac] 
----
The whole problem with the world is that fools and fanatics are always so certain of themselves, and wiser people so full of doubts. [Bertrand Russell] 
----
Doubt is not a pleasant state of mind, but certainty is absurd. [Voltaire] 
----
Education is not the filling of a pail, but the lighting of a fire. [William Butler Yeats] 
----
If you take yourself too seriously, no one else will take you seriously enough... [Eric Shulman] 
----
There are only four questions of value in life... What is sacred? Of what is the spirit made? What is worth living for, and what is worth dying for? The answer to each is the same: only love. [Don Juan ~DeMarco] 
----
If you are a dreamer, come in.  If you are a dreamer, a wisher, a liar, a hope-er, a pray-er, a magic bean buyer... If you're a pretender, come sit by my fire... For we have some flax-golden tales to spin.  Come in!  Come in! [Shel Silverstein] 
----
O money, money, money, I'm not necessarily one of those who think thee holy, But I often stop to wonder how thou canst go out so fast when thou comest in so slowly. [Ogden Nash] 
----
There is no progress without struggle. [Frederick Douglass] 
----
Before you can do something, you must become something. [Goethe] 
----
The man who follows the crowd will usually get no further than the crowd.  The man who walks alone is likely to find himself in places no one has ever been. [Alan ~Ashley-Pit] 
----
Weep not for the dead for they are but empty cages from which the bird has flown. [Tibetan Book of The Dead] 
----
I wish it would dawn upon engineers that, in order to be an engineer, it is not enough to be an engineer. [Jose Ortega y Gasset] 
----
Every exit is an entry somewhere. [Tom Stoppard] 
----
Wherever we are, it is but a stage on the way to somewhere else, and whatever we do, however well we do it, it is only a preparation to do something else that shall be different. [Robert Louis Stevenson] 
----
We judge ourselves by what we feel capable of doing, while others judge us by what we have already done. [Henry Wadsworth Longfellow] 
----
All our words are but crumbs that fall down from the feast of the mind. [Kahlil Gibran, "Sand and Foam"] 
----
It's a lot harder to find joy than it is to find bread.  Feed your soul first, then go shopping. [Eric Shulman] 
----
Why do you hasten to remove anything which hurts your eye, while if something affects your soul you postpone the cure until next year? [Horace] 
----
Not to know is bad.  Not to want to know is worse.  Not to hope is unthinkable.  Not to care is unforgivable.  [Nigerian folk saying] 
----
Only half of writing is saying what you mean. The other half is preventing people from reading what they expected you to mean. [James Richardson, 'Ploughshares'] 
----
There are no shortcuts to anyplace worth going. [Beverly Sills] 
----
Somewhere, something incredible is waiting to be known. [Carl Sagan] 
----
Courage is the price that Life extracts for granting peace. [Amelia Earhart] 
----
Great things are not done by impulse, but by a series of small things brought together. [Vincent van Gogh] 
----
Choose a job you love, and you will never have to work a day in your life. [Confucius] 
----
There is only one success - to be able to spend your life in your own way. [Christopher Morley] 
----
We choose our joys and sorrows long before we experience them. [Kahlil Gibran] 
----
It is all a frame of mind, this enjoyment of living. [Lin Yutang] 
----
Work for something because it is good, not just because it stands a chance to succeed. [Vaclav Havel] 
----
The easiest way to get what you want is to help others get what they want. [Deepak Chopra] 
----
All generalizations are false, including this one. [Bucky Radfish]
----
In science, 'fact' can only mean 'confirmed to such a degree that it would be perverse to withhold provisional assent.' I suppose that apples might start to rise tomorrow, but the possibility does not merit equal time in physics classrooms. [Stephen Jay Gould (1941 - 2002)]
----
Twenty years from now, you will be more disappointed by the things you didn't do, than by the ones you did. So throw off the bowlines. Sail away from the safe harbor. Catch the trade winds in your sails. Explore, dream... [Mark Twain]
----
To live only for some future goal is shallow.  It's the sides of the mountain that sustain life, not the top. [Robert M. Pirsig]
----
Nothing is so contagious as enthusiasm; it moves stones, it charms brutes.  Enthusiasm is the genius of sincerity, and truth accomplishes no victories without it. [Edward G. E. ~Bulwer-Lytton (1803 - 1873)]
----
The past is but the beginning of a beginning, and all that is and has been is but the twilight of the dawn. [Herbert George Wells]
----
We grow great by dreams. All big men are dreamers. They see things in the soft haze of a spring day or in the red fire of a long winter's evening. Some of us let these great dreams die, but others nourish and protect them; nurse them through bad days till they bring them to the sunshine and light, which comes always to those who sincerely hope that their dreams will come true. [Woodrow Wilson]
----
Be brave enough to live life creatively. The creative is the place where no one else has ever been.  You have to leave the city of your comfort and go into the wilderness of your intuition. You can't get there by bus, only by hard work and risk and by not quite knowing what you're doing. What you'll discover will be wonderful. What you'll discover will be yourself. [Alan Alda]
----
If we had no winter, the spring would not be so pleasant; if we did not sometimes taste of adversity, prosperity would not be so welcome.
----
Solitude, if rightly used, becomes not only a privilege but a necessity.  Only a superficial soul fears to fraternize with itself.
----
One of the symptoms of an approaching nervous breakdown is the belief that one's work is terribly important.
----
Hope is like a road in the country: there was never a road, but when many people walk on it, the road comes into existence.
----
You can only find truth with logic if you have already found truth without it.
----
Love is always bestowed as a gift - freely, willingly and without expectation. We don't love to be loved; we love to love.
----
Always listen to experts. They'll tell you what can't be done, and why. Then do it.
----
Distance between two hearts is not an obstacle; rather a great reminder of just how strong true love can be.
----
Not everything that can be counted counts, and not everything that counts can be counted.
----
Life's challenges are not supposed to paralyze you, they're supposed to help you discover who you are.
----
Nothing splendid has ever been achieved except by those who dared believe that something inside them was superior to circumstances.
----
Whether you think that you can, or that you can't, you are usually right.
----
The only time you run out of chances is when you stop taking them.
----
Knowledge speaks, but wisdom listens.
----
Too often we give our children answers to remember rather than problems to solve.
----
Books are the shoes with which we tread the footsteps of great minds.  A book may lie dormant for fifty years or for two thousand years in a forgotten corner of a library, only to reveal, upon being opened, the marvels or the abysses that it contains, or the line that seems to have been written for me alone. In this respect the writer is not different from any other human being: whatever we say or do can have far-reaching consequences.
----
A people that values its privileges above its principles soon loses both.
----
Treat everyone with politeness, even those who are rude to you. Not because they are nice, but because you are.
----
The ultimate measure of a man is not where he stands in moments of comfort and convenience, but where he stands in times of challenge and controversy.  What lies behind us and what lies before us, are only small matters compared to what lies within us. 
----
Being in charge of your own reality is a little tougher; it takes a lot of thinking and brutal honesty. [Phil Glatz]
----
There are always going to be amazingly creative people doing wonderful things. [Phil Glatz]
----
The trick is to rise above the symptoms of being aware, and actually BE aware. [Phil Glatz]
----
A revolution is coming - a revolution which will be peaceful if we are wise enough; compassionate if we care enough; successful if we are fortunate enough - but a revolution which is coming whether we will it or not. We can affect its character, we cannot alter its inevitability. [John F. Kennedy]
----
On two occasions I have been asked (by members of Parliament!), 'Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out?' I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question. [Charles Babbage]
----
In your presence even my shadow acquires the sensation of touch.
/***
|Name|QuoteOfTheDayPlugin|
|Source|http://www.TiddlyTools.com/#QuoteOfTheDayPlugin|
|Documentation|http://www.TiddlyTools.com/#QuoteOfTheDayPluginInfo|
|Version|1.4.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|Display a randomly selected "quote of the day" from a list defined in a separate tiddler|

!!!!!Documentation
>see [[QuoteOfTheDayPluginInfo]]
!!!!!Revisions
<<<
2008.03.21 [1.4.1] in showNextItem(), corrected handling for random selection so that //initial// index value will randomized correctly instead of always showing first item, even when randomizing.  Thanks to Riccardo Gherardi for finding this.
| Please see [[QuoteOfTheDayPluginInfo]] for previous revision details |
2005.10.21 [1.0.0] Initial Release.  Based on a suggestion by M.Russula
<<<
!!!!!Code
***/
//{{{
version.extensions.QOTD = {major: 1, minor: 4, revision: 1, date: new Date(2008,3,21)};
config.macros.QOTD = {
	clickTooltip: "click to view another item",
	timerTooltip: "auto-timer stopped...  'mouseout' to restart timer",
	timerClickTooltip: "auto-timer stopped...  click to view another item, or 'mouseout' to restart timer",
	handler:
	function(place,macroName,params) {
		var tid=params.shift(); // source tiddler containing HR-separated quotes
		var p=params.shift();
		var click=true; // allow click for next item
		var inline=false; // wrap in slider for animation effect
		var random=true; // pick an item at random (default for "quote of the day" usage)
		var folder=false; // use local filesystem folder list
		var cookie=""; // default to no cookie
		var next=0; // default to first item (or random item)
		while (p) {
			if (p.toLowerCase()=="noclick") var click=false;
			if (p.toLowerCase()=="inline") var inline=true;
			if (p.toLowerCase()=="norandom") var random=false;
			if (p.toLowerCase().substr(0,7)=="cookie:") var cookie=p.substr(8);
			if (!isNaN(p)) var delay=p;
			p=params.shift();
		}
		if ((click||delay) && !inline) {
			var panel = createTiddlyElement(null,"div",null,"sliderPanel");
			panel.style.display="none";
			place.appendChild(panel);
			var here=createTiddlyElement(panel,click?"a":"span",null,"QOTD");
		}
		else
			var here=createTiddlyElement(place,click?"a":"span",null,"QOTD");
		here.id=(new Date()).convertToYYYYMMDDHHMMSSMMM()+Math.random().toString(); // unique ID
		// get items from tiddler or file list
		var list=store.getTiddlerText(tid,"");
		if (!list||!list.length) { // not a tiddler... maybe an image directory?
			var list=this.getImageFileList(tid);
			if (!list.length) { // maybe relative path... fixup and try again
				var h=document.location.href;
				var p=getLocalPath(decodeURIComponent(h.substr(0,h.lastIndexOf("/")+1)));
				var list=this.getImageFileList(p+tid);
			}
		}
		if (!list||!list.length) return false; // no contents... nothing to display!
		here.setAttribute("list",list);
		if (delay) here.setAttribute("delay",delay);
		here.setAttribute("random",random);
		here.setAttribute("cookie",cookie);
		if (click) {
			here.title=this.clickTooltip
			if (!inline) here.style.display="block";
			here.setAttribute("href","javascript:;");
			here.onclick=function(event)
				{ config.macros.QOTD.showNextItem(this); }
		}
		if (config.options["txtQOTD_"+cookie]!=undefined) next=parseInt(config.options["txtQOTD_"+cookie]);
		here.setAttribute("nextItem",next);
		config.macros.QOTD.showNextItem(here);
		if (delay) {
			here.title=click?this.timerClickTooltip:this.timerTooltip
			here.onmouseover=function(event)
				{ clearTimeout(this.ticker); };
			here.onmouseout=function(event)
				{ this.ticker=setTimeout("config.macros.QOTD.tick('"+this.id+"')",this.getAttribute("delay")); };
			here.ticker=setTimeout("config.macros.QOTD.tick('"+here.id+"')",delay);
		}
	},
	tick: function(id) {
		var here=document.getElementById(id); if (!here) return;
		config.macros.QOTD.showNextItem(here);
		here.ticker=setTimeout("config.macros.QOTD.tick('"+id+"')",here.getAttribute("delay"));
	},
	showNextItem:
	function (here) {
		// hide containing slider panel (if any)
		var p=here.parentNode;
		if (p.className=="sliderPanel") p.style.display = "none"
		// get a new quote
		var index=here.getAttribute("nextItem"); 
		var items=here.getAttribute("list").split("\n----\n");
		if (index<0||index>=items.length) index=0;
		if (here.getAttribute("random")=="true") index=Math.floor(Math.random()*items.length);
		var txt=items[index];
		// re-render quote display element, and advance index counter
		removeChildren(here); wikify(txt,here);
		index++; here.setAttribute("nextItem",index);
		var cookie=here.getAttribute("cookie");
		if (cookie.length) {
			config.options["txtQOTD_"+cookie]=index.toString();
			saveOptionCookie("txtQOTD_"+cookie);
		}
		// redisplay slider panel (if any)
		if (p.className=="sliderPanel") {
			if(anim && config.options.chkAnimate)
				anim.startAnimating(new Slider(p,true,false,"none"));
			else p.style.display="block";
		}
	},
	getImageFileList: function(cwd) { // returns HR-separated list of image files
		function isImage(fn) {
			var ext=fn.substr(fn.length-3,3).toLowerCase();
			return ext=="jpg"||ext=="gif"||ext=="png";
		}
		var files=[];
		if (config.browser.isIE) {
			cwd=cwd.replace(/\//g,"\\");
			// IE uses ActiveX to read filesystem info
			var fso = new ActiveXObject("Scripting.FileSystemObject");
			if(!fso.FolderExists(cwd)) return [];
			var dir=fso.GetFolder(cwd);
			for(var f=new Enumerator(dir.Files); !f.atEnd(); f.moveNext())
				if (isImage(f.item().path)) files.push("[img[%0]]".format(["file:///"+f.item().path.replace(/\\/g,"/")]));
		} else {
			// FireFox (mozilla) uses "components" to read filesystem info
			// get security access
			if(!window.Components) return;
			try { netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); }
			catch(e) { alert(e.description?e.description:e.toString()); return []; }
			// open/validate directory
			var file=Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
			try { file.initWithPath(cwd); } catch(e) { return []; }
			if (!file.exists() || !file.isDirectory()) { return []; }
			var folder=file.directoryEntries;
			while (folder.hasMoreElements()) {
				var f=folder.getNext().QueryInterface(Components.interfaces.nsILocalFile);
				if (f instanceof Components.interfaces.nsILocalFile)
					if (isImage(f.path)) files.push("[img[%0]]".format(["file:///"+f.path.replace(/\\/g,"/")]));
			}
		}
		return files.join("\n----\n");
	}
}
//}}}
/***
|Name|QuoteOfTheDayPluginInfo|
|Source|http://www.TiddlyTools.com/#QuoteOfTheDayPlugin|
|Documentation|http://www.TiddlyTools.com/#QuoteOfTheDayPluginInfo|
|Version|1.4.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 QuoteOfTheDayPlugin|
!!!!!Usage
<<<
{{{<<QOTD tiddlername norandom noclick inline cookie:cookiename delay>>}}}
* ''tiddlername'' is the name of a tiddler containing your list of quotes, each separated by a horizontal line (use {{{----}}} on a line by itself).
* Each time the macro is rendered it will display a different quotation, selected at random from the specified tiddler.  To display quotes in the sequence in which they occur in the tiddler, you can use the ''norandom'' keyword.
* When using ''norandom'', you can also specify an optional ''cookie:cookiename'' parameter which will be used to track the //index// of the next quote to be displayed, so that each subsequent rendering of the macro can continue the sequence of quotes as entered in the source tiddler, even in between browser sessions.
* By default, clicking on the rendered quote will select and display another random quote.  Use the optional ''noclick'' keyword parameter to disable this "onClick" handling.
* By default, a clickable or timed quote will be displayed insider a 'slider' panel, so that standard TW animation effects will be used.  However, slider panels are always rendered as "block-level" content, forcing a newline both before and after the slider panel.  Use the ''inline'' keyword parameter to bypass this side-effect and display a clickable/timed quote without automatically adding surrounding linebreaks.
* The quote can also be refreshed automatically, by specifying a numeric ''delay'' parameter (in milliseconds) which enables a countdown timer.  When the mouse is over the quote, the timer is automatically stopped.  Moving the mouse away from the quote content restarts the timer.
<<<
!!!!!Example
<<<
{{{<<QOTD Quotations 10000>>}}}
<<QOTD Quotations 10000>>
<<<
!!!!!Revisions
<<<
2008.03.21 [1.4.1] in showNextItem(), corrected handling for random selection so that //initial// index value will randomized correctly instead of always showing first item, even when randomizing.  Thanks to Riccardo Gherardi for finding this.
2008.01.16 [1.4.0] support using a local image file directory instead of tiddler name for getting list of items.  If specified tiddler does not exist in the document, macro attempts to use tiddlername as a local directory name (using either absolute or relative path) and get list of all JPG/GIF/PNG files.
2007.08.06 [1.3.0] added support for "cookie:cookiename" param
2007.05.03 [1.2.1] corrected logic for handling "inline" display (i.e., bypass slider and use of 'block' for quote elements)
2007.05.03 [1.2.0] added sliderPanel wrapper around quote to take advantage of core-supported slider animation.  Use "noslider"/"inline" keyword param to suppress use of slider.  Also added tooltips for click, delay, and click+delay modes.
2007.04.16 [1.1.2] code cleanup
2007.04.16 [1.1.1] onClick handling now supports sequential as well as random order
2007.04.14 [1.1.0] added onClick handling for selecting and display a new random quote
2005.10.21 [1.0.0] Initial Release.  Based on a suggestion by M.Russula
<<<
Name: REDD
HeaderTop: #300
HeaderMid: #f00
HeaderBottom: #900
Background: #fff
Foreground: #000
PrimaryPale: #fff
PrimaryLight: #000
PrimaryMid: #900
PrimaryDark: #000 
SecondaryPale: #fff
SecondaryLight: #900
SecondaryMid: #900
SecondaryDark: #000
TertiaryPale: #fff
TertiaryLight: #900
TertiaryMid: #000
TertiaryDark: #900
Error: #f88
/***
|Name|RearrangeTiddlersPlugin|
|Source|http://www.TiddlyTools.com/#RearrangeTiddlersPlugin|
|Version|0.0.0|
|Author|Joe Raii|
|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.refreshTiddler|
|Description|drag tiddlers by title to re-order story column display|

adapted from: http://www.cs.utexas.edu/~joeraii/dragn/#Draggable
changes by ELS:
* hijack refreshTiddler() instead of overridding createTiddler()
* find title element by className instead of elementID
* set cursor style via code instead of stylesheet
* set tooltip help text
* set tiddler "position:relative" when starting drag event, restore saved value when drag ends
* update 2006.08.07: use getElementsByTagName("*") to find title element, even when it is 'buried' deep in tiddler DOM elements (due to custom template usage)
* update 2007.03.01: use apply() to invoke hijacked core function
* update 2008.01.13: only hijack core function once.  (allows for dynamic loading of plugin via bookmarklet)

***/
//{{{

if (Story.prototype.rearrangeTiddlersHijack_refreshTiddler===undefined) {
Story.prototype.rearrangeTiddlersHijack_refreshTiddler = Story.prototype.refreshTiddler;
Story.prototype.refreshTiddler = function(title,template)
{
	this.rearrangeTiddlersHijack_refreshTiddler.apply(this,arguments);
	var theTiddler = document.getElementById(this.idPrefix + title); if (!theTiddler) return;
	var theHandle;
	var children=theTiddler.getElementsByTagName("*");
	for (var i=0; i<children.length; i++) if (hasClass(children[i],"title")) { theHandle=children[i]; break; }
	if (!theHandle) return theTiddler;

	Drag.init(theHandle, theTiddler, 0, 0, null, null);
	theHandle.style.cursor="move";
	theHandle.title="drag title to re-arrange tiddlers"
	theTiddler.onDrag = function(x,y,myElem) {
		if (this.style.position!="relative")
			{ this.savedstyle=this.style.position; this.style.position="relative"; }
		y = myElem.offsetTop;
		var next = myElem.nextSibling;
		var prev = myElem.previousSibling;
		if (next && y + myElem.offsetHeight > next.offsetTop + next.offsetHeight/2) { 
			myElem.parentNode.removeChild(myElem);
			next.parentNode.insertBefore(myElem, next.nextSibling);//elems[pos+1]);
			myElem.style["top"] = -next.offsetHeight/2+"px";
		}
		if (prev && y < prev.offsetTop + prev.offsetHeight/2) { 
			myElem.parentNode.removeChild(myElem);
			prev.parentNode.insertBefore(myElem, prev);
			myElem.style["top"] = prev.offsetHeight/2+"px";
		}
	};
	theTiddler.onDragEnd = function(x,y,myElem) {
		myElem.style["top"] = "0px";
		if (this.savedstyle!=undefined)
			this.style.position=this.savedstyle;
	}
	return theTiddler;
}
}

/**************************************************
 * dom-drag.js
 * 09.25.2001
 * www.youngpup.net
 **************************************************
 * 10.28.2001 - fixed minor bug where events
 * sometimes fired off the handle, not the root.
 **************************************************/

var Drag = {
	obj:null,

	init:
	function(o, oRoot, minX, maxX, minY, maxY) {
		o.onmousedown = Drag.start;
		o.root = oRoot && oRoot != null ? oRoot : o ;
		if (isNaN(parseInt(o.root.style.left))) o.root.style.left="0px";
		if (isNaN(parseInt(o.root.style.top))) o.root.style.top="0px";
		o.minX = typeof minX != 'undefined' ? minX : null;
		o.minY = typeof minY != 'undefined' ? minY : null;
		o.maxX = typeof maxX != 'undefined' ? maxX : null;
		o.maxY = typeof maxY != 'undefined' ? maxY : null;
		o.root.onDragStart = new Function();
		o.root.onDragEnd = new Function();
		o.root.onDrag = new Function();
	},

	start:
	function(e) {
		var o = Drag.obj = this;
		e = Drag.fixE(e);
		var y = parseInt(o.root.style.top);
		var x = parseInt(o.root.style.left);
		o.root.onDragStart(x, y, Drag.obj.root);
		o.lastMouseX = e.clientX;
		o.lastMouseY = e.clientY;
		if (o.minX != null) o.minMouseX = e.clientX - x + o.minX;
		if (o.maxX != null) o.maxMouseX = o.minMouseX + o.maxX - o.minX;
		if (o.minY != null) o.minMouseY = e.clientY - y + o.minY;
		if (o.maxY != null) o.maxMouseY = o.minMouseY + o.maxY - o.minY;
		document.onmousemove = Drag.drag;
		document.onmouseup = Drag.end;
		Drag.obj.root.style["z-index"] = "10";
		return false;
	},

	drag:
	function(e) {
		e = Drag.fixE(e);
		var o = Drag.obj;
		var ey = e.clientY;
		var ex = e.clientX;
		var y = parseInt(o.root.style.top);
		var x = parseInt(o.root.style.left);
		var nx, ny;
		if (o.minX != null) ex = Math.max(ex, o.minMouseX);
		if (o.maxX != null) ex = Math.min(ex, o.maxMouseX);
		if (o.minY != null) ey = Math.max(ey, o.minMouseY);
		if (o.maxY != null) ey = Math.min(ey, o.maxMouseY);
		nx = x + (ex - o.lastMouseX);
		ny = y + (ey - o.lastMouseY);
		Drag.obj.root.style["left"] = nx + "px";
		Drag.obj.root.style["top"] = ny + "px";
		Drag.obj.lastMouseX = ex;
		Drag.obj.lastMouseY = ey;
		Drag.obj.root.onDrag(nx, ny, Drag.obj.root);
		return false;
	},

	end:
	function() {
		document.onmousemove = null;
		document.onmouseup = null;
		Drag.obj.root.style["z-index"] = "0";
		Drag.obj.root.onDragEnd(parseInt(Drag.obj.root.style["left"]), parseInt(Drag.obj.root.style["top"]), Drag.obj.root);
		Drag.obj = null;
	},

	fixE:
	function(e) {
		if (typeof e == 'undefined') e = window.event;
		if (typeof e.layerX == 'undefined') e.layerX = e.offsetX;
		if (typeof e.layerY == 'undefined') e.layerY = e.offsetY;
		return e;
	}
};
//}}}
|''Name''|Red1Theme|
|''Description''|Custom Theme Spawned from MPTW by MTP 11.08.08|
|''Last Revision''|MTP 12.31.08|

!Author Mode
|PageTemplate|ImgPageTemplate|
|ViewTemplate|CustomViewTemplate|
|EditTemplate|CustomEditTemplate|
|StyleSheet|##StyleSheet|
|ColorPalette|ColorPalette|


!StyleSheet
/*{{{*/
[[CustomStyleSheet]]
[[StyleSheetShortcuts]]
[[PluginStyles]]

/* Background Image */
body {
	background-image: url("theme/red1.jpeg") !important;
	background-repeat: repeat;
}
#topMenu, .header, .headerNow {
	background: transparent !important;
}
/*}}}*/
|''Name''|Red3Theme|
|''Description''|Custom Theme Spawned from MPTW by MTP 11.08.08|
|''Last Revision''|MTP 12.31.08|

!Author Mode
|PageTemplate|ImgPageTemplate|
|ViewTemplate|CustomViewTemplate|
|EditTemplate|CustomEditTemplate|
|StyleSheet|##StyleSheet|
|ColorPalette|ColorPalette|


!StyleSheet
/*{{{*/
[[CustomStyleSheet]]
[[StyleSheetShortcuts]]
[[PluginStyles]]

/* Background Image */
body {
	background-image: url("theme/red3.jpeg") !important;
	background-repeat: repeat;
}
#topMenu, .header, .headerNow {
	background: transparent !important;
}
/*}}}*/
|''Name''|Red7Theme|
|''Description''|Custom Theme Spawned from MPTW by MTP 11.08.08|
|''Last Revision''|MTP 12.31.08|

!Author Mode
|PageTemplate|ImgPageTemplate|
|ViewTemplate|CustomViewTemplate|
|EditTemplate|CustomEditTemplate|
|StyleSheet|##StyleSheet|
|ColorPalette|ColorPalette|


!StyleSheet
/*{{{*/
[[CustomStyleSheet]]
[[StyleSheetShortcuts]]
[[PluginStyles]]

/* Background Image */
body {
	background-image: url("theme/red7.jpeg") !important;
	background-repeat: repeat;
}
#topMenu, .header, .headerNow {
	background: transparent !important;
}
/*}}}*/
Name: RednBlack
HeaderTop: #300
HeaderMid: #f30
HeaderBottom: #300
Background: #FFF
Foreground: #900
PrimaryPale: #fff
PrimaryLight: #D00
PrimaryMid: #000
PrimaryDark: #F30
SecondaryPale: #CCC
SecondaryLight: #EEE
SecondaryMid: #F30
SecondaryDark: #000
TertiaryPale: #CCC
TertiaryLight: #000
TertiaryMid: #999
TertiaryDark: #F30
Error: #F30
Test: #F6F
Old Stylesheets & Templates for reference
<<LaunchApplicationLink "Refresh Root Array" "Program relative to Tiddly html file" "images/array_root.bat">>
<<LaunchApplicationLink "Refresh Home Array" "Program relative to Tiddly html file" "images/home/array_home.bat">>
<<LaunchApplicationLink "Refresh Work Array" "Program relative to Tiddly html file" "images/work/array_work.bat">>
/%
|Name|RefreshTiddler|
|Source|http://www.TiddlyTools.com/#RefreshTiddler|
|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|link that forces a refresh of the current tiddler|

usage: <<tiddler RefreshTiddler with: "label" "tooltip">>

where label and tooltip are optional and default to "refresh" and "redisplay tiddler content", respectively.

%/<script label="refresh" title="redisplay tiddler content">
	var here=story.findContainingTiddler(place); if (!here) return false;
	story.refreshTiddler(here.getAttribute("tiddler"),null,true);
	return false;
</script><script>
	if ("$1"!="$"+"1") place.lastChild.innerHTML="$1";
	if ("$2"!="$"+"2") place.lastChild.title="$2";
</script>
There is a lot of flexibility and power in [[ReminderMacros]].  You can set a reminder to fire on a particular date like August 8th,  or a more non-specific date like "every Friday".  Edit this tiddler and view the source to see the ReminderSyntax
!!!!reminder examples:
reminder month:8 day:17 title:"@@color(red):August 17th@@"
reminder dayofweek:5 title:"Next Friday"
reminder day:13 dayofweek:5 title:"Next Friday the 13th"
reminder day:8 offsetdayofweek:2 title:"Second Tuesday of the Month"
For more advanced examples, see: [[Personal Reminders]] and [[Holidays]]
!!!!newReminder example:
You can use the newReminder macro to bring up a form to fill out.  Hitting Ok will append the reminder to the end of the current tiddler. You can also [[add a newReminder button to each tiddler|Add a newReminder button to each tiddler]].
{{{<<newReminder>>}}}
!!!![[showReminders]] example:
You can also use the showReminders macro to search through all of your tiddlers and list the ones that will fire within a range from today

For more advanced usage, see [[showReminders]] and [[showRemindersSyntax]].

{{{<<showReminders leadtime:30 >>}}}
<<showReminders leadtime:30 >>

This is the same showReminders call, but formatted as a table.

{{{<<showReminders leadtime:30 format:"|DIFF|TITLE|TIDDLER|" >>}}}
<<showReminders leadtime:30 format:"|DIFF|TITLE|TIDDLER|" >>

!!!!The next two reminders flag the 15th and 27th of every month to pay bills
*The low leadtime keeps these from showing up in the showReminders macro until 2 days before they are due.
reminder day:15 title:"Bill Day" leadtime:2
reminder day:27 title:"Bill Day" leadtime:2

!!!Reminder that fires once every N days
*This is a reminder that fires every three weeks.  It's imperative to specify a base date with year, month and day if you want this to return consistent dates.
reminder year:2005 month:7 day:31 recurdays:28 title:"Haircut Day"

!!!!Tracking the number of years that a reminder has happened
*This is a reminder that uses firstyear to specify when something started.  Very useful for birthdays and anniversaries.
reminder month:9 day:20 title:"TiddlyWiki's First Release Anniversary" leadtime:60 firstyear:2004
/***
|''Name:''|ReminderPlugin|
|''Version:''|2.3.10 (Jun 28, 2007)|
|''Source:''|http://remindermacros.tiddlyspot.com|
|''Author:''|Jeremy Sheeley(pop1280 [at] excite [dot] com)<<br>>Maintainer: simon.baird@gmail.com|
|''Licence:''|[[BSD open source license]]|
|''Macros:''|reminder, showreminders, displayTiddlersWithReminders, newReminder|
|''TiddlyWiki:''|2.0+|
|''Browser:''|Firefox 1.0.4+; InternetExplorer 6.0|

!Description
This plugin provides macros for tagging a date with a reminder.  Use the {{{reminder}}} macro to do this.  The {{{showReminders}}} and {{{displayTiddlersWithReminder}}} macros automatically search through all available tiddlers looking for upcoming reminders.

!Installation
* Create a new tiddler in your tiddlywiki titled ReminderPlugin and give it the {{{systemConfig}}} tag.  The tag is important because it tells TW that this is executable code.
* Double click this tiddler, and copy all the text from the tiddler's body.
* Paste the text into the body of the new tiddler in your TW.
* Save and reload your TW.
* You can copy some examples into your TW as well.  See [[ReminderExamples]], [[Holidays]], [[showReminders]] and [[Personal Reminders]]

!Syntax:
|>|See [[ReminderSyntax]] and [[showRemindersSyntax]]|

!Revision history
* v2.3.10 (Jun 28, 2007)
** Removed window.story = window backwards compatibility hacks since they were breaking TW 2.2
* v2.3.9 (Apr 26, 2007)
** allow bracketed list format in tags param lets you use tags with spaces
* v2.3.8 (Mar 9, 2006)
**Bug fix: A global variable had snuck in, which was killing FF 1.5.0.1
**Feature: You can now use TIDDLER and TIDDLERNAME in a regular reminder format
* v2.3.6 (Mar 1, 2006)
**Bug fix: Reminders for today weren't being matched sometimes.
**Feature:  Solidified integration with DatePlugin and CalendarPlugin
**Feature:  Recurring reminders will now return multiple hits in showReminders and the calendar.
**Feature:  Added TIDDLERNAME to the replacements for showReminders format, for plugins that need the title without brackets.
* v2.3.5 (Feb 8, 2006)
**Bug fix: Sped up reminders lots.  Added a caching mechanism for reminders that have already been matched.
* v2.3.4 (Feb 7, 2006)
**Bug fix: Cleaned up code to hopefully prevent the Firefox 1.5.0.1 crash that was causing lots of plugins 
to crash Firefox.  Thanks to http://www.jslint.com
* v2.3.3 (Feb 2, 2006)
**Feature: newReminder now has drop down lists instead of text boxes.
**Bug fix:  A trailing space in a title would trigger an infinite loop.
**Bug fix:  using tag:"birthday !reminder" would filter differently than tag:"!reminder birthday"
* v2.3.2 (Jan 21, 2006)
**Feature: newReminder macro, which will let you easily add a reminder to a tiddler. Thanks to Eric Shulman (http://www.elsdesign.com) for the code to do this.
** Bug fix: offsetday was not working sometimes
** Bug fix: when upgrading to 2.0, I included a bit to exclude tiddlers tagged with excludeSearch.  I've reverted back to searching through all tiddlers
* v2.3.1 (Jan 7, 2006)
**Feature: 2.0 compatibility
**Feature AlanH sent some code to make sure that showReminders prints a message if no reminders are found.
* v2.3.0 (Jan 3, 2006)
** Bug Fix:  Using "Last Sunday (-0)" as a offsetdayofweek wasn't working.
** Bug Fix:  Daylight Savings time broke offset based reminders (for example year:2005 month:8 day:23 recurdays:7 would match Monday instead of Tuesday during DST.

!Code
***/
//{{{

//============================================================================
//============================================================================
//           ReminderPlugin
//============================================================================
//============================================================================

version.extensions.ReminderPlugin = {major: 2, minor: 3, revision: 8, date: new Date(2006,3,9), source: "http://remindermacros.tiddlyspot.com/"};

//============================================================================
// Configuration
// Modify this section to change the defaults for 
// leadtime and display strings
//============================================================================

config.macros.reminders = {};
config.macros["reminder"] = {};
config.macros["newReminder"] = {};
config.macros["showReminders"] = {};
config.macros["displayTiddlersWithReminders"] = {};

config.macros.reminders["defaultLeadTime"] = [0,6000];
config.macros.reminders["defaultReminderMessage"] = "DIFF: TITLE on DATE ANNIVERSARY";
config.macros.reminders["defaultShowReminderMessage"] = "DIFF: TITLE on DATE ANNIVERSARY -- TIDDLER";
config.macros.reminders["defaultAnniversaryMessage"] = "(DIFF)";
config.macros.reminders["untitledReminder"] = "Untitled Reminder";
config.macros.reminders["noReminderFound"] = "Couldn't find a match for TITLE in the next LEADTIMEUPPER days."
config.macros.reminders["todayString"] = "Today";
config.macros.reminders["tomorrowString"] = "Tomorrow";
config.macros.reminders["ndaysString"] = "DIFF days";
config.macros.reminders["emtpyShowRemindersString"] = "There are no upcoming events";


//============================================================================
//  Code
// You should not need to edit anything 
// below this.  Make sure to edit this tiddler and copy 
// the code from the text box, to make sure that 
// tiddler rendering doesn't interfere with the copy 
// and paste.
//============================================================================

//this object will hold the cache of reminders, so that we don't
//recompute the same reminder over again.
var reminderCache = {};

config.macros.showReminders.handler = function showReminders(place,macroName,params)
{
   var now = new Date().getMidnight();
   var paramHash = {};
   var leadtime = [0,14];
   paramHash = getParamsForReminder(params);
   var bProvidedDate = (paramHash["year"] != null) || 
			(paramHash["month"] != null) || 
			(paramHash["day"] != null) || 
			(paramHash["dayofweek"] != null);
   if (paramHash["leadtime"] != null)
   {
      leadtime = paramHash["leadtime"];
      if (bProvidedDate)
      {
         //If they've entered a day, we need to make 
         //sure to find it.  We'll reset the 
         //leadtime a few lines down.
         paramHash["leadtime"] = [-10000, 10000];
      }
   }
   var matchedDate = now;
   if (bProvidedDate)
   {
      var leadTimeLowerBound = new Date().getMidnight().addDays(paramHash["leadtime"][0]);
      var leadTimeUpperBound = new Date().getMidnight().addDays(paramHash["leadtime"][1]);
      matchedDate = findDateForReminder(paramHash, new Date().getMidnight(), leadTimeLowerBound, leadTimeUpperBound); 
   }

   var arr = findTiddlersWithReminders(matchedDate, leadtime, paramHash["tag"], paramHash["limit"]);
   var elem = createTiddlyElement(place,"span",null,null, null);
   var mess = "";
   if (arr.length == 0)
   {
      mess += config.macros.reminders.emtpyShowRemindersString; 
   }
   for (var j = 0; j < arr.length; j++)
   {
      if (paramHash["format"] != null)
      {
         arr[j]["params"]["format"] = paramHash["format"];
      }
      else
      {
         arr[j]["params"]["format"] = config.macros.reminders["defaultShowReminderMessage"];
      }
      mess += getReminderMessageForDisplay(arr[j]["diff"], arr[j]["params"], arr[j]["matchedDate"], arr[j]["tiddler"]);
      mess += "\n";
   }
   wikify(mess, elem, null, null);
};


config.macros.displayTiddlersWithReminders.handler = function displayTiddlersWithReminders(place,macroName,params)
{
   var now = new Date().getMidnight();
   var paramHash = {};
   var leadtime = [0,14];
   paramHash = getParamsForReminder(params);
   var bProvidedDate = (paramHash["year"] != null) || 
			(paramHash["month"] != null) || 
			(paramHash["day"] != null) || 
			(paramHash["dayofweek"] != null);
   if (paramHash["leadtime"] != null)
   {
      leadtime = paramHash["leadtime"];
      if (bProvidedDate)
      {
         //If they've entered a day, we need to make 
         //sure to find it.  We'll reset the leadtime 
         //a few lines down.
         paramHash["leadtime"] = [-10000,10000];
      }
   }
   var matchedDate = now;
   if (bProvidedDate)
   {
      var leadTimeLowerBound = new Date().getMidnight().addDays(paramHash["leadtime"][0]);
      var leadTimeUpperBound = new Date().getMidnight().addDays(paramHash["leadtime"][1]);
      matchedDate = findDateForReminder(paramHash, new Date().getMidnight(), leadTimeLowerBound, leadTimeUpperBound); 
   }
   var arr = findTiddlersWithReminders(matchedDate, leadtime, paramHash["tag"], paramHash["limit"]);
   for (var j = 0; j < arr.length; j++)
   {
      displayTiddler(null, arr[j]["tiddler"], 0, null, false, false, false);
   }
};

config.macros.reminder.handler = function reminder(place,macroName,params)
{
   var dateHash = getParamsForReminder(params);
   if (dateHash["hidden"] != null)
   {
      return;
   }
   var leadTime = dateHash["leadtime"];
   if (leadTime == null)
   {
      leadTime = config.macros.reminders["defaultLeadTime"]; 
   }
   var leadTimeLowerBound = new Date().getMidnight().addDays(leadTime[0]);
   var leadTimeUpperBound = new Date().getMidnight().addDays(leadTime[1]);
   var matchedDate = findDateForReminder(dateHash, new Date().getMidnight(), leadTimeLowerBound, leadTimeUpperBound);
   if (!store.getTiddler) 
   {
      store.getTiddler=function(title) {return this.tiddlers[title];};
   }
   var title = window.story.findContainingTiddler(place).id.substr(7);
   if (matchedDate != null)
   {
      var diff = matchedDate.getDifferenceInDays(new Date().getMidnight());
      var elem = createTiddlyElement(place,"span",null,null, null);
      var mess = getReminderMessageForDisplay(diff, dateHash, matchedDate, title);
      wikify(mess, elem, null, null);
   }
   else
   {
      createTiddlyElement(place,"span",null,null, config.macros.reminders["noReminderFound"].replace("TITLE", dateHash["title"]).replace("LEADTIMEUPPER", leadTime[1]).replace("LEADTIMELOWER", leadTime[0]).replace("TIDDLERNAME", title).replace("TIDDLER", "[[" + title + "]]") );
   }
};

config.macros.newReminder.handler = function newReminder(place,macroName,params)
{
  var today=new Date().getMidnight();
  var formstring = '<html><form>Year: <select name="year"><option value="">Every year</option>';
  for (var i = 0; i < 5; i++)
  {
    formstring += '<option' + ((i == 0) ? ' selected' : '') + ' value="' + (today.getFullYear() +i) + '">' + (today.getFullYear() + i) + '</option>';
  }
  formstring += '</select>&nbsp;&nbsp;Month:<select name="month"><option value="">Every month</option>';
  for (i = 0; i < 12; i++)
  {
    formstring += '<option' + ((i == today.getMonth()) ? ' selected' : '') + ' value="' + (i+1) + '">' + config.messages.dates.months[i] + '</option>';
  }
  formstring += '</select>&nbsp;&nbsp;Day:<select name="day"><option value="">Every day</option>';
  for (i = 1; i < 32; i++)
  {
    formstring += '<option' + ((i == (today.getDate() )) ? ' selected' : '') + ' value="' + i + '">' + i + '</option>';
  }

formstring += '</select>&nbsp;&nbsp;Reminder Title:<input type="text" size="40" name="title" value="please enter a title" onfocus="this.select();"><input type="button" value="ok" onclick="addReminderToTiddler(this.form)"></form></html>';

  var panel = config.macros.slider.createSlider(place,null,"New Reminder","Open a form to add a new reminder to this tiddler");
  wikify(formstring ,panel,null,store.getTiddler(params[1]));
};

// onclick: process input and insert reminder at 'marker'
window.addReminderToTiddler = function(form) {
   if (!store.getTiddler) 
   {
      store.getTiddler=function(title) {return this.tiddlers[title];};
   }
   var title = window.story.findContainingTiddler(form).id.substr(7);
   var tiddler=store.getTiddler(title);
  var txt='\n<<reminder ';
  if (form.year.value != "")
    txt += 'year:'+form.year.value + ' ';
  if (form.month.value != "")
    txt += 'month:'+form.month.value + ' ';
  if (form.day.value != "")
    txt += 'day:'+form.day.value + ' ';
  txt += 'title:"'+form.title.value+'" ';
  txt +='>>';
   tiddler.set(null,tiddler.text + txt);
   window.story.refreshTiddler(title,1,true);
   store.setDirty(true);
};

function hasTag(tiddlerTags, tagFilters)
{
  //Make sure we respond well to empty tiddlerTaglists or tagFilterlists
  if (tagFilters.length==0 || tiddlerTags.length==0)
  {
    return true;
  }

  var bHasTag = false;
  
  /*bNoPos says: "'till now there has been no check using a positive filter"
     Imagine a filterlist consisting of 1 negative filter:
         If the filter isn't matched, we want hasTag to be true.
         Yet bHasTag is still false ('cause only positive filters cause bHasTag to change)
         
     If no positive filters are present bNoPos is true, and no negative filters are matched so we have not returned false
         Thus: hasTag returns true.
      
      If at any time a positive filter is encountered, we want at least one of the tags to match it, so we turn bNoPos to false, which
      means bHasTag must be true for hasTag to return true*/
  var bNoPos=true;
  
for (var t3 = 0; t3 < tagFilters.length; t3++)
  {
      for(var t2=0; t2<tiddlerTags.length; t2++)
      {
           if (tagFilters[t3].length > 1 && tagFilters[t3].charAt(0) == '!') 
           {
              if (tiddlerTags[t2] == tagFilters[t3].substring(1))
              {
                 //If at any time a negative filter is matched, we return false
                  return false;
              }
           }
           else 
           {
              if (bNoPos)
              {
                 //We encountered the first positive filter
                 bNoPos=false;
              }
              if (tiddlerTags[t2] == tagFilters[t3])
              {
                  //A positive filter is matched. As long as no negative filter is matched, hasTag will return true
                  bHasTag=true;
              }
           }
        }
    }
    return (bNoPos || bHasTag);
};

//This function searches all tiddlers for the reminder  //macro.  It is intended that other plugins (like //calendar) will use this function to query for 
//upcoming reminders.
//The arguments to this function filter out reminders //based on when they will fire.
//
//ARGUMENTS:
//baseDate is the date that is used as "now".  
//leadtime is a two element int array, with leadtime[0] 
//         as the lower bound and leadtime[1] as the
//         upper bound.  A reasonable default is [0,14]
//tags is a space-separated list of tags to use to filter 
//         tiddlers.  If a tag name begins with an !, then 
//         only tiddlers which do not have that tag will 
//         be considered.  For example "examples holidays"  
//         will search for reminders in any tiddlers that  
//         are tagged with examples or holidays and 
//         "!examples !holidays" will search for reminders 
//         in any tiddlers that are not tagged with 
//         examples or holidays.  Pass in null to search 
//         all tiddlers.
//limit.  If limit is null, individual reminders can 
//        override the leadtime specified earlier.  
//        Pass in 1 in order to override that behavior.

window.findTiddlersWithReminders = function findTiddlersWithReminders(baseDate, leadtime, tags, limit)
{
//function(searchRegExp,sortField,excludeTag)
//   var macroPattern = "<<([^>\\]+)(?:\\*)([^>]*)>>";
   var macroPattern = "<<(reminder)(.*)>>";
   var macroRegExp = new RegExp(macroPattern,"mg");
   var matches = store.search(macroRegExp,"title","");
   var arr = [];
   var tagsArray = null;
   if (tags != null)
   {
      // tagsArray = tags.split(" ");
      tagsArray = tags.readBracketedList(); // allows tags with spaces. thanks Robin Summerhill, 4-Oct-06.
   }
   for(var t=matches.length-1; t>=0; t--)
   {
      if (tagsArray != null)
      {
         //If they specified tags to filter on, and this tiddler doesn't 
	 //match, skip it entirely.
         if ( ! hasTag(matches[t].tags, tagsArray))
         {
            continue;
         }
      }

      var targetText = matches[t].text;
      do {
         // Get the next formatting match
         var formatMatch = macroRegExp.exec(targetText);
         if(formatMatch && formatMatch[1] != null && formatMatch[1].toLowerCase() == "reminder")
         {
            //Find the matching date.
            
            var params = formatMatch[2] != null ? formatMatch[2].readMacroParams() : {};
            var dateHash = getParamsForReminder(params);
            if (limit != null || dateHash["leadtime"] == null)
            {
               if (leadtime == null)
                   dateHash["leadtime"] = leadtime;
               else
               {
                  dateHash["leadtime"] = [];
                  dateHash["leadtime"][0] = leadtime[0];
                  dateHash["leadtime"][1] = leadtime[1];
               }
            }
	    if (dateHash["leadtime"] == null)
               dateHash["leadtime"] = config.macros.reminders["defaultLeadTime"]; 
            var leadTimeLowerBound = baseDate.addDays(dateHash["leadtime"][0]);
            var leadTimeUpperBound = baseDate.addDays(dateHash["leadtime"][1]);
            var matchedDate = findDateForReminder(dateHash, baseDate, leadTimeLowerBound, leadTimeUpperBound);
            while (matchedDate != null)
            {
               var hash = {};
               hash["diff"] = matchedDate.getDifferenceInDays(baseDate);
               hash["matchedDate"] = new Date(matchedDate.getFullYear(), matchedDate.getMonth(), matchedDate.getDate(), 0, 0);
               hash["params"] = cloneParams(dateHash);
               hash["tiddler"] = matches[t].title;
               hash["tags"] = matches[t].tags;
               arr.pushUnique(hash);
	       if (dateHash["recurdays"] != null || (dateHash["year"] == null))
	       {
	         leadTimeLowerBound = leadTimeLowerBound.addDays(matchedDate.getDifferenceInDays(leadTimeLowerBound)+ 1);
                 matchedDate = findDateForReminder(dateHash, baseDate, leadTimeLowerBound, leadTimeUpperBound);
	       }
	       else matchedDate = null;
            }
         }
      }while(formatMatch);
   }
   if(arr.length > 1)  //Sort the array by number of days remaining.
   {
      arr.sort(function (a,b) {if(a["diff"] == b["diff"]) {return(0);} else {return (a["diff"] < b["diff"]) ? -1 : +1; } });
   }
   return arr;
};

//This function takes the reminder macro parameters and
//generates the string that is used for display.
//This function is not intended to be called by 
//other plugins.
 window.getReminderMessageForDisplay= function getReminderMessageForDisplay(diff, params, matchedDate, tiddlerTitle)
{
   var anniversaryString = "";
   var reminderTitle = params["title"];
   if (reminderTitle == null)
   {
      reminderTitle = config.macros.reminders["untitledReminder"];
   }
   if (params["firstyear"] != null)
   {
      anniversaryString = config.macros.reminders["defaultAnniversaryMessage"].replace("DIFF", (matchedDate.getFullYear() - params["firstyear"]));
   }
   var mess = "";
   var diffString = "";
   if (diff == 0)
   {
      diffString = config.macros.reminders["todayString"];
   }
   else if (diff == 1)
   {
      diffString = config.macros.reminders["tomorrowString"];
   }
   else
   {
      diffString = config.macros.reminders["ndaysString"].replace("DIFF", diff);
   }
   var format = config.macros.reminders["defaultReminderMessage"];
   if (params["format"] != null)
   {
      format = params["format"];
   }
   mess = format;
//HACK!  -- Avoid replacing DD in TIDDLER with the date
   mess = mess.replace(/TIDDLER/g, "TIDELER");
   mess = matchedDate.formatStringDateOnly(mess);
   mess = mess.replace(/TIDELER/g, "TIDDLER");
   if (tiddlerTitle != null)
   {
      mess = mess.replace(/TIDDLERNAME/g, tiddlerTitle);
      mess = mess.replace(/TIDDLER/g, "[[" + tiddlerTitle + "]]");
   }
   
   mess = mess.replace("DIFF", diffString).replace("TITLE", reminderTitle).replace("DATE", matchedDate.formatString("DDD MMM DD, YYYY")).replace("ANNIVERSARY", anniversaryString);
   return mess;
};

// Parse out the macro parameters into a hashtable.  This
// handles the arguments for reminder, showReminders and 
// displayTiddlersWithReminders.
window.getParamsForReminder = function getParamsForReminder(params)
{
   var dateHash = {};
   var type = "";
   var num = 0;
   var title = "";
   for(var t=0; t<params.length; t++)
   {
      var split = params[t].split(":");
      type = split[0].toLowerCase();
      var value = split[1];
      for (var i=2; i < split.length; i++)
      {
         value += ":" + split[i];
      }
      if (type == "nolinks" || type == "limit" || type == "hidden")
      {
         num = 1;
      }
      else if (type == "leadtime")
      {
         var leads = value.split("...");
         if (leads.length == 1)
         {
            leads[1]= leads[0];
            leads[0] = 0;
         }
         leads[0] = parseInt(leads[0], 10);
         leads[1] = parseInt(leads[1], 10);
         num = leads;
      }
      else if (type == "offsetdayofweek")
      {
          if (value.substr(0,1) == "-")
          {
             dateHash["negativeOffsetDayOfWeek"] = 1;
	     value = value.substr(1);
          }
          num = parseInt(value, 10);
      }
      else if (type != "title" && type != "tag" && type != "format")
      {
         num = parseInt(value, 10);
      }
      else
      {
         title = value;
         t++;
         while (title.substr(0,1) == '"' && title.substr(title.length - 1,1) != '"' && params[t] != undefined)
         {
            title += " " + params[t++];
         }
         //Trim off the leading and trailing quotes
         if (title.substr(0,1) == "\"" && title.substr(title.length - 1,1)== "\"")
         {
            title = title.substr(1, title.length - 2);
            t--;
         }
         num = title;
      }
      dateHash[type] = num;
   }
   //date is synonymous with day
   if (dateHash["day"] == null)
   {
      dateHash["day"] = dateHash["date"];
   }
   return dateHash;
};

//This function finds the date specified in the reminder 
//parameters.  It will return null if no match can be
//found.  This function is not intended to be used by
//other plugins.
window.findDateForReminder= function findDateForReminder( dateHash, baseDate, leadTimeLowerBound, leadTimeUpperBound)
{
   if (baseDate == null)
   {
     baseDate = new Date().getMidnight();
   }
   var hashKey = baseDate.convertToYYYYMMDDHHMM();
   for (var k in dateHash)
   {
      hashKey += "," + k + "|" + dateHash[k];
   }
   hashKey += "," + leadTimeLowerBound.convertToYYYYMMDDHHMM();
   hashKey += "," + leadTimeUpperBound.convertToYYYYMMDDHHMM();
   if (reminderCache[hashKey] == null)
   {
      //If we don't find a match in this run, then we will
      //cache that the reminder can't be matched.
      reminderCache[hashKey] = false;
   }
   else if (reminderCache[hashKey] == false)
   {
      //We've already tried this date and failed
      return null;
   }
   else
   {
      return reminderCache[hashKey];
   }
   
   var bOffsetSpecified = dateHash["offsetyear"] != null || 
				dateHash["offsetmonth"] != null || 
				dateHash["offsetday"] != null || 
				dateHash["offsetdayofweek"] != null || 
				dateHash["recurdays"] != null;
   
   // If we are matching the base date for a dayofweek offset, look for the base date a 
   //little further back.
   var tmp1leadTimeLowerBound = leadTimeLowerBound;  
   if ( dateHash["offsetdayofweek"] != null)
   {
      tmp1leadTimeLowerBound = leadTimeLowerBound.addDays(-6);  
   }
   var matchedDate = baseDate.findMatch(dateHash, tmp1leadTimeLowerBound, leadTimeUpperBound);
   if (matchedDate != null)
   {
      var newMatchedDate = matchedDate;
      if (dateHash["recurdays"] != null)
      {
         while (newMatchedDate.getTime() < leadTimeLowerBound.getTime())
         {
            newMatchedDate = newMatchedDate.addDays(dateHash["recurdays"]);
         }
      }
      else if (dateHash["offsetyear"] != null || 
		dateHash["offsetmonth"] != null || 
		dateHash["offsetday"] != null || 
		dateHash["offsetdayofweek"] != null)
      {
         var tmpdateHash = cloneParams(dateHash);
         tmpdateHash["year"] = dateHash["offsetyear"];
         tmpdateHash["month"] = dateHash["offsetmonth"];
         tmpdateHash["day"] = dateHash["offsetday"];
         tmpdateHash["dayofweek"] = dateHash["offsetdayofweek"];
	 var tmpleadTimeLowerBound = leadTimeLowerBound;
	 var tmpleadTimeUpperBound = leadTimeUpperBound;
	 if (tmpdateHash["offsetdayofweek"] != null)
	 {
	 	if (tmpdateHash["negativeOffsetDayOfWeek"] == 1)
		{
		   tmpleadTimeLowerBound = matchedDate.addDays(-6);
		   tmpleadTimeUpperBound = matchedDate;

		}
		else
		{
		   tmpleadTimeLowerBound = matchedDate;
		   tmpleadTimeUpperBound = matchedDate.addDays(6);
		}

	 }
	 newMatchedDate = matchedDate.findMatch(tmpdateHash, tmpleadTimeLowerBound, tmpleadTimeUpperBound);
         //The offset couldn't be matched.  return null.
         if (newMatchedDate == null)
         {
            return null;
         }
      }
      if (newMatchedDate.isBetween(leadTimeLowerBound, leadTimeUpperBound))
      {
         reminderCache[hashKey] = newMatchedDate;
         return newMatchedDate;
      }
   }
   return null;
};

//This does much the same job as findDateForReminder, but
//this one doesn't deal with offsets or recurring 
//reminders.
Date.prototype.findMatch = function findMatch(dateHash, leadTimeLowerBound, leadTimeUpperBound)
{

   var bSpecifiedYear =     (dateHash["year"] != null);
   var bSpecifiedMonth =     (dateHash["month"] != null);
   var bSpecifiedDay =     (dateHash["day"] != null);
   var bSpecifiedDayOfWeek =     (dateHash["dayofweek"] != null);
   if (bSpecifiedYear && bSpecifiedMonth && bSpecifiedDay)
   {
      return new Date(dateHash["year"], dateHash["month"]-1, dateHash["day"], 0, 0);
   }
   var bMatchedYear = !bSpecifiedYear;
   var bMatchedMonth = !bSpecifiedMonth;
   var bMatchedDay = !bSpecifiedDay;
   var bMatchedDayOfWeek = !bSpecifiedDayOfWeek;
   if (bSpecifiedDay && bSpecifiedMonth && !bSpecifiedYear && !bSpecifiedDayOfWeek)
   {

      //Shortcut -- First try this year.  If it's too small, try next year.
      var tmpMidnight = this.getMidnight();
      var tmpDate = new Date(this.getFullYear(), dateHash["month"]-1, dateHash["day"], 0,0);
      if (tmpDate.getTime() < leadTimeLowerBound.getTime())
      {
         tmpDate = new Date((this.getFullYear() + 1), dateHash["month"]-1, dateHash["day"], 0,0);
      }
      if ( tmpDate.isBetween(leadTimeLowerBound, leadTimeUpperBound))
      {
         return tmpDate;
      }
      else
      {
         return null;
      }
   }

   var newDate = leadTimeLowerBound; 
   while (newDate.isBetween(leadTimeLowerBound, leadTimeUpperBound))
   {
      var tmp = testDate(newDate, dateHash, bSpecifiedYear, bSpecifiedMonth, bSpecifiedDay, bSpecifiedDayOfWeek);
      if (tmp != null)
        return tmp;
      newDate = newDate.addDays(1);
   }
};

function testDate(testMe, dateHash, bSpecifiedYear, bSpecifiedMonth, bSpecifiedDay, bSpecifiedDayOfWeek)
{
   var bMatchedYear = !bSpecifiedYear;
   var bMatchedMonth = !bSpecifiedMonth;
   var bMatchedDay = !bSpecifiedDay;
   var bMatchedDayOfWeek = !bSpecifiedDayOfWeek;
   if (bSpecifiedYear)
   {
      bMatchedYear = (dateHash["year"] == testMe.getFullYear());
   }
   if (bSpecifiedMonth)
   {
      bMatchedMonth = ((dateHash["month"] - 1)  == testMe.getMonth() );
   }
   if (bSpecifiedDay)
   {
      bMatchedDay = (dateHash["day"] == testMe.getDate());
   }
   if (bSpecifiedDayOfWeek)
   {
      bMatchedDayOfWeek = (dateHash["dayofweek"] == testMe.getDay());
   }

   if (bMatchedYear && bMatchedMonth && bMatchedDay && bMatchedDayOfWeek)
   {
      return testMe;
   }
};

//Returns true if the date is in between two given dates
Date.prototype.isBetween = function isBetween(lowerBound, upperBound)
{
  return (this.getTime() >= lowerBound.getTime() && this.getTime() <= upperBound.getTime());
}
//Return a new date, with the time set to midnight (0000)
Date.prototype.getMidnight = function getMidnight()
{
   return new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0);
};
// Add the specified number of days to a date.
Date.prototype.addDays = function addDays(numberOfDays)
{
   return new Date(this.getFullYear(), this.getMonth(), this.getDate() + numberOfDays, 0, 0);
};
//Return the number of days between two dates.
Date.prototype.getDifferenceInDays = function getDifferenceInDays(otherDate)
{
//I have to do it this way, because this way ignores daylight savings
   var tmpDate = this.addDays(0);
   if (this.getTime() > otherDate.getTime())
   {
      var i = 0;
      for (i = 0; tmpDate.getTime() > otherDate.getTime(); i++)
      {
         tmpDate = tmpDate.addDays(-1);
      }
      return i;
   }
   else
   {
      var i = 0;
      for (i = 0; tmpDate.getTime() < otherDate.getTime(); i++)
      {
         tmpDate = tmpDate.addDays(1);
      }
      return i * -1;
   }
   return 0;
};
function cloneParams(what) {
    var tmp = {};
    for (var i in what) {
        tmp[i] = what[i];
    }
    return tmp;
}
// Substitute date components into a string
Date.prototype.formatStringDateOnly = function formatStringDateOnly(template)
{
	template = template.replace("YYYY",this.getFullYear());
	template = template.replace("YY",String.zeroPad(this.getFullYear()-2000,2));
	template = template.replace("MMM",config.messages.dates.months[this.getMonth()]);
	template = template.replace("0MM",String.zeroPad(this.getMonth()+1,2));
	template = template.replace("MM",this.getMonth()+1);
	template = template.replace("DDD",config.messages.dates.days[this.getDay()]);
	template = template.replace("0DD",String.zeroPad(this.getDate(),2));
	template = template.replace("DD",this.getDate());
	return template;
};

//}}}
The reminder macro can take the following arguments.

!!!!date syntax
* @@{{{year:NUMBER}}}@@ - The four digit representation of the year (for example {{{year:2046}}} or {{{year:1999}}}
* @@{{{month:NUMBER}}}@@ - The numerical representation of the month (for example {{{month:1}}} for January, {{{month:12}}} for December)
* @@{{{day:NUMBER}}}@@ - The numerical representation of the day of the month (for example {{{day:15}}} will match the 15th day of the month)
* @@{{{dayofweek:NUMBER}}}@@ - The numerical representation of the day of the week.  Valid values are in the range of 0-6.  {{{dayofweek:0}}} will match Sunday, and {{{dayofweek:6}}} will match Saturday.

!!!!offsets
* @@{{{offsetdayofweek:NUMBER}}}@@ - The numerical representation of a day of the week.  Valid values are in the range of 0-6.  0 will match Sunday, and 6 will match Saturday.  If offsetdayofweek is specified, the year, month, day and dayofweek will be matched as usual, and the reminder will be set to the next occurence of the day of the week specified by offsetdayofweek. For example, the first Thursday of the month can be specified as {{{day:1 offsetdayofweek:4}}} and the second Thursday can be specified as {{{day:8 offsetdayofweek4}}} If offsetdayofweek is negative, the search will be performed backward.  For example, the last Thursday in August can be found by {{{month:8 day:31 offsetdayofweek:-4}}}
* @@{{{recurdays:NUMBER}}}@@ - If recurdays is set, then the reminder will fire on the base date specified by year, month, day, and dayofweek and also every N days afterward.  For example, if the reminder is specified with {{{year:2005 month:8 day:16 recurdays:2}}} it will match August 16, 18, 20, etc.  Please make sure that you fully specify year, month and day in any recurring reminder.

!!!!leadtime
* @@{{{leadtime:NUMBER}}}@@ - Use this to specify when this reminder will appear in [[showReminders]].  If a reminder has a leadtime of 2, it will only show up in showReminders if it will be matched in the next two days.  Likewise, a reminder with a leadtime of 60 will show up in showReminders even if showReminders has a lower leadtime.  showReminders can override this behavior with the limit argument.

!!!!Reminder display options
* @@{{{title:"STRING"}}}@@ - A string used to identify this reminder when it is shown in a list of reminders. For example, {{{title:"New Year's Day"}}} or {{{title:"Elvis' Birthday"}}}.  You can put standard TiddlyWiki formatting in the title.
* @@{{{format:"STRING"}}}@@ - Use this argument to override the default string used for display.  You can put standard TiddlyWiki formatting in the format.  The following substitutions will be made in the string before it is displayed.
** DIFF will be replaced with the one of the strings "Today", "Tommorrow", or "N days", where N is the number of days between now and the date of the reminder.  
** TITLE will be replaced with the title of the reminder
** DATE will be replaced with the matched date of the reminder.
** ANNIVERSARY will be replaced with the number of years since between the matched date and firstyear
The default string is "DIFF: TITLE on DATE ANNIVERSARY"
* @@{{{firstyear:NUMBER}}}@@ - The first year that a reminder occurred, in four digit format.  For example {{{firstyear:2001}}}.  This is used when calculating the number of years that a reminder has happened.
* @@{{{hidden}}}@@ - If this option is present, the reminder will not be displayed in the regular view of the tiddler.  You can use this to have reminders for [[displayTiddlersWithReminders]] to find, without having the countdown appear.  See [[Season's Greetings example]] for an example.
!!Reminders
<<showReminders>>
/***
| 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();

//}}}
/***
Found @ http://tiddlywikitips.com/TiddlyWikiTasks.html
Intended for use in ViewTemplate
Example from ViewTemplate
<span style="padding-right:0.75em;" class='fakeButton' macro="runMacroIfTagged Plugins toggleTag systemConfig"></span>
!Examples
|{{{<<runMacroIfTagged [[Groceries]] toggleTag Buy>>}}}|<<runMacroIfTagged [[Groceries]] toggleTag Buy>>|
|{{{<<runMacroIfTagged systemConfig toggleTag systemConfigDisable>>}}}|<<runMacroIfTagged systemConfig toggleTag systemConfigDisable>>|
***/
//{{{

// This function contributed by Eric Shulman
function toggleTag(title,tag) {
  var t=store.getTiddler(title); if (!t || !t.tags) return;
  if (t.tags.find(tag)==null) t.tags.push(tag)
  else t.tags.splice(t.tags.find(tag),1)
}

// This function contributed by Eric Shulman
function isTagged(title,tag) {
  var t=store.getTiddler(title); if (!t) return false;
  return (t.tags.find(tag)!=null);
}

config.macros.runMacroIfTagged = {};
config.macros.runMacroIfTagged.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
	if (isTagged(tiddler.title,params[0]))
		config.macros[params[1]].handler(place,params[1],params.slice(2),wikifier,paramString/*fixme*/,tiddler);
}

//}}}
/***
!Todo
* paramString needs to have the first word removed from the front of it at fixme above
***/
Name: STRM Blue 1
HeaderTop: #fff
HeaderMid: #699bcc
HeaderBottom: #14163d
Background:#06c
Foreground: #fff
PrimaryPale: #9eccf9
PrimaryLight: #fff
PrimaryMid: #14163d
PrimaryDark: #72a3e4
SecondaryPale: #0252b1
SecondaryLight: #1e90ff
SecondaryMid: #9be1ff
SecondaryDark: #9be1ff
TertiaryPale: #586588
TertiaryLight: #14163d
TertiaryMid: #ccc
TertiaryDark: #000
Error: #f00
Test: #0F0
Name: STRM Blue 2
HeaderTop: #699bcc
HeaderMid: #bbb
HeaderBottom: #06c
Background: #222
Foreground: #fff
PrimaryPale: #9eccf9
PrimaryLight: #fff
PrimaryMid: #06c
PrimaryDark: #72a3e4
SecondaryPale: #0252b1
SecondaryLight: #1e90ff
SecondaryMid: #9be1ff
SecondaryDark: #9be1ff
TertiaryPale: #ddd
TertiaryLight: #06c
TertiaryMid: #ccc
TertiaryDark: #ccc
Error: #f00
Test: #0f0
Name: STRM Blue 3
HeaderTop: #fff
HeaderMid: #06c
HeaderBottom: #14163d
Background:#aaa
Foreground: #fff
PrimaryPale: #9eccf9
PrimaryLight: #fff
PrimaryMid: #14163d
PrimaryDark: #72a3e4
SecondaryPale: #0252b1
SecondaryLight: #1e90ff
SecondaryMid: #9be1ff
SecondaryDark: #9be1ff
TertiaryPale: #ddd
TertiaryLight: #14163d
TertiaryMid: #555
TertiaryDark: #000
Error: #f00
Test: #0f0
!!!My Personal TiddlyWiki Experiment and Idea Holder @@color:#000;''(<html><a href="javascript:;"onclick="window.location.reload( false );">Reload</a></html>)''@@
{{small{<script>
javascript:(function(){document.write('\nLast modified: '+document.lastModified);})()
</script>}}}[>img(40%,auto)[Click for Full size (Eris Sig)|Images/erissigyb1.jpg][ES]]
/%http://www.TiddlyTools.com/#ShowTiddlerStatistics%/
<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="{{nowrap{";
	out+="There are [["+tiddlers.length+" tiddlers|SideBarTabs]], including ";
	out+="''<<tag systemConfig [["+store.getTaggedTiddlers("systemConfig").length+" plugins]]>>''and ";
	out+="''<<tag Tricks [["+store.getTaggedTiddlers("Tricks").length+" Tricks]]>>''";
	out+="{{fine{("+total+" bytes)}}}\n";
	out+="|borderless|k\n";
	out+="| last change:&nbsp;|[["+last.title+"]]";
	out+=" {{fine{(updated "+last.modified.formatString("MMM DDth YYYY, 0hh:0mm")+")}}}|\n";
	out+="| newest:&nbsp;|[["+newtid.title+"]]";
	out+=" {{fine{(created "+newtid.created.formatString("MMM DDth YYYY, 0hh:0mm")+")}}}|\n";
	out+="| oldest:&nbsp;|[["+oldtid.title+"]]";
	out+=" {{fine{(created "+oldtid.created.formatString("MMM DDth YYYY, 0hh:0mm")+")}}}|\n";
	out+="| smallest:&nbsp;|[["+smalltid.title+"]]";
	out+=" {{fine{("+smalltid.text.length+" bytes)}}}|\n";
	out+="| largest:&nbsp;|[["+largetid.title+"]]";
	out+=" {{fine{("+largetid.text.length+" bytes)}}}|\n";
	out+="}}}";
	return(out);
</script>

{{smallform{<<tiddlerTweaker>>}}}
/***
|Name|SaveAndReloadMacro|
|Created by|SaqImtiaz|
|Location|http://tw.lewcid.org/#SaveAndReloadMacro|
|Version|1.0|
|Requires|~TW2.x|
!Description:
Provides a button to save and reload TW. Useful if you are testing code and dont have AutoSave enabled.

!Demo:
{{{<<saveAndReload>>}}}<<saveAndReload>>

!Installation:
Copy the contents of this tiddler to your TW, tag with systemConfig, save and reload your TW.

!History:
*24-07-06: ver 1.0

!Code
***/
//{{{
config.macros.saveAndReload={};
config.macros.saveAndReload.handler= function(place,macroName,params,wikifier,paramString,tiddler)
{
        var label = params[0]||"Save & Reload";
        var tooltip = params[1]||"Save & reload";
        createTiddlyButton(place,label,tooltip,this.onclick);
}
config.macros.saveAndReload.onclick= function()
{
       saveChanges();
       window.location.reload( false );
}
//}}}
/***
|Name|SaveAsPlugin|
|Source|http://www.TiddlyTools.com/#SaveAsPlugin|
|Documentation|http://www.TiddlyTools.com/#SaveAsPluginInfo|
|Version|2.3.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|Save current document to a different path/filename|
This plugin automatically adds a 'save as' command to the TiddlyWiki 'backstage' menu that allows you to quickly create an exact copy of the current TiddlyWiki document.  The plugin also defines a macro that you can use to place a "save as..." command link into your sidebar/mainmenu/any tiddler (or wherever you like).
>//Note: This plugin now supersedes [[NewDocumentPlugin]], which has been retired and is no longer being distributed.  In addition, the HTML+CSS "snapshot" functionality previous provided by that plugin has been moved to a separate plugin.  Please see [[SnapshotPlugin]] for additional information.//
!!!!!Documentation
<<<
see [[SaveAsPluginInfo]]
<<<
!!!!!Revisions
<<<
2008.09.19 [2.3.2] fixed backstage SaveAs command (was defaulting to empty document).  in formatItem(), removed unnecessary convertUnicodeToUTF8() (was causing double-conversion!)
2008.09.16 [2.3.1] fixed IE 'navigate away' error by returning false from button onclick handler
2008.09.11 [2.3.0] added support for alternative file formats: ~PlainText (TX), ~PureStore (PS), or ~NewsFeed (XML) in addition to existing ~TiddlyWiki (TW) document format
| Please see [[SaveAsPluginInfo]] for additional revision details |
2006.02.03 [1.0.0] Created.
<<<
!!!!!Code
***/
//{{{
version.extensions.SaveAsPlugin= {major: 2, minor: 3, revision: 2, date: new Date(2008,9,19)};

config.macros.saveAs = {
	label: "save as...",
	labelparam: "label:",
	prompt: "Save current document to a different path/file",
	promptparam: "prompt:",
	filePrompt: "Please select or enter a target path/filename",
	defaultFilename: "new.html",
	typeparam: "type:",
	type_TW: "tw", type_PS: "ps", type_TX: "tx", type_NF: "nf", // file type tokens
	type_map: { // map filetype param alternatives/abbreviations to token values
		tiddlywiki:"tw", tw:"tw", wiki: "tw",
		purestore: "ps", ps:"ps", store:"ps",
		plaintext: "tx", tx:"tx", text: "tx",
		newsfeed:  "nf", nf:"nf", xml:  "nf", rss:"nf"
	},
	quietparam: "quiet",
	openparam: "open",
	askParam: "ask",
	askMsg: "Enter a tag filter (use * for all tiddlers, 'none' for blank document)",
	emptyParam: "none",
	confirmmsg: "Found %0 tiddlers matching\n\n'%1'\n\nPress OK to proceed",
	mergeprompt: "%0\nalready contains tiddler definitions.\n"
		+"\nPress OK to add new/revised tiddlers to current file contents."
		+"\nPress Cancel to completely replace file contents",
	mergestatus: "Merged %0 new/revised tiddlers and %1 existing tiddlers",
	okmsg: "%0 tiddlers written to %1",
	failmsg: "An error occurred while creating %1",
	filter: "",
	handler: function(place,macroName,params) {
		if (params[0] && params[0].substr(0,this.labelparam.length)==this.labelparam)
			var label=params.shift().substr(this.labelparam.length);
		if (params[0] && params[0].substr(0,this.promptparam.length)==this.promptparam)
			var prompt=params.shift().substr(this.promptparam.length);
		if (params[0] && params[0].substr(0,this.typeparam.length)==this.typeparam)
			var filetype=this.type_map[params.shift().substr(this.typeparam.length).toLowerCase()];
		var quiet=(params[0] && params[0]==this.quietparam); if (quiet) params.shift();
		var autoopen=(params[0] && params[0]==this.openparam); if (autoopen) params.shift();
		var btn=createTiddlyButton(place,label||this.label,prompt||this.prompt,
			function(){config.macros.saveAs.go(
				this.getAttribute('filetype'),
				this.getAttribute('filter'),
				this.getAttribute('quiet')=="true",
				this.getAttribute('autoopen')=="true");  return false;}
		);
		btn.setAttribute("filetype",filetype||this.type_TW);
		btn.setAttribute("filter",params.join(" "));
		btn.setAttribute("quiet",quiet?"true":"false");
		btn.setAttribute("autoopen",autoopen?"true":"false");
	},
	go: function(filetype,filter,quiet,autoopen) {
		var cm=config.messages; // abbreviation
		var cms=config.macros.saveAs; // abbreviation
		if (window.location.protocol!="file:") // make sure we are local
			{ displayMessage(cm.notFileUrlError); return; }

		// get tidders, confirm filtered results
		var tids=cms.selectTiddlers(filter);
		if (tids===false) return; // cancelled by user
		if (cms.filter!=cms.emptyParam && cms.filter.length && !quiet)
			if (!confirm(cms.confirmmsg.format([tids.length,cms.filter]))) return;

		// get target path/filename
		if (!filetype) filetype=this.type_TW;
		var target=cms.getTarget(filetype==this.type_TX?'txt':'html');
		if (!target) return; // cancelled by user

		var notes="";
		var total={val:0};
		var out=this.assembleFile(target,filetype,tids,notes,total);
		var link="file:///"+target.replace(/\\/g,'/');
		var ok=saveFile(target,out);
		displayMessage((ok?this.okmsg:this.failmsg).format([total.val,target]),link);
		if (ok && autoopen) { var w=window.open(link); w.focus(); }
	},
	selectTiddlers: function(filter) {
		var cms=config.macros.saveAs; // abbreviation
		cms.filter=filter||"";
		if (filter==cms.emptyParam) return [];
		if (!filter||!filter.length) return store.getTiddlers("title");
		// get filtered tiddlers
		if (filter==config.macros.saveAs.askParam) {
			filter=prompt(config.macros.saveAs.askMsg,"");
			if (!filter) return false;  // cancelled by user
			cms.filter=filter=="*"?"":filter;
			if (filter=="*") return store.getTiddlers("title");
		}
		return store.filterTiddlers("[tag["+filter+"]]");
	},
	getTarget: function(defExt) {
		var cms=config.macros.saveAs; // abbreviation
		// get new target path/filename
		var newPath=getLocalPath(window.location.href);
		var slashpos=newPath.lastIndexOf("/"); if (slashpos==-1) slashpos=newPath.lastIndexOf("\\"); 
		if (slashpos!=-1) newPath=newPath.substr(0,slashpos+1); // trim filename
		var defFilename=cms.defaultFilename.replace(/.html$/,'.'+defExt);
		var target=cms.askForFilename(cms.filePrompt,newPath,defFilename,defExt);
		if (!target) return; // cancelled by user
		// if specified file does not include a path, assemble fully qualified path and filename
		var slashpos=target.lastIndexOf("/"); if (slashpos==-1) slashpos=target.lastIndexOf("\\");
		if (slashpos==-1) target=target+cms.defaultFilename;
		return target;
	},
	askForFilename: function(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);
				var thispath = Components.classes['@mozilla.org/file/local;1'].createInstance(Components.interfaces.nsILocalFile);
				thispath.initWithPath(path);
				picker.displayDirectory=thispath;
				picker.defaultExtension=defExt||'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/Vista only
				var s = new ActiveXObject('UserAccounts.CommonDialog');
				s.Filter='All files|*.*|Text files|*.txt|HTML files|*.htm;*.html|';
				s.FilterIndex=(defExt=='txt')?2: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;
	},
	plainTextHeader:
		 '// Source'+':\n//\t%0\n'
		+'// Title:\n//\t%1\n'
		+'// Subtitle:\n//\t%2\n'
		+'// Created:\n//\t%3 by %4\n'
		+'// Application:\n//\tTiddlyWiki %5 / %6 %7\n',
	plainTextTiddler:
		'\n// ----- %0 (by %1 on %2) -----\n\n%3',
	plainTextFooter:
		'',
	newsFeedHeader:
		 '<'+'?xml version="1.0"?'+'>\n'
		+'<rss version="2.0">\n'
		+'<channel>\n'
		+'<title>%1</title>\n'
		+'<link>%0</link>\n'
		+'<description>%2</description>\n'
		+'<language>en-us</language>\n'
		+'<copyright>Copyright '+(new Date().getFullYear())+' %4</copyright>\n'
		+'<pubDate>%3</pubDate>\n'
		+'<lastBuildDate>%3</lastBuildDate>\n'
		+'<docs>http://blogs.law.harvard.edu/tech/rss</docs>\n'
		+'<generator>TiddlyWiki %5 / %6 %7</generator>\n',
	newsFeedTiddler:
		'\n%0\n',
	newsFeedFooter:
		'</channel></rss>',
	pureStoreHeader:
		 '<html><body>'
		+'<style type="text/css">'
		+'	#storeArea {display:block;margin:1em;}'
		+'	#storeArea div {padding:0.5em;margin:1em;border:2px solid black;height:10em;overflow:auto;}'
		+'	#pureStoreHeading {width:100%;text-align:left;background-color:#eeeeee;padding:1em;}'
		+'</style>'
		+'<div id="pureStoreHeading">'
		+'	TiddlyWiki "PureStore" export file<br>'
		+'	Source'+': <b>%0</b><br>'
		+'	Title: <b>%1</b><br>'
		+'	Subtitle: <b>%2</b><br>'
		+'	Created: <b>%3</b> by <b>%4</b><br>'
		+'	TiddlyWiki %5 / %6 %7<br>'
		+'	Notes:<hr><pre>%8</pre>'
		+'</div>'
		+'<div id="storeArea">',
	pureStoreTiddler:
		'%0\n%1',
	pureStoreFooter:
		'</div><!--POST-BODY-START-->\n<!--POST-BODY-END--></body></html>',
	assembleFile: function(target,filetype,tids,notes,total) {
		var revised="";
		var now = new Date().toLocaleString();
		var src=convertUnicodeToUTF8(document.location.href);
		var title = convertUnicodeToUTF8(wikifyPlain("SiteTitle").htmlEncode());
		var subtitle = convertUnicodeToUTF8(wikifyPlain("SiteSubtitle").htmlEncode());
		var user = convertUnicodeToUTF8(config.options.txtUserName.htmlEncode());
		var twver = version.major+"."+version.minor+"."+version.revision;
		var v=version.extensions.SaveAsPlugin; var pver = v.major+"."+v.minor+"."+v.revision;
		var headerargs=[src,title,subtitle,now,user,twver,"SaveAsPlugin",pver,notes];
		switch (filetype) {
			case this.type_TX: // plain text
				var header=this.plainTextHeader.format(headerargs);
				var footer=this.plainTextFooter;
				break;
			case this.type_NF: // news feed (XML)
				headerargs[0]=store.getTiddlerText("SiteUrl","");
				var header=this.newsFeedHeader.format(headerargs);
				var footer=this.newsFeedFooter;
				break;
			case this.type_PS: // PureStore (no code)
				var header=this.pureStoreHeader.format(headerargs);
				var footer=this.pureStoreFooter;
				break;
			case this.type_TW: // full TiddlyWiki
			default:
				var currPath=getLocalPath(window.location.href);
				var original=loadFile(currPath);
				if (!original) { displayMessage(config.messages.cantSaveError); return; }
				var posDiv = locateStoreArea(original);
				if (!posDiv) { displayMessage(config.messages.invalidFileError.format([currPath])); return; }
				var header = original.substr(0,posDiv[0]+startSaveArea.length)+"\n";
				var footer = "\n"+original.substr(posDiv[1]);
				break;
		}
		var out=this.getData(target,filetype,tids);
		var revised = header+convertUnicodeToUTF8(out.join("\n"))+footer;
		// if full TW, insert page title and language attr, and reset all MARKUP blocks...
		if (filetype==this.type_TW) {
			var newSiteTitle = convertUnicodeToUTF8(getPageTitle()).htmlEncode();
			revised = revised.replaceChunk("<title"+">","</title"+">"," " + newSiteTitle + " ");
			revised = updateLanguageAttribute(revised);
			revised = updateMarkupBlock(revised,"PRE-HEAD");
			revised = updateMarkupBlock(revised,"POST-HEAD");
			revised = updateMarkupBlock(revised,"PRE-BODY");
			revised = updateMarkupBlock(revised,"POST-SCRIPT");
		}
		total.val=out.length;
		return revised;
	},
	formatItem: function(s,f,t,u) {
		if (f==this.type_TW)
			var r=s.getSaver().externalizeTiddler(s,t);
		if (f==this.type_PS)
			var r=this.pureStoreTiddler.format([t.title,s.getSaver().externalizeTiddler(s,t)]);
		if (f==this.type_NF)
			var r=this.newsFeedTiddler.format([t.saveToRss(u)]);
		if (f==this.type_TX)
			var r=this.plainTextTiddler.format([t.title,t.modifier,t.modified.toLocaleString(),t.text]);
		return r||"";
	},
	getData: function(target,filetype,tids) {
		// output selected tiddlers and gather list of titles (for use with merge)
		var out=[]; var titles=[];
		var url=store.getTiddlerText("SiteUrl","");
		for (var i=0; i<tids.length; i++) {
			out.push(this.formatItem(store,filetype,tids[i],url));
			titles.push(tids[i].title);
		}
		// if TW or PureStore format, ask to merge with existing tiddlers (if any)
		if (filetype==this.type_TW || filetype==this.type_PS) {
			var text=loadFile(target);
			if (text && text.length) {
				var remoteStore=new TiddlyWiki();
				if (remoteStore.importTiddlyWiki(text) && confirm(this.mergeprompt.format([target]))) {
					var existing=remoteStore.getTiddlers("title");
					for (var i=0; i<existing.length; i++)
						if (!titles.contains(existing[i].title))
							out.push(this.formatItem(remoteStore,filetype,existing[i],url));
					displayMessage(this.mergestatus.format([tids.length,out.length-tids.length]));
				}
			}
		}
		return out;
	}
};
//}}}
//{{{
// automatically add saveAs to backstage
config.tasks.saveAs = {
	text: "saveAs",
	tooltip: config.macros.saveAs.prompt,
	action: function(){ clearMessage(); config.macros.saveAs.go(); }
}
config.backstageTasks.splice(config.backstageTasks.indexOf("save")+1,0,"saveAs");
//}}}
/***
| 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;
		}
	}

});

//}}}
The <script>return store.getTaggedTiddlers("Script").length.toString();
</script> tiddlers tagged [[Script]] use InlineJavascriptPlugin to embed javascript code directly in tiddler content.
<<search>>

Insert following line in hover menu - need to figure out css styling
{{{<<slider chkSlider SearchMenu ?>>}}}

See:
http://angusprune.googlepages.com/test.html
~~My Section~~
<<tiddler SourceTiddler##MySection>>
~~My Slice~~
<<tiddler "SourceTiddler::MySlice">>
/***
| 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|
| Removed Last line of Code MTP 11.09.08|{{{config.shadowTiddlers.OptionsPanel = "<<selectPalette>>\n\n" + config.shadowTiddlers.OptionsPanel;}}}|

/***
!!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();
		}
	}
});

//}}}
/%
|Name|SetTiddlerBackground|
|Source|http://www.TiddlyTools.com/#SetTiddlerBackground|
|Version|1.1.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|script|
|Requires|InlineJavascriptPlugin|
|Overrides||
|Description|set tiddler background and font color CSS attributes|

usage:
	<<tiddler SetTiddlerBackground with: bgstyle fgstyle matchtag class>>
where:
	'bgstyle' and 'fgstyle' (optional, but specify at least one)
		are CSS background style attributes (most often color values, e.g., #rgb or #rrggbb)
	'matchtag' (optional)
		is a tag value that allows selective control of tiddler background/foreground colors
	'class' (optional)
		is the class of the tiddler element to which the fgstyle/bgstyle will be applied (default is "viewer").
		Use "title" to set the background of the tiddler's 'title' area instead of its 'viewer' area.

The bgstyle and fgstyle assignments are only performed if the tiddler has the matching tag (or if no matchtag value is specfied).  In addition, to set just the background or the foreground color (but not both), you can use a dash ("-") as a placeholder value for whichever value you do NOT want to set.  For example:
	<<tiddler SetTiddlerBackground with: #F00 - urgent>>
sets the background color (but NOT the foreground color) to RED for only those tiddlers tagged with "urgent".  Also, note that in that instead of using #RGB color definitions, you can also use CSS color keywords (i.e., "red", "yellow", "green") or *any* other valid CSS value that can be applied to the 'background' style attribute.  For example, to use a background image for any tiddler tagged with "wallpaper", you can write:
        <<tiddler SetTiddlerBackground with: url(images/bg.jpg) - wallpaper>>

You can use this script several times in a row to define a set of tag-to-color mappings, stored in a *single* convenient tiddler... first, create a tiddler (e.g. [[BackgroundColors]]) containing something like this:
	<<tiddler SetTiddlerBackground with: red - urgent>>
	<<tiddler SetTiddlerBackground with: yellow - active>>
	<<tiddler SetTiddlerBackground with: green - done>>

To apply tag-based color mapping to any specific tiddler, just embed:
	<<tiddler BackgroundColors>>
directly in that tiddler's content and set the appropriate tag to select the desired background color.

To apply tag-based color mapping to ALL tiddlers in your document without having to embed the <<tiddler BackgroundColors>> macro into each 'colorized' tiddler, add:
        <span macro="tiddler BackgroundColors" style="display:none"></span>
in your [[ViewTemplate]].  Then, anytime you want to add another tag-to-color mapping, all you have to do is just edit the [[BackgroundColors]] tiddler and then start tagging the desired tiddlers accordingly.

%/<script>
	if ("$1"!="$"+"1" && "$1"!="-") var bg="$1";
	if ("$2"!="$"+"2" && "$2"!="-") var fg="$2";
	if ("$3"!="$"+"3" && "$3"!="-") var tag="$3";
	if ("$4"!="$"+"4" && "$4"!="-") var c="$4"; else var c="viewer";
	var here=story.findContainingTiddler(place); if (!here) return;
	var tiddler=store.getTiddler(here.getAttribute("tiddler"));
	if (tag && (!tiddler||!tiddler.isTagged(tag))) return;
	if (c=="tiddler") target=here;
	else {
		var children=here.getElementsByTagName("*");
		for (var i=0; i<children.length; i++)
			if (hasClass(children[i],c)) { var target=children[i]; break; }
	}
	if (!target) return;
	if (bg) target.style.background=bg;
	if (fg) target.style.color=fg;
</script>
/***
|Name|SetUserNamePlugin|
|Source|http://www.TiddlyTools.com/#SetUserNamePlugin|
|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|plugin|
|Requires||
|Overrides||
|Description|prompt for TiddlyWiki username|
!!!!!Usage
<<<
{{{
<<setUserName force>>
}}}
This macro prompts for a new username if the default username ("YourName") is currently set.  Use optional 'force' keyword to trigger a prompt even if username has already been set.

If you are using the default (shadow) EditTemplate definition, it will be updated to invoke this macro, via the following template syntax:
{{{
<span macro='setUserName'></span>
}}}
so that whenever a user attempts to edit/create a tiddler AND have not yet entered a username, they will be automatically prompted to enter a new username.  If you are using a customized EditTemplate, you will need to edit it yourself to add the above.
<<<
!!!!!Revisions
<<<
2006.12.01 [1.0.0] initial release - converted from SetUserName inline script
<<<
!!!!!Code
***/
//{{{
version.extensions.SetUserNamePlugin= {major: 1, minor: 0, revision: 0, date: new Date(2006,12,1)};

config.macros.setUserName = {
	msg: "Please set your username",
	handler: function(place,macroName,params) {
		// only prompt when needed or forced
		var force=params[0]&&params[0].toLowerCase()=="force";
		if (!force && (readOnly || config.options.txtUserName!="YourName")) return;
		var opt="txtUserName";
		var who=prompt(this.msg,config.options[opt]);
		if (!who||!who.trim().length) return; // cancelled by user
		config.options[opt]=who;
		saveOptionCookie(opt);
		config.macros.option.propagateOption(opt,"value",config.options[opt],"input");
	}
}

// add trigger to default shadow EditTemplate (custom templates: add this by hand)
config.shadowTiddlers.EditTemplate+="<span macro='setUserName'></span>";
//}}}
<<timeline "modified" "15" "0MM.0DD.YYYY">> 
/%
|Name|ShowAllByTags|
|Source|http://www.TiddlyTools.com/#ShowAllByTags|
|Version|1.1.0|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|script|
|Requires|InlineJavascriptPlugin|
|Description|for each tag, show a numbered list of all tiddlers with that tag|

Usage:
	<<tiddler ShowAllByTags with: "tag tag tag">>
where
	"tag tag tag" (optional)
		quoted, space-separated, bracketed list of tags to **exclude** from the display

!Revisions
2008.08.04 [1.1.0] added optional parameter to exclude specified tags
!end Revisions

%/<script>
	var ex=[];
	if ("$1"!="$"+"1") ex="$1".readBracketedList();
	var tags = store.getTags();
	if(tags.length == 0) return "no tags in document";
	var out="";
	for(var t=0; t<tags.length; t++) {
		if (ex.contains(tags[t][0])) continue;
		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>
/%
|Requires|InlineJavascriptPlugin|
|Description|tag list with exclude filter|
|Source|http://groups.google.com/group/tiddlywiki/browse_thread/thread/fc474311e7a65dc/df94ec42103fdd5f?lnk=gst&q=ShowAllByTags#df94ec42103fdd5f|
Usage:
	<<tiddler ShowAllByTagsB with: "tag tag tag">>
where
	"tag tag tag" (optional)
		quoted, space-separated, bracketed list of tags to **exclude** from the display
%/<script>
var ex=[];
if ("$1"!="$"+"1") ex="$1".readBracketedList();
var tags = store.getTags();
if(tags.length == 0) return "no tags in document";
var out="";
for(var t=0; t<tags.length; t++) {
if (ex.contains(tags[t][0])) continue;
//	out+="*<<tag [["+tags[t][0]+"]]>>"+"\n"; 
	out+="* <<tag [["+tags[t][0]+"]]>> ("+tags[t][1]+")"+"\n"; 
}

return out;
</script>
/%
|Name|ShowAllPermalinks|
|Source|http://www.TiddlyTools.com/#ShowAllPermalinks|
|Version|1.0.0|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|script|
|Description|generate a list containing permalinks for every tiddler in the document|
%/{{small smallform{<html><form style='display:inline'>
	<textarea name=txt rows=10 style='width:100%' onfocus="this.select()"></textarea>
</form></html><script>
	var out=outtxt=""; 
	var tids=store.getTiddlers("title","excludeLists");
	for (var t=0; t<tids.length; t++) {
		var url=store.getTiddlerText("SiteUrl");
		if (!url) url=document.location.href;
		var permalink=encodeURIComponent(String.encodeTiddlyLink(tids[t].title));
		out+="[["+tids[t].title+"|"+url+"#"+permalink+"]]\n";
		outtxt+=url+"#"+permalink+"\n";
	}
	place.lastChild.firstChild.txt.value=outtxt;
	return "{{threecolumns{"+out+"}}}";
</script>}}}
/***
!Example Usage
{{{
| Local|<<showClock>>|
| Queensland|<<showClock +10>>|
| England (DST)|<<showClock +1>>|
| California (DST)|<<showClock -7>>|
}}}
| Local|<<showClock>>|
| Queensland|<<showClock +10>>|
| England (DST)|<<showClock +1>>|
| California (DST)|<<showClock -7>>|

***/
//{{{
version.extensions.ShowClockMacro = { major: 0, minor: 0, revision: 1, date: new Date(2006,7,12),
	source: "http://tiddlyspot.com/timezones/#ShowClockMacro"
};

config.macros.showClock = {

	defaultClass: 'clock',
	tickDelay: 1000, 
	format: "mmm DD YYYY, hh12:0mm:0ss am",

	styles: 
		".clock {\n"+
		"  padding:0 0.5em;\n"+
		"}\n" +
		".clock .dow    { color:#000; }\n" +
		".clock .time   { color:#000; }\n" +
		".clock .offset { color:#999; }\n" +
		"",

	count: 0,

	handler: function (place,macroName,params,wikifier,paramString,tiddler) {
		var offset = params[0] || '';
		var useClass = params[1] || this.defaultClass;
		var c = this.count++;
		var clockElement = createTiddlyElement(place, "span", "clock" + c, useClass);
		clockElement.setAttribute("offset",offset);
		this.refreshDisplay(c);
		this.waitForTick(c);
	},

	waitForTick: function(c) {
		setTimeout("config.macros.showClock.tick(" + c + ")", this.tickDelay);
	},

	tick: function(c) {
		if (this.stillHere(c)) {
			this.refreshDisplay(c)
			this.waitForTick(c);
		}
	},

	getClock: function(c) {
		return document.getElementById("clock" + c);
	},

	stillHere: function(c) {
		return this.getClock(c) != null;
	},

	refreshDisplay: function(c) {
		var clock = this.getClock(c);
		var offset = clock.getAttribute("offset")
		var now = new Date();
		//var label = "local";
		var label = "";
		if (offset && offset != '') {
			var offsetInt = parseInt(offset);
			now.setHours(now.getHours() + (now.getTimezoneOffset() / 60) + offsetInt);
			label = "GMT " + (offsetInt == 0 ? "" : offsetInt > 0 ? "+"+offsetInt : offsetInt);
		}
		clock.innerHTML =
			'<span class="dow">' + now.formatString("DDD").substr(0,3) + ' </span>' +
			'<span class="time">' + now.formatString(this.format) + '</span>' + 
			'<span class="offset"> ' + label + '</span>'
	}

};

setStylesheet(config.macros.showClock.styles,"showClockStyles");

//}}}
/%
|Name|ShowCookies|
|Source|http://www.TiddlyTools.com/#ShowCookies|
|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||
%/{{smallform{<html><form style="display:inline;margin:0;padding:0"><select style="width:99px" name="list"
 onchange="this.form.val.value=this.value.length?config.options[this.value]:'';"><!--
--></select>
<input type="text" style="width:98px;margin:0;" name="val" title="enter an option value">
<input type="button" style="width:33px;margin:0;" value="get" title="refresh list"
 onclick="window.setCookieEditorList(this.form.list);"><!--
--><input type="button" style="width:33px;margin:0;" value="set" title="save cookie value"
 onclick="var opt=this.form.list.value; var v=this.form.val.value; config.options[opt]=opt.substr(0,3)=='txt'?v:(v.toLowerCase()=='true'); saveOptionCookie(opt);window.setCookieEditorList(this.form.list);"><!--
--><input type="button" style="width:33px;margin:0;" value="del" title="remove cookie"
 onclick="var ex=new Date(); ex.setTime(ex.getTime()-1000); document.cookie=this.form.list.value+'=novalue; path=/; expires='+ex.toGMTString(); window.setCookieEditorList(this.form.list);"></form></html><script>
 window.setCookieEditorList = function(list) {
 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 opt=new Array(); for (var i in config.options) if (cookies[i]) opt.push(i); opt.sort();
 var sel=list.selectedIndex;
 while (list.options.length > 1) { list.options[1]=null; } // clear list (except for header item)
 list.options[0]=new Option("There are "+opt.length+" cookies...","",false,false);
 if (!opt.length) { list.form.val.value=""; return; } // no cookies
 var c=1;
 for(var i=0; i<opt.length; i++) {
 var txt="";
 if (opt[i].substr(0,3)=="chk")
 txt+="["+(config.options[opt[i]]?"x":"_")+"] ";
 txt+=opt[i];
 list.options[c++]=new Option(txt,opt[i],false,false);
 }
 list.selectedIndex=sel>0?sel:0;
 list.form.val.value=sel>0?config.options[list.options[sel].value]:"";
 }
 window.setCookieEditorList(place.lastChild.firstChild.list); 
</script>}}}
/%
|Name|ShowLocalDirectory|
|Source|http://www.TiddlyTools.com/#ShowLocalDirectory|
|Version|1.2.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 local filesystem directory listings|

usage: <<tiddler ShowLocalDirectory>> or <<tiddler ShowLocalDirectory with: localpath format>>

where:
	"localpath" uses system-specific file naming conventions (or keyword "here" for the
	current document directory).  Note: for Windows filesystem, use doubled backslashes and
	enclose the entire path in square brackets (e.g., [[C:\\temp\\foo]])
and
	"format" determines the type of output produced:
		"plain"
			show fully-qualified path/filenames AS-IS, without any additional formatting.
		"list"
			show fully-qualified path/filenames using formatted "PrettyLinks", so that the
			local system-specific filename can be *displayed* while linking to a valid
			system-independent "file:" URL for browser navigation.
		"directory" (default)
			show header followed by a formatted table, containing PrettyLinks for
			filenames, filesizes (in bytes), and modification dates, plus a summary
			footer reporting the total file and byte counts.

%/<script>
	window.getCurrentFolder=function() {
		var h=document.location.href;
		return getLocalPath(decodeURIComponent(h.substr(0,h.lastIndexOf("/")+1)));
	}
	window.getParentFolder=function(cwd) {
		var lastchar=cwd.substr(cwd.length-1,1);
		if (lastchar=="/" || lastchar=="\\") cwd=cwd.substr(0,cwd.length-1);
		var pos=cwd.lastIndexOf("/"); if (pos==-1) pos=cwd.lastIndexOf("\\");
		return pos!=-1?cwd.substr(0,pos+1):null;
	}
	window.askForFolder=function(cwd) {
		if (config.browser.isIE) {
			try { // XPSP2 IE only
				var s = new ActiveXObject('UserAccounts.CommonDialog');
				s.InitialDir=cwd.replace(/\//g,"\\");
				s.FileName=''; s.Filter='All files|*.*|'; s.FilterIndex=1;
				var path=s.showOpen()?s.FileName.substr(0,s.FileName.lastIndexOf("\\")+1):null;
			}
			catch(e) { var path=prompt("Enter a directory path:",cwd.replace(/\//g,"\\"));	}
		} else { // FireFox
			if(!window.Components) return;
			try { netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); }
			catch(e) { alert(e.description?e.description:e.toString()); return; }
			var nsIFilePicker = window.Components.interfaces.nsIFilePicker;
			var picker = Components.classes['@mozilla.org/filepicker;1'].createInstance(nsIFilePicker);
			picker.init(window, "Select a folder", nsIFilePicker.modeGetFolder);
			var thispath = Components.classes['@mozilla.org/file/local;1'].createInstance(Components.interfaces.nsILocalFile);
			try { thispath.initWithPath(cwd.replace(/\\/g,"/")); }
			catch(e) { thispath.initWithPath(getLocalPath(decodeURIComponent(document.location.href.substr(0,document.location.href.lastIndexOf("/")+1)))); }
			picker.displayDirectory=thispath;
			picker.appendFilters(nsIFilePicker.filterAll); picker.defaultString=''; picker.defaultExtension=''; 
			var path=picker.show()!=nsIFilePicker.returnCancel?picker.file.persistentDescriptor:null;
		}
		return path;
	}

	window.getFileList=function(cwd) { // returns array of file info (path,name,size,isFolder,url,modified)
		var files=[];
		if (config.browser.isIE) {
			cwd=cwd.replace(/\//g,"\\");
			var fso = new ActiveXObject("Scripting.FileSystemObject");
			if(!fso.FolderExists(cwd)) return [];
			var dir=fso.GetFolder(cwd);
			for(var f=new Enumerator(dir.SubFolders); !f.atEnd(); f.moveNext())
				files.push({ path:f.item().path, name:f.item().name, size:f.item().size,
					url:"file:///"+f.item().path.replace(/\\/g,"/"), isFolder:fso.FolderExists(f.item().path),
					modified:new Date(f.item().DateLastModified).formatString("YYYY.0MM.0DD 0hh:0mm:0ss")});
			for(var f=new Enumerator(dir.Files); !f.atEnd(); f.moveNext())
				files.push({ path:f.item().path, name:f.item().name, size:f.item().size,
					url:"file:///"+f.item().path.replace(/\\/g,"/"), isFolder:fso.FolderExists(f.item().path),
					modified:new Date(f.item().DateLastModified).formatString("YYYY.0MM.0DD 0hh:0mm:0ss")});
		} else { // FF
			if(!window.Components) return;
			try { netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); }
			catch(e) { alert(e.description?e.description:e.toString()); return null; }
			var file=Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
			try { file.initWithPath(cwd); } catch(e) { return []; }
			if (!file.exists() || !file.isDirectory()) { return []; }
			var folder=file.directoryEntries;
			while (folder.hasMoreElements()) {
				var f=folder.getNext().QueryInterface(Components.interfaces.nsILocalFile);
				if (f instanceof Components.interfaces.nsILocalFile)
					files.push({path:f.path, name:f.leafName, size:f.fileSize,
						isFolder:f.isDirectory(), url:"file:///"+f.path.replace(/\\/g,"/"),
						modified:new Date(f.lastModifiedTime).formatString("YYYY.0MM.0DD 0hh:0mm:0ss")});
			}
		}
		return files;
	}

	window.renderDirectoryList=function(target,cwd,fmt) {
		var files=getFileList(cwd);
		if (!files||!files.length) { // maybe relative directory... fixup and try again...
			var fixup=getCurrentFolder()+cwd;
			var files=getFileList(fixup);
			if (!files||!files.length) {
				var out="{{errorButton{error reading "+cwd+"}}}";
				removeChildren(target); wikify(out,target);
				target.style.display="block";
				return false;
			} else cwd=fixup;
		}
		if (!cwd||!cwd.length) cwd=config.options.txtLocalDirectory;
		if (!cwd||!cwd.length) cwd=getCurrentFolder();
		config.options.txtLocalDirectory=cwd;
		var header=""; var item=""; var folderitem=""; var folderscript=""; var footer="";
		switch (fmt) {
			case "plain": item=folderitem="<nowiki>%0</nowiki>\n"; break;
			case "list": item=folderitem="[[%1|file:///%0]]\n"; break;
			default:
				var header="Index of {{{%0}}}\n^^(as of %1)^^\n|filename&nbsp;&nbsp;| size&nbsp;&nbsp;|modified|h\n";
				var item="|[[%1|%2]]&nbsp;&nbsp;| %3&nbsp;&nbsp;|%4|\n";
				var folderscript='<'+'script label="%1" title="open %1...">';
				folderscript+='		var t=place.parentNode.parentNode.parentNode.parentNode.parentNode;';
				folderscript+='		window.renderDirectoryList(t,"%0","");';
				folderscript+='		return false;';
				folderscript+='	</'+'script>';
				var folderitem='|'+folderscript+'&nbsp;&nbsp;| |%4|\n';
				var footer="|>|>|>| !Total of %0 bytes in %1 files |f\n|borderless sortable|k\n";
				var showDirectory=true;
				break;
		}
		var out=header.format([cwd,new Date().toLocaleString()]);
		if (showDirectory) {
			var p=getParentFolder(cwd);
			if (p) files.unshift({path:p, name:"(parent folder)", size:0, isFolder:true, url:"file:///"+p.replace(/\\/g,"/"),
				modified:new Date().formatString("YYYY.0MM.0DD 0hh:0mm:0ss")});
		}
		var total=0;
		for (var i=0; i<files.length; i++) {
			var line=(files[i].isFolder?folderitem:item).format([files[i].path,files[i].name,files[i].url,files[i].size,files[i].modified]);
			if (showDirectory) line=line.replace(/\\/g,"\\\\"); // fixup for PC-style file paths embedded in 'folderscript'
			if (!files[i].isFolder) total+=files[i].size;
			out+=line;
		}
		out+=footer.format([total,files.length]);
		removeChildren(target); wikify(out,target); target.style.display="block";

		// make table sortable (code adapted from [[TableSortingPlugin]]
		var c = config.tableSorting; if (!c) return; // no sortable tables
		var table = target.getElementsByTagName("table")[0];
		var x=null, rev, thead=table.getElementsByTagName('thead')[0], headers=thead.rows[thead.rows.length-1].cells;
		for (var j=0; j<headers.length; j++){
			var h = headers[j];
			if (hasClass(h,"nosort")) continue;
			h.setAttribute("index",j);
			h.onclick = function(){c.sortTable(this); return false;};
			h.ondblclick = stopEvent;
			if(h.getElementsByTagName("span").length == 0) createTiddlyElement(h,"span",null,"hidden",c.uarrow); 
			if(!x && hasClass(h,"autosort")) { x = j; rev = hasClass(h,"reverse"); }
		}
		if(x) c.sortTable(headers[x],rev);		
	}

</script>{{hidden small{
<script label="select a folder...">
	var path=askForFolder(getCurrentFolder());
	if (path) window.renderDirectoryList(place.parentNode.nextSibling,path,"");
	return false;
</script> | <script label="use document location...">
	window.renderDirectoryList(place.parentNode.nextSibling,getCurrentFolder(),"");
	return false;
</script> | <script label="refresh list...">
	window.renderDirectoryList(place.parentNode.nextSibling,config.options.txtLocalDirectory,"");
	return false;
</script>
----
}}}@@display:none;/% content automatically replaced %/@@<script>
	var cwd=getCurrentFolder(); // default to current folder
	if ("$1"=="$"+"1") place.lastChild.previousSibling.style.display="block"; // show 'select a folder' command
	else if ("$1".toLowerCase()=="here") cwd=getCurrentFolder(); // "here" = use document directory
	else cwd="$1"; // use path param as specified
	window.renderDirectoryList(place.lastChild,cwd,"$2");
</script>
/%
|Name|ShowPopup|
|Source|http://www.TiddlyTools.com/#ShowPopup|
|Version|1.0.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|transcluded html|
|Requires||
|Overrides||
|Description|display tiddler content in a TW popup|

usage: <<tiddler ShowPopup with: TiddlerName label tooltip buttonClass width popupClass>>

%/<html><a href="javascript:;" class="$4" title="$3" onclick="var p=Popup.create(this); if (!p) return; var t=store.getTiddler('$1'); if (!t) return; p.className+=' $6'; var d=createTiddlyElement(p,'div'); d.style.whiteSpace='normal'; d.style.width='$5'; d.style.padding='2px'; wikify(t.text,d); Popup.show(p,false); event.cancelBubble = true; if (event.stopPropagation) event.stopPropagation(); return(false);">$2</a></html>
/%
!info
|Name|ShowSimilarTiddlers|
|Source|http://www.TiddlyTools.com/#ShowSimilarTiddlers|
|Version|2.0.0|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|Type|transclusion|
|Description|list tiddlers, by number of shared tags|
Usage
<<<
{{{
<<tiddler ShowSimilarTiddlers>>
<<tiddler ShowSimilarTiddlers with: TiddlerName limit>>
}}}
*''~TiddlerName'' (optional)<br>title of the tiddler whose tags are to be matched (default=current tiddler)
*''limit'' (optional)<br>only report tiddlers if they have //at least// the indicated number of tags in common (default=1)
<<<
Example
<<<
{{{<<tiddler ShowSimilarTiddlers>>}}}
<<tiddler ShowSimilarTiddlers##show>>
<<<
!end
!out
$1
!end
!show
<<tiddler ShowSimilarTiddlers##out with: {{
	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);
	var tids=store.reverseLookup('tags','excludeLists');
	if (tid) 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(', ')]));
	}
	out.join('\n');
}}>>
!end
%/<<tiddler {{var src='ShowSimilarTiddlers'; src+(tiddler&&tiddler.title==src?'##info':'##show');}}
	with: [[$1]]>>
/%
|Name|ShowTabsForTags|
|Source|http://www.TiddlyTools.com/#ShowTabsForTags|
|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||
|Overrides||
|Description|automatically 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(); // get tags list from param
	if ("$1"=="$"+"1") { // if no tags were specified, then ASK for tags...
		var response=prompt("enter tag(s) to match:","faq");  
		if (!response) return "no tags specified"; // cancelled by user
		var tags=response.readBracketedList(); 
	}
	// get tiddlers with a least one matching tag, in date order (newest first)
	// and, for each tiddler that matches ALL tags, add macro params to output...
	var out="";
	// var tids=store.getTaggedTiddlers(tags[0],'modified').reverse();
	var tids=store.getTaggedTiddlers(tags[0],'title');
	for (var t=0; t<tids.length; t++)
		if (tids[t].tags.containsAll(tags)) out+='[[%0 ]] "view %0" [[%0]]'.format([tids[t].title]); 
	// if any tiddlers matched, output the <<tabs>> macro...
	if (out.length) return "<<tabs tabTabsForTags "+out+">>";
	// otherwise, output a message with popups for each specified tag...
	return "There are no tiddlers tagged with <<tag "+tags.join(">> and <<tag ")+">>";
</script>}}}
/%
|Name|ShowTiddlerStatistics|
|Source|http://www.TiddlyTools.com/#ShowTiddlerStatistics|
|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|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="{{nowrap{";
	out+="There are [["+tiddlers.length+" tiddlers|SideBarTabs]], including ";
	out+="''<<tag systemConfig [["+store.getTaggedTiddlers("systemConfig").length+" plugins]]>>''and ";
	out+="''<<tag Tricks [["+store.getTaggedTiddlers("Tricks").length+" Tricks]]>>''";
	out+="{{fine{("+total+" bytes)}}}\n";
	out+="|borderless|k\n";
	out+="| last change:&nbsp;|[["+last.title+"]]";
	out+=" {{fine{(updated "+last.modified.formatString("MMM DDth YYYY, 0hh:0mm")+")}}}|\n";
	out+="| newest:&nbsp;|[["+newtid.title+"]]";
	out+=" {{fine{(created "+newtid.created.formatString("MMM DDth YYYY, 0hh:0mm")+")}}}|\n";
	out+="| oldest:&nbsp;|[["+oldtid.title+"]]";
	out+=" {{fine{(created "+oldtid.created.formatString("MMM DDth YYYY, 0hh:0mm")+")}}}|\n";
	out+="| smallest:&nbsp;|[["+smalltid.title+"]]";
	out+=" {{fine{("+smalltid.text.length+" bytes)}}}|\n";
	out+="| largest:&nbsp;|[["+largetid.title+"]]";
	out+=" {{fine{("+largetid.text.length+" bytes)}}}|\n";
	out+="}}}";
	return(out);
</script>
/%
|Name|ShowUserName|
|Source|http://www.TiddlyTools.com/#ShowUserName|
|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|Displays current username, Click for prompt box to change name|
%//%

usage: <<tiddler ShowUserName>>

%/<script label="username">
	var opt="txtUserName";
	var who=prompt("Please set your username",config.options[opt]);
	if (!who||!who.trim().length) return false;
	config.options[opt]=who;
	saveOptionCookie(opt);
	var tid=story.findContainingTiddler(place);
	if (tid) story.refreshTiddler(tid.getAttribute("tiddler"),null,true); // sync containing tiddler
	config.macros.option.propagateOption(opt,"value",config.options[opt],"input");
	return false;
</script><script>
	place.lastChild.title="click to change your username";
	place.lastChild.innerHTML=config.options.txtUserName;
</script>
{{center{[img[images/ankhsm.png]]}}}
----
+++[Commands »]...
<<collapseAll>>
<<expandAll>>
<<closeAll>>
----
<<newTiddler>>
<<newJournal "0MM.0DD.YYYY">>
----
<<saveChanges>>
<<saveAndReload>>
<<emptyTrash>>
<<permaview>><<renameButton 'Snap Shot'>>
===

+++(calendar)[Calendar »]...
	{{groupbox{{{small{<<calendar thismonth>><script>
		place.lastChild.style.width="100%";
	</script>
===

+++[Options »|Change TiddlyWiki advanced options »]...
<<tiddler OptionsPanel>>
===
&nbsp;&nbsp;+++[Contents »|Contents »]
<<tiddler TabContents>>
===
----
/***
This CSS by DaveBirss.
***/
/*{{{*/


.tabSelected {
 background: #fff;
}

.tabUnselected {
 background: #eee;
}

#sidebar {
 color: #000;
 background: transparent; 
}

#sidebarOptions {
 background: #fff;
}

#sidebarOptions input {
	border: 1px solid #ccc;
}

#sidebarOptions input:hover, #sidebarOptions input:active,  #sidebarOptions input:focus {
	border: 1px solid #000;
}

#sidebarOptions .button {
 color: #999;
}

#sidebarOptions .button:hover {
 color: #000;
 background: #fff;
 border-color:white;
}

#sidebarOptions .button:active {
 color: #000;
 background: #fff;
}

#sidebarOptions .sliderPanel {
 background: transparent;
}

#sidebarOptions .sliderPanel A {
 color: #999;
}

#sidebarOptions .sliderPanel A:hover {
 color: #000;
 background: #fff;
}

#sidebarOptions .sliderPanel A:active {
 color: #000;
 background: #fff;
}

.sidebarSubHeading {
 color: #000;
}

#sidebarTabs {`
 background: #fff
}

#sidebarTabs .tabSelected {
 color: #000;
 background: #fff;
 border-top: solid 1px #ccc;
 border-left: solid 1px #ccc;
 border-right: solid 1px #ccc;
 border-bottom: none;
}

#sidebarTabs .tabUnselected {
 color: #999;
 background: #eee;
 border-top: solid 1px #ccc;
 border-left: solid 1px #ccc;
 border-right: solid 1px #ccc;
 border-bottom: none;
}

#sidebarTabs .tabContents {
 background: #fff;
}


#sidebarTabs .txtMoreTab .tabSelected {
 background: #fff;
}

#sidebarTabs .txtMoreTab .tabUnselected {
 background: #eee;
}

#sidebarTabs .txtMoreTab .tabContents {
 background: #fff;
}

#sidebarTabs .tabContents .tiddlyLink {
 color: #999;
 border:none;
}

#sidebarTabs .tabContents .tiddlyLink:hover {
 background: #fff;
 color: #000;
 border:none;
}

#sidebarTabs .tabContents {
 color: #000;
}

#sidebarTabs .button {
 color: #666;
}

#sidebarTabs .tabContents .button:hover {
 color: #000;
 background: #fff;
}

#sidebar {color:#999;}
/*}}}*/
 my <html><a href="javascript:;" onclick="story.closeAllTiddlers();restart();">experimental</a></html> [[Encryptable|Encrypted]] Notebook v<<version>>
<<tiddler ShowUserName>>'s [[TW|TiddlyWiki]] SandBox[IMG[Images/gir.gif]]
|''Name''|Skull3Theme|
|''Description''|Custom Theme Spawned from MPTW by MTP 11.08.08|
|''Last Revision''|MTP 12.31.08|

!Author Mode
|PageTemplate|ImgPageTemplate|
|ViewTemplate|CustomViewTemplate|
|EditTemplate|CustomEditTemplate|
|StyleSheet|##StyleSheet|
|ColorPalette|ColorPalette|


!StyleSheet
/*{{{*/
[[CustomStyleSheet]]
[[StyleSheetShortcuts]]
[[PluginStyles]]

/* Background Image */
body {
	background-image: url("theme/skull3.jpeg") !important;
	background-repeat: repeat;
}
#topMenu, .header, .headerNow {
	background: transparent !important;
}
/*}}}*/
|''Name''|Skull4Theme|
|''Description''|Custom Theme Spawned from MPTW by MTP 11.08.08|
|''Last Revision''|MTP 12.31.08|

!Author Mode
|PageTemplate|ImgPageTemplate|
|ViewTemplate|CustomViewTemplate|
|EditTemplate|CustomEditTemplate|
|StyleSheet|##StyleSheet|
|ColorPalette|ColorPalette|


!StyleSheet
/*{{{*/
[[CustomStyleSheet]]
[[StyleSheetShortcuts]]
[[PluginStyles]]

/* Background Image */
body {
	background-image: url("theme/skull4.jpeg") !important;
	background-repeat: repeat;
}
#topMenu, .header, .headerNow {
	background: transparent !important;
}
/*}}}*/
|''Name''|Skull5Theme|
|''Description''|Custom Theme Spawned from MPTW by MTP 11.08.08|
|''Last Revision''|MTP 12.31.08|

!Author Mode
|PageTemplate|ImgPageTemplate|
|ViewTemplate|CustomViewTemplate|
|EditTemplate|CustomEditTemplate|
|StyleSheet|##StyleSheet|
|ColorPalette|ColorPalette|


!StyleSheet
/*{{{*/
[[CustomStyleSheet]]
[[StyleSheetShortcuts]]
[[PluginStyles]]

/* Background Image */
body {
	background-image: url("theme/skull5.jpeg") !important;
	background-repeat: repeat;
}
#topMenu, .header, .headerNow {
	background: transparent !important;
}
/*}}}*/
|''Name''|Skull5bTheme|
|''Description''|Custom Theme Spawned from MPTW by MTP 11.08.08|
|''Last Revision''|MTP 12.31.08|

!Author Mode
|PageTemplate|ImgPageTemplate|
|ViewTemplate|CustomViewTemplate|
|EditTemplate|CustomEditTemplate|
|StyleSheet|##StyleSheet|
|ColorPalette|ColorPalette|


!StyleSheet
/*{{{*/
[[CustomStyleSheet]]
[[StyleSheetShortcuts]]
[[PluginStyles]]

/* Background Image */
body {
	background-image: url("theme/skull5b.jpeg") !important;
	background-repeat: repeat;
}
#topMenu, .header, .headerNow {
	background: transparent !important;
}
/*}}}*/
|''Name''|Skull8Theme|
|''Description''|Custom Theme Spawned from MPTW by MTP 11.08.08|
|''Last Revision''|MTP 12.31.08|

!Author Mode
|PageTemplate|ImgPageTemplate|
|ViewTemplate|CustomViewTemplate|
|EditTemplate|CustomEditTemplate|
|StyleSheet|##StyleSheet|
|ColorPalette|ColorPalette|


!StyleSheet
/*{{{*/
[[CustomStyleSheet]]
[[StyleSheetShortcuts]]
[[PluginStyles]]

/* Background Image */
body {
	background-image: url("theme/skull8.jpeg") !important;
	background-repeat: repeat;
}
#topMenu, .header, .headerNow {
	background: transparent !important;
}
/*}}}*/
/***
|Name|SliceGridPlugin|
|Source|http://www.TiddlyTools.com/#SliceGridPlugin|
|Documentation|http://www.TiddlyTools.com/#SliceGridPluginInfo|
|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.3|
|Type|plugin|
|Requires||
|Overrides||
|Description|Generate a "slice grid" table to get an instant 'birds-eye' overview of your entire document|
Rows are tiddlers, columns are slice names.  If a tiddler has a value defined for a given slice, that grid cell is colored. Move the mouse over a grid cell to view the value for that tiddler slice.  To keep the grid display from getting very wide, the slice names used as column headings are not initially displayed.  ''Click directly above the column to show/hide that heading'', or toggle all column headings at once by clicking the {{{>>>}}} symbol in the upper-left corner of the grid display.
!!!!!Documentation
>see [[SliceGridPluginInfo]]
!!!!!Revisions
<<<
2008.08.15 [1.0.3] add brackets around row headings when wikifying so that non-wikiword tiddler titles are linked
2008.08.13 [1.0.2] wikify row headings (in addition to slice value cells) whenever 'wikify' param is used
|please see [[SliceGridPluginInfo]] for additional revision details|
2007.01.30 [0.0.1] started
<<<
!!!!!Code
***/
//{{{
version.extensions.SliceGridPlugin= {major: 1, minor: 0, revision: 3, date: new Date(2008,8,15)};

config.macros.sliceGrid= {
	sizeSliceName: "TiddlerSize", // shadow slice used for retrieving and showing tiddler size as a grid column
	noSlicesMsg: "\n|~SliceGrid: there are no slices to display|\n",
	handler:
	function(place,macroName,params) {
		this.slicesRE=/(?:^\|\s*[\'\/]*~?(\w+)\:?[\'\/]*\s*\|\s*(.*?)\s*\|$)/gm;
		this.wikify=false; // wiki-syntax in slices
		this.edit=false; // 'click-to-edit' feature
		this.verbose=false; // debugging/performance feedback messages
		this.alltiddlers=false; // rows for all tiddlers (even if no slices)
		this.inline=false; // slice value in cell (instead of mouseover)
		this.headers=false; // column headers
		this.cliplength=0; // limit inline display text length (0=no limit)
		this.slices=[]; // slices to show (columns)
		var tablewidth="auto"; // default CSS for table width
		var p=params.shift();
		while (p) {
			if (p.substr(0,6).toUpperCase()=="WIDTH:")
				tablewidth=p.substr(6);
			else if (p.substr(0,5).toUpperCase()=="TAGS:") {
				if (p.substr(5,1)=="@") { // get tags from tiddler
					var tid=store.getTiddler(p.substr(6));
					if (p.substr(6)=="here") {
						var here=story.findContainingTiddler(place);
						if (here) var tid=store.getTiddler(here.getAttribute("tiddler"));
					}
					if (tid) var tags=tid.tags;
				}
				else if (p.substr(5,1)=="+") { // get tags from tiddler contents
					var tid=store.getTiddler(p.substr(6));
					if (p.substr(6)=="here") {
						var here=story.findContainingTiddler(place);
						if (here) var tid=store.getTiddler(here.getAttribute("tiddler"));
					}
					if (tid)
						{ var tags=tid.text.readBracketedList(); }
				}
				else var tags=p.substr(5).readBracketedList();
			}
			else if (p.substr(0,7).toUpperCase()=="SLICES:") {
				if (p.substr(7,1)=="@") { // get slices from tiddler
					var tid=p.substr(8);
					var tiddler=store.getTiddler(tid);
					if (tid=="here") {
						var here=story.findContainingTiddler(place);
						if (here) var tiddler=store.getTiddler(here.getAttribute("tiddler"));
					}
					if (tiddler) {
						var slices=tiddler.getSlices(tiddler.title); for (var s in slices) this.slices.push(s);
					}
				}
				else if (p.substr(7,1)=="+") { // get slices from tiddler contents
					var tid=p.substr(8);
					var tiddler=store.getTiddler(tid);
					if (tid=="here") {
						var here=story.findContainingTiddler(place);
						if (here) var tiddler=store.getTiddler(here.getAttribute("tiddler"));
					}
					if (tiddler)
						{ this.slices=tiddler.text.readBracketedList(); }
				}
				else this.slices=p.substr(7).readBracketedList();
			}
			else switch (p.toUpperCase()) {
				case "EDIT":
					this.edit=true && !readOnly; break; // no editing allowed if readOnly mode
				case "WIKIFY":
					this.wikify=true; break;
				case "VERBOSE":
					this.verbose=true; break;
				case "ALL":
					this.alltiddlers=true; break;
				case "INLINE":
					this.inline=true; this.headers=true; break; // default to show headers with inline grid
				default:
					if (!isNaN(p)) { this.cliplength=p; break; }
					else displayMessage("unrecognized parameter: "+p);
			}
			p=params.shift();
		}
		// get rows and columns
		var rows=[]; var cols=[]; var total=0;
		var tiddlers=store.getTiddlers("title","excludeLists"); // get all tiddlers (except hidden ones)
		if (tags && tags.length) for (t=0;t<tiddlers.length;t++) // filter out tiddlers with no matching tags
			if (!tiddlers[t].tags.containsAny(tags)) { tiddlers.splice(t,1); t--; } // remove non-matching tiddler
		for (i=0; i<tiddlers.length; i++) {
			var slices=this.getSlices(tiddlers[i].title);
			var count=0; for (var s in slices) { cols.pushUnique(s); count++; total++;}
			if (count || this.alltiddlers) rows.push(tiddlers[i].title); // only show rows for tiddlers with slices
		}
		if (!cols.length) { wikify(this.noSlicesMsg,place); return; }
		if (this.verbose) displayMessage("Found %0 slices using %1 slice names in %2 tiddlers".format([total, cols.length,rows.length]));

		// get optional list of slices to show
		if (this.slices.length) var cols=this.slices;

		// generate HTML table
		var out="";
		out+="<html><table cellpadding='0' cellspacing='0' style='border:0;border-collapse:collapse;width:"+tablewidth+"'>";
		// column headings
		out+="<tr style='border:0;'><td style='text-align:right;border:0'>";
		out+="<a href='javascript:;' style='font-size:80%;'";
		out+="	title='show all column headings'";
		out+="	onclick='return config.macros.sliceGrid.toggleAllColumns(this,event,"+(this.headers?"true":"false")+")'>";
		out+=this.headers?"&lt;&lt;&lt;":"&gt;&gt;&gt;";
		out+="</a>";
		out+="</td>";
		for (var i=0;i<cols.length;i++) {
			out+="<td style='text-align:center;cursor:pointer;border:0;padding-left:2px;padding-right:2px;' ";
			out+="	title='show/hide column heading' ";
			out+="	onclick='return config.macros.sliceGrid.toggleColumn(this,event)'>";
			out+="<span style='display:"+(this.headers?"block":"none")+"'>"+cols[i]+"</span>";
			out+="</td>";
		}
		out+="</tr>";
		for (var i=0;i<rows.length;i++) {
			var tiddlersrc=rows[i].replace(/"/g,"&#x22;");
			out +="<tr style='border:0'>";
			// row heading
			out +="<td style='text-align:right;border:0;padding-right:2px;white-space:nowrap;"+(this.inline?'width:1%':'')+";'>";
			out +="<a href='javascript:;' tid=\""+tiddlersrc+"\" class='slicegrid_heading' ";
			out +="		onclick='story.displayTiddler(this,this.getAttribute(\"tid\"));return false'>"+tiddlersrc+"</a>";
			out +="</td>";
			var slices=this.getSlices(rows[i]);
			for (var j=0;j<cols.length;j++) {
				var val=slices[cols[j]]; if (!val) val="";
				var bgcolor=val.length?"#999":"transparent";
				var content="&nbsp;";
				if (val.length && this.inline) {
					content=val.htmlEncode();
					if (this.cliplength) content=val.substr(0,this.cliplength)+(val.length>this.cliplength?"...":"");
					bgcolor="transparent";
				}
				out+="<td style='background-color:"+bgcolor+";border:1px solid;"+(!this.inline?'width:1em;':'');
				if (this.inline && cols[j]==this.sizeSliceName) out+="text-align:right !important;"; // right align tiddler size pseudo-slice
				out+="'"; 
				if (this.edit && !(cols[j]==this.sizeSliceName)) { // add edit-in-place, except for tiddler size pseudo-slice
					var onclick="return config.macros.sliceGrid.editSlice(this,event,this.getAttribute(\"tid\"),\""+cols[j]+"\","+(this.inline?"true":"false")+")";
					out+=" tid=\""+tiddlersrc+"\" onclick='"+onclick+"'";
				}
				out+=" title=\""+tiddlersrc+"::"+cols[j]+(!this.inline?("="+val):"")+"\"";
				out+="><span class='slicegrid_content'>"+content+"</span></td>";
			}
			out+="</tr>";
		}
		out+="</table>";
		out+="</html>";
		var span=createTiddlyElement(place,"span")
		span.innerHTML=out;
		if (this.wikify) {
			// find all TD's in table and replace span content with wikified elements
			var tds=span.getElementsByTagName("td");
			for (var t=0; t<tds.length; t++) {
				var content=tds[t].firstChild;
				if (hasClass(content,"slicegrid_heading")||hasClass(content,"slicegrid_content")) {
					var txt=getPlainText(content);
					if (hasClass(content,"slicegrid_heading")) txt="[["+txt+"]]";
					removeChildren(content);
					wikify(txt,content);
				}
			}
		}
	},
	toggleAllColumns:
	function(here,event,defOpen) {
		if (here.expanded==undefined) here.expanded=defOpen;
		var ex=here.expanded=!here.expanded; 
		here.innerHTML=ex?"&lt;&lt;&lt;":"&gt;&gt;&gt;";
		here.title=ex?'hide all column headings':'show all column headings';
		var cells=here.parentNode.parentNode.getElementsByTagName("td");
		for (i=1; i<cells.length; i++) cells[i].firstChild.style.display=ex?"inline":"none";
		event.cancelBubble = true;
		if (event.stopPropagation) event.stopPropagation();
		return(false);
	},
	toggleColumn:
	function(here,event) {
		here.firstChild.style.display=(here.firstChild.style.display=="none")?"inline":"none";
		event.cancelBubble = true;
		if (event.stopPropagation) event.stopPropagation();
		return(false);
	},
	editSlice:
	function(here,event,tid,slice,inline) {
		// replace prompt box with edit field that is displayed until onBlur
		if (here.editing) return false; // already editing... don't re-init

		var onkeyup='if (event.keyCode==13)'; // SAVE and END
		onkeyup+='	{ config.macros.sliceGrid.setSlice(this.getAttribute(\"tid\"),"'+slice+'",this.value); this.blur(); }';
		onkeyup+='else if (event.keyCode==27)'; // END without saving
		onkeyup+='	{ this.blur(); }';

		var onblur="var tid=this.getAttribute(\"tid\"); var slice=\""+slice+"\"; var currval=config.macros.sliceGrid.getSlice(tid,slice); ";
		onblur+="if (this.value!=currval && confirm(tid+\"::\"+slice+\" has changed... save value?\"))";
		onblur+="	{ config.macros.sliceGrid.setSlice(tid,slice,this.value); currval=this.value; }";
		onblur+="var target=this.parentNode;";
		onblur+="target.editing=false;";
		onblur+="target.style.backgroundColor=target.getAttribute(\"savedColor\");";
		onblur+="target.style.padding=target.getAttribute(\"savedPadding\");";
		onblur+="target.style.width=target.getAttribute(\"savedWidth\");";
		onblur+="if (config.macros.sliceGrid.wikify) { removeChildren(target); wikify(currval,target); }";
		onblur+="else target.innerHTML="+(inline?'currval':'\"&nbsp;\"')+";";

		var style="font-size:1em;font-family:inherit;width:95%;margin:0px;padding:1px 0px 1px 3px;border:0;";
		var title=tid+"::"+slice+" (ENTER=submit, ESC=cancel)";

		here.setAttribute("savedWidth",here.style.width); if (!inline) here.style.width="99%";
		here.setAttribute("savedPadding",here.style.padding); here.style.padding="0px"; 
		here.setAttribute("savedColor",here.style.backgroundColor); here.style.backgroundColor="#fff";
		here.innerHTML="<input type='text' tid=\""+tid.replace(/"/g,"&#x22;")+"\" onkeyup='"+onkeyup+"' onblur='"+onblur+"' style='"+style+"' title='"+title+"'>";
		here.firstChild.value=config.macros.sliceGrid.getSlice(tid,slice); // avoids conflicts with nested quoting in HTML
		here.firstChild.focus();
		here.firstChild.select();
		here.editing=true;

		event.cancelBubble = true; if (event.stopPropagation) event.stopPropagation(); return(false);
	},
	getSlice:
	function(tid,slice) {
		var slices=config.macros.sliceGrid.getSlices(tid);
		return slices[slice]?slices[slice]:"";
	},
	getSlices:
	function(tid) {
		var slices = {};
		var text = store.getTiddlerText(tid,"");
		slices[this.sizeSliceName]=text.length.toString();  // 'shadow slice' for displaying tiddler size
		this.slicesRE.lastIndex = 0;
		do {
			var m = this.slicesRE.exec(text);
			if (m) { if (m[1]) slices[m[1]] = m[2]; else slices[m[3]] = m[4]; }
		} while(m);
		return slices;
	},
	setSlice:
	function(tid,slice,val) {
		var oldval=this.getSlice(tid,slice);
		if (val==oldval) return false; // value is unchanged... do nothing
		// find slice within tiddler text
		var tiddler=store.getTiddler(tid);
		this.slicesRE.lastIndex = 0;
		var lastIndex=0;
		do {
			var m=this.slicesRE.exec(tiddler.text);
			if (m && (m[1]==slice||m[3]==slice)) break;
			if (m) lastIndex=this.slicesRE.lastIndex;
		} while(m);
		if (m) { // if matching slice was found
			if (oldval.length) { // replace old value with new value
				var pos=RegExp.lastMatch.indexOf(oldval);
				var newSlice=RegExp.lastMatch.substr(0,pos)+val+RegExp.lastMatch.substr(pos+oldval.length);
			} else // insert new value into empty slice
				var newSlice=RegExp.lastMatch.substr(0,RegExp.lastMatch.length-1)+val+"|";
			var newText=RegExp.leftContext+newSlice+RegExp.rightContext;
		} else { // create new slice following last slice (or at start of tiddler if no slices)
			var newSlice="|"+slice+"|"+val+"|\n";
			var newText=newSlice+tiddler.text
			if (lastIndex) var newText=tiddler.text.substr(0,lastIndex+1)+newSlice+tiddler.text.substr(lastIndex+1);
		}
		// write tiddler contents
		var user=config.options.txtUserName; var mod=new Date();
		if (config.options.chkForceMinorUpdate)
			{ var user=tiddler.modifier; var mod=tiddler.modified; }
		store.saveTiddler(tid,tid,newText,user,mod,tiddler.tags,tiddler.fields);
		displayMessage(tid+"::"+slice+" has been "+(m?"updated":"created"));
		return(false);
	}
};
//}}}
/***
|Name|SliceGridPluginInfo|
|Source|http://www.TiddlyTools.com/#SliceGridPlugin|
|Documentation|http://www.TiddlyTools.com/#SliceGridPluginInfo|
|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.3|
|Type|documentation|
|Requires||
|Overrides||
|Description|documentation for SliceGridPlugin|
Rows are tiddlers, columns are slice names.  If a tiddler has a value defined for a given slice, that grid cell is colored. Move the mouse over a grid cell to view the value for that tiddler slice.  To keep the grid display from getting very wide, the slice names used as column headings are not initially displayed.  ''Click directly above the column to show/hide that heading'', or toggle all column headings at once by clicking the {{{>>>}}} symbol in the upper-left corner of the grid display.
!!!!!Usage
<<<
{{{<<sliceGrid [[tags:tag tag...]] [[slices:slice slice...]]  inline wikify edit all cliplength verbose>>}}}

all parameters are optional, where:
''tags:'' (list)
> display rows only for those tiddlers with at least ONE of the specified tags (space-separated).  default is to show all tiddlers that have at least one slice defined, regardless of tags
> To use a list of tags defined in a separate tiddler, specify ''{{{tags:+TiddlerName}}}''.  To use the same tags that are being used by a given tiddler, use ''{{{tags:@TiddlerName}}}''
''slices:'' (list)
> display columns for the specified slices.  Default is to display all defined slices
> To use a list of slices defined in a separate tiddler, specify ''{{{slices:+TiddlerName}}}''.  To use the same slices that are being used by a given tiddler, use ''{{{slices:@TiddlerName}}}''.  Note: a special "shadow slice", ''TiddlerSize'', can be used to automatically compute and display the tiddler size in a grid column.  If a tiddler contains a slice named ''TiddlerSize'', then it supercedes the computed value.
''inline'' (keyword)
> display slice value directly in table cell.  Default is to use colored blocks for defined slices, with mouseover 'tooltip' to show value
''wikify'' (keyword)
> parse and format wiki-syntax contained in slice values.  Default is to show slice values "as-is", without converting embedded formatting.
''edit'' (keyword)
> enable click-to-edit to change slice values.  Default is to display only.
''all'' (keyword)
> display a row for each tiddler, even tiddlers that have NO slices defined.   Default is to only show tiddlers that have slices defined. Note: if tags: param is used to select tiddler by tag, then only tiddlers with matching tags are included.
''cliplength'' (number)
> # of characters to show in table cell when using 'inline' keyword.  Text display is truncated with "..."
''verbose'' (keyword)
> adds messages to report on slice grid processing

Note: uses modified version of slices pattern:
{{{slicesRE = /(?:^\|[\'\/]*~?(\w+)\:?[\'\/]*\|\s*(.*?)\s*\|$)/gm;}}}
* eliminates TONS of spurious slices caused by over-eager "description" format pattern matches
* enforces beginning-of-line and end-of-line sequences.  (Allows slice values to contain |, such as in pretty links)
<<<
!!!!!Examples
<<<
{{{<<sliceGrid inline wikify edit [[slices:Version Description]]>>}}}
+++[click to view example...]...<<sliceGrid inline wikify edit [[slices:Version Description]]>>===

{{{<<sliceGrid edit tags:systemConfig>>}}}
+++[click to view example...]...<<sliceGrid edit tags:systemConfig>>===
<<<
!!!!!Revisions
<<<
2008.08.15 [1.0.3] add brackets around row headings when wikifying so that non-wikiword tiddler titles are linked
2008.08.13 [1.0.2] wikify row headings (in addition to slice value cells) whenever 'wikify' param is used
2008.05.01 [1.0.1] in editSlice(), corrected fixup for titles containing double-quotes
2007.09.18 [1.0.0] added 'wikify' param and handling to format wiki-syntax contained in slice values
2008.05.01 [1.0.1] in editSlice(), corrected fixup for titles containing double-quotes
2007.09.18 [1.0.0] added 'wikify' param and handling to format wiki-syntax contained in slice values
2007.08.02 [0.9.8] when generating HTML, replace double-quotes in tiddler titles with {{{&#x22;}}} (entity equivalence) to avoid ambiguity with quotes used as HTML attribute syntax delimiters.
2007.07.22 [0.9.7] removed hard-coded 99% 'width bias' and wordwrap from Description cells, default to autosize (equal size for all columns).  Added width:xxxx param to easily stretch table to fit containing space
2007.06.08 [0.9.6] fixed generation of javascript for rows headings and in edit_slice(), so tiddler titles containing single-quote characters will not create syntax errors in the DOM event handlers
2007.04.24 [0.9.5] added 'shadow slice', "TiddlerSize", so that tiddler size can be retrieved and displayed as a grid column.  Also, fixed click on column headings for show/hide...
2007.04.13 [0.9.4] when getting tiddlers, honor "excludeLists" tag so that 'hidden' tiddlers aren't displayed in the grid
2007.04.08 [0.9.3] corrected setting of cell background color (non-inline grid 'blocks') after edit-in-place adds/clears a slice value
2007.04.07 [0.9.2] support edit in place for non-inline grids (color 'blocks'), and also handle creating new slices in tiddlers where a slice didn't exist previously
2007.04.07 [0.9.1] use locally-defined slicesRE (and getSlice() method) instead of re-defining core slicesRE.  Avoids breaking use of shadow ColorPalette slices.  
2007.04.05 [0.9.0] Added functioning "set slice" handler and "edit-in-place" feature.  Eliminated mouseover popups (use tooltips instead).  Added ''tags:'', ''slices:'' and ''edit'' params.  Lots of code cleanup.
2007.04.04 [0.8.1] in info() and popup() functions, instead of creating popup display, use element tooltip to show mouseover details.   Avoids incorrect positioning of popup if the 'root' element for the popup is in a DIV that has been scrolled.
2007.03.25 [0.8.0] change to BETA status and added support for "tags:tag tag tag tag" filtering param
2007.02.03 [0.0.2] change display of slices from "tiddler[slidename]" to "tiddler:slicename" to match TW slice syntax
2007.01.30 [0.0.1] started (adapted from TagGridPlugin)
<<<
<script show>
   var out=[];
   var fmt='|%0|%1|%2|';
   var tids=store.getTaggedTiddlers('someTag');
   for (var i=0; i<tids.length; i++) { var t=tids[i].title;
      var val1=store.getTiddlerSlice(t,'SomeSlice1')
      var val2=store.getTiddlerSlice(t,'SomeSlice2')
      var val3=store.getTiddlerSlice(t,'SomeSlice3')
      out.push(fmt.format([val1,val2,val3]));
   }
   return out.join('\n');
</script> 

[format] specify the output format
   var fmt="..."

[tag] select specific tiddlers by tag or tag expression
   var tids=store.getTaggedTiddlers("...");

[sliceList] extract and render slices from tiddler
   var val1=...
   var val2=...
   var val3=...
   out.push(fmt.format([val1,val2,val3]));
and could be generalized using arrays of slices and values:
   var slices=['sliceOne','sliceTwo','sliceThree'];
   var values=[];
   for (var s=0; s<slices.length; s++)
         values.push(store.getTiddlerSlice(t,slices[s]));
   out.push(fmt.format(values));

[sliceMatch] include/exclude certain tiddlers based on slice-testing
conditionals
   skipping over undesired tiddlers can be easily added at the start
of the 'for' loop:
      if (store.getTiddlerSlice(t,"someSlice") > someValue) continue;
      if (store.getTiddlerSlice(t,"someSlice") != someValue) continue;
      if ( ... some other use-case specific condition ... ) continue;

[header] and [footer] content output preceding/following the slice
data output
   can be easily added before the loop:
      out.push("...header content...");
   and after the loop:
      out.push("...footer content..."); 

<script show>
   // change the values and conditionals here:
   var fmt='|%0|%1|%2|';
   var slices=['sliceOne','sliceTwo','sliceThree'];
   var header="...header text...";
   var footer="... footer text ... ";
   var tag="... some tag ...";
   function skipTiddler(t) {
      if (store.getTiddlerSlice(t,"someSlice") > someValue) return
true;
      if (store.getTiddlerSlice(t,"someSlice") != someValue) return
true;
      return false;
   }
   // this code does not change:
   var out=[];
   var values=[];
   var tids=store.getTaggedTiddlers(tag);
   out.push(header);
   for (var i=0; i<tids.length; i++) {
      var t=tids[i].title;
      if (skipTiddler(t)) continue;
      for (var s=0; s<slices.length; s++)
            values.push(store.getTiddlerSlice(t,slices[s]));
            out.push(fmt.format(values));
      }
   }
   out.push(footer);
   return out.join('\n');
</script> 
<<slider Slider001 SliderHelp "Click here to slide out the Help File">>
See [[Slider]]

There are four elements to the syntax, enclosed by double angle brackets, each divided by a space:

   1. The word 'slider' so that TiddlyWiki knows what kind of macro it is
   2. A name for your slider so that TiddlyWiki distinguishes it from other sliders.
   3. The name of the Tiddler that you want to open by clicking on the slider. Clicking the macro above opens the tiddler that lists all the tags in thisTiddlyWiki file.
   4. The label for your slider - in other words, the text you want to appear in your slider box. For example, you could change the slider above to say 'Spaghetti'.
<<photoGallery url:images/MPHeader-*.png first:1 last:4 height:200 time:2000 labels:SubTitles numbers>>
<html>
<div macro="photoGallery url:images/FamSlide-*.jpg first:1 last:11 width:300 time:2000 labels:SubTitles numbers" style='width: 300px; float: right;'>
</html>
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
// //''Name:'' InsertSmiley
// //''Version:'' <<getversion smiley>> (<<getversiondate smiley "DD MMM YYYY">>)
// //''Author:'' AlanHecht
// //''Type:'' [[Macro|Macros]]

// //''Description:'' Inserts a small smiley graphic at the location of the macro and does not require any external graphics. The method used should work on most current browser platforms.

// //''Syntax:'' << {{{smiley ;-)}}}>>
// //Examples: <<smiley>> <<smiley :-(>> <<smiley ;-)>> <<smiley :-|>> <<smiley :-D>>

// //''Directions:'' <<tiddler MacroDirections>>

// //''Notes:'' A regular smiley <<smiley>> will be displayed if no smiley string is provided. Most smileys will work with or without the "nose" -- e.g. {{{;-)}}} is the same as {{{;)}}}

// //''Revision History:''
// // v0.1.0 (20 July 2005): initial release
// // v0.1.1 (20 July 2005): << {{{smiley}}}>> with no parameter displays a standard smiley

// //''Code section:''
version.extensions.smiley = {major: 0, minor: 1, revision: 1, date: new Date("Jul 20, 2005")};
config.macros.smiley = {}
config.macros.smiley.handler = function(place,macroName,params)
{
 var palette = ["transparent","#000000","#1a1507","#352e18","#464646","#666666","#a3141e","#b06b63","#cc9900","#dd9030","#dddddd","#e89d00","#edc32a","#f3cb3c","#fdf201","#fdf526","#ff3149","#ffac00","#ffbf06","#ffc846","#ffcc66","#ffd758","#ffdd01","#ffea7b","#ffed55","#ffffff"];
 var data = params;
 var imageMap = null;
 if(!data[0] || data[0] == ":-)" || data[0] == ":)")
 imageMap = "aaaaabbbbbaaaaaaaabdtyyvtdbaaaaabnyxxxxxujbaaabmyyffyffuujbaadyyyeeyeetttdabppppddyddpmmlbbwoooooooowsrlbbwwpooooowwmrlbbwwboooowwwbllbbwwwboooowbrllbacwwwbbbbbrllcaablswwwwsrrlibaaablsssrrllibaaaaabcrrlllcbaaaaaaaabbbbbaaaaa";
 else if(data[0] == ":-(" || data[0] == ":(")
 imageMap = "aaaaabbbbbaaaaaaaabdtyyvtdbaaaaabnyxxxxxujbaaabmyyyyyyyuujbaadyyyeeyeetttdabppppddyddpmmlbbwoooooooowsrlbbwwpooooowwmrlbbwwoooooowwrllbbwwwwbbbbbsrllbacwwbwwwwsbllcaablswwwwsrrlibaaablsssrrllibaaaaabcrrlllcbaaaaaaaabbbbbaaaaa";
 else if(data[0] == ";-)" || data[0] == ";)")
 imageMap = "aaaaabbbbbaaaaaaaabdtyyvtdbaaaaabnyxxxxxujbaaabmyyxxxxxuujbaadyyyxxxeetttdabppphddyddpmmlbbwoooooooowsrlbbwwpooooowwmrlbbwwboooowwwbllbbwwwboooowbrllbacwwwbbbbbrllcaablswwwwsrrlibaaablsssrrllibaaaaabcrrlllcbaaaaaaaabbbbbaaaaa";
 else if(data[0] == ":-|" || data[0] == ":|")
 imageMap = "aaaaabbbbbaaaaaaaabdtyyvtdbaaaaabnyxxxxxujbaaabmyyffyffuujbaadyyyeeyeetttdabppppddyddpmmlbbwoooooooowsrlbbwwpooooowwmrlbbwwoooooowwrllbbwwwwbbbbbsrllbacwwwwwwwsrllcaablswwwwsrrlibaaablsssrrllibaaaaabcrrlllcbaaaaaaaabbbbbaaaaa";
 else if(data[0] == ":-D" || data[0] == ":D")
 imageMap = "aaaaabbbbbaaaaaaaabdtyyvtdbaaaaabnyxxxxxujbaaabmyyeeyeeuujbaadyyyeeyeetttdabppppyyyyypmmlbbwbbbbbbbbbbblbbwbkzzzzzzzkbwbbwbfzzzzzzzfbwbbwbkzzzzzzzkbwbacwbkzzzzzkblcaablsbkzzzkblibaaablsbbbbblibaaaaabcrrlllcbaaaaaaaabbbbbaaaaa";
 else
 createTiddlyElement(place,"span",null,"errorNoSuchMacro","unknown smiley");
 if(imageMap)
 {
 var box = createTiddlyElement(place,"span",null,"smiley",String.fromCharCode(160));
 box.style.position = "relative";
 box.style.width = "15px";
 box.style.height = "15px";
 box.style.marginLeft = "1px";
 box.style.marginRight = "1px";
 box.style.paddingRight = "12px";
 box.style.verticalAlign = "top";

 //now divide into 15x15 grid and create each pixel
 // rows
 for(r=0; r<15; r++)
 {
 // columns
 for(c=0; c<15; c++)
 {
 //create each pixel with the correct background
 var pix = document.createElement("img");
 pix.className = "smileyPixel";
 pix.style.position = "absolute";
 pix.border = 0;
 pix.style.top = r + "px";
 pix.style.left = c + "px";
 pix.style.width = "1px";
 pix.style.height = "1px";
 pix.style.backgroundColor = palette[imageMap.charCodeAt((r*15)+c)-97];
 pix.src = "data:image/gif,GIF89a%01%00%01%00%91%FF%00%FF%FF%FF%00%00%00%C0%C0%C0%00%00%00!%F9%04%01%00%00%02%00%2C%00%00%00%00%01%00%01%00%40%02%02T%01%00%3B";
 box.appendChild(pix);
 }
 }
 }
}
Examples: <<smiley>> <<smiley :-(>> <<smiley ;-)>> <<smiley :-|>> <<smiley :-D>>
~MySlice: test text My Slice

!!!MySection
test text My Section

@@display:none;!!!!End Sections@@
/***
These 'style tweaks' can be easily included in other stylesheet tiddler so they can share a baseline look-and-feel that can then be customized to create a wide variety of 'flavors'.
/***
!body /%==================================================%/
IE needs explicit "position:static" declaration (fixes 'partial background display bug')
***/
/*{{{*/
body { font-family: Verdana,Arial,Helvetica; position:static; }
/*}}}*/

/***
!backstage /%==================================================%/
fix for bug #347/#349, wherein backstageCloak covers backstagePanel whenever fixed elements are present
***/
/*{{{*/
#backstageCloak { z-index:49; }
#backstagePanel { margin:0em 0.5em 0em 0.5em; } 
#backstageButton a:hover
	{background-color:transparent !important;}
/*}}}*/

/***
!common colors /%==================================================%/
***/
/*{{{*/
/* these seem to have been omitted from the core defaults for link styles */
a { color:#014; }
a:hover	{ color:#def; }
/*}}}*/

/***
!HTML forms /%==================================================%/
***/
/*{{{*/
/* eliminate whitespace before/after form controls */
form { margin:0;padding:0; }
/*}}}*/

/***
!basic styling /%==================================================%/
***/
/*{{{*/
/* reduce whitespace before/after horizontal rule */
hr { margin:2px 0 1px 0;padding:0; }
/*}}}*/

/***
!header and titles /%==================================================%/
IE needs explicit "position:static" declaration (fixes 'background display hides text bug')
***/
/*{{{*/
.header
	{ background:transparent; padding:.2em 1em; position:static; margin-bottom:.5em; }
.headerShadow, .headerForeground
	{ padding:.5em; }
.header a, .header .button, .header .tiddlyLinkExisting, .header .tiddlyLinkNonExisting
	{ font-weight: normal; }
.header .externalLink,
.siteSubtitle a, .siteSubtitle .button, .siteSubtitle .tiddlyLinkExisting, .siteSubtitle .tiddlyLinkNonExisting
	{ text-decoration:none; }
.header table
	{ border-collapse: collapse !important; }

/*}}}*/

/***
!displayArea /%==================================================%/
***/
/*{{{*/
#displayArea
	{ margin:0em 17em 0em 11em; }
/*}}}*/


/***
!popups /%==================================================%/
white-space:nowrap prevents items from wrapping if popup is near right edge of window
z-index:1000 makes sure popup is above EVERYTHING else
***/
/*{{{*/
.popup
	{ white-space: nowrap; z-index:1000; color: #000; background: #ffe; border: 1px solid #000;
		-moz-border-radius-topright: 5px; -moz-border-radius-bottomleft: 5px; -moz-border-radius-bottomright: 5px; }
.popup a, .popup .button, .popup .tiddlyLinkExisting, .popup .tiddlyLinkNonExisting
	{ font-weight: normal; font-style: normal; }
.popup hr
	{ color: #000; background: #ddd; border: 0; }
.popup li.disabled
	{ color: #999; }
.popup li a, .popup li a:visited
	{ color: #300; padding:1px; }
.popup li a:hover
	{ background: #006; color: #fff !important;}
/*}}}*/

/***
!messageArea /%==================================================%/
***/
/*{{{*/
#messageArea
	{ font-size:90%; -moz-border-radius:1em; background:#eee; }
/*}}}*/

/***
!main menu (left sidebar) /%==================================================%/
***/
/*{{{*/
#mainMenu
	{ z-index:1; width:9em; text-align:left; margin:0; margin-left:1.5em; padding:0; clear:both; }
*[id="mainMenu"] /* moz browsers only */
	{ width:auto !important; } 
/*}}}*/

/***
!sidebar (right sidebar) /%==================================================%/
***/
/*{{{*/
#sidebar
	{ width:18em; margin-right:1em; clear:both; }
#sidebarTabs .tab
	{ font-size:90%; -moz-border-radius-topleft:.5em; -moz-border-radius-topright:.5em; }
#sidebarTabs .tabContents
	{ background:transparent; border:1px solid #999; padding:.5em; height:auto; overflow:auto; width:92.5%; }
#sidebarTabs .tabContents .tabContents
	{ background:transparent; border:1px solid #999; padding:.5em; height:auto; }
#sidebarOptions input[type="text"]
	{ font-size:8pt; }
}
*/
/*}}}*/

/***
!tabs /%==================================================%/
***/
/*{{{*/
.tabset
	{ padding: 0.2em 0 0 0; }
.tab
	{ padding:0 1px 0 1px; }
.viewer .tab
	{ padding:0 .5em 0 .5em; }
.tabSelected
	{ border: 1px solid; border-bottom: 0px !important; margin-bottom:-2px !important; -moz-border-radius-topleft:.5em; -moz-border-radius-topright:.5em;}
.tabUnselected
	{ border: 1px solid #999; border-bottom:0px; -moz-border-radius-topleft:.5em; -moz-border-radius-topright:.5em;}
.tabContents
	{ border: 1px solid; -moz-border-radius:1em; padding: 1em; }
/*}}}*/

/***
!tiddler display elements /%==================================================%/
***/
/*{{{*/
.tiddler
	{ padding: 0 1em 1em 1em; }
.button, .button:hover, .button:active,
.viewer .button, .viewer .button:hover, .viewer .button:active
	{ background:transparent; border:0; }
.toolbar
	{ float:right; display:inline; padding-bottom:0; visibility:hidden; }
.selected .toolbar
	{ visibility:visible; }
.toolbar .floatingPanel
	{ visibility:visible !important; } /* make sure floating panels from toolbars don't disappear on mouseout */
.toolbar .button, .toolbar a
	{ border:1px solid transparent; background:transparent; margin:0px 1px; padding:0px .2em; -moz-border-radius:.5em; }
.toolbar
	{color:[[ColorPalette::TertiaryLight]];}
.toolbar a
	{color:[[ColorPalette::TertiaryLight]];}
.selected .toolbar
	{color:[[ColorPalette::Foreground]];}
.selected .toolbar, .selected .toolbar .button, .selected .toolbar a
	{ color:#006; }
.toolbar .button:hover, .toolbar a:hover
	{ border:1px solid #69c !important; background:#006 !important; color:#fff !important; }
.shadow .tagging, .shadow .tagged
	{ display:none; }
.tagging, .tagged
	{ background-color: #ccc; border: 1px solid; }
.selected .tagging, .selected .tagged
	{ background-color:#eee; border: 1px solid #999; }
.tagging, .tagged
	{ -moz-border-radius:1em; }
.subtitle
	{ font-size:90%; }
.shadow input, .shadow textarea, .shadow button, .shadow checkbox, .shadow radio, .shadow select
	{ font-size:90%; }
.shadow input, .shadow textarea, .shadow button, .shadow checkbox, .shadow radio, .shadow select
	{ font-size:90%; }
.editor input
	{ font-size: 8pt;}
.editor textarea
	{ font-size: 8pt; font-family:monospace; }
.editor select
	{ font-size: 8pt; border:1px solid; }
.title
	{ font-size: 12pt; line-height:120%; }
.viewer
	{ font-size: 9pt; padding: 0.7em; text-align:justify; }
.viewer pre, .viewer code, .viewer blockquote
	{ font-size:8pt; text-align:left; }
.viewer pre 
	{ background:#ffe; border:1px solid; }
.viewer table, .viewer table tr, .viewer table td
	{ border:1px solid; }
.viewer hr {
	margin: 1px; padding:1px;
	border:0;
	border-top: solid 1px #666;
	color: #666;
}
.viewer blockquote {
	line-height: 1.5em;
	padding-left: 1em;
	margin-left: 1em;
	border-left: 1px dotted;
}
/*}}}*/
/***
|Name|StyleSheetPrint|
|Version|09/30/08 MTP|
|~CoreVersion|2.1|
|Type|CSS|
|Description|adjustments for printing|
***/

/*{{{*/
@media print {

#mainMenu, #sidebar, #messageArea, #toolbar, #hoverMenu, .toolbar, .tagged, .tagging, .subtitle, .header, #backstageArea, #backstageButton, #topMenu, .siteTitle, .siteSubtitle, .tiddler .subtitle, .tiddler .tagging, .tiddler .tagged, .tiddler .toolbar, .hoverMenu
	{display: none !important;}
#breadCrumbs, #siteMenu, #storyMenu
	{ display:none !important; }
#displayArea
	{ margin: 1em !important; }
noscript /* Fixes a feature in Firefox 1.5.0.2 where print preview displays the noscript content */
	{ display:none; }

/* not sure if we need all the importants */
.tiddler {
	overflow:visible;
	border-style: none ! important;
	margin:0px ! important;
	padding:0px ! important;
	padding-bottom:2em ! important;
	page-break-after: auto;
	page-break-before: auto;
}
.tagglyTagging .button, .tagglyTagging .hidebutton {
	display: none ! important;
}
.headerShadow {
visibility: hidden ! important;
}
.tagglyTagged .quickopentag, .tagged .quickopentag, .hD, .fD {
	border-style: none ! important;
}
.quickopentag a.button, .miniTag {
	display: none ! important;
}
}
/*}}}*/
/***
|Name|StyleSheetShortcuts|
|Source|http://www.TiddlyTools.com/#StyleSheetShortcuts|
|Version||
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|CSS|
|Description|'convenience' classes for common formatting, alignment, boxes, tables, etc.|

These 'style tweaks' can be easily included in other stylesheet tiddler so they can share a baseline look-and-feel that can then be customized to create a wide variety of 'flavors'.
***/
/*{{{*/

/* text alignments */
.left
	{ display:block;text-align:left; }
.center
	{ display:block;text-align:center; }
.center table
	{ margin:auto !important; }
.right	
	{ display:block;text-align:right; }
.justify
	{ display:block;text-align:justify; }
.indent
	{ display:block;margin:0;padding:0;border:0;margin-left:2em; }
.floatleft
	{ float:left; }
.floatright
	{ float:right; }
.valignTop, .valignTop table, .valignTop tbody, .valignTop th, .valignTop tr, .valignTop td
	{ vertical-align:top; }
.valignBottom, .valignBottom table, .valignBottom tbody, .valignBottom th, .valignBottom tr, .valignBottom td
	{ vertical-align:bottom; }
.clear
	{ clear:both; }
.wrap
	{ white-space:normal; }
.nowrap
	{ white-space:nowrap; }
.hidden
	{ display:none; }
.show
	{ display:inline !important; }
.span
	{ display:span; }
.block
	{ display:block; }
.relative
	{ position:relative; }
.absolute
	{ position:absolute; }

/* font sizes */
.big
	{ font-size:14pt;line-height:120% }
.medium
	{ font-size:12pt;line-height:120% }
.normal
	{ font-size:9pt;line-height:120% }
.small
	{ font-size:8pt;line-height:120% }
.fine
	{ font-size:7pt;line-height:120% }
.tiny
	{ font-size:6pt;line-height:120% }
.larger
	{ font-size:120%; }
.smaller
	{ font-size:80%; }

/* font styles */
.bold
	{ font-weight:bold; }
.italic
	{ font-style:italic; }
.underline
	{ text-decoration:underline; }

/* plain list items (no bullets or indent) */
.nobullets li { list-style-type: none; margin-left:-2em; }

/* vertical tabsets - courtesy of Tobias Beer */
.vTabs .tabset {float:left;display:block;padding:0px;margin-top:.5em;min-width:20%;}
.vTabs .tabset .tab {display:block;text-align:right;padding:2px 3px 2px 7px; margin:0 1px 1px 0;}
.vTabs .tabContents {margin-left:20%;max-width:80%;padding:5px;}
.vTabs .tabContents .tabContents {border:none; background:transparent;}

/* multi-column tiddler content (not supported in Internet Explorer) */
.twocolumns { display:block;
	-moz-column-count:2; -moz-column-gap:1em; -moz-column-width:50%; /* FireFox */
	-webkit-column-count:2; -webkit-column-gap:1em; -webkit-column-width:50%; /* Safari */
	column-count:2; column-gap:1em; column-width:50%; /* Opera */
}
.threecolumns { display:block;
	-moz-column-count:3; -moz-column-gap:1em; -moz-column-width:33%; /* FireFox */
	-webkit-column-count:3; -webkit-column-gap:1em; -webkit-column-width:33%; /* Safari */
	column-count:3; column-gap:1em; column-width:33%; /* Opera */
}
.fourcolumns { display:block;
	-moz-column-count:4; -moz-column-gap:1em; -moz-column-width:25%; /* FireFox */
	-webkit-column-count:4; -webkit-column-gap:1em; -webkit-column-width:25%; /* Safari */
	column-count:4; column-gap:1em; column-width:25%; /* Opera */
}

/* page breaks */
.breakbefore { page-break-before:always; }
.breakafter { page-break-before:always; } 

/* show/hide browser-specific content for InternetExplorer vs. non-IE ("moz") browsers */
*[class="ieOnly"]
	{ display:none; } /* hide in moz (uses CSS selector) */
* html .mozOnly, *:first-child+html .mozOnly
	{ display: none; } /* hide in IE (uses IE6/IE7 CSS hacks) */

/* borderless tables */
.borderless, .borderless table, .borderless td, .borderless tr, .borderless th, .borderless tbody
	{ border:0 !important; margin:0 !important; padding:0 !important; }
.widetable, .widetable table
	{ width:100%; }

/* thumbnail images (fixed-sized scaled images) */
.thumbnail img { height:5em !important; }

/* stretchable images (auto-size to fit tiddler) */
.stretch img { width:95%; }

/* grouped content */
.outline
	{ display:block; padding:1em; -moz-border-radius:1em;-webkit-border-radius:1em; border:1px solid; }
.menubox
	{ display:block; padding:1em; -moz-border-radius:1em;-webkit-border-radius:1em; border:1px solid; background:#fff; color:#000; }
.menubox .button, .menubox .tiddlyLinkExisting, .menubox .tiddlyLinkNonExisting
	{ color:#009 !important; }
.groupbox
	{ display:block; padding:1em; -moz-border-radius:1em;-webkit-border-radius:1em; border:1px solid; background:#ffe; color:#000; }
.groupbox a, .groupbox .button, .groupbox .tiddlyLinkExisting, .groupbox .tiddlyLinkNonExisting
	{ color:#009 !important; }
.groupbox code
	{ color:#333 !important; }
.borderleft
	{ margin:0;padding:0;border:0;margin-left:1em; border-left:1px dotted; padding-left:.5em; }
.borderright
	{ margin:0;padding:0;border:0;margin-right:1em; border-right:1px dotted; padding-right:.5em; }
.borderbottom
	{ margin:0;padding:1px 0;border:0;border-bottom:1px dotted; margin-bottom:1px; padding-bottom:1px; }
.bordertop
	{ margin:0;padding:0;border:0;border-top:1px dotted; margin-top:1px; padding-top:1px; }

/* scrolled content */
.scrollbars { overflow:auto; }
.height10em { height:10em; }
.height15em { height:15em; }
.height20em { height:20em; }
.height25em { height:25em; }
.height30em { height:30em; }
.height35em { height:35em; }
.height40em { height:40em; }

/* compact form */
.smallform
	{ white-space:nowrap; }
.smallform input, .smallform textarea, .smallform button, .smallform checkbox, .smallform radio, .smallform select
	{ font-size:8pt; }

/* stretchable edit fields and textareas (auto-size to fit tiddler) */
.stretch input { width:99%; }
.stretch textarea { width:99%; }

/* compact input fields (limited to a few characters for entering percentages and other small values) */
.onechar input   { width:1em; }
.twochar input   { width:2em; }
.threechar input { width:3em; }
.fourchar input  { width:4em; }
.fivechar input  { width:5em; }

/* text colors */
.white { color:#fff !important }
.gray  { color:#999 !important }
.black { color:#000 !important }
.red   { color:#f66 !important }
.green { color:#0c0 !important }
.blue  { color:#99f !important }

/* rollover highlighting */
.mouseover 
	{color:[[ColorPalette::TertiaryLight]] !important;}
.mouseover a
	{color:[[ColorPalette::TertiaryLight]] !important;}
.selected .mouseover
	{color:[[ColorPalette::Foreground]] !important;}
.selected .mouseover .button, .selected .mouseover a
	{color:[[ColorPalette::PrimaryDark]] !important;}

/* rollover zoom text */
.zoomover
	{ font-size:80% !important; }
.selected .zoomover
	{ font-size:100% !important; }

/* [[ColorPalette]] text colors */
.Background	{ color:[[ColorPalette::Background]];	 }
.Foreground	{ color:[[ColorPalette::Foreground]];	 }
.PrimaryPale	{ color:[[ColorPalette::PrimaryPale]];	 }
.PrimaryLight	{ color:[[ColorPalette::PrimaryLight]];	 }
.PrimaryMid	{ color:[[ColorPalette::PrimaryMid]];	 }
.PrimaryDark	{ color:[[ColorPalette::PrimaryDark]];	 }
.SecondaryPale	{ color:[[ColorPalette::SecondaryPale]]; }
.SecondaryLight	{ color:[[ColorPalette::SecondaryLight]];}
.SecondaryMid	{ color:[[ColorPalette::SecondaryMid]];	 }
.SecondaryDark	{ color:[[ColorPalette::SecondaryDark]]; }
.TertiaryPale	{ color:[[ColorPalette::TertiaryPale]];	 }
.TertiaryLight	{ color:[[ColorPalette::TertiaryLight]]; }
.TertiaryMid	{ color:[[ColorPalette::TertiaryMid]];	 }
.TertiaryDark	{ color:[[ColorPalette::TertiaryDark]];	 }
.Error		{ color:[[ColorPalette::Error]];	 }

/* [[ColorPalette]] background colors */
.BGBackground	  { background-color:[[ColorPalette::Background]];	}
.BGForeground	  { background-color:[[ColorPalette::Foreground]];	}
.BGPrimaryPale	  { background-color:[[ColorPalette::PrimaryPale]];	}
.BGPrimaryLight	  { background-color:[[ColorPalette::PrimaryLight]];	}
.BGPrimaryMid	  { background-color:[[ColorPalette::PrimaryMid]];	}
.BGPrimaryDark	  { background-color:[[ColorPalette::PrimaryDark]];	}
.BGSecondaryPale  { background-color:[[ColorPalette::SecondaryPale]]; 	}
.BGSecondaryLight { background-color:[[ColorPalette::SecondaryLight]];	}
.BGSecondaryMid	  { background-color:[[ColorPalette::SecondaryMid]];	}
.BGSecondaryDark  { background-color:[[ColorPalette::SecondaryDark]]; 	}
.BGTertiaryPale	  { background-color:[[ColorPalette::TertiaryPale]];	}
.BGTertiaryLight  { background-color:[[ColorPalette::TertiaryLight]]; 	}
.BGTertiaryMid	  { background-color:[[ColorPalette::TertiaryMid]];	}
.BGTertiaryDark	  { background-color:[[ColorPalette::TertiaryDark]];	}
.BGError	  { background-color:[[ColorPalette::Error]];	 	}
/*}}}*/
/*{{{*/
#tiddlersBar .button {border:0}
#tiddlersBar .tab {white-space:nowrap}
#tiddlersBar {padding : 0em 2.5em 2px 2.5em}
.tabUnselected .tabButton, .tabSelected .tabButton {padding : 0 2px 0 2px; margin: 0 0 0 4px;}
/*}}}*/
{{{
<<checkbox [[]] [[]] [[]] [[]] [[{
var here=story.findContainingTiddler(place);
if (!here) return;
var t=store.getTiddler(here.getAttribute('tiddler'));
	if (t.tags.containsAll(['Complete','Test Tag'])&&!t.tags.contains('tag 2')) {store.setTiddlerTag(t.title,0,'Complete');
	store.setTiddlerTag(t.title,1,'Next');  
	}
	else if (!t.tags.containsAny(['Complete','tag 2'])&&t.tags.contains('Test Tag')) {store.setTiddlerTag(t.title,1,'Complete');
	store.setTiddlerTag(t.title,0,'Next');
	}
}]]>>
}}}
<<checkbox [[]] [[]] [[]] [[]] [[{var here=story.findContainingTiddler(place); if (!here) return; var t=store.getTiddler(here.getAttribute('tiddler')); if (t.tags.containsAll(['Complete','Test Tag'])&&!t.tags.contains('tag 2')) {store.setTiddlerTag(t.title,0,'Complete'); store.setTiddlerTag(t.title,1,'Next');  } else if (!t.tags.containsAny(['Complete','tag 2'])&&t.tags.contains('Test Tag')) {store.setTiddlerTag(t.title,1,'Complete'); store.setTiddlerTag(t.title,0,'Next');}}]]>>  Super Tag Checkbox

!!!Explanation
Try the example here: http://cmariexamples.tiddlyspot.com/
Here's an attempt to explain the logic:
1. In all cases, the tiddler must contain the tag "Test Tag' .
2. If it is tagged 'Complete' AND NOT tagged 'tag 2' (the addition of
'tag 2' was just to demonstrate that the conditions could be more
complex), then checking the box will remove 'Complete' and add 'Next'.
3. If it is NOT tagged 'Complete' AND NOT tagged 'tag 2', then
checking the box will add 'Complete'.  If 'Next' is present, it will
be removed.

cmari 
/***
|Name|SwitchThemePlugin|
|Source|http://www.TiddlyTools.com/#SwitchThemePlugin|
|Documentation|http://www.TiddlyTools.com/#SwitchThemePluginInfo|
|Version|5.3.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.3|
|Type|plugin|
|Requires||
|Overrides||
|Description|Select alternative TiddlyWiki template/stylesheet 'themes' from a droplist|
!!!!!Documentation
>see [[SwitchThemePluginInfo]]
!!!!!Configuration
<<<
Current theme:<<switchTheme width:auto>>
<<option chkRandomTheme>> select a random theme at startup
//Note: to prevent a given theme from being chosen at random, tag it with <<tag noRandom>>//
<<<
!!!!!Installation Note
>As of 4/13/2008, a "core patch" function that provides backward-compatibility with TW2.3.x has been split into a separate [[SwitchThemePluginPatch]] tiddler to reduce installation overhead for //this// plugin.  ''You should only install [[SwitchThemePluginPatch]] when using this plugin in documents based on a core version prior to TW2.4.0''
!!!!!Revisions
<<<
2008.04.23 [5.3.0] added option for chkRandomTheme (select random theme at startup)
2008.04.13 [5.2.0] moved TW2.3.x fixup for core's switchTheme() function to [[SwitchThemePluginPatch]] and simplified random theme handling.  Also, changed "Web*" prefix to "*ReadOnly" suffix for compatibility with TW240 core convention.
| Please see [[SwitchThemePluginInfo]] for previous revision details |
2008.01.22 [5.0.0] Completely re-written and renamed from [[SelectStylesheetPlugin]] (now retired)
>//history for retired [[SelectStylesheetPlugin]] omitted//
2005.07.20 [1.0.0] Initial Release
<<<
!!!!!Code
***/
//{{{
version.extensions.SwitchThemePlugin= {major: 5, minor: 3, revision: 0, date: new Date(2008,4,23)};

config.macros.switchTheme = {
	handler: function(place,macroName,params) {
		setStylesheet(".switchTheme {width:100%;font-size:8pt;margin:0em}","switchThemePlugin");
		if (params[0] && (params[0].substr(0,6)=="width:"))	var width=(params.shift()).substr(6);
		if (params[0] && (params[0].substr(0,6)=="label:"))	var label=(params.shift()).substr(6);
		if (params[0] && (params[0].substr(0,7)=="prompt:"))	var prompt=(params.shift()).substr(7);
		if (params[0] && params[0].trim().length) // create a link that sets a specific theme
			createTiddlyButton(place,label?label:params[0],prompt?prompt:params[0],
				function(){ config.macros.switchTheme.set(params[0]); return false;});
		else { // create a select list of available themes
			var theList=createTiddlyElement(place,"select",null,"switchTheme",null);
			theList.size=1;
			if (width) theList.style.width=width;
			theList.onchange=function() { config.macros.switchTheme.set(this.value); return true; };
			this.refresh(theList);
		}
	},
	refresh: function(list) {
		var indent = String.fromCharCode(160)+String.fromCharCode(160);
		while(list.length > 0){list.options[0]=null;} // clear list
		list.options[list.length] = new Option("select a theme:","",true,true);
		list.options[list.length] = new Option(indent+"[default]","StyleSheet");
		list.options[list.length] = new Option(indent+"[random]","*");
		var themes=store.getTaggedTiddlers("systemTheme");
		for (var i=0; i<themes.length; i++) if (themes[i].title!="StyleSheet")
			list.options[list.length]=new Option(indent+themes[i].title,themes[i].title);
		// show current selection
		for (var t=0; t<list.options.length; t++)
			if (list.options[t].value==config.options.txtTheme)
				{ list.selectedIndex=t; break; }
	},
	set: function(theme) {
		if (!theme||!theme.trim().length) return;
		if (theme=="*") { // select a random theme (excluding themes tagged with "noRandom")
			var themes=store.getTaggedTiddlers("systemTheme"); if (!themes.length) return false;
			var which=Math.floor(Math.random()*themes.length);
			while (themes[which].title==config.options.txtTheme||themes[which].isTagged("noRandom"))
				which=Math.floor(Math.random()*themes.length);
			theme=themes[which].title;
		}
		// apply and remember selected theme
		story.switchTheme(theme);
		config.options.txtTheme=theme;
		saveOptionCookie("txtTheme");
		// sync theme droplists
		var elems=document.getElementsByTagName("select");
		var lists=[]; for (var i=0; i<elems.length; i++)
			if (hasClass(elems[i],"switchTheme")) lists.push(elems[i]);
		for (var k=0; k<lists.length; k++)
			for (var t=0; t<lists[k].options.length; t++)
				if (lists[k].options[t].value==config.options.txtTheme)
					{ lists[k].selectedIndex=t; break; }
		return;
	}
}
//}}}

// // select a random theme at startup (if enabled)
//{{{
if (config.options.chkRandomTheme===undefined)
	config.options.chkRandomTheme=false;
if (config.options.chkRandomTheme)
	config.macros.switchTheme.set("*");
//}}}
/***
|Name|SwitchThemePluginInfo|
|Source|http://www.TiddlyTools.com/#SwitchThemePlugin|
|Documentation|http://www.TiddlyTools.com/#SwitchThemePluginInfo|
|Version|5.3.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.3|
|Type|documentation|
|Requires||
|Overrides||
|Description|documentation for SwitchThemePlugin|
This plugin replaces the features previously provided by SelectStylesheetPlugin (which has been retired from distribution because it is no longer compatible with the current release of the TiddlyWiki core).

Please note: ''//This plugin requires TiddlyWiki version 2.3.0 or later//''
!!!!!Usage
<<<
{{medium{__Defining a theme:__}}}
First, create a new tiddler (or import an existing tiddler) containing the desired CSS definitions and tag that tiddler with<<tag systemTheme>>.  At the top of that tiddler, embed a //slice table// that defines at least one slice, "~StyleSheet", whose value is the name of the tiddler itself, e.g., in a tiddler called [[MyTheme]], you would write:
{{{
/***
|StyleSheet|MyTheme|
***/
}}}
>Take note of the use of {{{/***}}} and {{{***/}}} surrounding the slice table syntax.   This is a ~TiddlyWiki-enhanced comment syntax that, when used in a stylesheet, permits the browser to ignore any wiki-syntax that has been embedded within the tiddler while still processing the ~CSS-syntax it contains.
In addition to the "~StyleSheet" slice entry, a theme tiddler can also contain one or more slices that associate customized versions of [[PageTemplate]], [[ViewTemplate]], and/or [[EditTemplate]], for use with that theme:
{{{
/***
|PageTemplate|MyPageTemplate|
|ViewTemplate|MyViewTemplate|
|EditTemplate|MyEditTemplate|
***/
}}}
where the slice //name// is the standard template name, and the slice //value// is the title of the alternative custom template that will be used when that theme is selected.

You can also associate a secondary set of ''"read only" templates that will be automatically applied whenever a document is being viewed online'' (i.e., via http: protocol)
{{{
|PageTemplateReadOnly|MyWebPageTemplate|
|ViewTemplateReadOnly|MyWebViewTemplate|
|EditTemplateReadOnly|MyWebEditTemplate|
}}}
These definitions can be used to seemlessly present a reduced-feature "reader" interface when your document is being viewed on-line by others, while still offering you access to the full-featured "author" interface when you are updating your content locally.

{{medium{__Selecting a theme from a droplist:__}}}
To display a droplist of available themes, use this syntax:
{{{
<<switchTheme width:nnn>>
}}}
where ''width:nnn[cm|px|em|%]'' is optional, and overrides the built-in CSS width declaration (=100%).  Use standard CSS width units (cm=centimeters, px=pixels, em=M-space, %=proportional to containing area).  You can also use a ".switchTheme" custom CSS class definition to override the built-in CSS declarations.}}}

All tiddlers tagged with<<tag systemTheme>> will be included in the droplist of available themes for you to select.  The currently selected theme is remembered between browser sessions using a TiddlyWiki option cookie ("txtTheme").  Each time you reload your document, the selected theme is automatically re-applied, based on the stored cookie value.  If there is no cookie or the selected theme no longer exists in the document (e.g., it was deleted/renamed after being selected), the [default] CSS tiddler, [[StyleSheet]], will be used as a fallback theme.  If [random] is seleced, the plugin automatically selects a random theme.  You can exclude a theme from being randomly selected by tagging it with <<tag noRandom>>.

Example:
{{{<<switchTheme width:30%>>}}}
<<switchTheme width:30%>>

{{medium{__Selecting a theme from a command link:__}}}
The {{{<<switchTheme>>}}} macro can also be used to embed a command link that, when clicked, will apply a specific, pre-selected theme, using the following syntax:
{{{
<<switchTheme "label:link text" "prompt:tooltip text" TiddlerName>>
}}}
where:
* {{block{
''label:text'' and ''prompt:text'' (optional)
define the link text the 'tooltip' text that appears near the mouse pointer when placed over the link, respectively.}}}
* {{block{
''~TiddlerName''
specifies the name of the theme tiddler to be applied (e.g., {{{<<switchTheme [[Woodshop]]>>}}}}}}
Examples:
{{{
<<switchTheme Plain>>
<<switchTheme Blackout>> 
<<switchTheme Woodshop>>
<<switchTheme Textures>>
<<switchTheme [[Edge of Night]]>>
<<switchTheme label:[default] StyleSheet>>
<<switchTheme label:randomize *>>
}}}
<<switchTheme Plain>> <<switchTheme Blackout>> <<switchTheme Woodshop>> <<switchTheme Textures>> <<switchTheme [[Edge of Night]]>> <<switchTheme label:[default] StyleSheet>> <<switchTheme label:randomize *>>

NOTE:
>You can also create a command link that specifies "*" for the theme name.  This will select a theme //at random// from the current list of available themes.  Once selected, the theme is re-applied each time the document is loaded, unless a different theme selection is subsequently made.  To prevent a given theme from being chosen at random, tag it with <<tag noRandom>>.
<<<
!!!!!Configuration
<<<
<<option chkRandomTheme>> select a random theme at startup
//Note: to prevent a given theme from being chosen at random, tag it with <<tag noRandom>>//
<<<
!!!!!Revisions
<<<
2008.04.23 [5.3.0] added option for chkRandomTheme (select random theme at startup)
2008.04.13 [5.2.0] moved TW2.3.x fixup for core's switchTheme() function to [[SwitchThemePluginPatch]] and simplified random theme handling.  Also, changed "Web*" prefix to "*ReadOnly" suffix for compatibility with TW240 core convention.
2008.02.01 [5.1.3] in response to a change for core ticket #435 (see http://trac.tiddlywiki.org/changeset/3450) -- in switchTheme, use config.refresherData.* values (if defined), instead of config.refreshers.*  This change allows the plugin to work with both the current release (~TW230) AND the upcoming ~TW240 release.
2008.02.01 [5.1.2] in switchTheme, replace hard-coded "~StyleSheet" with config.refreshers.stylesheet (used as name of loaded styles)
2008.01.30 [5.1.1] changed tag-detection to use "systemTheme" instead of "theme" for compatibility with core theme switching mechanism.
2008.01.26 [5.1.0] added support for txtTheme="*" (applies random theme at startup) and {{{<<randomTheme>>}}} macro (selects/applies a random theme when a command link is clicked)
2008.01.25 [5.0.1] in refresh() and set(), removed use of ">" to indicate current theme 
2008.01.22 [5.0.0] Completely re-written and renamed from [[SelectStylesheetPlugin]] (now retired)
>//previous history for [[SelectStylesheetPlugin]] omitted//
2005.07.20 [1.0.0] Initial Release
<<<
ⓐ ⓑ ⓒ ⓓ ⓔ ⓕ ⓖ ⓗ ⓘ ⓙ ⓚ ⓛ ⓜ ⓝ ⓞ ⓟ ⓠ ⓡ ⓢ ⓣ ⓤ ⓥ ⓦ ⓧ ⓨ ⓩ


✖ ✗ ✘ ♒ ♬ ✄ ✂ ✆ ✉ ✦ ✧ ♱ ♰ ♂ ♀ ☿ ❤ ❥ ❦ ❧ ™ ® © ♡ ♦ ♢ ♔ ♕ ♚ ♛ ★ ☆ ✮ ✯ ☄ ☾ ☽ ☼ ☀ ☁ ☂ ☃ ☻ ☺ ☹ ☮ ۞ ۩


εїз ☎ ☏ ¢ ☚ ☛ ☜ ☝ ☞ ☟ ✍ ✌ ☢ ☣ ☠ ☮ ☯ ♠ ♤ ♣ ♧ ♥


♨ ๑ ❀ ✿ ψ ♆ ☪ ☭ ♪ ♩ ♫ ℘ ℑ ℜ ℵ ♏ η α


ʊ ϟ ღ ツ 回 ₪ 卐 ™ © ® ¿ ¡ ½ ⅓ ⅔ ¼ ¾ ⅛ ⅜ ⅝ ⅞ ℅ № ⇨ ❝ ❞ # & ℃


◠ ◡ ╭ ╮ ╯ ╰ ★ ☆
⊙¤㊣★☆♀◆◇◣◢◥▲▼△▽⊿◤ ◥▆ ▇ █ █ ■ ▓ 回 □ 〓≡ ╝╚╔ ╗╬ ═ ╓ ╩ ┠ ┨┯ ┷┏┓┗ ┛┳⊥﹃﹄┌ ┐└
┘∟「」↑↓→←↘↙♀♂┇┅ ﹉﹊﹍﹎╭╮╰ ╯ *^_^* ^*^ ^-^ ^_^ ^︵^ ∵∴‖︱ ︳︴﹏﹋﹌ ♂ ♀ ♥ ♡ ☜ ☞ ☎
☏ ⊙ ◎ ☺ ☻ ► ◄ ▧ ▨ ♨ ◐ ◑ ↔ ↕ ▪ ▫ ☼ ♦ ▀ ▄ █ ▌ ▐ ░ ▒▬ ♦ ◊ ◦ ☼ ♠ ♣ ▣ ▤ ▥ ▦
▩ ぃ◘ ◙ ◈ ♫ ♬ ♪ ♩ ♭ ♪ の ☆ → あ £ ❤ 。◕‿◕。 ✎ ✟ஐ ≈ ๑۩۩.. ..۩۩๑ ๑۩۞۩๑ ✲ ❈ ➹
~.~ ◕‿-。 ☀☂☁【】┱ ┲ ❣ ✚ ✪ ✣ ✤ ✥ ✦ ❉❥ ❦ ❧ ❃ ❂ ❁ ❀ ✄ ☪ ☣ ☢ ☠ ☭ ♈ ➸ ✓ ✔ ✕ ✖
㊚ ㊛ *.:。✿*゚‘゚・
⊙¤㊣★☆♀◆◇◣◢◥▲▼△▽⊿◤ ◥▆ ▇ █ █ ■ ▓ 回 □ 〓≡ ╝╚╔ ╗╬ ═ ╓ ╩ ┠ ┨┯ ┷┏┓┗ ┛┳⊥﹃﹄┌
┐└ ┘∟「」↑↓→←↘↙♀♂┇┅ ﹉﹊﹍﹎╭╮╰ ╯ *^_^* ^*^ ^-^ ^_^ ^︵^ ∵∴‖︱ ︳︴﹏﹋﹌ ♂ ♀ ♥ ♡ ☜
☞ ☎ ☏ ⊙ ◎ ☺ ☻ ► ◄ ▧ ▨ ♨ ◐ ◑ ↔ ↕ ▪ ▫ ☼ ♦ ▀ ▄ █ ▌ ▐ ░ ▒▬ ♦ ◊ ◦ ☼ ♠ ♣ ▣ ▤
▥ ▦ ▩ ぃ◘ ◙ ◈ ♫ ♬ ♪ ♩ ♭ ♪ の ☆ → あ £ ❤ 。◕‿◕。 ✎ ✟ஐ ≈ ๑۩۩.. ..۩۩๑ ๑۩۞۩๑ ✲ ❈
➹ ~.~ ◕‿-。 ☀☂☁【】┱ ┲ ❣ ✚ ✪ ✣ ✤ ✥ ✦ ❉❥ ❦ ❧ ❃ ❂ ❁ ❀ ✄ ☪ ☣ ☢ ☠ ☭ ♈ ➸ ✓ ✔ ✕
✖ ㊚ ㊛ *.:。✿*゚‘゚・
◊ ♥ ╠ ═ ╝▫ ■ ๑ » « ¶ ஐ © † εïз ♪ ღ ♣ ♠ • ± ° •ิ. • ஐ இ * × ○ ▫ ♂ • ♀
◊ © ¤ ▲ ↔ ™ ® ☎ εїз ♨ ☏ ☆ ★ ▽ △ ▲ ∵ ∴ ∷ # ♂ ♀ ♥ ♠ ♣ ♧ ♤ ♧ ♡ ♬ ♪ ♭ ♫♪ ﻬ
ஐღ ↔ ↕ ↘••● ¤ ╬ ﹌ ▽ ☜♥☞
♬ ✞ ♥ ♕ ☯ ☭ ☠ ☃
α в c ∂ ε f g н ι נ к ℓ м η σ ρ q я s т υ v ω x y z άв ς đ έ f ģ ħ ί ј
ķ Ļ м ή ό ρ q ŕ ş ţ ù ν ώ x ч ž Å Á Ä Ã å á ä ã æ ß b c © Ð d é ê f ƒ g
h ï î j k £ m Ñ ñ η ô õ ø
Þ þ p q ® § š t ú û µ v w x ý ÿ z ž ¿ ¶ $ € ¤¨¨¤ ¤¨¨¤
(¨`v´¨) (¨`v´¨)
isнιηε
»-(¯`v´¯)-» »-(¯`v´¯)-» •:*:• •:*:•
¯`°¤.¸.¤ ¯`°¤.¸.¤ ¸¸.•*´¯`v´¯`*•.¸¸ ¸¸.•*´¯`v´¯`*•.¸¸
(¯`•._) (¯`•._) •´`•.¸.» •´`•.¸.»
¸¸.•´°¤ ¸¸.•´°¤ »--» »--»
() () ¤´¯`-´¯`¤ ¤´¯`-´¯`¤
°o.O °o.O .•´¸.•´¨¤ .•´¸.•´¨¤
-»¦«- -»¦«
☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼ !"#$%♣c÷\à☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼ !"#$%♣c÷\à
◕‿◕
❤ ツ ♥ ☺ ☻ ♦ ♣ ♠ • ◘ ○ ◙ ♀ ♂ ♪ ♫ ☼ ► ◄ ↕ ‼ ¶ § ▬ ↨ ☆ ℓ εïз ☠♫✈☹☺☻∞♥♣©®☎☑☞▲
▼׬|»¤¸„ø¤º☮☆●♫★♥☆♪¤«|¬☺☻♥♦♣♠•◘○♂
☮☮☮☮☮☮☮☮☮☮☮☮☮☮
♪♫✈☺†∞♥♣©® ☎ ☑☞
$%^&@!$%*()[]{}
♪♥♫◦°°◦°°◦♫♥♪?
.(....\............../....)
. \....\........... /..../
...\....\........../..../
....\..../´¯.I.¯`\./
..../... I....I..(¯¯¯`\
...I.....I....I...¯¯.\...\
...I.....I´¯.I´¯.I..\...)
...\.....` ¯..¯ ´.......'
....\_________.·´
(¯`v´¯)
.`·.¸.·´ ¸.·´¸.·´¨) ¸.·*¨)
(¸.·´ (¸.·´ .·´ ¸¸.·¨ `*~*~*☜ ☞ ☎ ☏ ⊙ ◎ ☺ ☻ ► ◄ ▧ ▨ ♨ ◐ ◑ ↔ ↕ ▪ ▫ ☼ ♦ ▀
▄ █ ▌ ▐ ░ ▒▬ ♦ ◊ ◦ ☼ ♠ ♣ ▣ ▤ ▥ ▦ ▩ ぃ◘ ◙ ◈ ♫ ♬ ♪ ♩ ♭ ♪ の ☆ → あ £ ❤ 。◕‿◕。
✎ ✟ஐ ≈ ๑۩۩.. ..۩۩๑ ๑۩۞۩๑ ✲ ❈ ➹ ~.~ ◕‿-。 ☀☂☁【】┱ ┲ ❣ ✚ ✪ ✣ ✤ ✥ ✦ ❉❥ ❦ ❧ ❃
❂ ❁ ❀ ✄ ☪ ☣ ☢ ☠ ☭ ♈ ➸ ✓ ✔ ✕ ✖ ㊚ ㊛ *.:。✿*゚‘゚・
⊙¤㊣★☆♀◆◇◣◢◥▲▼△▽⊿◤ ◥▆ ▇ █ █ ■ ▓ 回 □ 〓≡ ╝╚╔ ╗╬ ═ ╓ ╩ ┠ ┨┯ ┷┏┓┗ ┛┳⊥﹃﹄┌ ┐└ ┘∟「」↑↓→←↘↙♀♂┇┅
<script show>
	var tag=store.getMatchingTiddlers("TaskTabs && !Trash");
	var fmt="[[%0]] 'view %0' [[%0]]";
	var out="";
	for (var i=0; i<tag.length; i++)
		out+=(fmt.format([tag[i].title]));
//	alert(out);
	if (out.length) return "<<tabs tabTabsForTags "+out+">>";
		return "There are no tiddlers tagged with <<tag TaskTabs>>";
</script>
<<tabs txtMainTab
"Tags" "All tags" TabTags 
"No Tag" "All tiddlers with no tags" UnTagged 
"History" "Timeline" TabTimeline 
"More" "More lists" TabMore
>>
<<tabs txtMoreTab 
"All" "All tiddlers" TabAll 
"Missing" "Missing tiddlers" TabMoreMissing
"Orphan" "Orphaned tiddlers" TabMoreOrphans 
"Shadow" "Shadowed tiddlers" TabMoreShadowed
>>
version.extensions.ta = {
	//VERSION
	major: 0, 
	minor: 1, 
	revision: 0, 
	date: new Date(2006,5,24),
	name:"TableAggregate",
	author:"MarceloAdamatti",
	source:"http://adamatti.tiddlyspot.com/#TableAggregatePlugin"	
}
config.macros.ta = {
	counter:0,
	//PROCESS ROW
	processR:function(funcao,idDiv){
		var div = document.getElementById("div" + idDiv);
		var td = div.parentNode;
		while(td.tagName!="TD" && td.tagName!="TH"){
			td=td.parentNode;	
		}
		var tr = td.parentNode;
		for (var i=0;i<tr.childNodes.length;i++){
			var aux = tr.childNodes[i];
			if (aux.tagName=="TD" || aux.tagName=="TH") {	
				try{	
					var x=0;
					if(document.all){
						x = parseFloat(aux.innerText);			
					}else{
						x = parseFloat(aux.textContent);			
					}
					if (!isNaN(x))
						funcao.process(x);
				}catch(e){}
			}
		}
		div.innerHTML=funcao.resultado.toFixed(2);
	},
	//PROCESS COL
	processC:function(funcao,idDiv){
		var div = document.getElementById("div" + idDiv);
		var td = div.parentNode;
		while(td.tagName!="TD" && td.tagName!="TH")
			td=td.parentNode;		
		var coluna = td.cellIndex;
		var tbody = td.parentNode.parentNode;
		for (var i=0;i<tbody.childNodes.length;i++){	
			var tr = tbody.childNodes[i];
			var aux = tr.childNodes[coluna];
			if (aux.tagName=="TD" || aux.tagName=="TH") {	
				try{	
					var x=0;
					if(document.all){
						x = parseFloat(aux.innerText);			
					}else{
						x = parseFloat(aux.textContent);			
					}
					if (!isNaN(x))
						funcao.process(x);
				}catch(e){}
			}
		}
		div.innerHTML=funcao.resultado.toFixed(2);
	},
	//FUNCTIONS
	funcs:{
		avg:function() {
			this.qtd=0;
			this.somador=0;
			this.resultado=0;
			this.process=function (valor){
				this.somador+=parseFloat(valor);
				this.qtd++;
				this.resultado=(this.somador/this.qtd);
			}				
		},
		sum:function (){
			this.resultado=0;	
			this.process=function (valor){
				this.resultado+=valor;
			}	
		},
		min: function(){
			this.resultado="";
			this.process=function (valor){
				if (this.resultado=="")
					this.resultado=valor;
				if (valor<=this.resultado)
					this.resultado=valor;
			}
		},
		max:function(){
			this.resultado="";
			this.process=function (valor){
				if (this.resultado=="")
					this.resultado=valor;
				if (valor>=this.resultado)
					this.resultado=valor;
			}
		},
		count: function(){
			this.resultado=0;
			this.process=function (valor){
				this.resultado+=1;
			}
		}
	},
	handler:function(place,macroName,params) {
		var rowCol = params[0].toUpperCase();
		var func = params[1].toLowerCase();
		var counter=++config.macros.ta.counter;
		place.innerHTML="<div id=div" + counter + "></div><iframe "
					  + "onload='{var o=new config.macros.ta.funcs." + func + "();"
					  + "config.macros.ta.process" + rowCol + "(o," + counter + ");}' "
					  + "style='display:none'>"
					  "<\/iframe>";
	}
};
||sum|avg|max|min|count||h
|sum|1|2|3|4|5|''<<ta r sum>>''|
|avg|6|7|8|9|10|''<<ta r avg>>''|
|max|11|12|13|14|15|''<<ta r max>>''|
|min|16|17|18|19|20|''<<ta r min>>''|
|count|21|22|23|24|25|''<<ta r count>>''|
||''<<ta c sum>>''|''<<ta c avg>>''|''<<ta c max>>''|''<<ta c min>>''|''<<ta c count>>''||
/***
|''Name:''|TableSortingPlugin|
|''Description:''|Dynamically sort tables by clicking on column headers|
|''Author:''|Saq Imtiaz ( lewcid@gmail.com )|
|''Source:''|http://tw.lewcid.org/#TableSortingPlugin|
|''Code Repository:''|http://tw.lewcid.org/svn/plugins|
|''Version:''|2.02|
|''Date:''|25-01-2008|
|''License:''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|''~CoreVersion:''|2.2.3|
!!Usage:
* Make sure your table has a header row
** {{{|Name|Phone Number|Address|h}}}<br> Note the /h/ that denote a header row 
* Give the table a class of 'sortable'
** {{{
|sortable|k
|Name|Phone Number|Address|h
}}}<br>Note the /k/ that denotes a class name being assigned to the table.
* To disallow sorting by a column, place {{{<<nosort>>}}} in it's header
* To automatically sort a table by a column, place {{{<<autosort>>}}} in the header for that column
** Or to sort automatically but in reverse order, use {{{<<autosort reverse>>}}}

!!Example:
|sortable|k
|Name |Salary |Extension |Performance |File Size |Start date |h
|ZBloggs, Fred |$12000.00 |1353 |+1.2 |74.2Kb |Aug 19, 2003 21:34:00 |
|ABloggs, Fred |$12000.00 |1353 |1.2 |3350b |09/18/2003 |
|CBloggs, Fred |$12000 |1353 |1.200 |55.2Kb |August 18, 2003 |
|DBloggs, Fred |$12000.00 |1353 |1.2 |2100b |07/18/2003 |
|Bloggs, Fred |$12000.00 |1353 |01.20 |6.156Mb |08/17/2003 05:43 |
|Turvey, Kevin |$191200.00 |2342 |-33 |1b |02/05/1979 |
|Mbogo, Arnold |$32010.12 |2755 |-21.673 |1.2Gb |09/08/1998 |
|Shakespeare, Bill |£122000.00|3211 |6 |33.22Gb |12/11/1961 |
|Shakespeare, Hamlet |£9000 |9005 |-8 |3Gb |01/01/2002 |
|Fitz, Marvin |€3300.30 |5554 |+5 |4Kb |05/22/1995 |

***/
// /%
//!BEGIN-PLUGIN-CODE
config.tableSorting = {
	
	darrow: "\u2193",
	
	uarrow: "\u2191",
	
	getText : function (o) {
		var p = o.cells[SORT_INDEX];
		return p.innerText || p.textContent || '';
	},
	
	sortTable : function (o,rev) {
		SORT_INDEX = o.getAttribute("index");
		var c = config.tableSorting;
		var T = findRelated(o.parentNode,"TABLE");
		if(T.tBodies[0].rows.length<=1) 
			return;
		var itm = "";
		var i = 0;
		while (itm == "" && i < T.tBodies[0].rows.length) {
			itm = c.getText(T.tBodies[0].rows[i]).trim();
			i++;
		}
		if (itm == "") 
			return; 	
		var r = [];
		var S = o.getElementsByTagName("span")[0];		
		c.fn = c.sortAlpha; 
		if(!isNaN(Date.parse(itm)))
			c.fn = c.sortDate; 
		else if(itm.match(/^[$|£|€|\+|\-]{0,1}\d*\.{0,1}\d+$/)) 
			c.fn = c.sortNumber; 
		else if(itm.match(/^\d*\.{0,1}\d+[K|M|G]{0,1}b$/)) 
			c.fn = c.sortFile; 
		for(i=0; i<T.tBodies[0].rows.length; i++) {
			 r[i]=T.tBodies[0].rows[i]; 
		} 
		r.sort(c.reSort);
		if(S.firstChild.nodeValue==c.darrow || rev) {
			r.reverse();
			S.firstChild.nodeValue=c.uarrow;
		} 
		else 
			S.firstChild.nodeValue=c.darrow;
		var thead = T.getElementsByTagName('thead')[0]; 
		var headers = thead.rows[thead.rows.length-1].cells;
		for(var k=0; k<headers.length; k++) {
			if(!hasClass(headers[k],"nosort"))
				addClass(headers[k].getElementsByTagName("span")[0],"hidden");
		}
		removeClass(S,"hidden");
		for(i=0; i<r.length; i++) { 
			T.tBodies[0].appendChild(r[i]);
			c.stripe(r[i],i);
			for(var j=0; j<r[i].cells.length;j++){
				removeClass(r[i].cells[j],"sortedCol");
			}
			addClass(r[i].cells[SORT_INDEX],"sortedCol");
		}
	},
	
	stripe : function (e,i){
		var cl = ["oddRow","evenRow"];
		i&1? cl.reverse() : cl;
		removeClass(e,cl[1]);
		addClass(e,cl[0]);
	},
	
	sortNumber : function(v) {
		var x = parseFloat(this.getText(v).replace(/[^0-9.-]/g,''));
		return isNaN(x)? 0: x;
	},
	
	sortDate : function(v) {
		return Date.parse(this.getText(v));
	},

	sortAlpha : function(v) {
		return this.getText(v).toLowerCase();
	},
	
	sortFile : function(v) { 		
		var j, q = config.messages.sizeTemplates, s = this.getText(v);
		for (var i=0; i<q.length; i++) {
			if ((j = s.toLowerCase().indexOf(q[i].template.replace("%0\u00a0","").toLowerCase())) != -1)
				return q[i].unit * s.substr(0,j);
		}
		return parseFloat(s);
	},
	
	reSort : function(a,b){
		var c = config.tableSorting;
		var aa = c.fn(a);
		var bb = c.fn(b);
		return ((aa==bb)? 0 : ((aa<bb)? -1:1));
	}
};

Story.prototype.tSort_refreshTiddler = Story.prototype.refreshTiddler;
Story.prototype.refreshTiddler = function(title,template,force,customFields,defaultText){
	var elem = this.tSort_refreshTiddler.apply(this,arguments);
	if(elem){
		var tables = elem.getElementsByTagName("TABLE");
		var c = config.tableSorting;
		for(var i=0; i<tables.length; i++){
			if(hasClass(tables[i],"sortable")){
				var x = null, rev, table = tables[i], thead = table.getElementsByTagName('thead')[0], headers = thead.rows[thead.rows.length-1].cells;
				for (var j=0; j<headers.length; j++){
					var h = headers[j];
					if (hasClass(h,"nosort"))
						continue;
					h.setAttribute("index",j);
					h.onclick = function(){c.sortTable(this); return false;};
					h.ondblclick = stopEvent;
					if(h.getElementsByTagName("span").length == 0)
						createTiddlyElement(h,"span",null,"hidden",c.uarrow); 
					if(!x && hasClass(h,"autosort")) {
						x = j;
						rev = hasClass(h,"reverse");
					}
				}
				if(x)
					c.sortTable(headers[x],rev);		
			}
		}
	}
	return elem; 
};

setStylesheet("table.sortable span.hidden {visibility:hidden;}\n"+
	"table.sortable thead {cursor:pointer;}\n"+
	"table.sortable .nosort {cursor:default;}\n"+
	"table.sortable td.sortedCol {background:#ffc;}","TableSortingPluginStyles");

function stopEvent(e){
	var ev = e? e : window.event;
	ev.cancelBubble = true;
	if (ev.stopPropagation) ev.stopPropagation();
	return false;	
}	

config.macros.nosort={
	handler : function(place){
		addClass(place,"nosort");
	}	
};

config.macros.autosort={
	handler : function(place,m,p,w,pS){
		addClass(place,"autosort"+" "+pS);		
	}	
};
//!END-PLUGIN-CODE
// %/
The tabs macro creates an area where it displays one of several tiddlers alternately, as the user clicks on the tab labels at the top.

It is used like this:

<<tabs ID Label1 Tip1 Tiddler1 Label2 Tip2 Tiddler2 [Label3 ...]>>

    * ID: specifies the name of a cookie used to save the information about which tab was displayed last.
    * Label1, Label2, ... define the labels that are displayed at the top of the area for each tab
    * Tip1, Tip2, ... define tooltips that explain, somewhat more verbosely than the labels, what you can expect to find on each tab.
    * Tiddler1, Tiddler2, ... name the tiddlers that are displayed on each tab. 

Obviously, there must be exactly three strings for each tab.

The syntax for the tabs macro looks like this:
!Code:
{{{<<tabs txt[TabCookie]
	"[Home]" "[Home Projects]" [[Home]]
	"[Work]" "[Work Projects]" [[Work]]
	"[Tricks]" "[My Tips & Tricks]" [[Tricks]]
>>}}}
!Example:
<<tabs txt[TabCookie]
	"[Home]" "[Home Projects]" [[Home]]
	"[Work]" "[Work Projects]" [[Work]]
	"[Tricks]" "[My Tips & Tricks]" [[Tricks]]
>>
<script>
var prefix ="s";
var out = "" ;
var tags= store.getTags() ;

for(var i=0;i<tags.length;i++) {
  str = new String(tags[i]) ;
  if(! str.startsWith(prefix)) continue ;
//  out += str.split(",")[0] + "\n" ;
  out+="* <<tag [["+tags[i][0]+"]]>> ("+tags[i][1]+")"+"\n"; 
}
return out ;
</script>
/***
|Name|TagCloudPlugin|
|Source|http://www.TiddlyTools.com/#TagCloudPlugin|
|Version|1.2.0|
|Author|Eric Shulman|
|Original Author|Clint Checketts|
|License|unknown|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|present a 'cloud' of tags using proportional font display|
!Usage
<<<
{{{<<tagCloud>>}}}
> show all tags in the document
{{{<<tagCloud tag tag tag...>>}}}
> show all tags except those listed as parameters
{{{<<tagCloud =tagvalue>>}}}
> show only tags that are themselves tagged with the indicated tag value (i.e., ~TagglyTagging usage)
<<<
!Examples
<<<
{{{<<tagCloud>>}}}
<<tagCloud>>
----
{{{<<tagCloud excludeLists>>}}}
<<tagCloud excludeLists>>
----
{{{<<tagCloud =Tricks>>}}}
<<tagCloud =Tricks>>
<<<
!Revisions
<<<
2008.09.05 [1.2.0] ELS: added '=tagname' parameter to include only tags that are themselves tagged with the specified value (i.e., ~TagglyTagging usage)
2008.07.03 [1.1.0] ELS: added 'segments' property to macro object.  Extensive code cleanup
<<<
!Code
***/
//{{{
version.extensions.tagCloud = {major: 1, minor: 2 , revision: 0, date: new Date(2008,9,5)};
//Created by Clint Checketts, contributions by Jonny Leroy and Eric Shulman

config.shadowTiddlers.TagCloud="<<tagCloud>>";

setStylesheet("\
	.tagCloud span{height: 3.5em;margin: 3px;}\
	.tagCloud1{font-size: 80%;}\
	.tagCloud2{font-size: 100%;}\
	.tagCloud3{font-size: 120%;}\
	.tagCloud4{font-size: 150%;}\
	.tagCloud5{font-size: 180%;}\
	.tagCloud6{font-size: 200%;}\
	",
	"tagCloudsStyles");

config.macros.tagCloud = {
	noTags: "No tag cloud created because there are no tags.",
	tooltip: "%1 tiddlers tagged with '%0'",
	segments: 5,
	handler: function(place,macroName,params) {

		var tags=store.getTags();

		if (params.length) {
			if (params[0].substr(0,1)=="=") {
				// include only specifically tagged tags
				var tagged=store.getTaggedTiddlers(params[0].substr(1));
				for (var t=0; t<tagged.length; t++)
					tagged[t]=tagged[t].title;
				for (var t=0; t<tags.length; t++)
					if (!tagged.contains(tags[t][0])) tags[t][0]="";
			} else {
				// include all tags except those listed as params
				for (var t=0; t<tags.length; t++)
					if (params.contains(tags[t][0])) tags[t][0]="";
			}
		}

		// get maximum number of tags to calculate tagCloud segment sizes
		var mostTags=0;
		for (var t=0; t<tags.length; t++) if (tags[t][0].length > 0)
			if (tags[t][1]>mostTags) mostTags=tags[t][1];
		var tagSegment=mostTags/config.macros.tagCloud.segments;

		// output
		var tagCloudWrapper = createTiddlyElement(place,"div",null,"tagCloud",null);
		if(!tags.length)
			createTiddlyElement(tagCloudWrapper,"span",null,null,this.noTags);
		else for (var t=0; t<tags.length; t++) if (tags[t][0].length > 0){
			tagCloudWrapper.appendChild(document.createTextNode(" "));
			var theTag = createTiddlyButton(tagCloudWrapper,
				tags[t][0],this.tooltip.format(tags[t]),onClickTag,
				"tagCloudtag tagCloud" + (Math.round(tags[t][1]/tagSegment)+1));
			theTag.setAttribute("tag",tags[t][0]);
		}
	}
};
//}}}
/***
!10.08.08 MTP:
{{{<<tagger>>>}}}<<tagger>>
Tag this tiddler with default Tagger tags

{{center{<<tagCloud>>}}}
***/
/*{{{*/

/*}}}*/
/***
|Name|TaggedTemplateTweak|
|Source|http://www.TiddlyTools.com/#TaggedTemplateTweak|
|Documentation|http://www.TiddlyTools.com/#TaggedTemplateTweakInfo|
|Version|1.4.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|Story.prototype.chooseTemplateForTiddler()|
|Description|use alternative ViewTemplate/EditTemplate for tiddler's tagged with specific tag values|
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.'' 
!!!!!Documentation
>see [[TaggedTemplateTweakInfo]]
!!!!!Revisions
<<<
2008.08.29 [1.4.1] corrected handling for tiddlers with no matching tagged template when non-default theme is in effect (e.g., use "MyTheme##ViewTemplate").
| please see [[TaggedTemplateTweakInfo]] for previous revision details |
2007.06.11 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.TaggedTemplateTweak= {major: 1, minor: 4, revision: 1, date: new Date(2008,8,29)};

Story.prototype.taggedTemplate_chooseTemplateForTiddler = Story.prototype.chooseTemplateForTiddler
Story.prototype.chooseTemplateForTiddler = function(title,template)
{
	// get default template from core
	var coreTemplate=this.taggedTemplate_chooseTemplateForTiddler.apply(this,arguments);

	// if the tiddler doesn't exist yet or is untagged, return core result
	var tiddler=store.getTiddler(title);
	if (!tiddler || !tiddler.tags.length)
		return coreTemplate;

	// split core template into theme prefix and template name
	var theme="";
	var template=coreTemplate;
	var parts=template.split(config.textPrimitives.sectionSeparator);
	if (parts[1]) { theme=parts[0]; template=parts[1]; }
	else theme=config.options.txtTheme||""; // fallback if theme is not specified
	theme+=config.textPrimitives.sectionSeparator;

	// look for template whose prefix matches a tag on this tiddler (if any)
	for (i=0; i<tiddler.tags.length; i++) {
		var t=tiddler.tags[i]+template; // add tag prefix to template
		var c=t.substr(0,1).toUpperCase()+t.substr(1); // capitalized for WikiWord title
		if (store.getTiddlerText(theme+t))	{ return theme+t; } // theme##tagTemplate
		if (store.getTiddlerText(theme+c))	{ return theme+c; } // theme##TagTemplate
		if (store.getTiddlerText(t)) 		{ return t; }	     // tagTemplate
		if (store.getTiddlerText(c))		{ return c; }	     // TagTemplate
	}
	return coreTemplate; // no matching tag, return core result
}
//}}}
/***
|Name|TaggedTemplateTweakInfo|
|Source|http://www.TiddlyTools.com/#TaggedTemplateTweak|
|Documentation|http://www.TiddlyTools.com/#TaggedTemplateTweakInfo|
|Version|1.4.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 TaggedTemplateTweak|
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]].

To use 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.//

To use templates contained as //sections// within a systemTheme definition, the plugin also tries prepending the currently selected theme (specified by {{{config.options.txtTheme}}}) plus the 'section separator' (##) to the template name (e.g. ''[[SomeTheme##MediaViewTemplate]]'').

If no matching alternative template can be found by using //any// of the tiddler's tags (either "as-is" or capitalized, with or without a section prefix), 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)//
<<<
!!!!!Revisions
<<<
2008.08.29 [1.4.1] corrected handling for tiddlers with no matching tagged template when non-default theme is in effect (e.g., use "MyTheme##ViewTemplate").
2008.05.15 [1.4.0] support use of *shadow* tagged templates (e.g., [[DiscussionViewTemplate]] created by [[DiscussionPlugin]])
2008.05.10 [1.3.0] corrected handling for determining core template when using theme with sections
2008.05.01 [1.2.5] added support for tagged templates stored as sections in a theme
2008.04.01 [1.2.0] added support for using systemTheme section-based template definitions (requested by Phil Hawksworth)
2008.01.22 [*.*.*] plugin size reduction - documentation moved to [[TaggedTemplateTweakInfo]]
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
<<<
/***
|''Name:''|~TaggerPlugin|
|''Version:''|1.0.1 (2006-06-01)|
|''Source:''|http://tw.lewcid.org//#TaggerPlugin|
|''Author:''|SaqImtiaz|
|''Description:''|Provides a drop down listing current tiddler tags, and allowing toggling of tags.|
|''Documentation:''|[[TaggerPluginDocumentation]]|
|''Source Code:''|[[TaggerPluginSource]]|
|''~TiddlyWiki:''|Version 2.0.8 or better|
|''Requires ''|[[DeprecatedFunctionsPlugin]]|
|''Stylesheet Changes ''|ViewTemplate|
|See Above |<div class='toolbar'><span style="padding-right:2.45em;" macro='tagger source:TagDB exclude:excludeLists'></span></div>|


***/
//{{{

config.tagger={
       defaults:{
              label: 'Tags: ',
              tooltip: 'Manage tiddler tags',
              taglist: 'true',
              excludeTags: '',
              notags: 'tiddler has no tags',
              aretags: 'current tiddler tags:',
              toggletext: 'add tags:'
       }
};

config.macros.tagger={};
config.macros.tagger.arrow = (document.all?"▼":"▾"); // the fat one is the only one that works in IE
config.macros.tagger.handler =  function(place,macroName,params,wikifier,paramString,tiddler) {
       var defaults = config.tagger.defaults;
       var nAV = paramString.parseParams('tagman', null, true);
       var label = ((nAV[0].label)&&(nAV[0].label[0])!='.')?nAV[0].label[0]+this.arrow: defaults.label+this.arrow;
       var tooltip = ((nAV[0].tooltip)&&(nAV[0].tooltip[0])!='.')?nAV[0].tooltip[0]: defaults.tooltip;
       var taglist = ((nAV[0].taglist)&&(nAV[0].taglist[0])!='.')?nAV[0].taglist[0]: defaults.taglist;
       var exclude = ((nAV[0].exclude)&&(nAV[0].exclude[0])!='.')?(nAV[0].exclude[0]).readBracketedList(): defaults.excludeTags.readBracketedList();
       if ((nAV[0].source)&&(nAV[0].source[0])!='.')var source = nAV[0].source[0];
       if (source&&!store.getTiddler(source)) return false;

       var onclick = function(e) {
                   if (!e) var e = window.event;
                   var popup = Popup.create(this);
                   var tagsarray = store.getTags();
                   var tags=new Array();

                   for (var i=0; i<tagsarray.length; i++){
                       tags.push(tagsarray[i][0]);}

                   if (source)
                      {var sourcetiddler=store.getTiddler(source);
                       tags=sourcetiddler.tags.sort();}

                   var currentTags = tiddler.tags.sort();

                   var createButtons=function(text,theTag,tooltipPrefix){
                       var sp = createTiddlyElement(createTiddlyElement(popup,"li"),"span",null,"tagger");
                       var theToggle = createTiddlyButton(sp,text,tooltipPrefix+" '"+theTag+"'",taggerOnToggle,"button","toggleButton");
                       theToggle.setAttribute("tiddler",tiddler.title);
                       theToggle.setAttribute("tag",theTag);
                       insertSpacer(sp);
                       if (window.createTagButton_orig_mptw)
                           createTagButton_orig_mptw(sp,theTag);
                       else
                           createTagButton(sp,theTag);
                       }

                   createTiddlyElement(popup,"li",null,"listTitle",(tiddler.tags.length == 0 ? defaults.notags : defaults.aretags));

                   for (var t=0; t<currentTags.length; t++){
                      createButtons("[x]",currentTags[t],"remove tag ");
                       }

                   createTiddlyElement(createTiddlyElement(popup,"li"),"hr");

                   if (taglist!='false')
                      { createTiddlyElement(popup,"li",null,"listTitle",defaults.toggletext);
                        for (var i=0; i<tags.length; i++){
                          if (!tiddler.tags.contains(tags[i])&&!exclude.contains(tags[i]))
                                  {createButtons("[ ]",tags[i],"add tag ");
                                  }
                          }
                          createTiddlyElement(createTiddlyElement(popup,"li"),"hr");
                      }

                   var newTagButton = createTiddlyButton(createTiddlyElement(popup,"li"),("Create new tag"),null,taggerOnToggle);
                   newTagButton.setAttribute("tiddler",tiddler.title);
                   if (source) newTagButton.setAttribute("source",source);

                   Popup.show(popup,false);
                   e.cancelBubble = true;
                   if (e.stopPropagation) e.stopPropagation();
                   return(false);
                   };

       createTiddlyButton(place,label,tooltip,onclick,"button","taggerDrpBtn");
};

window.taggerOnToggle = function(e) {
              var tag = this.getAttribute("tag");
              var title = this.getAttribute("tiddler");
              var tiddler = store.getTiddler(title);
              if (!tag)
                 {
                 var newtag=prompt("Enter new tag:","");
                 if (newtag!=''&&newtag!=null)
                    {
                    var tag=newtag;
                    if (this.getAttribute("source"))
                    {var sourcetiddler =  store.getTiddler(this.getAttribute("source"));
                    sourcetiddler.tags.pushUnique(newtag);}
                    }
                 else
                     {return false;};
                 }
              if (!tiddler || !tiddler.tags)
                 {store.saveTiddler(title,title,'',config.options.txtUserName,new Date(),tag);}
              else
                  {if (tiddler.tags.find(tag)==null)
                     {tiddler.tags.push(tag)}
                  else if(!newtag)
                      {tiddler.tags.splice(tiddler.tags.find(tag),1)};
                  store.saveTiddler(tiddler.title,tiddler.title,tiddler.text,tiddler.modifier,tiddler.modified,tiddler.tags);};
              story.refreshTiddler(title,null,true);
              if(config.options.chkAutoSave)
                  saveChanges();
              return false;
};

setStylesheet(
 ".tagger a.button {font-weight: bold;display:inline; padding:0px;}\n"+
 ".tagger #toggleButton {padding-left:2px; padding-right:2px; margin-right:1px; font-size:110%;}\n"+
 "#nestedtagger {background:#2E5ADF; border: 1px solid #0331BF;}\n"+
 ".popup .listTitle {color:#000;}\n"+
 "",
"TaggerStyles");

window.lewcidTiddlerSwapTag =  function (tiddler, oldTag, newTag){
                    for (var i = 0; i < tiddler.tags.length; i++)
			  if (tiddler.tags[i] == oldTag) {
				  tiddler.tags[i] = newTag;
				  return true;}
                         return false;
}

window.lewcidRenameTag = function(e) {
                    var tag=this.getAttribute("tag");
                    var newtag=prompt("Rename tag '"+tag+"' to:",tag);

                    if ((newtag==tag)||(newtag==null)) {return false;}

                    if(store.tiddlerExists(newtag))
                               {if(confirm(config.messages.overwriteWarning.format([newtag.toString()])))
                                             story.closeTiddler(newtag,false,false);
                               else
                                             return null;}

                    tagged=store.getTaggedTiddlers(tag);
                    if (tagged.length!=0){
                          for (var j = 0; j < tagged.length; j++)
                              lewcidTiddlerSwapTag(tagged[j],tag,newtag);}

                    if (store.tiddlerExists(tag))
                       {store.saveTiddler(tag,newtag);}
                    if (document.getElementById("tiddler"+tag))
                       {var oldTagTiddler =  document.getElementById(story.idPrefix + tag);
                       var before= story.positionTiddler(oldTagTiddler);
                       var place = document.getElementById(story.container);
                       story.closeTiddler(tag,false,false);
                       story.createTiddler(place,before,newtag,null);
                       story.saveTiddler(newtag);}
                    if(config.options.chkAutoSave)
                                                      saveChanges();
                    return false;
}


window.onClickTag=function(e)
{
	if (!e) var e = window.event;
	var theTarget = resolveTarget(e);

        var nested = (!isNested(theTarget));
        if ((Popup.stack.length > 1)&&(nested==true)) {Popup.removeFrom(1);}
        else if(Popup.stack.length > 0 && nested==false) {Popup.removeFrom(0);};

        var theId = (nested==false)? "popup" : "nestedtagger";
        var popup = createTiddlyElement(document.body,"ol",theId,"popup",null);
        Popup.stack.push({root: this, popup: popup});

	var tag = this.getAttribute("tag");
	var title = this.getAttribute("tiddler");
	if(popup && tag)
		{
		var tagged = store.getTaggedTiddlers(tag); 
		var titles = [];
		var li,r;
		for(r=0;r<tagged.length;r++)
			if(tagged[r].title != title)
				titles.push(tagged[r].title);
		var lingo = config.views.wikified.tag;
		if(titles.length > 0)
			{
			var openAll = createTiddlyButton(createTiddlyElement(popup,"li"),lingo.openAllText.format([tag]),lingo.openAllTooltip,onClickTagOpenAll);
			openAll.setAttribute("tag",tag);
			createTiddlyElement(createTiddlyElement(popup,"li"),"hr");
			for(r=0; r<titles.length; r++)
				{
				createTiddlyLink(createTiddlyElement(popup,"li"),titles[r],true);
				}
			}
		else
			createTiddlyText(createTiddlyElement(popup,"li",null,"disabled"),lingo.popupNone.format([tag]));
		createTiddlyElement(createTiddlyElement(popup,"li"),"hr");
		var h = createTiddlyLink(createTiddlyElement(popup,"li"),tag,false);
		createTiddlyText(h,lingo.openTag.format([tag]));

		createTiddlyElement(createTiddlyElement(popup,"li"),"hr");

		var renameTagButton = createTiddlyButton(createTiddlyElement(popup,"li"),("Rename tag '"+tag+"'"),null,lewcidRenameTag);
		renameTagButton.setAttribute("tag",tag)
		}
	Popup.show(popup,false);
	e.cancelBubble = true;
	if (e.stopPropagation) e.stopPropagation();
	return(false);
}

if (!window.isNested)
   window.isNested = function(e) {
        while (e != null) {
                var contentWrapper = document.getElementById("contentWrapper");
                if (contentWrapper == e) return true;
                e = e.parentNode;
                }
        return false;
   };

config.shadowTiddlers.TaggerPluginDocumentation="The documentation is available [[here.|http://tw.lewcid.org/#TaggerPluginDocumentation]]";

config.shadowTiddlers.TaggerPluginSource="The uncompressed source code is available [[here.|http://tw.lewcid.org/#TaggerPluginSource]]";
//}}}
''If you want this documentation available offline, copy this tiddler to your TW.''

!Description:
The tagger plugin is a result of combining key features from the dropTags and tagAdder macro's. However, since it departs somewhat from the interface tagAdder users will be familiar with, I'm making this available as a new plugin alongside tagAdder.

Tagger provides a dropdown list of the current tiddler tags, along with the ability to toggle them. Further it can optionally display a list of tags in the dropdown, which can be addded to the tiddler.

*Clicking on ''[x]'' and ''[_]'' removes and adds the tag respectively.
*Clicking on the tag text displays the tag dropdown for that tag, listing tiddlers tagged with it.
*The ''Create new tag'' lets you quickly type in a new tag not in the list.
*Click on this button to see the dropdown: <<tagger>>

Further note that each tag dropdown has a ''Rename tag'' option. This can be used to quickly rename a tag in the entire TW, also rename it's tiddler if it exists.

//''tagAdder, dropTags and the future''
- tagAdder will no longer will be developed, but will remain available. I encourage all tagAdder users to upgrade to tagger.
- dropTags will still be developed for those users that dont want the 'tag editing' features.//

!Examples & Usage:
*At it's simplest, using tagger is as simple as {{{<<tagger>>}}} <<tagger>>
**This gives a dropdown with the current tiddler tags, followed by all the tags in the TW.
*You can also use a list of specified tags instead of all tags in the TW, by specifying a source tiddler.
**{{{<<tagger source:TagDB>>}}} <<tagger source:TagDB>>
*You can also display ONLY the current tiddler tags
**{{{<<tagger taglist:false>>}}} <<tagger taglist:false>>

*To exclude tags from the list: {{{<<tagger exclude:"excludeLists Reference [[Tag with spaces]]">>}}} <<tagger exclude:"excludeLists Reference [[Tag with spaces]]">>

*To exclude tags from the list: {{{<<tagger source:TagDB exclude:"excludeLists">>}}} <<tagger source:TagDB exclude:"excludeLists">>

*For a custom button label: {{{<<tagger label:"custom label">>}}} <<tagger label:"custom label">>
*For a custom tooltip: {{{<<tagger tooltip:"custom tooltip">>}}} <<tagger tooltip:"custom tooltip">>

!CSS and Styling:
For those wishing to customize the popup appearance:
*the main popup has a class and id of popup has with all other popups.
*the nested tag popups have an id of nestedpopup

!Advanced Users:
You can change the global defaults for tagger, like the button label, the tags to exclude or whether to display the taglist or not, by editing the ''config.tagger.defaults'' section in the code.

!To Do:
*code optimization
*possibly a 'delete this tag' option.

!History
*version 1.0.1 (2006-06-01): fixed conflicts with QuickOpenTag (TagglyTagging) and AutoTagger.
/***
|''Note''|This has been modified from the original, see http://groups.google.com/group/tiddlywiki/browse_thread/thread/f249920a35dae415. |
|''Name:''|~TaggerPluginHack|
|''Version:''|1.0.2 (2010-04-23)|
|''Source:''|http://tw.lewcid.org//#TaggerPlugin|
|''Author:''|SaqImtiaz|
|''Modified By:''|Neil M. Sheldon|
|''Description:''|Provides a drop down listing current tiddler tags, and allowing toggling of tags.|
|''Documentation:''|[[TaggerPluginDocumentation]]|
|''Source Code:''|[[TaggerPluginSource]]|
|''~TiddlyWiki:''|Version 2.6.0 or better|
!Modifications:
# use 'array.indexOf' instead of deprecated 'array.find' 
# Only 'save' the tiddler if view template is active, otherwise 'setTiddlerTag'.
# Make sure refreshing is done with the same current template, otherwise, using this in an EditTemplate causes it to switch to viewing mode.
# Added dontChangeSource parameter, which prevents the plugin from modifying the tag data source tiddler if a new tag is added.

I don't know when the .find method was deprecated, I just know that it did not exist in 2.6.0, so that's the version this requires.

[[Works On My Machine|http://www.codinghorror.com/blog/2007/03/the-works-on-my-machine-certification-program.html]]

***/
//{{{

config.tagger={
       defaults:{
              label: 'Tags: ',
              tooltip: 'Manage tiddler tags',
              taglist: 'true',
              excludeTags: '',
              notags: 'tiddler has no tags',
              aretags: 'current tiddler tags:',
              toggletext: 'add tags:'
       }
};

config.macros.tagger={};
config.macros.tagger.arrow = (document.all?"▼":"▾"); // the fat one is the only one that works in IE
config.macros.tagger.handler =  function(place,macroName,params,wikifier,paramString,tiddler) {
       var defaults = config.tagger.defaults;
       var nAV = paramString.parseParams('tagman', null, true);
       var label = ((nAV[0].label)&&(nAV[0].label[0])!='.')?nAV[0].label[0]+this.arrow: defaults.label+this.arrow;
       var tooltip = ((nAV[0].tooltip)&&(nAV[0].tooltip[0])!='.')?nAV[0].tooltip[0]: defaults.tooltip;
       var taglist = ((nAV[0].taglist)&&(nAV[0].taglist[0])!='.')?nAV[0].taglist[0]: defaults.taglist;
       var exclude = ((nAV[0].exclude)&&(nAV[0].exclude[0])!='.')?(nAV[0].exclude[0]).readBracketedList(): defaults.excludeTags.readBracketedList();
       if ((nAV[0].source)&&(nAV[0].source[0])!='.')var source = nAV[0].source[0];
       if (source&&!store.getTiddler(source)) return false;
       // NMS: Allow the source to remain unchanged.
       var dontChangeSource = (nAV[0].dontChangeSource);

       var onclick = function(e) {
                   if (!e) var e = window.event;
                   var popup = Popup.create(this);
                   var tagsarray = store.getTags();
                   var tags=new Array();

                   for (var i=0; i<tagsarray.length; i++){
                       tags.push(tagsarray[i][0]);}

                   if (source)
                      {var sourcetiddler=store.getTiddler(source);
                       tags=sourcetiddler.tags.sort();}

                   var currentTags = tiddler.tags.sort();

                   var createButtons=function(text,theTag,tooltipPrefix){
                       var sp = createTiddlyElement(createTiddlyElement(popup,"li"),"span",null,"tagger");
                       var theToggle = createTiddlyButton(sp,text,tooltipPrefix+" '"+theTag+"'",taggerOnToggle,"button","toggleButton");
                       theToggle.setAttribute("tiddler",tiddler.title);
                       theToggle.setAttribute("tag",theTag);
                       insertSpacer(sp);
                       if (window.createTagButton_orig_mptw)
                           createTagButton_orig_mptw(sp,theTag);
                       else
                           createTagButton(sp,theTag);
                       }

                   createTiddlyElement(popup,"li",null,"listTitle",(tiddler.tags.length == 0 ? defaults.notags : defaults.aretags));

                   for (var t=0; t<currentTags.length; t++){
                      createButtons("[x]",currentTags[t],"remove tag ");
                       }

                   createTiddlyElement(createTiddlyElement(popup,"li"),"hr");

                   if (taglist!='false')
                      { createTiddlyElement(popup,"li",null,"listTitle",defaults.toggletext);
                        for (var i=0; i<tags.length; i++){
                          if (!tiddler.tags.contains(tags[i])&&!exclude.contains(tags[i]))
                                  {createButtons("[ ]",tags[i],"add tag ");
                                  }
                          }
                          createTiddlyElement(createTiddlyElement(popup,"li"),"hr");
                      }

                   var newTagButton = createTiddlyButton(createTiddlyElement(popup,"li"),("Create new tag"),null,taggerOnToggle);
                   newTagButton.setAttribute("tiddler",tiddler.title);
// NMS: Allow source to remain unchanged.
                   if (source && !dontChangeSource) newTagButton.setAttribute("source",source);

                   Popup.show(popup,false);
                   e.cancelBubble = true;
                   if (e.stopPropagation) e.stopPropagation();
                   return(false);
                   };

       createTiddlyButton(place,label,tooltip,onclick,"button","taggerDrpBtn");
};

window.taggerOnToggle = function(e) {
              var tag = this.getAttribute("tag");
              var title = this.getAttribute("tiddler");
              var tiddler = store.getTiddler(title);
              if (!tag)
                 {
                 var newtag=prompt("Enter new tag:","");
                 if (newtag!=''&&newtag!=null)
                    {
                    var tag=newtag;
                    if (this.getAttribute("source"))
                    {var sourcetiddler =  store.getTiddler(this.getAttribute("source"));
                    sourcetiddler.tags.pushUnique(newtag);}
                    }
                 else
                     {return false;};
                 }
// NMS: Modified the rest to:
// 1. use 'indexOf' instead of 'find' (which is deprecated)
// 2. Only 'save' the tiddler if view template is active, otherwise 'setTiddlerTag'.
// 3. Make sure refreshing is done with the same current template.
              var tiddlerElem = story.getTiddler(title)
              var currTemplate = tiddlerElem.getAttribute("template");
              var isViewed=tiddlerElem.getAttribute("template").indexOf("ViewTemplate")!=-1;
              if (!tiddler || !tiddler.tags) {
                     if (isViewed) {
                        store.saveTiddler(title,title,'',config.options.txtUserName,new Date(),tag);
                     } else {
                       story.setTiddlerTag(title,tag,0);
                     }
              } else {
                    if (tiddler.tags.indexOf(tag)==-1) {
                         tiddler.tags.push(tag)
                    } else if(!newtag) {
                         tiddler.tags.splice(tiddler.tags.indexOf(tag),1)
                    };
                    if (isViewed) {
                       store.saveTiddler(tiddler.title,tiddler.title,tiddler.text,
                                          tiddler.modifier,tiddler.modified,tiddler.tags);
                    } else {
                       story.setTiddlerTag(title,tag,0);
                    }
              };
              if (isViewed) {
                 story.refreshTiddler(title,currTemplate,true);
              }
              if(config.options.chkAutoSave)
                  saveChanges();

};

setStylesheet(
 ".tagger a.button {font-weight: bold;display:inline; padding:0px;}\n"+
 ".tagger #toggleButton {padding-left:2px; padding-right:2px; margin-right:1px; font-size:110%;}\n"+
 "#nestedtagger {background:#2E5ADF; border: 1px solid #0331BF;}\n"+
 ".popup .listTitle {color:#000;}\n"+
 "",
"TaggerStyles");

window.lewcidTiddlerSwapTag =  function (tiddler, oldTag, newTag){
                    for (var i = 0; i < tiddler.tags.length; i++)
			  if (tiddler.tags[i] == oldTag) {
				  tiddler.tags[i] = newTag;
				  return true;}
                         return false;
}

window.lewcidRenameTag = function(e) {
                    var tag=this.getAttribute("tag");
                    var newtag=prompt("Rename tag '"+tag+"' to:",tag);

                    if ((newtag==tag)||(newtag==null)) {return false;}

                    if(store.tiddlerExists(newtag))
                               {if(confirm(config.messages.overwriteWarning.format([newtag.toString()])))
                                             story.closeTiddler(newtag,false,false);
                               else
                                             return null;}

                    tagged=store.getTaggedTiddlers(tag);
                    if (tagged.length!=0){
                          for (var j = 0; j < tagged.length; j++)
                              lewcidTiddlerSwapTag(tagged[j],tag,newtag);}

                    if (store.tiddlerExists(tag))
                       {store.saveTiddler(tag,newtag);}
                    if (document.getElementById("tiddler"+tag))
                       {var oldTagTiddler =  document.getElementById(story.idPrefix + tag);
                       var before= story.positionTiddler(oldTagTiddler);
                       var place = document.getElementById(story.container);
                       story.closeTiddler(tag,false,false);
                       story.createTiddler(place,before,newtag,null);
                       story.saveTiddler(newtag);}
                    if(config.options.chkAutoSave)
                                                      saveChanges();
                    return false;
}


window.onClickTag=function(e)
{
	if (!e) var e = window.event;
	var theTarget = resolveTarget(e);

        var nested = (!isNested(theTarget));
        if ((Popup.stack.length > 1)&&(nested==true)) {Popup.removeFrom(1);}
        else if(Popup.stack.length > 0 && nested==false) {Popup.removeFrom(0);};

        var theId = (nested==false)? "popup" : "nestedtagger";
        var popup = createTiddlyElement(document.body,"ol",theId,"popup",null);
        Popup.stack.push({root: this, popup: popup});

	var tag = this.getAttribute("tag");
	var title = this.getAttribute("tiddler");
	if(popup && tag)
		{
		var tagged = store.getTaggedTiddlers(tag);
		var titles = [];
		var li,r;
		for(r=0;r<tagged.length;r++)
			if(tagged[r].title != title)
				titles.push(tagged[r].title);
		var lingo = config.views.wikified.tag;
		if(titles.length > 0)
			{
			var openAll = createTiddlyButton(createTiddlyElement(popup,"li"),lingo.openAllText.format([tag]),lingo.openAllTooltip,onClickTagOpenAll);
			openAll.setAttribute("tag",tag);
			createTiddlyElement(createTiddlyElement(popup,"li"),"hr");
			for(r=0; r<titles.length; r++)
				{
				createTiddlyLink(createTiddlyElement(popup,"li"),titles[r],true);
				}
			}
		else
			createTiddlyText(createTiddlyElement(popup,"li",null,"disabled"),lingo.popupNone.format([tag]));
		createTiddlyElement(createTiddlyElement(popup,"li"),"hr");
		var h = createTiddlyLink(createTiddlyElement(popup,"li"),tag,false);
		createTiddlyText(h,lingo.openTag.format([tag]));

		createTiddlyElement(createTiddlyElement(popup,"li"),"hr");

		var renameTagButton = createTiddlyButton(createTiddlyElement(popup,"li"),("Rename tag '"+tag+"'"),null,lewcidRenameTag);
		renameTagButton.setAttribute("tag",tag)
		}
	Popup.show(popup,false);
	e.cancelBubble = true;
	if (e.stopPropagation) e.stopPropagation();
	return(false);
}

if (!window.isNested)
   window.isNested = function(e) {
        while (e != null) {
                var contentWrapper = document.getElementById("contentWrapper");
                if (contentWrapper == e) return true;
                e = e.parentNode;
                }
        return false;
   };

config.shadowTiddlers.TaggerPluginDocumentation="The documentation is available [[here.|http://tw.lewcid.org/#TaggerPluginDocumentation]]";

config.shadowTiddlers.TaggerPluginSource="The uncompressed source code is available [[here.|http://tw.lewcid.org/#TaggerPluginSource]]";
//}}}
The TaggingMacro produces a list of links to tiddlers that carry the specified tag. If no tag is specified, it looks for tiddlers tagged with the name of the current tiddler. It looks like this:
{{{<<tagging>>
<<tagging TiddlerTitle>>
<<tagging sep:[[, ]]>>}}}
In HTML, the list is formatted like so:
{{{<ul>
<li class="listTitle">List title label</li>
<li><a class="tiddlyLink ..." href="javascript:;" onclick="..."
	   refresh="link" tiddlyLink="ExampleOne">ExampleOne</a></li>
</ul>}}}

The optional {{{sep}}} parameter specifies a string of characters to be inserted as a separator between each {{{<li>}}} element. In conjunction with the CSS {{{ul li {display: none;} }}} this allows the tagging list to be formatted as a nicely formatted inline list.

!Example 1:
{{{<<tagging Tricks>>}}}
<<tagging Tricks>>

!Example 2:
<html>
<head>
<style>

</style>
</head>
<body>
<p style="background: blue; color: white;">A new background and font color with inline CSS</p>
<p style="background: red; color: black;">This is workin'</p>
</body>
</html>

!Example 3:
{{{<<tag Tricks>>}}}
<<tag Tricks>>

Special Tags:
excludeSearch - Add this tag to a tiddler to remove it from the search results.
excludeLists - Add this tag to the tags field to remove it from the sidebar.
/***
|Name:|TagglyTaggingPlugin|
|Description:|tagglyTagging macro is a replacement for the builtin tagging macro in your ViewTemplate|
|Version:|3.3.1 ($Rev: 6100 $)|
|Date:|$Date: 2008-07-27 01:42:07 +1000 (Sun, 27 Jul 2008) $|
|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
***/
//{{{

merge(String.prototype,{

	parseTagExpr: function(debug) {

		if (this.trim() == "")
			return "(true)";

		var anyLogicOp = /(!|&&|\|\||\(|\))/g;
		var singleLogicOp = /^(!|&&|\|\||\(|\))$/;

		var spaced = this.
			// because square brackets in templates are no good
			// this means you can use [(With Spaces)] instead of [[With Spaces]]
			replace(/\[\(/g," [[").
			replace(/\)\]/g,"]] "). 
			// space things out so we can use readBracketedList. tricky eh?
			replace(anyLogicOp," $1 ");

		var expr = "";

		var tokens = spaced.readBracketedList(false); // false means don't uniq the list. nice one JR!

		for (var i=0;i<tokens.length;i++)
			if (tokens[i].match(singleLogicOp))
				expr += tokens[i];
			else
				expr += "tiddler.tags.contains('%0')".format([tokens[i].replace(/'/,"\\'")]); // fix single quote bug. still have round bracket bug i think

		if (debug)
			alert(expr);

		return '('+expr+')';
	}

});

merge(TiddlyWiki.prototype,{
	getTiddlersByTagExpr: function(tagExpr,sortField) {

		var result = [];

		var expr = tagExpr.parseTagExpr();

		store.forEachTiddler(function(title,tiddler) {
			if (eval(expr))
				result.push(tiddler);
		});

		if(!sortField)
			sortField = "title";

		result.sort(function(a,b) {return a[sortField] < b[sortField] ? -1 : (a[sortField] == b[sortField] ? 0 : +1);});
		
		return result;
	}
});

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':",
			exprLabel:  "Matching tag expression '%0':",
			excerpts:   "excerpts",
			descr:      "descr",
			slices:     "slices",
			contents:   "contents",
			sliders:    "sliders",
			noexcerpts: "title only",
			noneFound:  "(none)"
		},

		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",
			descr:      "Click to show the description slice",
			slices:     "Click to show all slices",
			contents:   "Click to show entire tiddler contents",
			sliders:    "Click to show tiddler contents in sliders",
			noexcerpts: "Click to show entire title only"
		},

		tooDeepMessage: "* //sitemap too deep...//"
	},

	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","descr","slices","contents","sliders"]
		},
		valuePrefix: "taggly.",
		excludeTags: ["excludeLists","excludeTagging"],
		excerptSize: 50,
		excerptMarker: "/%"+"%/",
		siteMapDepthLimit: 25
	},

	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(),"");
		// 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.getTiddlersByTagExpr(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,isTagExpr) {
		switch(this.getTagglyOpt(title,"listMode")) {
			case "group":  return this.createTagglyListGrouped(place,title,isTagExpr); break;
			case "normal": return this.createTagglyListNormal(place,title,false,isTagExpr); break;
			case "commas": return this.createTagglyListNormal(place,title,true,isTagExpr); break;
			case "sitemap":return this.createTagglyListSiteMap(place,title,isTagExpr); break;
		}
	},

	getTaggingCount: function(title,isTagExpr) {
		// thanks to Doug Edmunds
		if (this.config.showTaggingCounts) {
			var tagCount = config.taggly.getTiddlers(title,'title',isTagExpr).length;
			if (tagCount > 0)
				return " ("+tagCount+")";
		}
		return "";
	},

	getTiddlers: function(titleOrExpr,sortBy,isTagExpr) {
		return isTagExpr ? store.getTiddlersByTagExpr(titleOrExpr,sortBy) : store.getTaggedTiddlers(titleOrExpr,sortBy);
	},

	getExcerpt: function(inTiddlerTitle,title,indent) {
		if (!indent)
			indent = 1;

		var displayMode = this.getTagglyOpt(inTiddlerTitle,"excerpts");
		var t = store.getTiddler(title);

		if (t && displayMode == "excerpts") {
			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 (t && displayMode == "contents") {
			return "\n{{contents indent"+indent+"{\n" + t.text + "\n}}}";
		}
		else if (t && displayMode == "sliders") {
			return "<slider slide>\n{{contents{\n" + t.text + "\n}}}\n</slider>";
		}
		else if (t && displayMode == "descr") {
			var descr = store.getTiddlerSlice(title,'Description');
			return descr ? " {{excerpt{" + descr  + "}}}" : "";
		}
		else if (t && displayMode == "slices") {
			var result = "";
			var slices = store.calcAllSlices(title);
			for (var s in slices)
				result += "|%0|<nowiki>%1</nowiki>|\n".format([s,slices[s]]);
			return result ? "\n{{excerpt excerptIndent{\n" + result  + "}}}" : "";
		}
		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,isTagExpr) {

		var list = config.taggly.getTiddlers(title,this.getTagglyOpt(title,"sortBy"),isTagExpr);

		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,isTagExpr) {
		var sortBy = this.getTagglyOpt(title,"sortBy");
		var sortOrder = this.getTagglyOpt(title,"sortOrder");

		var list = config.taggly.getTiddlers(title,sortBy,isTagExpr);

		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,isTagExpr) {

		var list = config.taggly.getTiddlers(title,sortBy,isTagExpr);

		if (sortOrder == "desc")
			list.reverse();

		var indent = "";
		for (var j=0;j<depth;j++)
			indent += "*"

		var childOutput = "";

		if (depth > this.config.siteMapDepthLimit)
			childOutput += indent + this.lingo.tooDeepMessage;
		else
			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,false);

		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,isTagExpr) {
		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"),isTagExpr);
		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 parsedParams = paramString.parseParams("tag",null,true);
				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);

				var tag = getParam(parsedParams,"tag");
				var expr = getParam(parsedParams,"expr");

				if (expr) {
					refreshContainer.setAttribute("isTagExpr","true");
					refreshContainer.setAttribute("title",expr);
					refreshContainer.setAttribute("showEmpty","true");
				}
				else {
					refreshContainer.setAttribute("isTagExpr","false");
					if (tag) {
        				refreshContainer.setAttribute("title",tag);
						refreshContainer.setAttribute("showEmpty","true");
					}
					else {
        				refreshContainer.setAttribute("title",tiddler.title);
						refreshContainer.setAttribute("showEmpty","false");
					}
				}
				this.refresh(refreshContainer);
			},

			refresh: function(place) {
				var title = place.getAttribute("title");
				var isTagExpr = place.getAttribute("isTagExpr") == "true";
				var showEmpty = place.getAttribute("showEmpty") == "true";
				removeChildren(place);
				addClass(place,"tagglyTagging");
				var countFound = config.taggly.getTiddlers(title,'title',isTagExpr).length
				if (countFound > 0 || showEmpty) {
					var lingo = config.taggly.lingo;
					config.taggly.createListControl(place,title,"hideState");
					if (config.taggly.getTagglyOpt(title,"hideState") == "show") {
						createTiddlyElement(place,"span",null,"tagglyLabel",
								isTagExpr ? lingo.labels.exprLabel.format([title]) : 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,isTagExpr);
						if (countFound == 0 && showEmpty)
							createTiddlyElement(place,"div",null,"tagglyNoneFound",lingo.labels.noneFound);
					}
				}
			}
		}
	},

	// 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]]; }",
".excerptIndent { margin-left:4em; }",
"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; }",
".tagglyNoneFound { margin-left:2em; color:[[ColorPalette::TertiaryMid]]; font-size:90%; font-style:italic; }",
"/*}}}*/",
		""].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
// added + syntax to start open instead of closed

***/
//{{{
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[2] + " "+"\u00BB",lookaheadMatch[2],this.onClickSlider,"button sliderButton");
			var panel = createTiddlyElement(w.output,"div",null,"sliderPanel");
			panel.style.display = (lookaheadMatch[1] == '+' ? "block" : "none");
			wikify(lookaheadMatch[3],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;
	}
});

//}}}
/***
|''Name:''|TagsTreePlugin|
|''Description:''|Displays tags hierachy as a tree of tagged tiddlers.<br>Can be used to create dynamic outline navigation.|
|''Version:''|1.0.1|
|''Date:''|Jan 04,2008|
|''Source:''|http://visualtw.ouvaton.org/VisualTW.html|
|''Author:''|Pascal Collin|
|''License:''|[[BSD open source license|License]]|
|''~CoreVersion:''|2.1.0|
|''Browser:''|Firefox 2.0; InternetExplorer 6.0|
!Demo
On the plugin [[homepage|http://visualtw.ouvaton.org/VisualTW.html]] :
*Try to tag some <<newTiddler>> with a tag displayed in the menu and edit MainMenu.
*Look at some tags like [[Plugins]] or [[menu]].
!Installation
#import the plugin,
#save and reload,
#optionally, edit TagsTreeStyleSheet.
! Usage
{{{<<tagsTree>>}}} macro accepts the following //optional// parameters.
|!#|!parameter|!description|!by default|
|1|{{{root}}}|Uses {{{root}}} tag as tree root|- In a //tiddler// content or template : uses the tiddler as root tag.<br>- In the //page// content or template (by ex MainMenu) : displays all untagged tags.|
|2|{{{excludeTag}}}|Excludes all such tagged tiddlers from the tree|Uses default excludeLists tag|
|3|{{{level}}}|Expands nodes until level {{{level}}}.<br>Value {{{0}}} hides expand/collapse buttons.|Nodes are collapsed on first level|
|4|{{{depth}}}|Hierachy depth|6 levels depth (H1 to H6 header styles)|
|5|{{{sortField}}}|Alternate sort field. By example : "index".|Sorts tags and tiddlers alphabetically (on their title)|
|6|{{{labelField}}}|Alertnate label field. By example : "label".|Displays tiddler's title|

!Useful addons
*[[FieldsEditorPlugin]] : //create//, //edit//, //view// and //delete// commands in toolbar <<toolbar fields>>.
*[[TaggerPlugin]] : Provides a drop down listing current tiddler tags, and allowing toggling of tags.
!Advanced Users
You can change the global defaults for TagsTreePlugin, like default {{{level}}} value or level styles, by editing or overriding the first config.macros.tagsTree attributes below.
!Code
***/
//{{{
config.macros.tagsTree = {
	expand : "+",
	collapse : "–",
	depth : 6,
	level : 1,
	sortField : "",	
	labelField : "",
	styles : ["h1","h2","h3","h4","h5","h6"],
	trees : {}
}

config.macros.tagsTree.handler = function(place,macroName,params,wikifier,paramString,tiddler)
{
	var root = params[0] ? params[0] : (tiddler ? tiddler.title : null);
	var excludeTag = params[1] ? params[1] : "excludeTagsTree";
	var level = params[2] ? params[2] : config.macros.tagsTree.level;
	var depth = params[3] ? params[3] : config.macros.tagsTree.depth;
	var sortField = params[4] ? params[4] : config.macros.tagsTree.sortField;
	var labelField = params[5] ? params[5] : config.macros.tagsTree.labelField;
	var showButtons = (level>0);
	var id = config.macros.tagsTree.getId(place);
	if (config.macros.tagsTree.trees[id]==undefined) config.macros.tagsTree.trees[id]={};
	config.macros.tagsTree.createSubTree(place,id,root,excludeTag,[],level>0 ? level : 1,depth, sortField, labelField,showButtons);
}

config.macros.tagsTree.createSubTree = function(place, id, root, excludeTag, ancestors, level, depth, sortField, labelField,showButtons){
	var childNodes = root ? this.getChildNodes(root, ancestors) : this.getRootTags(excludeTag);
	var isOpen = (level>0) || (!showButtons);
	if (root && this.trees[id][root]!=undefined) isOpen = this.trees[id][root]; 
	if (root && ancestors.length) {
		var t = store.getTiddler(root);
		if (childNodes.length && depth>0) {
			var wrapper = createTiddlyElement(place , this.styles[Math.min(Math.max(ancestors.length,1),6)-1],null,"branch");
			if (showButtons) {
				b = createTiddlyButton(wrapper, isOpen ? config.macros.tagsTree.collapse : config.macros.tagsTree.expand, null, config.macros.tagsTree.onClick);
				b.setAttribute("treeId",id);
				b.setAttribute("tiddler",root);					
			}
			createTiddlyText(createTiddlyLink(wrapper, root),t&&labelField ? t.fields[labelField] ? t.fields[labelField] : root : root);
		}
		else 
			createTiddlyText(createTiddlyLink(place, root,false,"leaf"),t&&labelField ? t.fields[labelField] ? t.fields[labelField] : root : root);
	}
	if (childNodes.length && depth) {
		var d = createTiddlyElement(place,"div",null,"subtree");
		d.style.display= isOpen ? "block" : "none";
		if (sortField)
			childNodes.sort(function(a, b){
				var fa=a.fields[sortField];
				var fb=b.fields[sortField];
				return (fa==undefined && fb==undefined) ? a.title < b.title ? -1 : a.title > b.title ? 1 : 0 : (fa==undefined && fb!=undefined) ? 1 :(fa!=undefined && fb==undefined) ? -1 : fa < fb ? -1 : fa > fb ? 1 : 0;
			})
		for (var cpt=0; cpt<childNodes.length; cpt++)
			this.createSubTree(d, id, childNodes[cpt].title, excludeTag, ancestors.concat(root), level-1, depth-1, sortField, labelField, showButtons);	
	}	
}

config.macros.tagsTree.onClick = function(e){
	var id = this.getAttribute("treeId");
	var tiddler = this.getAttribute("tiddler");	
	var n = this.parentNode.nextSibling;
	var isOpen = n.style.display != "none";
	if(config.options.chkAnimate && anim && typeof Slider == "function")
		anim.startAnimating(new Slider(n,!isOpen,null,"none"));
	else
		n.style.display = isOpen ? "none" : "block";
	this.firstChild.nodeValue = isOpen ? config.macros.tagsTree.expand : config.macros.tagsTree.collapse;
	config.macros.tagsTree.trees[id][tiddler]=!isOpen;
	return false;
}

config.macros.tagsTree.getChildNodes = function(root ,ancestors){
	var childs = store.getTaggedTiddlers(root);
	var result = new Array();
	for (var cpt=0; cpt<childs.length; cpt++)
		if (childs[cpt].title!=root && ancestors.indexOf(childs[cpt].title)==-1) result.push(childs[cpt]);
	return result;
}

config.macros.tagsTree.getRootTags = function(excludeTag){
	var tags = store.getTags(excludeTag);
	tags.sort(function(a,b) {return a[0].toLowerCase() < b[0].toLowerCase() ? -1 : (a[0].toLowerCase() == b[0].toLowerCase() ? 0 : +1);});
	var result = new Array();
	for (var cpt=0; cpt<tags.length; cpt++) {
		var t = store.getTiddler(tags[cpt][0]);
		if (!t || t.tags.length==0) result.push(t ? t : {title:tags[cpt][0],fields:{}});
	}
	return result;
}

config.macros.tagsTree.getId = function(element){
	while (!element.id && element.parentNode) element=element.parentNode;
	return element.id ? element.id : "<html>";
}

config.shadowTiddlers.TagsTreeStyleSheet = "/*{{{*/\n";
config.shadowTiddlers.TagsTreeStyleSheet +=".leaf, .subtree {display:block; margin-left : 0.5em}\n";
config.shadowTiddlers.TagsTreeStyleSheet +=".subtree {margin-bottom:0.5em}\n";
config.shadowTiddlers.TagsTreeStyleSheet +="#mainMenu {text-align:left}\n";
config.shadowTiddlers.TagsTreeStyleSheet +=".branch .button {border:1px solid #DDD; color:#AAA;font-size:9px;padding:0 2px;margin-right:0.3em;vertical-align:middle;text-align:center;}\n";
config.shadowTiddlers.TagsTreeStyleSheet +="/*}}}*/";

store.addNotification("TagsTreeStyleSheet", refreshStyles); 

config.shadowTiddlers.MainMenu="<<tagsTree>>"

config.shadowTiddlers.PageTemplate = config.shadowTiddlers.PageTemplate.replace(/id='mainMenu' refresh='content' /,"id='mainMenu' refresh='content' force='true' ")

//}}}
/***
|''Name:''|TaskOrganizerPlugin|
|''Description:''|A simple task manager|
|''Version:''|1.2.5|
|''Date:''|Dec 19, 2008|
|''Source:''|http://www.math.ist.utl.pt/~psoares/addons.html|
|''Documentation:''|[[TaskOrganizerPlugin Documentation|TaskOrganizerPluginDoc]]|
|''Author:''|Paulo Soares|
|''License:''|[[Creative Commons Attribution-Share Alike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|''~CoreVersion:''|2.1.0|
|''Requires:''|CheckboxPlugin (Eric Shulman), InlineJavascriptPlugin (Eric Shulman) and PartTiddlerPlugin (Udo Borkowski)|
|''Optional:''|ReminderMacros (Jeremy Sheeley)|
***/
//{{{
config.macros.button = {};

config.macros.button.handler=function(place,macroName,params,wikifier,paramString,tiddler) {
 if(params.length<3) return;
 var myFunction = eval(params[2]);
 place.appendChild(createTiddlyButton(place,params[0],params[1],myFunction));
}

config.macros.taskOrganizer = {};

config.macros.taskOrganizer.options = {
 pendingTask: "Pending",
 completedTask: "Completed",
 newTask: {label: "New task", tooltip: "Add a new task"},
 addTaskCategory: {label: "New category", tooltip: "Add a new task category"},
 deleteTaskCategory: {label: "Delete category", tooltip: "Delete this task category"},
 deleteCategoryConfirmation: "Are you sure you want to delete this category?",
 deleteTasksConfirmation: "Are you sure you want to delete all tasks associated to the category?",
 newTaskCategoryPrompt: "Enter the new task category name:"
}

config.macros.taskOrganizer.addCategory = function() {
 var cm = config.macros.taskOrganizer;
 if(typeof arguments[0] != 'string'){
 var newTask = prompt(cm.options.newTaskCategoryPrompt,"");
 var rebuild = false;
 var taskTag = this.parentNode.getAttribute("tag");
 var title = this.parentNode.getAttribute("tiddlerTitle");
 } else {
 var newTask = arguments[0];
 var holder= document.getElementById("tiddler"+arguments[1]);
 var taskTag = holder.getAttribute("tag");
 var title = arguments[1];
 var rebuild = true;
 }
 if(!newTask) return;

 var tabTiddler = new Tiddler();
 tabTiddler.title = title+ ":" + newTask;
 tabTiddler.tags[0] = taskTag;
 tabTiddler.tags[1] = "excludeLists";
 tabTiddler.modifier = config.options.txtUserName;
 var titleTask = newTask.replace(/ /g,"=");

 tabTiddler.text = "<<tabs \"top" + title + ":" + titleTask + "\"\n" + cm.options.pendingTask + " " + cm.options.pendingTask + " \"" + title + ":" + newTask + "/Pending" + "\"\n";
 tabTiddler.text += cm.options.completedTask + " " + cm.options.completedTask + " \"" + title + ":" + newTask + "/Completed" + "\"\n>>\n";
 tabTiddler.text += "<<button '" + cm.options.newTask.label + "' '" + cm.options.newTask.tooltip + "' 'config.macros.taskOrganizer.newTask'>>";
 tabTiddler.text += " <<button '" + cm.options.deleteTaskCategory.label + "' '" + cm.options.deleteTaskCategory.tooltip + "' 'config.macros.taskOrganizer.deleteCategory'>>\n";

 tabTiddler.text += "<part Pending hidden>";
 tabTiddler.text += "<script>\n var list = \"\";\n";
 tabTiddler.text += "var tiddlers = store.getTaggedTiddlers(\"" + taskTag + "." + newTask + "\", \"created\");\n";
 if(config.macros.reminders) tabTiddler.text += "var regexp = new RegExp(\"<<re\"+\"minder .+>>\", \"g\");\n"
 tabTiddler.text += "for(var i=0; i<tiddlers.length; i++){\nif(!tiddlers[i].tags.contains (\"completed\")){\nvar newEntry=tiddlers[i].title.split(\"#\");\nlist+=\"[X(\"+tiddlers[i].title+\":completed)] [[\"+newEntry[newEntry.length-1]+\"|\"+tiddlers[i].title+\"]]\\n\";\n";
 if(config.macros.reminders){
 tabTiddler.text += "var reminder = tiddlers[i].text.match(regexp);\n";
 tabTiddler.text += "if(reminder){\n for(var j=0; j<reminder.length; j++){\n list += \"*\" + reminder[j] + \"\\n\";}}";
 }
 tabTiddler.text+= "}}\n return list;\n";
 tabTiddler.text += "</script>";
 tabTiddler.text += "</part>\n";

 tabTiddler.text += "<part Completed hidden>";
 tabTiddler.text += "<script>\n var list = \"\";\n";
 tabTiddler.text += "var tiddlers = store.getTaggedTiddlers(\"" + taskTag + "." + newTask + "\", \"created\");\n";
 tabTiddler.text += "for(var i=0; i<tiddlers.length; i++){if(tiddlers[i].tags.contains (\"completed\")){\n var newEntry=tiddlers[i].title.split(\"#\");\nlist+=\"[X(\"+tiddlers[i].title+\":completed)] [[\"+newEntry[newEntry.length-1]+\"|\"+tiddlers[i].title+\"]]\\n\";}}\n";
 tabTiddler.text+= "return list;\n";
 tabTiddler.text += "</script>";
 tabTiddler.text += "</part>";

 store.addTiddler(tabTiddler);
 if(!rebuild) refreshDisplay();
}

config.macros.taskOrganizer.deleteCategory=function(){
 if(typeof arguments[0] != 'string'){
 var category = this.parentNode.firstChild.className.split(":")[1];
 category = category.replace(/=/g," ");
 var rebuild = false;
 var taskTag = this.parentNode.parentNode.parentNode.getAttribute("tag");
 var title = this.parentNode.parentNode.parentNode.getAttribute("tiddlerTitle");
 } else {
 var category = arguments[0].split(":")[1];
 var rebuild = true;
 var holder= document.getElementById("tiddler"+arguments[1]);
 var taskTag = holder.getAttribute("tag");
 var title = arguments[1];
 }

 var cm = config.macros.taskOrganizer;
 var conf = true;
 if(!rebuild) conf = confirm(cm.options.deleteCategoryConfirmation); 
 if(conf){
 store.removeTiddler(title+ ":" + category);
 if(!rebuild){
 refreshDisplay();
 var tiddlers = store.getTaggedTiddlers(taskTag + "." + category);
 if(tiddlers.length>0){
 conf = confirm(cm.options.deleteTasksConfirmation); 
 if(conf){
 for(var i=0; i<tiddlers.length; i++) store.removeTiddler(tiddlers[i].title);
 }
 }
 }
 }
}

config.macros.taskOrganizer.newTask=function(){
 var category = this.parentNode.firstChild.className.split(":")[1];
 category = category.replace(/=/g," ");
 var cm = config.macros.taskOrganizer;
 var taskTag = this.parentNode.parentNode.parentNode.getAttribute("tag");
 var title = this.parentNode.parentNode.parentNode.getAttribute("tiddlerTitle");
 var tiddlerName = title + "#" + category + "#";
 var newTiddler = new Tiddler();
 newTiddler.title = tiddlerName;
 newTiddler.tags[0] = taskTag + "." + category;
 newTiddler.tags[1] = "excludeLists";
 newTiddler.modifier = config.options.txtUserName;
 if(config.macros.reminders){
 newTiddler.text = "<<newReminder>>";
 } else {newTiddler.text = "";}
 store.addTiddler(newTiddler);
 story.displayTiddler(null,tiddlerName,DEFAULT_EDIT_TEMPLATE);
 story.focusTiddler(tiddlerName,"title");
}

config.macros.taskOrganizer.handler=function(place,macroName,params,wikifier,paramString,tiddler) {
 if(!(version.extensions.CheckboxPlugin && version.extensions.inlineJavascript && version.extensions.PartTiddlerPlugin)){
 var text = "Some required macros are missing!\nPlease check the requirements of this macro [[here|TaskOrganizerPlugin]].";
 } else {
 if(!params) return;
 var taskTag=params[0];
 var rebuild = (params[1]=='rebuild');
 var cm = config.macros.taskOrganizer;
 var tiddlerTitle;
 var tiddlers = store.getTaggedTiddlers(taskTag,"modified");
 var title = tiddler.title;
 place.setAttribute("tiddlerTitle",title);
 place.setAttribute("tag",taskTag);
 var text = "<<tabs 'top" + title + "'\n";
 if(rebuild){
 for(var i=0; i<tiddlers.length; i++) cm.deleteCategory(tiddlers[i].title.split(":")[1], title);
 for(var i=0; i<tiddlers.length; i++) cm.addCategory(tiddlers[i].title.split(":")[1], title);
 }
 for(var i=0; i<tiddlers.length; i++){
 tiddlerTitle = tiddlers[i].title.substring(title.length+1);
 text += "\"" + tiddlerTitle + "\" \"" + tiddlerTitle + "\" [[" + tiddlers[i].title + "\]]\n";
 }
 text += ">>\n";
 text += "<<button '" + cm.options.addTaskCategory.label + "' '" + cm.options.addTaskCategory.tooltip + "' 'config.macros.taskOrganizer.addCategory'>>";
 }
 wikify(text,place);
}

config.shadowTiddlers.TaskOrganizerPluginDoc="The documentation is available [[here.|http://www.math.ist.utl.pt/~psoares/addons.html#TaskOrganizerPluginDoc]]";

//}}}
<<taskOrganizer Test>>

!Description
This plugin creates a simple task manager with a variable number of tasks' categories. The management of categories and tasks has been automated. There's also some integration with the ReminderMacros.
This is based on previous work by Jim Barr at http://tiddlywikitips.com/TiddlyWikiTasks.html.

This plugin has been tested in Firefox and Internet Explorer. Let me know if something seems broken.
!Usage
Install this tiddler and drop {{{<<taskOrganizer taskTag>>}}} at the beginning of the tiddler, where taskTag is the tag you want to use with your tasks. You will get an empty task manager. Start adding categories and tasks and it will turn into something like this TaskOrganizerExample. 
!How to update
Because this plugin is still in development, some changes make necessary to rebuild the categories' tiddlers (but not the individual tasks!). This can be done manually deleting all your categories (remember to NOT delete the associated tasks) and then recreate them all, one by one. To avoid this procedure I created an option to do this automatically. So, to rebuild all the categories' tiddlers, edit the tiddler with your TaskOrganizer and change {{{<<taskOrganizer taskTag>>}}} to {{{<<taskOrganizer taskTag rebuild>>}}}. Save the tiddler, reopen it and change the text back to {{{<<taskOrganizer taskTag>>}}}. Save again and it should be done. @@Remember to play safely, that is, create a backup before the update.@@
!Revision history
1.2.4 - 11/09/2006

A kind contribution by ''Matthew Phillips'' fixed two problems:
#spaces in the categories' names
#a task tiddler can have any number of tags
You need to rebuild your categories as described above.

1.2.3 - 08/02/2006
#global vars were eliminated. It's now possible to have several {{{<<taskOrganizer>>}}} entries in the same TW and even in the same tiddler (you need to recreate the categories' tiddlers).
#the default name for tasks includes the {{{<<taskOrganizer>>}}} tiddler title and category. If you accept this name convention (eg, 'Tasks#Category#task description') this will appear in RSS feeds but will be simplified to 'task description' in the taskOrganizer.
1.2.2 - 30/01/2006
#missing requirements handled gracefully (no need to recreate the categories' tiddlers)
1.2.1 - 28/01/2006
#ReminderMacros are no longer required and are only used if installed
#assorted small fixes
#included an option to rebuild the categories' tiddlers (used for updates)
1.2.0 - 26/01/2006
#fixed problem with IE (thanks to Ken Girard) - it looks ugly in IE but seems to work!
#integration with ReminderMacros
#dependency on ForEachTiddlerPlugin replaced by InlineJavascriptPlugin for increased flexibility
#added dependency on the amazing PartTiddlerPlugin (less tiddlers are created this way)
1.1.1 - 25/01/2006
#fixed problem with spaces in categories' names (thanks to Ken Girard)
1.1.0 - 24/01/2006 
#removed dependency on NewerTiddler plugin
#added the possibility to delete categories of tasks
1.0.0 - 21/01/2006
#initial release
<<tabs "topTaskOrganizerPluginDoc:Test"
Pending Pending "TaskOrganizerPluginDoc:Test/Pending"
Completed Completed "TaskOrganizerPluginDoc:Test/Completed"
>>
<<button 'New task' 'Add a new task' 'config.macros.taskOrganizer.newTask'>> <<button 'Delete category' 'Delete this task category' 'config.macros.taskOrganizer.deleteCategory'>>
<part Pending hidden><script>
 var list = "";
var tiddlers = store.getTaggedTiddlers("Test.Test", "created");
var regexp = new RegExp("<<re"+"minder .+>>", "g");
for(var i=0; i<tiddlers.length; i++){
if(!tiddlers[i].tags.contains ("completed")){
var newEntry=tiddlers[i].title.split("#");
list+="[X("+tiddlers[i].title+":completed)] [["+newEntry[newEntry.length-1]+"|"+tiddlers[i].title+"]]\n";
var reminder = tiddlers[i].text.match(regexp);
if(reminder){
 for(var j=0; j<reminder.length; j++){
 list += "*" + reminder[j] + "\n";}}}}
 return list;
</script></part>
<part Completed hidden><script>
 var list = "";
var tiddlers = store.getTaggedTiddlers("Test.Test", "created");
for(var i=0; i<tiddlers.length; i++){if(tiddlers[i].tags.contains ("completed")){
 var newEntry=tiddlers[i].title.split("#");
list+="[X("+tiddlers[i].title+":completed)] [["+newEntry[newEntry.length-1]+"|"+tiddlers[i].title+"]]\n";}}
return list;
</script></part>
<<tabs "topTaskOrganizerPluginDoc:Test2"
Pending Pending "TaskOrganizerPluginDoc:Test2/Pending"
Completed Completed "TaskOrganizerPluginDoc:Test2/Completed"
>>
<<button 'New task' 'Add a new task' 'config.macros.taskOrganizer.newTask'>> <<button 'Delete category' 'Delete this task category' 'config.macros.taskOrganizer.deleteCategory'>>
<part Pending hidden><script>
 var list = "";
var tiddlers = store.getTaggedTiddlers("Test.Test2", "created");
var regexp = new RegExp("<<re"+"minder .+>>", "g");
for(var i=0; i<tiddlers.length; i++){
if(!tiddlers[i].tags.contains ("completed")){
var newEntry=tiddlers[i].title.split("#");
list+="[X("+tiddlers[i].title+":completed)] [["+newEntry[newEntry.length-1]+"|"+tiddlers[i].title+"]]\n";
var reminder = tiddlers[i].text.match(regexp);
if(reminder){
 for(var j=0; j<reminder.length; j++){
 list += "*" + reminder[j] + "\n";}}}}
 return list;
</script></part>
<part Completed hidden><script>
 var list = "";
var tiddlers = store.getTaggedTiddlers("Test.Test2", "created");
for(var i=0; i<tiddlers.length; i++){if(tiddlers[i].tags.contains ("completed")){
 var newEntry=tiddlers[i].title.split("#");
list+="[X("+tiddlers[i].title+":completed)] [["+newEntry[newEntry.length-1]+"|"+tiddlers[i].title+"]]\n";}}
return list;
</script></part>
!!!Show Array
<script show>
/*** <script src="images/array_root.js" show> using  [[LoadScripts]] to preload array***/
var rr=array_root.length
document.write(array_root)
document.write('<br>' + rr + ' array items')
</script>
!!!Random 
<script show>
/*** <script src="images/array_root.js" show> using  [[LoadScripts]] to preload array***/
function random_imglink(){
	var ry=Math.floor(Math.random()*array_root.length)
	if (ry==0)
	ry=1
	document.write(ry)
	}
random_imglink()
</script>
!!!Complete
<script show>
/***using  [[MarkupPreBody]] to preload array***/
function random_imglink(){
	var ry=Math.floor(Math.random()*array_root.length)
	var pre='[>img(400px+,auto)[Random Picture|';
	var dir='images/'
	var post=']]';
	wikify(' '+pre+''+dir+''+array_root[ry]+''+post+' ',place);
	}
random_imglink();
setTimeout("story.refreshTiddler('Example1',null,true)",600000);
</script>
!!!Refresh Tiddler
{{{
<script show>
   setTimeout("story.refreshTiddler('Test Random JS from Bat',null,true)",600000);
</script>
}}}


test text for test tiddler
<<newReminder>>
<<reminder year:2008 month:7 day:7 title:"Test Tiddler 1" >>
<<newReminder>>
<<newReminder>>
<<newReminder>>
Name: TestPalette
HeaderTop: #fff
HeaderMid: #00f
HeaderBottom: #0f0
Background: #000
Foreground: #ff0
PrimaryPale: #ccc
PrimaryLight: #6cf
PrimaryMid: #0b0
PrimaryDark: #ff9
SecondaryPale: #f00
SecondaryLight: #f0f
SecondaryMid: #c06
SecondaryDark: #306
TertiaryPale: #f60
TertiaryLight: #f9c
TertiaryMid: #996
TertiaryDark: #601
/***
|Name|TextAreaPlugin|
|Source|http://www.TiddlyTools.com/#TextAreaPlugin|
|Documentation|http://www.TiddlyTools.com/#TextAreaPluginInfo|
|Version|2.1.9|
|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.focusTiddler|
|Options|##Configuration|
|Description|Adds Find/Again keyboard search, autosize, and 'stretch bar' resize for textarea controls|
* ''Control-F'' and ''control-G'' will ''"Find text"'' and ''"find text aGain"'', respectively, allowing you to copy, find, paste, findagain, paste, etc to perform "search-and-replace" actions.  
* ''autosizeEditor'' - toggles the tiddler editor textarea height between fixed-height and "automatically fit the contents".
* ''resizeEditor'' - adds 'grab handle' below textarea to stretch field height
!!!!!Documentation
>see [[TextAreaPluginInfo]]
!!!!!Configuration
<<<
<<option chkTextAreaExtensions>> use control-f (find), control-g (find again) inside text area
<<option chkDisableAutoSelect>> place cursor at start of textarea instead of pre-selecting content
<<option chkResizeEditor>> modify shadow EditTemplate to add resizeable text area (and autosize command)
<<<
!!!!!Revisions
<<<
2008.01.08 [2.1.9] fixed default setting of uninitialized option values so that "false" is not treated as "undefined"
|please see [[TextAreaPluginInfo]] for additional revision details|
2006.01.22 [1.0.0] Moved from temporary "System Tweaks" tiddler into 'real' TextAreaPlugin tiddler.
<<<
!!!!!Code
***/
//{{{
version.extensions.TextAreaPlugin= {major: 2, minor: 1, revision: 9, date: new Date(2008,1,8)};

if (config.options.chkTextAreaExtensions===undefined) config.options.chkTextAreaExtensions=true;
if (config.options.chkDisableAutoSelect===undefined) config.options.chkDisableAutoSelect=true;
if (config.options.chkResizeEditor===undefined) config.options.chkResizeEditor=true;

// automatically tweak shadow EditTemplate to add "autosizeEditor" toolbar command
if (config.options.chkResizeEditor)
	config.shadowTiddlers.EditTemplate=config.shadowTiddlers.EditTemplate.replace(/deleteTiddler/,"deleteTiddler autosizeEditor");
// automatically tweak shadow EditTemplate to add "resizeEditor" macro
if (config.options.chkResizeEditor)
	config.shadowTiddlers.EditTemplate+="<span macro='resizeEditor'></span>";

// Put focus in a specified tiddler field
Story.prototype.TextAreaExtensions_focusTiddler=Story.prototype.focusTiddler;
Story.prototype.focusTiddler = function(title,field)
{
	this.TextAreaExtensions_focusTiddler.apply(this,arguments); // first call core
	var e = this.getTiddlerField(title,field);
	if (e && config.options.chkDisableAutoSelect) {
		if (e.setSelectionRange) // FF
			e.setSelectionRange(0,0);
		else if (e.createTextRange) // IE
			{ var r=e.createTextRange(); r.collapse(true); r.select(); }
	}
	if (e && config.options.chkTextAreaExtensions) addKeyDownHandlers(e);
}
//}}}

//{{{
function addKeyDownHandlers(e)
{
	// exit if not textarea or element doesn't allow selections
	if (e.tagName.toLowerCase()!="textarea"||!e.setSelectionRange||e.initialized) return;

	// utility function: exits keydown handler and prevents browser from processing the keystroke
	var processed=function(ev) {
		ev.cancelBubble=true; // IE4+
		try{event.keyCode=0;}catch(e){}; // IE5
		if (window.event) ev.returnValue=false; // IE6
		if (ev.preventDefault) ev.preventDefault(); // moz/opera/konqueror
		if (ev.stopPropagation) ev.stopPropagation(); // all
		return false;
	}
	// capture keydown in edit field
	e.saved_onkeydown=e.onkeydown; // save current keydown handler (if any)
	e.onkeydown=function(ev) { if (!ev) var ev=window.event;
		var key=ev.keyCode;
		if (!key) {
			var char=event.which?event.which:event.charCode;
			if (char==102) key=70;
			if (char==103) key=71;
		}
		// process CTRL-F (find matching text) or CTRL-G (find next match)
		if (ev.ctrlKey && (key==70||key==71)) {

			// prompt for text to find
			var defFind=e.findText?e.findText:e.value.substring(e.selectionStart,e.selectionEnd);
			if (key==70||!e.findText||!e.findText.length) // ctrl-f or no saved search text
				{ var f=prompt("find:", defFind); e.focus(); if (f) e.findText=f; }
			if (!e.findText||!e.findText.length) return processed(ev); //  if no search text, exit

			// do case-insensitive match with 'wraparound'...  if not found, alert and exit 
			var newstart=e.value.toLowerCase().indexOf(e.findText.toLowerCase(),e.selectionStart+1);
			if (newstart==-1) newstart=e.value.toLowerCase().indexOf(e.findText.toLowerCase());
			if (newstart==-1) { alert("'"+e.findText+"' not found"); e.focus(); return processed(ev); }

			// set new selection, scroll it into view, and report line position in status bar
			e.setSelectionRange(newstart,newstart+e.findText.length);
			var linecount=e.value.split('\n').length;
			var thisline=e.value.substr(0,e.selectionStart).split('\n').length;
			e.scrollTop=Math.floor((thisline-1-e.rows/2)*e.scrollHeight/linecount);
			window.status="line: "+thisline+"/"+linecount;
			return processed(ev);
		}
		if (e.saved_onkeydown) // call previous keydown handler (if any)
			e.saved_onkeydown(ev);
	}
	e.initialized=true;
}
//}}}

// // 'autosize' toolbar command
//{{{
config.commands.autosizeEditor = {
	text: 'autosize',
	tooltip: 'automatically adjust the editor height to fit the contents',
	text_alt: '\u221Aautosize',
	hideReadOnly: false,
	handler: function(event,src,title) {
		var here=story.findContainingTiddler(src); if (!here) return;
		var ta=here.getElementsByTagName('textarea'); if (!ta) return;
		for (i=0;i<ta.length;i++) {
			// only autosize textareas actually used to edit tiddler fields
			if (ta[i].getAttribute("edit")==undefined) continue;
			ta[i].button=src;
			if (!ta[i].maxed)
				config.commands.autosizeEditor.on(ta[i]);
			else
				config.commands.autosizeEditor.off(ta[i],true);
		}
		return false;
	},
	on: function(e) {
		if (e.maxed) return; // already autosizing!
		if (e.savedheight==undefined)
			e.savedheight=e.style.height;
		if (e.savedkeyup==undefined) {
			e.savedkeyup=e.onkeyup;
			e.onkeyup=function(ev) {
				if (!ev) var ev=window.event; var e=resolveTarget(ev);
				e.style.height=e.scrollHeight+'px';
				if (e.savedkeyup) e.savedkeyup();
			}
		}
		// IE reports error: "not implemented" for onkeypress
		if (!config.browser.isIE && e.savedkeypress==undefined) {
			e.savedkeypress=e.onkeypress;
			e.onkeypress=function(ev) {
				if (!ev) var ev=window.event; var e=resolveTarget(ev);
				if (ev.keyCode==33) { // PGUP
					if (window.scrollByPages) window.scrollByPages(-1);
					return false;
				}
				if (ev.keyCode==34) { // PGDN
					if (window.scrollByPages) window.scrollByPages(1);
					return false;
				}
				if (e.savedkeypress) e.savedkeypress();
			}
		}
		e.style.height=e.scrollHeight+'px';
		e.button.innerHTML=config.commands.autosizeEditor.text_alt;
		e.maxed=true;
	},
	off: function(e,resetHeight) {
		if (resetHeight) e.style.height=e.savedheight;
		e.onkeyup=e.savedkeyup;
		// IE reports error: "not implemented" for onkeypress
		if (!config.browser.isIE) e.onkeypress=e.savedkeypress;
		e.button.innerHTML=config.commands.autosizeEditor.text;
		e.maxed=false;
	}
};
//}}}

// // grab-and-stretch handle
//{{{
config.macros.resizeEditor = { // add stretch bar to editor textarea
	handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		var here=story.findContainingTiddler(place); if (!here) return;
		var ta=here.getElementsByTagName('textarea');
		if (ta) for (i=0;i<ta.length;i++) {
			// only resize tiddler editor textareas
			if (ta[i].getAttribute("edit")==undefined) continue;
			new window.TextAreaResizer(ta[i]);
		}
	}
}

config.macros.resizeTiddler = { // add stretch bar to tiddler viewer element
	handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		var here=story.findContainingTiddler(place); if (!here) return;
		var elems=here.getElementsByTagName('div');
		if (elems) for (i=0;i<elems.length;i++) if (hasClass(elems[i],'viewer')) break;
		if (i<elems.length) new window.TextAreaResizer(elems[i]);
	}
}

config.macros.resizeFrame = { // add stretch bar to iframes
	handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		var here=story.findContainingTiddler(place); if (!here) return;
		var fr=here.getElementsByTagName('iframe');
		if (fr) for (i=0;i<fr.length;i++) new window.TextAreaResizer(fr[i]);
	}
}

// TextAreaResizer script by Jason Johnston (jj@lojjic.net)
// Created August 2003.  Use freely, but give me credit.
// adds a handle below textareas that the user can drag with the mouse to resize the textarea.
// MODIFIED by ELS for cross-browser (IE) compatibility, including:
//    fixups and adjustments to CSS styles,
//    use 'old style' assignment of mouse event handlers instead of using addEventListener(),
//    use window.event if event param is null,
//    use offsetHeight instead of getComputedStyle()
//    use explicit window.* global scope declaration for functions called from event handlers

window.TextAreaResizer = function(elt) {
	this.element = elt;
	this.create();
}
window.TextAreaResizer.prototype = {
	create : function() {
		var elt = this.element;
		var thisRef = this;
		var h = this.handle = document.createElement("div");
		h.style.height = "3px"; // was 4px... looked too fat!
		h.style.overflow = "hidden"; // ELS: force IE to trim height to < 1em
		h.style.width="auto";
		h.style.backgroundColor = "#999"; // ELS: standard mid-tone (dark) gray
		h.style.cursor = "s-resize";
		h.title = "Drag to resize text box";
		h.onmousedown=function(evt){thisRef.dragStart(evt)};
		elt.parentNode.insertBefore(h, elt.nextSibling);
	},
	dragStart : function(evt) {
		if (!evt) var evt=window.event;
		this.dragStop(evt); // ELS: stop any current drag processing first
		var thisRef = this;
		this.dragStartY = evt.clientY;
		this.dragStartH = this.element.offsetHeight;
		document.savedmousemove=document.onmousemove;
		document.onmousemove=this.dragMoveHdlr=function(evt){thisRef.dragMove(evt)};
		document.savedmouseup=document.onmouseup;
		document.onmouseup=this.dragStopHdlr=function(evt){thisRef.dragStop(evt)};
	},
	dragMove : function(evt) {
		if (!evt) var evt=window.event;
		// ELS: make sure height is at least 10px
		var h=this.dragStartH+evt.clientY-this.dragStartY;
		if (h<10) h=10; this.element.style.height=h+"px";
		// ELS: match handle to textarea width (which may have changed due to document scrollbars)
		this.handle.style.width=(this.element.offsetWidth-4)+"px"; // 4-pixel fudge factor for textarea border edge
		// ELS: when manually resizing, disable autoresizing (without restoring saved height)
		if (this.element.maxed!=undefined && this.element.maxed)
			config.commands.autosizeEditor.off(this.element,false);
	},
	dragStop : function(evt) {
		if (!evt) var evt=window.event;
		document.onmousemove=(document.savedmousemove!=undefined)?document.savedmousemove:null;
		document.onmousemove=(document.savedmouseup!=undefined)?document.savedmouseup:null;
	},
	destroy : function() {
		var elt = this.element;
		elt.parentNode.removeChild(this.handle);
		elt.style.height = "";
	}
};
//}}}
/***
|Name|TextAreaPluginInfo|
|Source|http://www.TiddlyTools.com/#TextAreaPlugin|
|Documentation|http://www.TiddlyTools.com/#TextAreaPluginInfo|
|Version|2.1.9|
|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 TextAreaPlugin|
Adds Find/Again keyboard search, autosize, and 'stretch bar' resize for textarea controls
!!!!!Usage
<<<
* ''Control-F'' and ''control-G'' will ''"Find text"'' and ''"find text aGain"'', respectively, allowing you to copy, find, paste, findagain, paste, etc to perform "search-and-replace" actions.
* ''autosizeEditor'' - toggles the tiddler editor textarea height between fixed-height and "automatically fit the contents".
* ''resizeEditor'' - adds 'grab handle' below textarea to stretch field height
<<<
!!!!!Configuration
<<<
<<option chkTextAreaExtensions>> use control-f (find), control-g (find again) inside text area
<<option chkDisableAutoSelect>> place cursor at start of textarea instead of pre-selecting content
<<option chkResizeEditor>> modify shadow EditTemplate to add resizeable text area (and autosize command)
> Note: if you are using the default (shadow) EditTemplate, the plugin automatically updates the template to include the ''autosizeEditor'' toolbar command and ''resizeEditor'' macro.  If you have created a custom EditTemplate tiddler, you will need to manually add the ''autosizeEditor'' toolbar command and ''resizeEditor'' macro to your existing template:
{{{
<!-- add 'autosizeEditor' command to end of existing editor toolbar definition -->
<div class='toolbar' macro='toolbar ... autosizeEditor'>
}}}
and
{{{
<!-- add span with 'resizeEditor' macro anywhere in the edit template -->
<span macro='resizeEditor'></span>
}}}
<<<
!!!!!Revisions
<<<
2008.01.08 [2.1.9] fixed default setting of uninitialized option values so that "false" is not treated as "undefined"
2008.01.07 [2.1.8] added 'initialized' flag so keyDownHandlers() will only be added once to each control (prevents recursion errors)
2007.12.21 [2.1.7] in dragMove(), subtract 4-pixel 'fudge factor' when adjusting drag bar width to match textarea width.  Apparently textarea 'offsetWidth' includes the 2-pixel surrounding edge, but CSS 100% calculation does NOT, resulting is an increase in the textarea width when displayed in a variable-width moveable panel.
2007.11.19 [2.1.6] fix fatal IE errors by NOT setting 'onkeypress' handler (which IE reports as "not implemented").  Also, only add autosize grab bar to textareas that are actually used to edit tiddler fields (i.e., they have an "edit=fieldname" attribute).  This prevents undesirable autosizing of textareas used for HTML/DOM display by [[PreviewPlugin]].
2007.11.18 [2.1.5] in config.commands.autosizeEditor, changed alt command text to use character-based "psuedo-checkbox" instead of embedded html fragment
2007.09.04 [2.1.4] in window.TextAreaResizer.prototype.create(), set initial grab handle width to auto instead of matching textarea.offsetWidth (which can be initially==0)
2007.04.29 [2.1.3] in addKeyDownHandlers(), used 'findText' instead of 'find', hopefully to avoid strict ECMAScript1.5 error on certain browsers.
2007.03.01 [2.1.2] use apply() to invoke hijacked core function
2006.11.16 [2.1.0] restored chkDisableAutoSelect (place cursor at start of textarea instead of pre-selecting content)
2006.11.16 [2.0.0] removed chkDisableEscapeKey (obsolete... use custom EditTemplate to change toolbar definition).  Rewrote focusTiddler as a HIJACK instead of just overwriting core function (permits other plugins to also hijack function).  Removed TAB character processing (now built-in as of TW2.1).  Merged code from ResizeEditorPlugin:
> 2006.11.16 [1.3.x] merged with TextAreaPlugin
> 2006.11.02 [1.3.1] in DragMove() and DragStop(), check for undefined properties so IE doesn't report "Not Implemented" error when property is referenced without having been previously initialized.
> 2006.11.01 [1.3.0] added 'resizeEditor' MACRO for 'grab handle' stretch resizing (based on code from Jon Scully and Jason Johnston (jj@lojjic.net).  
> 2006.11.01 [1.2.6] removed increaseEditor, decreaseEditor, and resizeEditor toolbar COMMAND definitions (resize by setting 'rows' property of textarea field conflicts with resize via style.height CSS attribute as set by autosize/drag).
> 2006.11.01 [1.2.5] fixed 'savedkeypress' handling (was writing to savedkeyup by mistake)
> 2006.10.28 [1.2.4] added '+' to 'saveTiddler' toolbar command (enables ctrl-enter keyhandling)
> 2006.10.18 [1.2.3] added decreaseEditor and increaseEditor commands
> 2006.10.18 [1.2.2] onkeypress handling to redirect PGUP/PGDN to window.scrollByPages() (works in FF, but not yet in IE)
> 2006.10.18 [1.2.1] fixed references to default string constants (oops!)
> 2006.10.18 [1.2.0] renamed 'resizeEditor' to 'autosizeEditor' and added new 'resizeEditor' toolbar command to prompt for # of rows to display
> 2006.10.02 [1.1.1] show checkbox in button label (when automatic resizing is enabled)
> 2006.10.01 [1.1.0] added 'onkeyup' automatic fit-to-contents handling
> 2006.09.30 [1.0.0] initial release
2006.08.01 [1.1.2] improved processed() utility function to handle IE5 and IE6, as well as calling preventDefault() for moz browsers.  Thanks to Bradley Meck for research and code examples.
2006.07.09 [1.1.1] removed chkDisableAutoSelect
2006.02.14 [1.1.0] added option for chkDisableEscapeKey (default is standard action)
2006.01.22 [1.0.1] only add extra key processing for TEXTAREA elements (not other edit fields).
added option to enable/disable textarea keydown extensions (default is "standard keys" only)
2006.01.22 [1.0.0] Moved from temporary "System Tweaks" tiddler into 'real' TextAreaPlugin tiddler.
<<<
/%
!info
|Name|ThumbThing|
|Source|http://www.TiddlyTools.com/#ThumbThing|
|Version|1.2.0|
|Author|Eric Shulman|
|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|transcluded html|
|Requires||
|Overrides||
|Description|display a scaled 'thumbnail' image with popup for full-sized image|

Usage:
<<<
{{{
<<tiddler ThumbThing with: image thumbWidth thumbHeight fullWidth fullHeight>>
}}}
*{{{image}}} is one of:
**a local path/file
**a remote URL reference
**the title of a tiddler containing an attached image (see [[AttachFilePlugin]])
*{{{thumbWidth, thumbHeight, fullWidth, fullHeight}}} are CSS measurements.  Use 'auto' (or omit values) for default (full-sized) image height and/or width.  For proportional scaling, specify a fixed-width OR fixed-height and use 'auto' for the other dimension.
<<<
Example:
<<<
{{{
<<tiddler ThumbThing with: images/meow2.jpg 100px>>
}}}
<<tiddler ThumbThing with: images/meow2.jpg 100px>>
<<<
See also:
>[[AllThumbs]]
!end
%/<<tiddler {{ 'ThumbThing##'+('$1'=='$'+'1'?'info':'show') }} with:
	{{ var cma=config.macros.attach; (cma&&cma.isAttachment('$1'))?cma.getAttachment('$1'):'$1'; }}
	[[$2]] [[$3]] [[$4]] [[$5]]>>/%
!show
<html><hide linebreaks>
<img src="$1" style="border=0;width:$2;height:$3;" title="$1" onclick="
	var p=Popup.create(this); if (!p) return; var s=p.style; s.border=s.padding='0'; s.background='none';
	p.innerHTML='<img src=\x22$1\x22 style=\x22border:1px solid #999;background:#eee;width:$4;height:$5\x22>';
	Popup.show(p,false); event.cancelBubble=true; if(event.stopPropagation)event.stopPropagation(); return(false);
"></html>
!end
%/
<<tiddler AllThumbs with: Thumbs##List 4 100px auto auto 600px>>

/%
!List
../Pictures/home/0708KKM.jpg
../Pictures/home/1108KKM2.jpg
../Pictures/work/crew.jpg
../Pictures/work/Hugo.jpg
!end
%/

<<tiddler ThumbThing with: images/KKM.jpg 100px auto auto 600px>>
<html>
<div macro="tiddler AllThumbs with: Thumbs##List 2 100px auto auto 400px" style='width: 210px; float: right;'>
<div macro="tiddler ThumbThing with: ../Pictures/home/1108KKM2.jpg 200px auto auto 600px" style='width: 210px; float: right;'>
</html>
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
<script>
        var out=[]; var who='';
        var tids=store.getTiddlers('modifier');
        for (i=0; i<tids.length; i++) { var t=tids[i];
                if (who!=t.modifier) {
                        who=t.modifier;
                        out.push('by '+who+':');
                }
                out.push('*[['+t.title+']]');
        }
        return out.join('\n');
</script> 
<script show>
        var out=[]; var fmt='%0: %1|'; var fmt2='\n|[[%0]]|';
        var tids=store.sortTiddlers(store.filterTiddlers("[tag[(Script AND NOT 'Sections n Slices')]]"), "modified");
        for (var i=0; i<tids.length; i++) {
                                out.push(fmt2.format([tids[i].title]));
                                        for (var f in tids[i].fields) out.push(fmt.format
([f,tids[i].fields [f]]));
        }
        return out.join('|');
</script> 
<html>
<div macro="tiddler 'Tiddler transclude center##Test'" style='float: left;'></div>
<div macro="tiddler 'Tiddler transclude center##Test'" style='float: right;'></div>
<div macro="tiddler SandBox" style='width: 700px; margin-left:auto; margin-right:auto;'></div>
</html>
/%
!!!Test
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
!!!End
%/
<html>
<div macro="tiddler SandBox" style='width: 700px; float: right;'>
</html>
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
Some Text Here
/***
|Name|TiddlerEncryptionPlugin|
|Author|Lyall Pearce|
|Source|http://www.Remotely-Helpful.com/TiddlyWiki/TiddlerEncryptionPlugin.html|
|License|[[Creative Commons Attribution-Share Alike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|Version|3.2.0|
|~CoreVersion|2.4.0|
|Requires|None|
|Overrides|store.getSaver().externalizeTiddler(), store.getTiddler() and store.getTiddlerText()|
|Description|Encrypt/Decrypt Tiddlers with a Password key|

!!!!!Usage
<<<
* Tag a tiddler with Encrypt(prompt)
** Consider the 'prompt' something to help you remember the password with. If multiple tiddlers can be encrypted with the same 'prompt' and you will only be asked for the password once.
* Upon save, the Tiddler will be encrypted and the tag replaced with Decrypt(prompt).
** Failure to encrypt (by not entering a password) will leave the tiddler unencrypted and will leave the Encrypt(prompt) tag in place. This means that the next time you save, you will be asked for the password again.
** To have multiple tiddlers use the same password - simply use the same 'prompt'.
** Tiddlers that are encrypted may be automatically tagged 'excludeSearch' as there is no point in searching encrypted data - this is configurable by an option - you still may want to search the titles of encrypted tiddlers
** Tiddlers that are encrypted may be automatically tagged 'excludeLists', if you have them encrypted, you may also want to keep them 'hidden' - this is configurable by an option.
** Automatic removal of excludeLists and excludeSearch tags is performed, if the above two options are set, only if these two tags are the last 2 tags for a tiddler, if they are positioned somewhere else in the tags list, they will be left in place, meaning that the decrypted tiddler will not be searchable and/or will not appear in lists.
** Encrypted tiddlers are stored as displayable hex, to keep things visibly tidy, should you display an encrypted tiddler. There is nothing worse than seeing a pile of gobbledy gook on your screen. Additionally, the encrypted data is easily cut/paste/emailed if displayed in hex form.
* Tiddlers are decrypted only if you click the decrypt button or the decryptAll button, not when you load the TiddlyWiki
** If you don't display a tiddler, you won't have the option to decrypt it (unless you use the {{{<<EncryptionDecryptAll>>}}} macro)
** Tiddlers will re-encrypt automatically on save.
** Decryption of Tiddlers does not make your TiddlyWiki 'dirty' - you will not be asked to save if you leave the page.
* Errors are reported via diagnostic messages.
** Empty passwords, on save, will result in the tiddler being saved unencrypted - this should only occur with new tiddlers, decrypted tiddlers or with tiddlers who have had their 'prompt' tag changed.
** Encrypted tiddlers know if they are decrypted successfully - failure to decrypt a tiddler will ''not'' lose your data.
** Editing of an encrypted (that has not been unencrypted) tiddler will result in loss of that tiddler as the SHA1 checksums will no longer match, upon decryption. To this end, it is best that you do not check the option. You can, however edit an encrypted tiddler tag list - just do ''not'' change the tiddler contents.
** To change the password on a Tiddler, change the Encrypt('prompt') tag to a new prompt value, after decrypting the tiddler.
** You can edit the tags of an encrypted tiddler, so long as you do not edit the text.
** To change the password for all tiddlers of a particular prompt, use the {{{<<EncryptionChangePassword ["button text" ["tooltip text" ["prompt string" ["accessKey"]]]]>>}}} macro.
** To decrypt all tiddlers of a particular "prompt string", use the {{{<<EncryptionDecryptAll ["button text" ["tooltip text" ["prompt string" ["accessKey"]]]]>>}}} macro - this will make tiddlers encrypted with "prompt string" searchable - or prompt for all 'prompt strings', if none is supplied.
<<<
!!!!!Configuration
<<<
Useful Buttons: 
<<EncryptionChangePassword>> - Change passwords of encrypted tiddlers.
<<EncryptionDecryptAll>> - Decrypt ALL tiddlers - enables searching contents of encrypted tiddlers.
<<option chkExcludeEncryptedFromSearch>> - If set, Encrypted Tiddlers are excluded from searching by tagging with excludeSearch. If Clear, excludeSearch is not added and it is also removed from existing Encrypted Tiddlers only if it is the last Tag. Searching of Encrypted Tiddlers is only meaningful for the Title and Tags.
<<option chkExcludeEncryptedFromLists>> - If set, Encrypted Tiddlers are excluded from lists by tagging with excludeLists. If Clear, excludeLists is not added and it is also removed from existing Encrypted Tiddlers only if it is the last Tag. Preventing encrypted tiddlers from appearing in lists effectively hides them.
<<<
!!!!!Revision History
<<<
* 3.2.0 - Ditched the 'Decrypt' button showing up in the tiddler contents if the tiddler is encrypted. It caused too much pain if you edit the tiddler without decrypting it - you lost your data as it was replaced by a Decrypt Macro call!  Additionally, a 'decrypt' button will now appear in the toolbar, just before the edit button, if the tiddler is encrypted. This button only appears if using core TiddlyWiki version 2.4 or above.
* 3.1.1 - Obscure bug whereby if an encrypted tiddler was a certain length, it would refuse to decrypt.
* 3.1.0 - When creating a new Encrypt(prompt) tiddler and you have not previously decrypted a tiddler with the same prompt, on save, you will be prompted for the password to encrypt the tiddler. Prior to encrypting, an attempt to decrypt all other tiddlers with the same prompt, is performed. If any tiddler fails to decrypt, the save is aborted - this is so you don't accidentally have 2 (or more!) passwords for the same prompt. Either you enter the correct password, change the prompt string and try re-saving or you cancel (and the tiddler is saved unencrypted).
* 3.0.1 - Allow Enter to be used for password entry, rather than having to press the OK button.
* 3.0.0 - Major revamp internally to support entry of passwords using forms such that passwords are no longer visible on entry. Completely backward compatible with old encrypted tiddlers. No more using the javascript prompt() function.
<<<
!!!!!Additional work

***/
//{{{
version.extensions.TiddlerEncryptionPlugin = {major: 3, minor: 2, revision: 0, date: new Date(2008,10,6)};

// where I cache the passwords - for want of a better place.
config.encryptionPasswords = new Array();
config.encryptionReEnterPasswords = false;

if(config.options.chkExcludeEncryptedFromSearch == undefined) config.options.chkExcludeEncryptedFromSearch = false;
if(config.options.chkExcludeEncryptedFromLists == undefined) config.options.chkExcludeEncryptedFromLists = false;

config.macros.EncryptionChangePassword = {};
config.macros.EncryptionChangePassword.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
    var theButton = createTiddlyButton(place,
				       (params[0] && params[0].length > 0) ? params[0] : "Change Passwords", 
				       (params[1] && params[1].length > 0) ? params[1] : "Change Passwords" + (params[2] ? " for prompt "+params[2] : ""), 
				       onClickEncryptionChangePassword,
				       null,
				       null,
				       params[3]);
    if(params[2] && params[2].length > 0) {
	theButton.setAttribute("promptString", params[2]);
    }
};

config.macros.EncryptionDecryptAll = {};
config.macros.EncryptionDecryptAll.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
    var theButton = createTiddlyButton(place,
				       (params[0] && params[0].length > 0) ? params[0] : "Decrypt All", 
				       (params[1] && params[1].length > 0) ? params[1] : "Decrypt All Tiddlers" + ((params[2] && params[2].length > 0) ? " for prompt "+params[2] : " for a given 'prompt string'"), 
				       onClickEncryptionDecryptAll,
				       null,
				       null,
				       params[3]);
    if(params[2] && params[2].length > 0) {
	theButton.setAttribute("promptString", params[2]);
    }
};

config.macros.EncryptionDecryptThis = {};
config.macros.EncryptionDecryptThis.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
    var theButton = createTiddlyButton(place,
				       (params[0] && params[0].length > 0) ? params[0] : "Decrypt", 
				       (params[1] && params[1].length > 0) ? params[1] : "Decrypt this Tiddler", 
				       onClickEncryptionDecryptThis,
				       null,
				       null,
				       params[3]);
    if(params[2] && params[2].length > 0) {
	theButton.setAttribute("theTiddler", params[2]);
    }
};
// toolbar button to decrypt tiddlers.
config.commands.decryptThis = {
  text: "decrypt",
  tooltip: "Decrypt this tiddler",
  isEnabled : function(tiddler) {
	// Only show decrypt button if tiddler is tagged as Decrypt(
	if(tiddler.tags.join().indexOf('Decrypt(') == -1)  {
	    return false;
	} else {
	    return true;
	}
    },	
  handler: function(event, src, title) {
	encryptionGetAndDecryptTiddler(title);
	return false; 
    }
};
// core version 2.4 or above get a 'decrypt' button in the toolbar.
if(config.shadowTiddlers && config.shadowTiddlers.ToolbarCommands  && config.shadowTiddlers.ToolbarCommands.indexOf('decryptThis') == -1) {
    // put our toolbar button in before the edit button.
    // won't work if editTiddler is not the default item (prefixed with plus)
    config.shadowTiddlers.ToolbarCommands.replace(/\+editTiddler/,'decryptThis +editTiddler');
}


// Called by the EncryptionChangePassword macro/button
// Also invoked by the callback for password entry
function onClickEncryptionChangePassword(eventObject) {
    var promptString;
    if(!promptString && this.getAttribute) {
	promptString = this.getAttribute("promptString");
    }
    // I do call this function directly
    if(!promptString && typeof(eventObject) == "string") {
	promptString = eventObject;
    }
    if(!promptString) {
	promptString = prompt("Enter 'prompt string' to change password for:","");
    }
    if(!promptString) {
	return;
    }
    if(! config.encryptionPasswords[promptString]) {
	var changePasswordContext = {changePasswordPromptString: promptString,
				     callbackFunction: MyChangePasswordPromptCallback_TiddlerEncryptionPlugin};
	MyPrompt_TiddlerEncryptionPlugin(promptString,"",changePasswordContext);
	return;
	// Callback function will re-invoke this function
    }

    // Decrypt ALL tiddlers for that prompt
    onClickEncryptionDecryptAll(promptString);
    // Now ditch the cached password, this will force the re-request for the new password, on save.
    displayMessage("Save TiddlyWiki to set new password for '"+promptString+"'");
    config.encryptionPasswords[promptString] = null;
    // mark store as dirty so a save will be requrested.
    store.setDirty(true);
    autoSaveChanges(); 
    return;
};
// Called by the password entry form when the user clicks 'OK' button.
function MyChangePasswordPromptCallback_TiddlerEncryptionPlugin(context) {
    config.encryptionPasswords[context.passwordPrompt] = context.password;
    onClickEncryptionChangePassword(context.changePasswordPromptString);
    return;
}
// Called by the EncryptionDecryptThis macro/button
function onClickEncryptionDecryptThis() {
    var theTiddler = this.getAttribute("theTiddler");
    if(!theTiddler) {
	return;
    }
    encryptionGetAndDecryptTiddler(theTiddler);
    return;
};

function encryptionGetAndDecryptTiddler(title) {
    config.encryptionReEnterPasswords = true;
    try {
	theTiddler = store.getTiddler(title);
	config.encryptionReEnterPasswords = false;
	story.refreshAllTiddlers();
    } catch (e) {
	if(e == "DecryptionFailed") {
	    displayMessage("Decryption failed");
	    return;
	}
    } // catch
    return;
};

// called by the EncryptionDecryptAlll macro/button
// Also called by the callback after the user clicks 'OK' button on the password entry form
function onClickEncryptionDecryptAll(eventObject) {
    var promptString;
    if(!promptString && this.getAttribute) {
	promptString = this.getAttribute("promptString");
    }
    // I do call this function directly
    if(!promptString && typeof(eventObject) == "string") {
	promptString = eventObject;
    }
    if(!promptString) {
	promptString = "";
    }

    // Loop through all tiddlers, looking to see if there are any Decrypt(promptString) tagged tiddlers
    // If there are, check to see if their password has been cached.
    // If not, ask for the first one that is missing, that we find
    // the call back function will store that password then invoke this function again, 
    // which will repeat the whole process. If we find all passwords have been cached
    // then we will finally do the decryptAll functionality, which will then
    // be able to decrypt all the required tiddlers, without prompting.
    // We have to do this whole rigmarole because we are using a 'form' to enter the password
    // rather than the 'prompt()' function - which shows the value of the password.
    var tagToSearchFor="Decrypt("+promptString;
    config.encryptionReEnterPasswords = true; 
    var promptGenerated = false;
    store.forEachTiddler(function(store,tiddler) {
	    // Note, there is no way to stop the forEachTiddler iterations
	    if(!promptGenerated && tiddler && tiddler.tags) {
		for(var ix=0; ix<tiddler.tags.length && !promptGenerated; ix++) {
		    if(tiddler.tags[ix].indexOf(tagToSearchFor) == 0) {
			var tag = tiddler.tags[ix];
			var lastBracket=tag.lastIndexOf(")");
			if(lastBracket >= 0) {
			    // Ok, tagged with Encrypt(passwordPrompt)
			    // extract the passwordPrompt name
			    var passwordPromptString=tag.substring(8,lastBracket);
			    if(!config.encryptionPasswords[passwordPromptString]) {
				// no password cached, prompt and cache it, rather than decryptAll
				// callback from prompting form will resume decryptAll attempt.
				var decryptAllContext = {decryptAllPromptString: promptString,
							 callbackFunction: MyDecryptAllPromptCallback_TiddlerEncryptionPlugin};
				MyPrompt_TiddlerEncryptionPlugin(passwordPromptString,"",decryptAllContext);
				promptGenerated = true;
			    } // if(!config.encryptionPasswords
			} // if(lastBracket
		    } // if(tiddler.tags[ix]..
		} // for
	    } // if
	}); // store.forEachTiddler
    // If we get here, all passwords have been cached.
    if(!promptGenerated) {
	config.encryptionReEnterPasswords = false;
	// Now do the decrypt all functionality
	try {
	    store.forEachTiddler(function(store,tiddler) {
		    // Note, there is no way to stop the forEachTiddler iterations
		    if(tiddler && tiddler.tags) {
			for(var ix=0; ix<tiddler.tags.length; ix++) {
			    if(tiddler.tags[ix].indexOf(tagToSearchFor) == 0) {
				try {
				    CheckTiddlerForDecryption_TiddlerEncryptionPlugin(tiddler);
				} catch (e) {
				    displayMessage("Decryption of '"+tiddler.title+"' failed.");
				    // throw e;
				}
			    } // if(tiddler.tags
			} // for
		    } // if
		}); // store.forEachTiddler
	    displayMessage("All tiddlers" + (promptString != "" ? " for '"+promptString+"'" : "") + " have been decrypted");
	} catch (e) {
	    if(e == "DecryptionFailed") {
		return;
	    }
	} // catch
    }
    return;
};

function MyDecryptAllPromptCallback_TiddlerEncryptionPlugin(context) {
    config.encryptionPasswords[context.passwordPrompt] = context.password;
    // restart the decryptAll process again after the user has entered a password.
    onClickEncryptionDecryptAll(context.decryptAllPromptString);
    return;
}

saveChanges_TiddlerEncryptionPlugin = saveChanges;
saveChanges = function(onlyIfDirty,tiddlers) {
    // Loop through all tiddlers, looking to see if there are any Encrypt(string) tagged tiddlers
    // If there are, check to see if their password has been cached.
    // If not, ask for the first one that is missing, that we find
    // the call back function will store that password then invoke this function again, 
    // which will repeat the whole process. If we find all passwords have been cached
    // then we will finally call the original saveChanges() function, which will then
    // be able to save the tiddlers.
    // We have to do this whole rigmarole because we are using a 'form' to enter the password
    // rather than the 'prompt()' function - which shows the value of the password.
    config.encryptionReEnterPasswords = true; 
    var promptGenerated = false;
    store.forEachTiddler(function(store,tiddler) {
	    if(!promptGenerated && tiddler && tiddler.tags) {
		for(var ix=0; ix<tiddler.tags.length && !promptGenerated; ix++) {
		    if(tiddler.tags[ix].indexOf("Encrypt(") == 0) {
			var tag = tiddler.tags[ix];
			var lastBracket=tag.lastIndexOf(")");
			if(lastBracket >= 0) {
			    // Ok, tagged with Encrypt(passwordPrompt)
			    // extract the passwordPrompt name
			    var passwordPrompt=tag.substring(8,lastBracket);
			    if(!config.encryptionPasswords[passwordPrompt]) {
				// no password cached, prompt and cache it, rather than save
				var saveContext = {onlyIfDirty: onlyIfDirty, 
						   tiddlers: tiddlers, 
				                   callbackFunction: MySavePromptCallback_TiddlerEncryptionPlugin};
				MyPrompt_TiddlerEncryptionPlugin(passwordPrompt,"",saveContext);
				promptGenerated = true;
			    } // if(!config.encryptionPasswords
			} // if(lastBracket
		    } // if(tiddler.tags[ix]..
		} // for
	    } // if
	}); // store.forEachTiddler
    // If we get here, all passwords have been cached.
    if(!promptGenerated) {
	config.encryptionReEnterPasswords = false;
	saveChanges_TiddlerEncryptionPlugin(onlyIfDirty,tiddlers);
    }
    return;
}

function MySavePromptCallback_TiddlerEncryptionPlugin(context) {
    config.encryptionPasswords[context.passwordPrompt] = context.password;
    // validate the password entered by attempting to decrypt all tiddlers
    // with the same encryption prompt string.
    onClickEncryptionDecryptAll(context.passwordPrompt);

    // restart the save process again
    saveChanges(context.onlyIfDirty, context.tiddlers);
    return;
}

store.getSaver().externalizeTiddler_TiddlerEncryptionPlugin = store.getSaver().externalizeTiddler;
store.getSaver().externalizeTiddler = function(store, tiddler) {
    // Ok, got the tiddler, track down the passwordPrompt in the tags.
    // track down the Encrypt(passwordPrompt) tag
    if(tiddler && tiddler.tags) {
	for(var g=0; g<tiddler.tags.length; g++) {
	    var tag = tiddler.tags[g];
	    if(tag.indexOf("Encrypt(") == 0) {
		var lastBracket=tag.lastIndexOf(")");
		if(lastBracket >= 0) {
		    // Ok, tagged with Encrypt(passwordPrompt)
		    // extract the passwordPrompt name
		    var passwordPrompt=tag.substring(8,lastBracket);
		    // Ok, Encrypt this tiddler!
		    var decryptedSHA1 = Crypto.hexSha1Str(tiddler.text);
		    var password =  GetAndSetPasswordForPrompt_TiddlerEncryptionPlugin(passwordPrompt);
		    if(password) {
			var encryptedText = TEAencrypt(tiddler.text, password);
			encryptedText = StringToHext_TiddlerEncryptionPlugin(encryptedText);
			tiddler.text = "Encrypted("+decryptedSHA1+")\n"+encryptedText;
			// Replace the Tag with the Decrypt() tag
			tiddler.tags[g]="Decrypt("+passwordPrompt+")";
			// let the store know it's dirty
			store.setDirty(tiddler.title, true);
			// prevent searches on encrypted tiddlers, still nice to search on title though.
			if(config.options.chkExcludeEncryptedFromSearch == true) {
			    tiddler.tags.push("excludeSearch");
			}
			// prevent lists of encrypted tiddlers
			if(config.options.chkExcludeEncryptedFromLists == true) {
			    tiddler.tags.push("excludeLists");
			}
		    } else {
			// do not encrypt - no password entered
		    }
		    break;
		} // if (lastBracket...
	    } // if(tag.indexOf(...
	} // for(var g=0;...
    } // if(tiddler.tags...
    
    // Then, finally, do the save by calling the function we override.

    return store.getSaver().externalizeTiddler_TiddlerEncryptionPlugin(store, tiddler);
};

function CheckTiddlerForDecryption_TiddlerEncryptionPlugin(tiddler) {
    if(tiddler && tiddler.tags) {
	for(var g=0; g<tiddler.tags.length; g++) {
	    var tag = tiddler.tags[g];
	    if(tag.indexOf("Decrypt(") == 0) {
		var lastBracket=tag.lastIndexOf(")");
		if(lastBracket >= 0) {
		    if(tiddler.text.substr(0,10) == "Encrypted(") {
			var closingSHA1Bracket = tiddler.text.indexOf(")");
			var decryptedSHA1 = tiddler.text.substring(10, closingSHA1Bracket);
			// Ok, tagged with Decrypt(passwordPrompt)
			// extract the passwordPrompt name
			var passwordPrompt=tag.substring(8,lastBracket);
			// Ok, Decrypt this tiddler!
			var decryptedText = tiddler.text.substr(closingSHA1Bracket+2);
			decryptedText = HexToString_TiddlerEncryptionPlugin(decryptedText);
                        // prompt("Decryption request for Tiddler '"+tiddler.title+"'");
			var password = GetAndSetPasswordForPromptToDecrypt_TiddlerEncryptionPlugin(passwordPrompt);
			if(password) {
			    decryptedText = TEAdecrypt(decryptedText, password );
			    var thisDecryptedSHA1 = Crypto.hexSha1Str(decryptedText);
			    if(decryptedSHA1 == thisDecryptedSHA1) {
				tiddler.text = decryptedText;
				// Replace the Tag with the Encrypt() tag
				tiddler.tags[g]="Encrypt("+passwordPrompt+")";
				if(tiddler.tags[tiddler.tags.length-1] == 'excludeLists') {
				    // Remove exclude lists only if it's the last entry
				    // as it's automatically put there by encryption
				    tiddler.tags.length--;
				}
				if(tiddler.tags[tiddler.tags.length-1] == 'excludeSearch') {
				    // Remove exclude search only if it's the last entry
				    // as it's automatically put there by encryption
				    tiddler.tags.length--;
				}
			    } else {
				// Did not decrypt, discard the password from the cache
				config.encryptionPasswords[passwordPrompt] = null;
				config.encryptionReEnterPasswords = false;
				throw "DecryptionFailed";
			    }
			} else {
			    // no password supplied, dont bother trying to decrypt
			    config.encryptionReEnterPasswords = false;
			    throw "DecryptionFailed";
			}
		    } else {
			// Tagged as encrypted but not expected format, just leave it unchanged
		    }
		    break; // out of for loop
		} // if (lastBracket...
	    } // if(tag.indexOf(...
	} // for(var g=0;...
    } // if (tiddler && tags)
    return tiddler;
};

store.getTiddler_TiddlerEncryptionPlugin = store.getTiddler;
store.getTiddler = function(title) {
    var tiddler = store.getTiddler_TiddlerEncryptionPlugin(title);
    if(tiddler) { // shadow tiddlers are not expected to be encrypted.
	try {
	    return CheckTiddlerForDecryption_TiddlerEncryptionPlugin(tiddler);
	} catch (e) {
	    return(tiddler);
	    // if(e == "DecryptionFailed") {
	    // 	var tiddler = store.getTiddler("DecryptionFailed");
	    // 	if(!tiddler) {
	    // 	    tiddler = new Tiddler();
	    // 	    tiddler.set(title,
	    // 			"<<EncryptionDecryptThis \"Decrypt\" \"Decrypt this tiddler\" \""+title+"\">>",
	    // 			config.views.wikified.shadowModifier,
	    // 			version.date,[],version.date);
	    // 	} 
	    // 	return tiddler;
	    // } // if(e)
	} // catch
    } // if(tiddler) {
    return null;
};

store.getTiddlerText_TiddlerEncryptionPlugin = store.getTiddlerText;
store.getTiddlerText = function(title,defaultText) {
    // Simply retrieve the tiddler, normally, if it requires decryption, it will be decrypted
    var decryptedTiddler = store.getTiddler(title);
    if(decryptedTiddler) {
	return decryptedTiddler.text;
    }
    //Ok, rather than duplicate all the core code, the above code should fail if we reach here
    // let the core code take over.
    return  store.getTiddlerText_TiddlerEncryptionPlugin(title,defaultText);
};

// Given a prompt, search our cache to see if we have already entered the password.
// Can return null if the user enters nothing.
function MyPrompt_TiddlerEncryptionPlugin(promptString,defaultValue,context) {
    if(!context) {
	context = {};
    }
    context.passwordPrompt = promptString;
    PasswordPrompt.prompt(MyPromptCallback_TiddlerEncryptionPlugin, context);
    return;
}

function MyPromptCallback_TiddlerEncryptionPlugin(context) {
    if(context.callbackFunction) {
	context.callbackFunction(context);
    } else {
	config.encryptionPasswords[context.passwordPrompt] = context.password;
	story.refreshAllTiddlers(true);
    }
    return;
}

function GetAndSetPasswordForPrompt_TiddlerEncryptionPlugin(promptString) {
    if(!config.encryptionPasswords[promptString]) {
	config.encryptionPasswords[promptString] = MyPrompt_TiddlerEncryptionPlugin(promptString, "");
    }
    return config.encryptionPasswords[promptString]; // may be null, prompt can be cancelled.
}

function GetAndSetPasswordForPromptToDecrypt_TiddlerEncryptionPlugin(promptString) {
    if(config.encryptionReEnterPasswords) {
	return GetAndSetPasswordForPrompt_TiddlerEncryptionPlugin(promptString);
    } else {
	return config.encryptionPasswords[promptString];
    }
}

// Make the encrypted tiddlies look a little more presentable.
function StringToHext_TiddlerEncryptionPlugin(theString) {
    var theResult = "";
    for(var i=0; i<theString.length; i++) {
	var theHex = theString.charCodeAt(i).toString(16);
	if(theHex.length<2) {
	    theResult += "0"+theHex;
	} else {
	    theResult += theHex;
	}
	if(i && i % 32 == 0)
	    theResult += "\n";
    }
    return theResult;
}

function HexToString_TiddlerEncryptionPlugin(theString) {
    var theResult = "";
    for(var i=0; i<theString.length; i+=2) {
	if(theString.charAt(i) == "\n") {
	    i--;	// cause us to skip over the newline and resume
	    continue;
	}
	theResult += String.fromCharCode(parseInt(theString.substr(i, 2),16));
    }
    return theResult;
}
//
// Heavily leveraged from http://trac.tiddlywiki.org/browser/Trunk/contributors/SaqImtiaz/verticals/Hesperian/PasswordPromptPlugin.js  Revision 5635
//
PasswordPrompt ={
  prompt : function(callback,context){
	if (!context) {
	    context = {};
	}
	var box = createTiddlyElement(document.getElementById("contentWrapper"),'div','passwordPromptBox');
	box.innerHTML = store.getTiddlerText('PasswordPromptTemplate');
	box.style.position = 'absolute';
	this.center(box);
	document.getElementById('promptDisplayField').value = context.passwordPrompt;
	var passwordInputField = document.getElementById('passwordInputField');
	passwordInputField.onkeyup = function(ev) {
	    var e = ev || window.event;
	    if(e.keyCode == 10 || e.keyCode == 13) { // Enter
		PasswordPrompt.submit(callback, context);
	    }
	};
	passwordInputField.focus();
	document.getElementById('passwordPromptSubmitBtn').onclick = function(){PasswordPrompt.submit(callback,context);};
	document.getElementById('passwordPromptCancelBtn').onclick = function(){PasswordPrompt.cancel(callback,context);};
    },     
 	       
  center : function(el){
	var size = this.getsize(el);
	el.style.left = (Math.round(findWindowWidth()/2) - (size.width /2) + findScrollX())+'px';
	el.style.top = (Math.round(findWindowHeight()/2) - (size.height /2) + findScrollY())+'px';
    },
 	       
  getsize : function (el){
	var x = {};
	x.width = el.offsetWidth || el.style.pixelWidth;
	x.height = el.offsetHeight || el.style.pixelHeight;
	return x;
    },
 	       
  submit : function(cb,context){
	context.passwordPrompt = document.getElementById('promptDisplayField').value;
	context.password = document.getElementById('passwordInputField').value;
	var box = document.getElementById('passwordPromptBox');
	box.parentNode.removeChild(box);
	cb(context);
	return false;
    },

  cancel : function(cb,context){
	var box = document.getElementById('passwordPromptBox');
	box.parentNode.removeChild(box);
	return false;
    },
 	       
  setStyles : function(){
	setStylesheet(
	    "#passwordPromptBox dd.submit {margin-left:0; font-weight: bold; margin-top:1em;}\n"+
	    "#passwordPromptBox dd.submit .button {padding:0.5em 1em; border:1px solid #ccc;}\n"+
	    "#passwordPromptBox dt.heading {margin-bottom:0.5em; font-size:1.2em;}\n"+
	    "#passwordPromptBox {border:1px solid #ccc;background-color: #eee;padding:1em 2em;}",'passwordPromptStyles');
    },
 	       
  template : '<form action="" onsubmit="return false;" id="passwordPromptForm">\n'+
  '    <dl>\n'+
  '        <dt class="heading">Please enter the password:</dt>\n'+
  '        <dt>Prompt:</dt>\n'+
  '        <dd><input type="text" readonly id="promptDisplayField" class="display"/></dd>\n'+
  '        <dt>Password:</dt>\n'+
  '        <dd><input type="password" tabindex="1" class="input" id="passwordInputField"/></dd>\n'+
  '        <dd class="submit">\n'+
  '            <a tabindex="2" href="javascript:;" class="button" id="passwordPromptSubmitBtn">OK</a>\n'+
  '            <a tabindex="3" href="javascript:;" class="button" id="passwordPromptCancelBtn">Cancel</a>\n'+
  '        </dd>\n'+
  '    </dl>\n'+
  '</form>',
 	                         
  init : function(){
	config.shadowTiddlers.PasswordPromptTemplate = this.template;
	this.setStyles();
    }
};
 	
PasswordPrompt.init();

// http://www.movable-type.co.uk/scripts/tea-block.html
//
// TEAencrypt: Use Corrected Block TEA to encrypt plaintext using password
//             (note plaintext & password must be strings not string objects)
//
// Return encrypted text as string
//
function TEAencrypt(plaintext, password)
{
    if (plaintext.length == 0) return('');  // nothing to encrypt
    // 'escape' plaintext so chars outside ISO-8859-1 work in single-byte packing, but keep
    // spaces as spaces (not '%20') so encrypted text doesn't grow too long (quick & dirty)
    var asciitext = escape(plaintext).replace(/%20/g,' ');
    var v = strToLongs(asciitext);  // convert string to array of longs
    if (v.length <= 1) v[1] = 0;  // algorithm doesn't work for n<2 so fudge by adding a null
    var k = strToLongs(password.slice(0,16));  // simply convert first 16 chars of password as key
    var n = v.length;

    var z = v[n-1], y = v[0], delta = 0x9E3779B9;
    var mx, e, q = Math.floor(6 + 52/n), sum = 0;

    while (q-- > 0) {  // 6 + 52/n operations gives between 6 & 32 mixes on each word
        sum += delta;
        e = sum>>>2 & 3;
        for (var p = 0; p < n; p++) {
            y = v[(p+1)%n];
            mx = (z>>>5 ^ y<<2) + (y>>>3 ^ z<<4) ^ (sum^y) + (k[p&3 ^ e] ^ z);
            z = v[p] += mx;
        }
    }

    var ciphertext = longsToStr(v);

    return escCtrlCh(ciphertext);
}

//
// TEAdecrypt: Use Corrected Block TEA to decrypt ciphertext using password
//
function TEAdecrypt(ciphertext, password)
{
    if (ciphertext.length == 0) return('');
    var v = strToLongs(unescCtrlCh(ciphertext));
    var k = strToLongs(password.slice(0,16)); 
    var n = v.length;

    var z = v[n-1], y = v[0], delta = 0x9E3779B9;
    var mx, e, q = Math.floor(6 + 52/n), sum = q*delta;

    while (sum != 0) {
        e = sum>>>2 & 3;
        for (var p = n-1; p >= 0; p--) {
            z = v[p>0 ? p-1 : n-1];
            mx = (z>>>5 ^ y<<2) + (y>>>3 ^ z<<4) ^ (sum^y) + (k[p&3 ^ e] ^ z);
            y = v[p] -= mx;
        }
        sum -= delta;
    }

    var plaintext = longsToStr(v);

    // strip trailing null chars resulting from filling 4-char blocks:
    plaintext = plaintext.replace(/\0+$/,'');

    return unescape(plaintext);
}


// supporting functions

function strToLongs(s) {  // convert string to array of longs, each containing 4 chars
    // note chars must be within ISO-8859-1 (with Unicode code-point < 256) to fit 4/long
    var l = new Array(Math.ceil(s.length/4));
    for (var i=0; i<l.length; i++) {
        // note little-endian encoding - endianness is irrelevant as long as 
        // it is the same in longsToStr() 
        l[i] = s.charCodeAt(i*4) + (s.charCodeAt(i*4+1)<<8) + 
               (s.charCodeAt(i*4+2)<<16) + (s.charCodeAt(i*4+3)<<24);
    }
    return l;  // note running off the end of the string generates nulls since 
}              // bitwise operators treat NaN as 0

function longsToStr(l) {  // convert array of longs back to string
    var a = new Array(l.length);
    for (var i=0; i<l.length; i++) {
        a[i] = String.fromCharCode(l[i] & 0xFF, l[i]>>>8 & 0xFF, 
                                   l[i]>>>16 & 0xFF, l[i]>>>24 & 0xFF);
    }
    return a.join('');  // use Array.join() rather than repeated string appends for efficiency
}

function escCtrlCh(str) {  // escape control chars etc which might cause problems with encrypted texts
    return str.replace(/[\0\t\n\v\f\r\xa0'"!]/g, function(c) { return '!' + c.charCodeAt(0) + '!'; });
}

function unescCtrlCh(str) {  // unescape potentially problematic nulls and control characters
    return str.replace(/!\d\d?\d?!/g, function(c) { return String.fromCharCode(c.slice(1,-1)); });
}

//}}}
/***
|Name|TiddlerTweakerPlugin|
|Source|http://www.TiddlyTools.com/#TiddlerTweakerPlugin|
|Version|2.2.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|plugin|
|Requires||
|Overrides||
|Description|select multiple tiddlers and modify author, created, modified and/or tag values|
~TiddlerTweaker is a tool for TiddlyWiki authors.  It allows you to select multiple tiddlers from a listbox, either by direct interaction or automatically matching specific criteria.  You can then modify the creator, author, created, modified and/or tag values of those tiddlers using a compact set of form fields.  The values you enter into the fields simultantously overwrite the existing values in all tiddlers you have selected.
!!!!!Usage
<<<
{{{<<tiddlerTweaker>>}}}
{{smallform{<<tiddlerTweaker>>}}}
By default, any tags you enter into the TiddlerTweaker will //replace// the existing tags in all the tiddlers you have selected.  However, you can also use TiddlerTweaker to quickly filter specified tags from the selected tiddlers, while leaving any other tags assigned to those tiddlers unchanged:
>Any tag preceded by a "+" (plus) or "-" (minus), will be added or removed from the existing tags //instead of replacing the entire tag definition// of each tiddler (e.g., enter "-excludeLists" to remove that tag from all selected tiddlers.  When using this syntax, care should be taken to ensure that //every// tag is preceded by "+" or "-", to avoid inadvertently overwriting any other existing tags on the selected tiddlers.  (note: the "+" or "-" prefix on each tag value is NOT part of the tag value, and is only used by TiddlerTweaker to control how that tag value is processed)
Important Notes:
* Inasmuch as TiddlerTweaker is a 'power user' tool that can perform 'batch' functions (operating on many tiddlers at once), you should always have a recent backup of your document (or "save changes" just *before* tweaking the tiddlers), just in case you "shoot yourself in the foot".
* By design, TiddlerTweaker does NOT update the 'modified' date of tiddlers simply by making changes to the tiddler's values.  A tiddler's dates are ONLY updated when the corresponding 'created' and/or 'modified' checkboxes are selected and you enter new values for those dates.  As a general rule, after using TiddlerTweaker, always ''//remember to save your document//'' when you are done, even though the tiddler timeline tab may not show any recently modified tiddlers.
* Because you may be changing the values on many tiddlers simultaneously, selecting and updating all tiddlers in a document operation may take a while and your browser might warn about an "unresponsive script"... you should give it a whole bunch of time to 'continue'... it should complete the processing... eventually.
<<<
!!!!!Revisions
<<<
2008.10.27 [2.2.3] in setTiddlers(), fixed Safari bug by replacing static Array.concat(...) with new Array().concat(...)
2008.09.07 [2.2.2] added removeCookie() function for compatibility with [[CookieManagerPlugin]]
2008.05.12 [2.2.1] replace built-in backstage "tweak" task with tiddler tweaker control panel (moved from BackstageTweaks)
2008.01.13 [2.2.0] added "auto-selection" links: all, changed, tags, title, text
2007.12.26 [2.1.0] added support for managing 'creator' custom field (see [[CoreTweaks]])
2007.11.01 [2.0.3] added config.options.txtTweakerSortBy for cookie-based persistence of list display order preference setting.
2007.09.28 [2.0.2] in settiddlers() and deltiddlers(), added suspend/resume notification handling (improves performance when operating on multiple tiddlers)
2007.08.03 [2.0.1] added shadow definition for [[TiddlerTweaker]] tiddler for use as parameter references with {{{<<tiddler>>, <<slider>> or <<tabs>>}}} macros.
2007.08.03 [2.0.0] converted from inline script
2006.01.01 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.TiddlerTweakerPlugin= {major: 2, minor: 2, revision: 3, date: new Date(2008,10,27)};

// shadow tiddler
config.shadowTiddlers.TiddlerTweaker="<<tiddlerTweaker>>";

/// backstage task
if (config.tasks) { // for TW2.2b3 or above
	config.tasks.tweak.tooltip="review/modify tiddler internals: dates, authors, tags, etc.";
	config.tasks.tweak.content="{{smallform small groupbox{<<tiddlerTweaker>>}}}";
}

if (config.options.txtTweakerSortBy==undefined) config.options.txtTweakerSortBy="modified";

// if removeCookie() function is not defined by TW core, define it here.
if (window.removeCookie===undefined) {
	window.removeCookie=function(name) {
		document.cookie = name+'=; expires=Thu, 01-Jan-1970 00:00:01 UTC; path=/;'; 
	}
}

config.macros.tiddlerTweaker = {
	html: '<form style="display:inline"><!--\
		--><table style="padding:0;margin:0;border:0;width:100%"><tr valign="top" style="padding:0;margin:0;border:0"><!--\
		--><td  style="text-align:center;white-space:nowrap;width:99%;padding:0;margin:0;border:0"><!--\
			--><font size=-2><div style="text-align:left;"><span style="float:right"><!--\
			-->&nbsp; <a href="javascript:;" \
				title="select all tiddlers"\
				onclick="\
				var f=this; while (f&&f.nodeName.toLowerCase()!=\'form\')f=f.parentNode;\
				for (var t=0; t<f.list.options.length; t++)\
					if (f.list.options[t].value.length) f.list.options[t].selected=true;\
				config.macros.tiddlerTweaker.selecttiddlers(f.list);\
				return false">all</a><!--\
			-->&nbsp; <a href="javascript:;" \
				title="select tiddlers that are new/changed since the last file save"\
				onclick="\
				var lastmod=new Date(document.lastModified);\
				var f=this; while (f&&f.nodeName.toLowerCase()!=\'form\')f=f.parentNode;\
				for (var t=0; t<f.list.options.length; t++) {\
					var tid=store.getTiddler(f.list.options[t].value);\
					f.list.options[t].selected=tid&&tid.modified>lastmod;\
				}\
				config.macros.tiddlerTweaker.selecttiddlers(f.list);\
				return false">changed</a><!--\
			-->&nbsp; <a href="javascript:;" \
				title="select tiddlers with at least one matching tag"\
				onclick="\
				var t=prompt(\'Enter space-separated tags (match ONE)\');\
				if (!t||!t.length) return false;\
				var tags=t.readBracketedList();\
				var f=this; while (f&&f.nodeName.toLowerCase()!=\'form\')f=f.parentNode;\
				for (var t=0; t<f.list.options.length; t++) {\
					f.list.options[t].selected=false;\
					var tid=store.getTiddler(f.list.options[t].value);\
					if (tid&&tid.tags.containsAny(tags)) f.list.options[t].selected=true;\
				}\
				config.macros.tiddlerTweaker.selecttiddlers(f.list);\
				return false">tags</a><!--\
			-->&nbsp; <a href="javascript:;" \
				title="select tiddlers whose titles include matching text"\
				onclick="\
				var txt=prompt(\'Enter a title (or portion of a title) to match\');\
				if (!txt||!txt.length) return false;\
				var f=this; while (f&&f.nodeName.toLowerCase()!=\'form\')f=f.parentNode;\
				for (var t=0; t<f.list.options.length; t++) {\
					f.list.options[t].selected=f.list.options[t].value.indexOf(txt)!=-1;\
				}\
				config.macros.tiddlerTweaker.selecttiddlers(f.list);\
				return false">titles</a><!--\
			-->&nbsp; <a href="javascript:;" \
				title="select tiddlers containing matching text"\
				onclick="\
				var txt=prompt(\'Enter tiddler text (content) to match\');\
				if (!txt||!txt.length) return false;\
				var f=this; while (f&&f.nodeName.toLowerCase()!=\'form\')f=f.parentNode;\
				for (var t=0; t<f.list.options.length; t++) {\
					var tt=store.getTiddlerText(f.list.options[t].value,\'\');\
					f.list.options[t].selected=(tt.indexOf(txt)!=-1);\
				}\
				config.macros.tiddlerTweaker.selecttiddlers(f.list);\
				return false">text</a> &nbsp;<!--\
			--></span><span>select tiddlers</span><!--\
			--></div><!--\
			--></font><select multiple name=list size="10" style="width:99.99%" \
				title="use click, shift-click and/or ctrl-click to select multiple tiddler titles" \
				onclick="config.macros.tiddlerTweaker.selecttiddlers(this)" \
				onchange="config.macros.tiddlerTweaker.setfields(this)"><!--\
			--></select><br><!--\
			-->show<input type=text size=1 value="10" \
				onchange="this.form.list.size=this.value; this.form.list.multiple=(this.value>1);"><!--\
			-->by<!--\
			--><select name=sortby size=1 \
				onchange="config.macros.tiddlerTweaker.init(this.form,this.value)"><!--\
			--><option value="title">title</option><!--\
			--><option value="size">size</option><!--\
			--><option value="modified">modified</option><!--\
			--><option value="created">created</option><!--\
			--></select><!--\
			--><input type="button" value="refresh" \
				onclick="config.macros.tiddlerTweaker.init(this.form,this.form.sortby.value)"<!--\
			--> <input type="button" name="stats" disabled value="totals..." \
				onclick="config.macros.tiddlerTweaker.stats(this)"><!--\
		--></td><td style="white-space:nowrap;padding:0;margin:0;border:0;width:1%"><!--\
			--><div style="text-align:left"><font size=-2>&nbsp;modify values</font></div><!--\
			--><table border=0 style="width:100%;padding:0;margin:0;border:0;"><tr style="padding:0;border:0;"><!--\
			--><td style="padding:1px;border:0;white-space:nowrap"><!--\
				--><input type=checkbox name=settitle unchecked \
					title="allow changes to tiddler title (rename tiddler)" \
					onclick="this.form.title.disabled=!this.checked">title<!--\
			--></td><td style="padding:1px;border:0;white-space:nowrap"><!--\
				--><input type=text name=title size=35 style="width:98%" disabled><!--\
			--></td></tr><tr style="padding:0;border:0;"><td style="padding:1px;border:0;white-space:nowrap"><!--\
				--><input type=checkbox name=setcreator unchecked \
					title="allow changes to tiddler creator" \
					onclick="this.form.creator.disabled=!this.checked">created by<!--\
			--></td><td style="padding:1px;border:0;white-space:nowrap"><!--\
				--><input type=text name=creator size=35 style="width:98%" disabled><!--\
			--></td></tr><tr style="padding:0;border:0;"><td style="padding:1px;border:0;white-space:nowrap"><!--\
				--><input type=checkbox name=setwho unchecked \
					title="allow changes to tiddler author" \
					onclick="this.form.who.disabled=!this.checked">modified by<!--\
			--></td><td style="padding:1px;border:0;white-space:nowrap"><!--\
				--><input type=text name=who size=35 style="width:98%" disabled><!--\
			--></td></tr><tr style="padding:0;border:0;"><td style="padding:1px;border:0;white-space:nowrap"><!--\
				--><input type=checkbox name=setcdate unchecked \
					title="allow changes to created date" \
					onclick="var f=this.form; f.cm.disabled=f.cd.disabled=f.cy.disabled=f.ch.disabled=f.cn.disabled=!this.checked"><!--\
				-->created on<!--\
			--></td><td style="padding:1px;border:0;white-space:nowrap"><!--\
				--><input type=text name=cm size=2 style="width:2em;padding:0;text-align:center" disabled><!--\
				--> / <input type=text name=cd size=2 style="width:2em;padding:0;text-align:center" disabled><!--\
				--> / <input type=text name=cy size=4 style="width:3em;padding:0;text-align:center" disabled><!--\
				--> at <input type=text name=ch size=2 style="width:2em;padding:0;text-align:center" disabled><!--\
				--> : <input type=text name=cn size=2 style="width:2em;padding:0;text-align:center" disabled><!--\
			--></td></tr><tr style="padding:0;border:0;"><td style="padding:1px;border:0;white-space:nowrap"><!--\
				--><input type=checkbox name=setmdate unchecked \
					title="allow changes to modified date" \
					onclick="var f=this.form; f.mm.disabled=f.md.disabled=f.my.disabled=f.mh.disabled=f.mn.disabled=!this.checked"><!--\
				-->modified on<!--\
			--></td><td style="padding:1px;border:0;white-space:nowrap"><!--\
				--><input type=text name=mm size=2 style="width:2em;padding:0;text-align:center" disabled><!--\
				--> / <input type=text name=md size=2 style="width:2em;padding:0;text-align:center" disabled><!--\
				--> / <input type=text name=my size=4 style="width:3em;padding:0;text-align:center" disabled><!--\
				--> at <input type=text name=mh size=2 style="width:2em;padding:0;text-align:center" disabled><!--\
				--> : <input type=text name=mn size=2 style="width:2em;padding:0;text-align:center" disabled><!--\
			--></td></tr><tr style="padding:0;border:0;"><td style="padding:1px;border:0;white-space:nowrap"><!--\
				--><input type=checkbox name=settags checked \
					title="allow changes to tiddler tags" \
					onclick="this.form.tags.disabled=!this.checked">tags<!--\
			--></td><td style="padding:1px;border:0;white-space:nowrap"><!--\
				--><input type=text name=tags size=35 value="" style="width:98%" \
					title="enter new tags or use \'+tag\' and \'-tag\' to add/remove tags from existing tags"><!--\
			--></td></tr></table><!--\
			--><div style="margin-top:.8em;text-align:center"><!--\
			--><nobr><input type=button name=display disabled style="width:32%" value="display tiddlers" \
				onclick="config.macros.tiddlerTweaker.displaytiddlers(this)"><!--\
			--> <input type=button name=del disabled style="width:32%" value="delete tiddlers" \
				onclick="config.macros.tiddlerTweaker.deltiddlers(this)"><!--\
			--> <input type=button name=set disabled style="width:32%" value="update tiddlers" \
				onclick="config.macros.tiddlerTweaker.settiddlers(this)"></nobr><!--\
			--></div><!--\
		--></td></tr></table><!--\
		--></form><span style="display:none"><!--content replaced by tiddler "stats"--></span>\
	',
	handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		var span=createTiddlyElement(place,"span");
		span.innerHTML=this.html;
		this.init(span.firstChild,config.options.txtTweakerSortBy);
	},
	init: function(f,sortby) { // initialize form controls
		if (!f) return; // form might not be rendered yet...
		while (f.list.options[0]) f.list.options[0]=null; // empty current list content
		var tids=store.getTiddlers(sortby);
		if (sortby=="size") // descending order (largest tiddlers listed first)
			tids.sort(function(a,b) {return a.text.length > b.text.length ? -1 : (a.text.length == b.text.length ? 0 : +1);});
		for (i=0; i<tids.length; i++) {
			var label=tids[i].title; var value=tids[i].title;
			if (sortby=="modified" || sortby=="created") {
				label=tids[tids.length-i-1][sortby].formatString("YY.0MM.0DD 0hh:0mm ")+tids[tids.length-i-1].title;
				value=tids[tids.length-i-1].title;
			}
			if (sortby=="size") label="["+tids[i].text.length+"] "+label;
			f.list.options[f.list.length]=new Option(label,value,false,false);
		}
		f.title.value=f.who.value=f.creator.value=f.tags.value="";
		f.cm.value=f.cd.value=f.cy.value=f.ch.value=f.cn.value="";
		f.mm.value=f.md.value=f.my.value=f.mh.value=f.mn.value="";
		f.stats.disabled=f.set.disabled=f.del.disabled=f.display.disabled=true;
		f.settitle.disabled=false;
		config.options.txtTweakerSortBy=sortby; // remember current setting
		f.sortby.value=sortby; // sync droplist selection with current setting
		if (sortby!="modified") // non-default preference... save cookie
			saveOptionCookie("txtTweakerSortBy");
		else removeCookie("txtTweakerSortBy"); // default preference... clear cookie
	},
	selecttiddlers: function(here) { // enable/disable tweaker fields based on number of items selected
		// count how many tiddlers are selected
		var f=here.form; var list=f.list;
		var c=0; for (i=0;i<list.length;i++) if (list.options[i].selected) c++;
		if (c>1) f.title.disabled=true;
		if (c>1) f.settitle.checked=false;
		f.set.disabled=(c==0);
		f.del.disabled=(c==0);
		f.display.disabled=(c==0);
		f.settitle.disabled=(c>1);
		f.stats.disabled=(c==0);
		var msg=(c==0)?'select tiddlers':(c+' tiddler'+(c!=1?'s':'')+' selected');
		here.previousSibling.firstChild.firstChild.nextSibling.innerHTML=msg;
		if (c) clearMessage(); else displayMessage("no tiddlers selected");
	},
	setfields: function(here) { // set tweaker edit fields from first selected tiddler
		var f=here.form;
		if (!here.value.length) {
			f.title.value=f.who.value=f.creator.value=f.tags.value="";
			f.cm.value=f.cd.value=f.cy.value=f.ch.value=f.cn.value="";
			f.mm.value=f.md.value=f.my.value=f.mh.value=f.mn.value="";
			return;
		}
		var tid=store.getTiddler(here.value); if (!tid) return;
		f.title.value=tid.title;
		f.who.value=tid.modifier;
		f.creator.value=tid.fields['creator']||''; // custom field - might not exist
		f.tags.value=tid.tags.join(' ');
		var c=tid.created; var m=tid.modified;
		f.cm.value=c.getMonth()+1;
		f.cd.value=c.getDate();
		f.cy.value=c.getFullYear();
		f.ch.value=c.getHours();
		f.cn.value=c.getMinutes();
		f.mm.value=m.getMonth()+1;
		f.md.value=m.getDate();
		f.my.value=m.getFullYear();
		f.mh.value=m.getHours();
		f.mn.value=m.getMinutes();
	},
	settiddlers: function(here) {
		var f=here.form; var list=f.list;
		var tids=[];
		for (i=0;i<list.length;i++) if (list.options[i].selected) tids.push(list.options[i].value);
		if (!tids.length) { alert("please select at least one tiddler"); return; }
		var cdate=new Date(f.cy.value,f.cm.value-1,f.cd.value,f.ch.value,f.cn.value);
		var mdate=new Date(f.my.value,f.mm.value-1,f.md.value,f.mh.value,f.mn.value);
		if (tids.length>1 && !confirm("Are you sure you want to update these tiddlers:\n\n"+tids.join(', '))) return;
		store.suspendNotifications();
		for (t=0;t<tids.length;t++) {
			var tid=store.getTiddler(tids[t]); if (!tid) continue;
			var title=!f.settitle.checked?tid.title:f.title.value;
			var who=!f.setwho.checked?tid.modifier:f.who.value;
			var tags=tid.tags
			if (f.settags.checked) { 
				var intags=f.tags.value.readBracketedList();
				var addtags=[]; var deltags=[]; var reptags=[];
				for (i=0;i<intags.length;i++) {
					if (intags[i].substr(0,1)=='+')
						addtags.push(intags[i].substr(1));
					else if (intags[i].substr(0,1)=='-')
						deltags.push(intags[i].substr(1));
					else
						reptags.push(intags[i]);
				}
				if (reptags.length)
					tags=reptags;
				if (addtags.length)
					tags=new Array().concat(tags,addtags);
				if (deltags.length)
					for (i=0;i<deltags.length;i++)
						{ var pos=tags.indexOf(deltags[i]); if (pos!=-1) tags.splice(pos,1); }
			}
			if (!f.setcdate.checked) cdate=tid.created;
			if (!f.setmdate.checked) mdate=tid.modified;
			store.saveTiddler(tid.title,title,tid.text,who,mdate,tags,tid.fields);
			if (f.setcreator.checked) store.setValue(tid.title,'creator',f.creator.value); // set creator
			if (f.setcdate.checked) tid.assign(null,null,null,null,null,cdate); // set create date
		}
		store.resumeNotifications();
		this.init(f,f.sortby.value);
	},
	displaytiddlers: function(here) {
		var f=here.form; var list=f.list;
		var tids=[];
		for (i=0; i<list.length;i++) if (list.options[i].selected) tids.push(list.options[i].value);
		if (!tids.length) { alert("please select at least one tiddler"); return; }
		story.displayTiddlers(story.findContainingTiddler(f),tids)
	},
	deltiddlers: function(here) {
		var f=here.form; var list=f.list;
		var tids=[];
		for (i=0;i<list.length;i++) if (list.options[i].selected) tids.push(list.options[i].value);
		if (!tids.length) { alert("please select at least one tiddler"); return; }
		if (!confirm("Are you sure you want to delete these tiddlers:\n\n"+tids.join(', '))) return;
		store.suspendNotifications();
		for (t=0;t<tids.length;t++) {
			var tid=store.getTiddler(tids[t]); if (!tid) continue;
			if (tid.tags.contains("systemConfig"))
				if (!confirm("'"+tid.title+"' is tagged with 'systemConfig'.\n\nRemoving this tiddler may cause unexpected results.  Are you sure?"))
					continue;
			store.removeTiddler(tid.title);
			story.closeTiddler(tid.title);
		}
		store.resumeNotifications();
		this.init(f,f.sortby.value);
	},
	stats: function(here) {
		var f=here.form; var list=f.list; var tids=[]; var out=''; var tot=0;
		var target=f.nextSibling;
		for (i=0;i<list.length;i++) if (list.options[i].selected) tids.push(list.options[i].value);
		if (!tids.length) { alert("please select at least one tiddler"); return; }
		for (t=0;t<tids.length;t++) {
			var tid=store.getTiddler(tids[t]); if (!tid) continue;
			out+='[['+tid.title+']] '+tid.text.length+'\n'; tot+=tid.text.length;
		}
		var avg=tot/tids.length;
		out=tot+' bytes in '+tids.length+' selected tiddlers ('+avg+' bytes/tiddler)\n<<<\n'+out+'<<<\n';
		removeChildren(target);
		target.innerHTML="<hr><font size=-2><a href='javascript:;' style='float:right' "
			+"onclick='this.parentNode.parentNode.style.display=\"none\"'>close</a></font>";
		wikify(out,target);
		target.style.display="block";
	}
};
//}}}
/***
|''Name:''|TiddlersBarPlugin|
|''Description:''|A bar to switch between tiddlers through tabs (like browser tabs bar).|
|''Version:''|1.2.5|
|''Date:''|Jan 18,2008|
|''Source:''|http://visualtw.ouvaton.org/VisualTW.html|
|''Author:''|Pascal Collin|
|''License:''|[[BSD open source license|License]]|
|''~CoreVersion:''|2.1.0|
|''Browser:''|Firefox 2.0; InternetExplorer 6.0, others|
!Demos
On [[homepage|http://visualtw.ouvaton.org/VisualTW.html]], open several tiddlers to use the tabs bar.
!Installation
#import this tiddler from [[homepage|http://visualtw.ouvaton.org/VisualTW.html]] (tagged as systemConfig)
#save and reload
#''if you're using a custom [[PageTemplate]]'', add {{{<div id='tiddlersBar' refresh='none' ondblclick='config.macros.tiddlersBar.onTiddlersBarAction(event)'></div>}}} before {{{<div id='tiddlerDisplay'></div>}}}
#optionally, adjust StyleSheetTiddlersBar
!Tips
*Doubleclick on the tiddlers bar (where there is no tab) create a new tiddler.
*Tabs include a button to close {{{x}}} or save {{{!}}} their tiddler.
*By default, click on the current tab close all others tiddlers.
!Configuration options 
<<option chkDisableTabsBar>> Disable the tabs bar (to print, by example).
<<option chkHideTabsBarWhenSingleTab >> Automatically hide the tabs bar when only one tiddler is displayed. 
<<option txtSelectedTiddlerTabButton>> ''selected'' tab command button.
<<option txtPreviousTabKey>> previous tab access key.
<<option txtNextTabKey>> next tab access key.
!Code
***/
//{{{
config.options.chkDisableTabsBar = config.options.chkDisableTabsBar ? config.options.chkDisableTabsBar : false;
config.options.chkHideTabsBarWhenSingleTab  = config.options.chkHideTabsBarWhenSingleTab  ? config.options.chkHideTabsBarWhenSingleTab  : false;
config.options.txtSelectedTiddlerTabButton = config.options.txtSelectedTiddlerTabButton ? config.options.txtSelectedTiddlerTabButton : "closeOthers";
config.options.txtPreviousTabKey = config.options.txtPreviousTabKey ? config.options.txtPreviousTabKey : "";
config.options.txtNextTabKey = config.options.txtNextTabKey ? config.options.txtNextTabKey : "";
config.macros.tiddlersBar = {
	tooltip : "see ",
	tooltipClose : "click here to close this tab",
	tooltipSave : "click here to save this tab",
	promptRename : "Enter tiddler new name",
	currentTiddler : "",
	previousState : false,
	previousKey : config.options.txtPreviousTabKey,
	nextKey : config.options.txtNextTabKey,	
	tabsAnimationSource : null, //use document.getElementById("tiddlerDisplay") if you need animation on tab switching.
	handler: function(place,macroName,params) {
		var previous = null;
		if (config.macros.tiddlersBar.isShown())
			story.forEachTiddler(function(title,e){
				if (title==config.macros.tiddlersBar.currentTiddler){
					var d = createTiddlyElement(null,"span",null,"tab tabSelected");
					config.macros.tiddlersBar.createActiveTabButton(d,title);
					if (previous && config.macros.tiddlersBar.previousKey) previous.setAttribute("accessKey",config.macros.tiddlersBar.nextKey);
					previous = "active";
				}
				else {
					var d = createTiddlyElement(place,"span",null,"tab tabUnselected");
					var btn = createTiddlyButton(d,title,config.macros.tiddlersBar.tooltip + title,config.macros.tiddlersBar.onSelectTab);
					btn.setAttribute("tiddler", title);
					if (previous=="active" && config.macros.tiddlersBar.nextKey) btn.setAttribute("accessKey",config.macros.tiddlersBar.previousKey);
					previous=btn;
				}
				var isDirty =story.isDirty(title);
				var c = createTiddlyButton(d,isDirty ?"!":"x",isDirty?config.macros.tiddlersBar.tooltipSave:config.macros.tiddlersBar.tooltipClose, isDirty ? config.macros.tiddlersBar.onTabSave : config.macros.tiddlersBar.onTabClose,"tabButton");
				c.setAttribute("tiddler", title);
				if (place.childNodes) {
					place.insertBefore(document.createTextNode(" "),place.firstChild); // to allow break line here when many tiddlers are open
					place.insertBefore(d,place.firstChild); 
				}
				else place.appendChild(d);
			})
	}, 
	refresh: function(place,params){
		removeChildren(place);
		config.macros.tiddlersBar.handler(place,"tiddlersBar",params);
		if (config.macros.tiddlersBar.previousState!=config.macros.tiddlersBar.isShown()) {
			story.refreshAllTiddlers();
			if (config.macros.tiddlersBar.previousState) story.forEachTiddler(function(t,e){e.style.display="";});
			config.macros.tiddlersBar.previousState = !config.macros.tiddlersBar.previousState;
		}
	},
	isShown : function(){
		if (config.options.chkDisableTabsBar) return false;
		if (!config.options.chkHideTabsBarWhenSingleTab) return true;
		var cpt=0;
		story.forEachTiddler(function(){cpt++});
		return (cpt>1);
	},
	selectNextTab : function(){  //used when the current tab is closed (to select another tab)
		var previous="";
		story.forEachTiddler(function(title){
			if (!config.macros.tiddlersBar.currentTiddler) {
				story.displayTiddler(null,title);
				return;
			}
			if (title==config.macros.tiddlersBar.currentTiddler) {
				if (previous) {
					story.displayTiddler(null,previous);
					return;
				}
				else config.macros.tiddlersBar.currentTiddler=""; 	// so next tab will be selected
			}
			else previous=title;
			});		
	},
	onSelectTab : function(e){
		var t = this.getAttribute("tiddler");
		if (t) story.displayTiddler(null,t);
		return false;
	},
	onTabClose : function(e){
		var t = this.getAttribute("tiddler");
		if (t) {
			if(story.hasChanges(t) && !readOnly) {
				if(!confirm(config.commands.cancelTiddler.warning.format([t])))
				return false;
			}
			story.closeTiddler(t);
		}
		return false;
	},
	onTabSave : function(e) {
		var t = this.getAttribute("tiddler");
		if (!e) e=window.event;
		if (t) config.commands.saveTiddler.handler(e,null,t);
		return false;
	},
	onSelectedTabButtonClick : function(event,src,title) {
		var t = this.getAttribute("tiddler");
		if (!event) event=window.event;
		if (t && config.options.txtSelectedTiddlerTabButton && config.commands[config.options.txtSelectedTiddlerTabButton])
			config.commands[config.options.txtSelectedTiddlerTabButton].handler(event, src, t);
		return false;
	},
	onTiddlersBarAction: function(event) {
		var source = event.target ? event.target.id : event.srcElement.id; // FF uses target and IE uses srcElement;
		if (source=="tiddlersBar") story.displayTiddler(null,'New Tiddler',DEFAULT_EDIT_TEMPLATE,false,null,null);
	},
	createActiveTabButton : function(place,title) {
		if (config.options.txtSelectedTiddlerTabButton && config.commands[config.options.txtSelectedTiddlerTabButton]) {
			var btn = createTiddlyButton(place, title, config.commands[config.options.txtSelectedTiddlerTabButton].tooltip ,config.macros.tiddlersBar.onSelectedTabButtonClick);
			btn.setAttribute("tiddler", title);
		}
		else
			createTiddlyText(place,title);
	}
}

story.coreCloseTiddler = story.coreCloseTiddler? story.coreCloseTiddler : story.closeTiddler;
story.coreDisplayTiddler = story.coreDisplayTiddler ? story.coreDisplayTiddler : story.displayTiddler;

story.closeTiddler = function(title,animate,unused) {
	if (title==config.macros.tiddlersBar.currentTiddler)
		config.macros.tiddlersBar.selectNextTab();
	story.coreCloseTiddler(title,false,unused); //disable animation to get it closed before calling tiddlersBar.refresh
	var e=document.getElementById("tiddlersBar");
	if (e) config.macros.tiddlersBar.refresh(e,null);
}

story.displayTiddler = function(srcElement,tiddler,template,animate,unused,customFields,toggle){
	story.coreDisplayTiddler(config.macros.tiddlersBar.tabsAnimationSource,tiddler,template,animate,unused,customFields,toggle);
	var title = (tiddler instanceof Tiddler)? tiddler.title : tiddler;  
	if (config.macros.tiddlersBar.isShown()) {
		story.forEachTiddler(function(t,e){
			if (t!=title) e.style.display="none";
			else e.style.display="";
		})
		config.macros.tiddlersBar.currentTiddler=title;
	}
	var e=document.getElementById("tiddlersBar");
	if (e) config.macros.tiddlersBar.refresh(e,null);
}

var coreRefreshPageTemplate = coreRefreshPageTemplate ? coreRefreshPageTemplate : refreshPageTemplate;
refreshPageTemplate = function(title) {
	coreRefreshPageTemplate(title);
	if (config.macros.tiddlersBar) config.macros.tiddlersBar.refresh(document.getElementById("tiddlersBar"));
}

ensureVisible=function (e) {return 0} //disable bottom scrolling (not useful now)

config.shadowTiddlers.StyleSheetTiddlersBar = "/*{{{*/\n";
config.shadowTiddlers.StyleSheetTiddlersBar += "#tiddlersBar .button {border:0}\n";
config.shadowTiddlers.StyleSheetTiddlersBar += "#tiddlersBar .tab {white-space:nowrap}\n";
config.shadowTiddlers.StyleSheetTiddlersBar += "#tiddlersBar {padding : 1em 0.5em 2px 0.5em}\n";
config.shadowTiddlers.StyleSheetTiddlersBar += ".tabUnselected .tabButton, .tabSelected .tabButton {padding : 0 2px 0 2px; margin: 0 0 0 4px;}\n";
config.shadowTiddlers.StyleSheetTiddlersBar += ".tiddler, .tabContents {border:1px [[ColorPalette::TertiaryPale]] solid;}\n";
config.shadowTiddlers.StyleSheetTiddlersBar +="/*}}}*/";
store.addNotification("StyleSheetTiddlersBar", refreshStyles);

config.refreshers.none = function(){return true;}
config.shadowTiddlers.PageTemplate=config.shadowTiddlers.PageTemplate.replace(/<div id='tiddlerDisplay'><\/div>/m,"<div id='tiddlersBar' refresh='none' ondblclick='config.macros.tiddlersBar.onTiddlersBarAction(event)'></div>\n<div id='tiddlerDisplay'></div>");

//}}}
http://www.tiddlywiki.com/

TiddlyWiki is a wiki-modeled client-side single-page application written by Jeremy Ruston that is designed to be used as a personal notebook. It is a single self-contained HTML file that includes CSS and ~JavaScript code. When the user downloads it to their PC, TiddlyWiki can save the entered information by overwriting itself on the user's disk, at the user's request. Following TiddlyWiki conventions, users can make a new entry, called a tiddler, in their local copy of the TiddlyWiki file and save it for future reference. Existing tiddlers can also be modified or deleted in the same way. Because it runs under most browsers and requires no installation, it can be easily used as a portable personal wiki.

TiddlyWiki is published by ~UnaMesa under a BSD open source license and is thus freely available. Developer Jeremy Ruston describes it as experimental, and in that spirit many people have used the original HTML file to create TiddlyWiki Adaptations. These fall under two general categories: those that retain the client-side write only feature, and those that add server-side file writing to make TiddlyWiki more like a traditional wiki. Links to both these kinds of Adaptations are put in the original TiddlyWiki file as they become known. TiddlyWiki Adaptations typically add features that were not originally envisioned by Ruston, and some of these features have been included in newer versions of TiddlyWiki.

A feature that sets TiddlyWiki apart from a standard wiki implementation is its content presentation. Jeremy Ruston had this to say about it:

A TiddlyWiki is like a blog because it's divided up into neat little chunks (tiddlers), but it encourages you to read it by hyperlinking rather than sequentially: if you like, a non-linear blog analogue that binds the individual microcontent items into a cohesive whole. I think that TiddlyWiki represents a novel medium for writing, and will promote its own distinctive writing style.

Plug-ins:
http://www.tiddlytools.com
http://tiddlywiki.abego-software.de/
http://tw.lewcid.org/

How To:
http://twhelp.tiddlyspot.com/index.html
http://www.giffmex.org/twfortherestofus.html
http://giffmex.tiddlyspot.com/
http://tiddlywikitips.com/

Support:
http://groups.google.com/group/TiddlyWiki
!!!Restart After 2min
<script show>setTimeout("story.closeAllTiddlers();restart();",60000);</script>
!!!Reload After 10min
<script show>setTimeout("window.location.reload( false );",600000);</script>
!!!End
/%
|Name|ToggleScrollingSidebars|
|Source|http://www.TiddlyTools.com/#ToggleScrollingSidebars|
|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|script|
|Requires|InlineJavascriptPlugin|
|Overrides||
|Description|enable/disable 'fixed' positioning of left and right sidebars|
%/<script>
	if (config.options.chkScrollSidebars==undefined)
		config.options.chkScrollSidebars=true;
	if (!config.options.txtOuterTabHeight||!config.options.txtOuterTabHeight.length)
		config.options.txtOuterTabHeight="25em";
	if (!config.options.txtInnerTabHeight||!config.options.txtInnerTabHeight.length)
		config.options.txtInnerTabHeight="21em";

	window.ToggleScrollingSidebars_setscroll = function() {
		var scroll=config.options.chkScrollSidebars?'':'fixed';
		document.getElementById('mainMenu').style.position=scroll;
		document.getElementById('sidebar').style.position=scroll;
		var outer=config.options.txtOuterTabHeight;
		if (config.options.chkScrollSidebars) outer="auto";
		var inner=config.options.txtInnerTabHeight;
		if (config.options.chkScrollSidebars) inner="auto";
		var css='#sidebarTabs .tabContents { height:'+outer+'; overflow:'+(outer!='auto'?'auto':'visible')+'; width:92.5%; }';
		css+='#sidebarTabs .tabContents .tabContents { height:'+inner+' !important; }';
		setStylesheet(css,'shortSidebarTabs');
	}
	window.ToggleScrollingSidebars_setscroll();
</script><<option chkScrollSidebars>><script>
	place.lastChild.checked=config.options.chkScrollSidebars;
	place.lastChild.onchange=function() {
		config.options.chkScrollSidebars=this.checked;
		saveOptionCookie("chkScrollSidebars");
		window.ToggleScrollingSidebars_setscroll();
	};
</script> sidebars scroll with page
!!!My Attempt (not working on tiddlers not yet created)
<script show>
var tag = tiddler.title ; 
var tags = store.getTiddler(tag).tags ;
if (tags.contains('systemConfig'))
	wikify("[x(systemConfigDisable){}{}{var id=story.findContainingTiddler(place).getAttribute('tiddler');}][[disable|systemConfigDisable]]", place);
</script>
!!!ELS refined
<script show>
if (tiddler && tiddler.isTagged('systemConfig')) 
	wikify("[x(systemConfigDisable){}{}{var id=story.findContainingTiddler(place).getAttribute('tiddler');}][[disable|systemConfigDisable]]", place);
</script>
!!!ELS Finished
<script show>
if (tiddler && tiddler.isTagged('systemConfig'))
   return "[x(systemConfigDisable)][[disable|systemConfigDisable]]";
</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;
			});
		}
	}
});

//}}}
!!!!!Toolbar definitions for templates:
ViewTemplate, EditTemplate & CollapsedTemplate Example:
{{{
<div class='toolbar' macro='toolbar [[ToolbarCommands::ViewToolbar]]'></div>
}}}
!!!!!Removed following toolbar commands: syncing permalink
<<<
Uses CoreTweaks (#609/#610) for extended "!" and 'toolbar include' syntax
|~ViewToolbar|~ToolbarCommands##spacer +decryptThis ~ToolbarCommands##systemConfig ~ToolbarCommands##palette ~ToolbarCommands##tagger collapseTiddler collapseOthers  closeTiddler closeOthers editTiddler ~ToolbarCommands##newHere * > ~ToolbarCommands##refreshTiddler ~ToolbarCommands##search fullscreen fields references jump deleteTiddler < |
|~ViewToolbarReadOnly|~ToolbarCommands##spacer +decryptThis collapseTiddler collapseOthers  closeTiddler closeOthers * > ~ToolbarCommands##refreshTiddler ~ToolbarCommands##search fullscreen references jump < |
|~EditToolbar|~ToolbarCommands##spacer ~ToolbarCommands##tagger +saveTiddler saveCloseTiddler closeOthers -cancelTiddler cancelCloseTiddler deleteTiddler toggleQuickEdit autosizeEditor|
|~EditToolbarReadOnly|~ToolbarCommands##spacer ~ToolbarCommands##cancelTiddler ! references jump|
|~CollapsedToolbar|~ToolbarCommands##spacer +expandTiddler collapseOthers closeTiddler closeOthers +editTiddler references jump|
<<<
!!!!!wiki-syntax toolbar commands
<<<
!!!!!spacer
{{{
/% force whitespace separation and baseline alignment of toolbar with tiddler title %/@@font-size:12pt;&nbsp;&nbsp;@@
}}}
!!!!!refreshTiddler
{{{
<script label="refresh" title="redisplay the contents of this tiddler">
	story.refreshTiddler(story.findContainingTiddler(place).getAttribute("tiddler"),null,true);
</script><script>
	place.lastChild.style.fontWeight="normal";
</script>
}}}
!!!!!tagger
{{{
<html>
<span macro='tagger source:TagDB dontChangeSource:true'></span>
<span style="padding:1.5em;"></span>
</html>
}}}
!!!!!palette
{{{
<html>
<span macro="showWhenTagged palette">
	<span macro="setPalette"></span></span>
<span style="padding:.5em;"></span>
</html>
}}}
!!!!!systemConfig
{{{
<html>
<span macro="showWhenTagged systemConfig">
	<span macro="toggleTag systemConfigDisable . '[[disable|systemConfigDisable]]'"></span>
</span>
</html>
}}}
!!!!!newHere
{{{
<html>
<span macro='newHere label:"new here"'></span>
</html>
}}}
!!!!!search
{{{
@@position:static;+++^15em^*[search|find tiddlers that match search text]...
	<<moveablePanel nofold>>{{small{
	{{floatright{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}}}/%
	%/<<search>>}}}===@@
}}}
!!!!!end of extra commands
<<<
/***
| Name:|TransclusionDoesNotExist|
| Description:|if you attempt to transclude a tiddler that does not exist you will be given a message|
| Version:|1.0|
| Date:|06.07.10|
| Author:|http://groups.google.com/group/tiddlywiki/browse_thread/thread/76663ed988fe5b30|
usage: {{{<<tiddler SomeTiddlerNotHere>>}}}
example: <<tiddler SomeTiddlerNotHere>>
***/
//{{{
(function(){

        var macro = config.macros.tiddler;

        var _transclude = macro.transclude;
        macro.transclude = function(wrapper, tiddlerName, args){
                // check to see if empty
                var text = store.getTiddlerText(tiddlerName);
                if(!text){
                        config.macros.tiddler.renderText(wrapper,tiddlerName+" does not exist",tiddlerName,params);
                } else {
                        // call original
                        _transclude(wrapper, tiddlerName, args);
                }

        };

})(); 
//}}}
/***
|Name:|TrashPlugin|
|Version:|1.1.0TT.4|
|Source:|http://ido-xp.tiddlyspot.com/#TrashPlugin|
|Author:|Ido Magal (idoXatXidomagalXdotXcom)|
|License:|[[BSD open source license]]|
|CoreVersion:|2.1.0|
!Description
When you click on 'delete', instead of asking for confirmation and then permanently deleting the tiddler, TrashPlugin simply marks the tiddler by tagging it with: //trash, excludeLists, excludeMissing, excludeSearch,// and //systemConfigDisable//... and then closes that tiddler.  Empty the trash by clicking on the <<emptyTrash>> button in the [[Trash]] tiddler or, you can add the {{{<<emptyTrash>>}}} macro to your [[SideBarOptions]] or other appropriate location.  To reclaim something from the Trash, open the [[Trash]] tiddler to view a list of tiddlers tagged with 'trash', click on the desired tiddler title to open it, and then edit it's tags to remove the 'trash' tag (as well as the other tags noted above, as desired).  TrashPlugin also supports TWO keyboard modifiers that can be used when clicking on the 'delete' toolbar command:
* hold CTRL while clicking 'delete' to ''bypass the trash''and use the normal delete handling (with the usual confirmation messages, if chkConfirmDelete is enabled).
* hold CTRL+SHIFT to ''bypass both the trash //and// the confirmation message'' and //immediately delete// the tiddler without any further interaction.
!Revisions
* V1.1.0TT.4 (TiddlyTools variant) (Nov 14, 2008)
** added SHIFT-CLICK = bypass trash and delete immediately WITHOUT CONFIRMATION
* V1.1.0TT.3 (TiddlyTools variant) (Oct 14, 2008)
** return FALSE from emptyTrash() handler (fixes IE page transition error)
* V1.1.0TT.2 (TiddlyTools variant) (May 18, 2008)
** when creating the Trash tiddler, pass an empty tags array [] instead of a null value, so other plugins (e.g., InstantTimestampPlugin) won't fail
* V1.1.0TT.1 (TiddlyTools variant) (Dec 21, 2006) 
** only call setDirty() when actually removing tiddlers from trash
* V1.1.0 (Dec 12, 2006) 
** added movedMsg (feedback when tiddler is tagged as Trash)
** make sure tiddler actually exists before tagging it with 'Trash'
** fetch correct tiddler before checking for 'systemConfig' tag
* V1.0.3TT.1 (TiddlyTools variant) (Dec 11, 2006) 
** don't create Trash tiddler until needed
** remove Trash tiddler when no trash remains
** don't tag Trash tiddler with 'TrashPlugin'
** moved all user-visible strings to variables so they can be translated by 'lingo' plugins
** use displayMessage() instead of alert()
* v1.0.3 (Dec 11, 2006)
** Fixed broken reference to core deleteTiddler.
** Now storing reference to core deleteTiddler in emptyTrash macro.
** Reduced deleteTiddler hijacking to only the handler.
* v1.0.2 (Dec 11, 2006)
** EmptyTrash now uses removeTiddler instead of deleteTiddler.
** Supports trashing systemConfig tiddlers (adds systemConfigDisable tag).
* v1.0.1 (Dec 10, 2006)
** Replaced TW version with proper Core reference.
** Now properly hijacking deleteTiddler command.
* v1.0.0 (Dec 10, 2006)
** First draft.
!Code
***/
//{{{
config.macros.emptyTrash = {
	tag: 'Trash',
	movedMsg: "'%0' has been tagged as %1",
	label: 'empty trash',
	tooltip: 'Delete all items tagged as %0',
	tooltipOlder: 'Delete items tagged as %0 that are older than %1 days old',
	emptyMsg: 'The trash is empty',
	noneToDeleteMsg: 'There are no items in the trash older than %0 days',
	confirmMsg: "The following tiddlers will be deleted:\n\n'%0'\n\nIs it OK to proceed?",
	deletedMsg: "Deleted '%0'",
	handler: function ( place,macroName,params,wikifier,paramString,tiddler ) {
		var namedParams = (paramString.parseParams(daysOld))[0];
		var daysOld = namedParams['daysOld'] ? namedParams['daysOld'][0] : 0; // default
		var buttonTitle = namedParams['title'] ? namedParams['title'][0] : this.label;
		var buttonTip=this.tooltip.format([ config.macros.emptyTrash.tag ])
		if (daysOld) buttonTip=this.tooltipOlder.format([ config.macros.emptyTrash.tag,daysOld ])
		createTiddlyButton ( place, buttonTitle, buttonTip, this.emptyTrash( daysOld ));
	},
	emptyTrash: function( daysOld ) {
		return function() {
			var collected = [];
			var compareDate = new Date();
			compareDate.setDate( compareDate.getDate() - daysOld );
			store.forEachTiddler(function ( title,tiddler ) {
				if ( tiddler.tags.contains( config.macros.emptyTrash.tag ) && tiddler.modified < compareDate )
					collected.push( title );
			});
			if ( collected.length == 0 ) {
				if ( daysOld == 0 )
					displayMessage( config.macros.emptyTrash.emptyMsg );
				else
					displayMessage( config.macros.emptyTrash.emptyMsg.format( [daysOld] ) );
			}
			else {
				if (	confirm( config.macros.emptyTrash.confirmMsg.format( [collected.join( "', '" )] ) ) ) {
					for ( var i=0;i<collected.length;i++ ) {
						store.removeTiddler( collected[i] );
						store.setDirty( true );
						displayMessage( config.macros.emptyTrash.deletedMsg.format( [collected[i]] ) );
					}
				}
			}
			// remove Trash tiddler if no trash remains
			if ( store.getTaggedTiddlers( config.macros.emptyTrash.tag ).length == 0 ) {
				story.closeTiddler( config.macros.emptyTrash.tag,true,false);
				store.removeTiddler( config.macros.emptyTrash.tag );
			}
			else
				story.refreshTiddler( config.macros.emptyTrash.tag,false,true );

			return false; // ELS: fixes IE page transition error
		}
	}
}

////////////////// hijack delete command

config.macros.emptyTrash.orig_deleteTiddler_handler = config.commands.deleteTiddler.handler;
config.commands.deleteTiddler.handler = function(event,src,title) {

	// BYPASS TRASH: CTRL=normal delete, CTRL+SHIFT=without confirmation
	if (event.ctrlKey) {
		if (event.shiftKey) { var temp=config.options.chkConfirmDelete; config.options.chkConfirmDelete=false; }
		config.macros.emptyTrash.orig_deleteTiddler_handler.apply(this,arguments);
		if (event.shiftKey) config.options.chkConfirmDelete=temp;
		story.refreshTiddler(config.macros.emptyTrash.tag,false,true);
		return false;
	}
	// if tiddler exists (i.e., not a NEW, unsaved tiddler in edit mode) and not bypassing Trash (holding CTRL or SHIFT key)
	if (store.tiddlerExists(title)) {
		// if Trash tiddler doesn't exist yet, create it now...
		if (!store.tiddlerExists(config.macros.emptyTrash.tag))
			store.saveTiddler( config.macros.emptyTrash.tag,config.macros.emptyTrash.tag,
				'<<emptyTrash>>','TrashPlugin',new Date(),[], {});
		// set tags on tiddler
		store.setTiddlerTag(title,1,config.macros.emptyTrash.tag);
		store.setTiddlerTag(title,1,'excludeLists');
		store.setTiddlerTag(title,1,'excludeMissing');
		var tiddler=store.fetchTiddler(title);
		if (tiddler.tags.contains('systemConfig')) store.setTiddlerTag(title,1,'systemConfigDisable');
		// close tiddler, autosave file (if set), and give user feedback
		story.closeTiddler(title,true);
		if(config.options.chkAutoSave) saveChanges();
		displayMessage(config.macros.emptyTrash.movedMsg.format([title,config.macros.emptyTrash.tag]));
	}
	story.refreshTiddler(config.macros.emptyTrash.tag,false,true);
	return false;
};
//}}}
My Tips and Tricks
<<forEachTiddler 
where
	'tiddler.tags.length == 0'
write
	'" [["+tiddler.title+"]]\n"'
>>
~~Requires: ForEachTiddlerPlugin~~
<script>return config.options.txtUserName</script>

<<option txtUserName>>

<<tiddler ShowUserName>>
/***
| Name:|[[ViewPalettePlugin]]|
| Description:|Defines the viewPalette macro for use in ViewTemplate|
| Version:|2.0.0|
| Date:|26-Sep-2006|
| Source:|http://simon.tiddlyspot.com/#ViewPalettePlugin|
| Author:|[[SimonBaird]]|
| CoreVersion:|2.1.x|
***/
//{{{
merge(config.macros,{
	viewPalette: {
		title: 'Palette Preview',
		handler: function(place,macroName,params,wikifier,paramString,tiddler) {
			var title = params[0] ? params[0] : tiddler.title;			
			var colors = store.calcAllSlices(title);
			var keys = [];
			for (c in colors) keys.push(c);
			var output = '';
			var prefix;
			var lastPrefix;
			output += ""+
				//'<h2>'+this.title+'</h2>'+
				'<table align="right" cellspacing="0" style="border-collapse:collapse;"><tr>'+
				'<td style="border:1px solid #555;font-size:50%;padding:0 2em;background:'+colors[keys[0]]+'">&nbsp;</td>'+
				'<td rowspan="'+keys.length+'">'+
				'<table cellspacing="0" style="border:1px solid #555;width:22em;background:%8;margin-left:2em;">'+
				'<tr><td colspan="2" style="font-size:120%;background:%0;width=200px;padding:1em;font-weight:bold;color:%1">'+
				'TiddlyWiki'+
				'</td>'+
				'<td style="background:%0;font-size:90%;text-align:right;">'+
				'<span style="background:%4;margin-right:1em;padding:0 1em;">message</span>'+
				'</td>'+
				'</tr>'+
				'<tr>'+
				'<td rowspan="3" style="color:%0;vertical-align:top;padding:4px;">Hello<br/>Started<br/>Monkey</td>'+
				'<td style="padding:0.7em;color:%3;"><b style="color:%5;font-size:120%;">HelloThere</b><br/>'+
				'Lorem ipsum <b style="color:%0">dolor</b> sit amet, consectetuer adipiscing elit. </td>'+
				'<td rowspan="3" style="vertical-align:top;font-size:80%;">search<br/>new tiddler<br/>options<br/>'+
				'<div style="background:%6;margin-top:0.5em;padding:2px;color:%7">'+
				'<span style="background:%7;color:%3;">Timeline</span>&nbsp;Tags</div>'+
				'<div style="background:%7;color:%0;padding:4px;">Ninja<br/>Dolphin<br/>FooBar<br/>BazQux</div>'+
				'</td>'+
				'</tr>'+
				'<tr>'+
				'<td style="padding:0.7em;color:%3;"><b style="color:%5;font-size:120%;">GettingStarted</b><br/>'+
				'Proin vel felis vel ipsum <b style="color:%0">fermentum</b> eleifend. </td>'+
				'</tr>'+
				'<tr>'+
				'<td style="padding:0.7em;">'+
				'<span style="padding:0 2px;background:%9;color:3%;">error</span>'+
				'</td>'+
				'</tr>'+
				'</table>'+
				'</td>'+
				'</tr>';

			for (var i=1;i<keys.length;i++)
				output += '<tr><td style="border:1px solid #ccc;font-size:50%;padding:0 2em;background:'+colors[keys[i]]+'">&nbsp;</td></tr>';

			output+= '</table>';
		
			wikify("<html>"+output.format([
				colors.PrimaryMid, //0
				colors.PrimaryPale, //1
				colors.PrimaryDark, //2
				colors.Foreground, //3
				colors.SecondaryMid, //4
				colors.SecondaryDark, //5
				colors.TertiaryMid, //6
				colors.TertiaryPale, //7
				colors.Background, //8
				colors.Error, //9
				''])+"</html>",place);
		}
	}
});

setStylesheet(''+
	'.viewPalette div { text-align:right; vertical-align:top; float:left; padding:2px; width:80px; height:50px; }\n'+
	'.viewPalette div span { padding:0 0.5em;background:white; border:1px solid black; font-size:80%; }\n'+
	'',"showPaletteStyles");

//}}}
|!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--}}}|
|Mono-spaced text|{{{text}}}|{{{{{}}}{{{{}}}{{{text}}}{{{}} } }}} (Consecutive curly braces!)|
|Links with wikiwords|EnchiLada (inactive link - no tiddler yet)<br>TiddlyWiki (active link to tiddler)|{{{EnchiLada}}}<br>{{{TiddlyWiki}}}|
|~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|ColorPalette]] - links to the tiddler of color palette|{{{[[display text|ColorPalette]]}}}|
|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|C~~2~~H~~5~~OH|{{{C~~2~~H~~5~~OH}}}|

''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

or
{{{

{{centeredTable{
|test1|test2|test3|
|test4|test5|test6|
}}}

}}}

{{centeredTable{
|test1|test2|test3|
|test4|test5|test6|
}}}

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]]

{{{[img[images/fire.png]]}}} is the formatting for:

[img[images/fire.png]]

''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: WiltedRose
HeaderTop: #300
HeaderMid: #dc9
HeaderBottom: #501
Background: #fff
Foreground: #996
PrimaryPale: #900
PrimaryLight: #cc9
PrimaryMid: #501
PrimaryDark: #b22222
SecondaryPale: #fff
SecondaryLight: #fff
SecondaryMid: #050
SecondaryDark: #050
TertiaryPale: #fff
TertiaryLight: #501
TertiaryMid: #996
TertiaryDark: #cc9
Error: #F30
Test: #0F0
/%
|Name|WordCount|
|Source|http://www.TiddlyTools.com/#WordCount|
|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|display a count of the number of white-space separated words in a tiddler|

Usage:
	<<tiddler WordCount>> or <<tiddler WordCount with: TiddlerName>>

Notes:
	when TiddlerName is omitted, the current tiddler is used.

%/<script>
	var tid="$1";
	if (tid=='$'+'1') { // use current tiddler
		var here=story.findContainingTiddler(place); if (!here) return;
		var tid=here.getAttribute('tiddler');
	}
	var re=new RegExp('\\S+','g');
	var txt=store.getTiddlerText(tid,'');
	return (txt.match(re)||[]).length.toString();
</script>
!Field Search
With 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 fields {{{title}}}, {{{text}}} and {{{tags}}}:
|!What you want|!What you type|!Example|
|Search ''titles only''|start word with ''!''|{{{!jonny}}} (shortcut for {{{title:jonny}}})|
|Search ''contents/text only''|start word with ''%''|{{{%football}}} (shortcut for {{{text:football}}})|
|Search ''tags only''|start word with ''#''|{{{#Plugin}}} (shortcut for {{{tags:Plugin}}})|

Using 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".

You may search a word in more than one field. E.g. {{{!#Plugin}}} (or {{{title:tags:Plugin}}} in the "long form") finds tiddlers containing "Plugin" either in the title or in the tags (but does not look for "Plugin" in the text). 

!Boolean Search
The Boolean Search is useful when searching for multiple words.
|!What you want|!What you type|!Example|
|''All words'' must exist|List of words|{{{jonny jeremy}}} (or {{{jonny and jeremy}}})|
|''At least one word'' must exist|Separate words by ''or''|{{{jonny or jeremy}}}|
|A word ''must not exist''|Start word with ''-''|{{{-jonny}}} (or {{{not jonny}}})|

''Note:'' When you specify two words, separated with a space, YourSearch finds all tiddlers that contain both words, but not necessarily 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"}}}.

Using 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 "jeremy".

!'Exact Word' Search
By default a search result all matches that 'contain' the searched text. E.g. if you search for {{{Task}}} you will get all tiddlers containing 'Task', but also '~CompletedTask', '~TaskForce' etc.

If 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 'Task', ignoring words that just contain 'Task' as a substring.

!~CaseSensitiveSearch and ~RegExpSearch
The standard search options ~CaseSensitiveSearch and ~RegExpSearch are fully supported by YourSearch. However when ''~RegExpSearch'' is on Filtered and Boolean Search are disabled.

In addition you may do a "regular expression" search even with the ''~RegExpSearch'' set to false by directly entering the regular expression into the search field, framed with {{{/.../}}}. 

Example: {{{/m[ae][iy]er/}}} will find all tiddlers that contain either "maier", "mayer", "meier" or "meyer".

!~JavaScript Expression Filtering
If you are familiar with JavaScript programming and know some TiddlyWiki internals 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 evaluate to {{{true}}} when the given tiddler should be included in the result. 

Example: {{{ { tiddler.modified > new Date("Jul 4, 2005")} }}} returns all tiddler modified after July 4th, 2005.

!Combined Search
You are free to combine the various search options. 

''Examples''
|!What you type|!Result|
|{{{!jonny !jeremy -%football}}}|all tiddlers with both {{{jonny}}} and {{{jeremy}}} in its titles, but no {{{football}}} in content.|
|{{{#=Task}}}|All tiddlers tagged with 'Task' (the exact word). Tags named '~CompletedTask', '~TaskForce' etc. are not considered.|

!Access Keys
You are encouraged to use the access keys (also called "shortcut" keys) for the most frequently used operations. For quick reference these shortcuts are also mentioned in the tooltip for the various buttons etc.

|!Key|!Operation|
|{{{Alt-F}}}|''The most important keystroke'': It moves the cursor to the search input field so you can directly start typing your query. Pressing {{{Alt-F}}} will also display the previous search result. This way you can quickly display multiple tiddlers using "Press {{{Alt-F}}}. Select tiddler." sequences.|
|{{{ESC}}}|Closes the [[YourSearch Result]]. When the [[YourSearch Result]] is already closed and the cursor is in the search input field the field's content is cleared so you start a new query.|
|{{{Alt-1}}}, {{{Alt-2}}},... |Pressing these keys opens the first, second etc. tiddler from the result list.|
|{{{Alt-O}}}|Opens all found tiddlers.|
|{{{Alt-P}}}|Toggles the 'Preview Text' mode.|
|{{{Alt-'<'}}}, {{{Alt-'>'}}}|Displays the previous or next page in the [[YourSearch Result]].|
|{{{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).|

//If some of these shortcuts don't work for you check your browser if you have other extensions installed that already "use" these shortcuts.//
/***
|''Name:''|YourSearchPlugin|
|''Version:''|2.1.3 (2008-04-16)|
|''Source:''|http://tiddlywiki.abego-software.de/#YourSearchPlugin|
|''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-2008 [[abego Software|http://www.abego-software.de]]|
|''~CoreVersion:''|2.1.0|
|''Community:''|[[del.icio.us|http://del.icio.us/post?url=http://tiddlywiki.abego-software.de/index.html%23YourSearchPlugin]]|
|''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.3.js]] to get the readable source code.
***/
///%
if(!version.extensions.YourSearchPlugin){version.extensions.YourSearchPlugin={major:2,minor:1,revision:3,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-2008 (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.consumeEvent=function(e){if(e.stopPropagation){e.stopPropagation();}
if(e.preventDefault){e.preventDefault();}
e.cancelBubble=true;e.returnValue=true;};abego.TiddlerFilterTerm=function(_27,_28){if(!_28){_28={};}
var _29=_27;if(!_28.textIsRegExp){_29=_27.escapeRegExp();if(_28.fullWordMatch){_29="\\b"+_29+"\\b";}}
var _2a=new RegExp(_29,"m"+(_28.caseSensitive?"":"i"));this.tester=new abego.MultiFieldRegExpTester(_2a,_28.fields,_28.withExtendedFields);};abego.TiddlerFilterTerm.prototype.test=function(_2b){return this.tester.test(_2b);};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 _30=m[2]?m[2].trim():"";r.push({name:"text",value:_30});r[0].text=[_30];return{title:m[1].trim(),params:r};}else{return{title:s.trim(),params:[[]]};}};abego.parseTiddlerFilterTerm=function(_31,_32,_33){var re=/\s*(?:(?:\{([^\}]*)\})|(?:(=)|([#%!])|(?:(\w+)\s*\:(?!\/\/))|(?:(?:("(?:(?:\\")|[^"])+")|(?:\/((?:(?:\\\/)|[^\/])+)\/)|(\w+\:\/\/[^\s]+)|([^\s\)\-\"]+)))))/mg;var _35={"!":"title","%":"text","#":"tags"};var _36={};var _37;re.lastIndex=_32;while(1){var i=re.lastIndex;var m=re.exec(_31);if(!m||m.index!=i){throw"Word or String literal expected";}
if(m[1]){var _3a={};var _3b=abego.getBracedText(_31,0,_3a);if(!_3b){throw"Invalid {...} syntax";}
var f=Function("tiddler","return ("+_3b+");");return{func:f,lastIndex:_3a.lastIndex,markRE:null};}
if(m[2]){_37=true;}else{if(m[3]){_36[_35[m[3]]]=1;}else{if(m[4]){_36[m[4]]=1;}else{var _3d=m[6];var _3e=m[5]?window.eval(m[5]):m[6]?m[6]:m[7]?m[7]:m[8];var _33=abego.copyOptions(_33);_33.fullWordMatch=_37;_33.textIsRegExp=_3d;var _3f=[];for(var n in _36){_3f.push(n);}
if(_3f.length==0){_33.fields=_33.defaultFields;}else{_33.fields=_3f;_33.withExtendedFields=false;}
var _41=new abego.TiddlerFilterTerm(_3e,_33);var _42=_3d?_3e:_3e.escapeRegExp();if(_42&&_37){_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+=m[0].length;_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;}
abego.consumeEvent(e);var _80=abego.toInt(this.getAttribute("page"),0);var _81=_7d.getCurrentPageIndex();if(_80==_81){return;}
var _82=_80*_7d.getItemsPerPage();_7d.setFirstIndexOnPage(_82);_7d.onPageChanged(_80,_81);};var _83;var _84=this.getCurrentPageIndex();var _85=this.getLastPageIndex();if(_84>0){_83=createTiddlyButton(_7c,"Previous","Go to previous page (Shortcut: Alt-'<')",_7e,"prev");_83.setAttribute("page",(_84-1).toString());_83.setAttribute("accessKey","<");}
for(var i=-this.getMaxPagesInNavigation();i<this.getMaxPagesInNavigation();i++){var _87=_84+i;if(_87<0){continue;}
if(_87>_85){break;}
var _88=(i+_84+1).toString();var _89=_87==_84?"currentPage":"otherPage";_83=createTiddlyButton(_7c,_88,"Go to page %0".format([_88]),_7e,_89);_83.setAttribute("page",(_87).toString());}
if(_84<_85){_83=createTiddlyButton(_7c,"Next","Go to next page (Shortcut: Alt-'>')",_7e,"next");_83.setAttribute("page",(_84+1).toString());_83.setAttribute("accessKey",">");}}});abego.LimitedTextRenderer=function(){var _8a=40;var _8b=4;var _8c=function(_8d,_8e,_8f){var n=_8d.length;if(n==0){_8d.push({start:_8e,end:_8f});return;}
var i=0;for(;i<n;i++){var _92=_8d[i];if(_92.start<=_8f&&_8e<=_92.end){var r;var _94=i+1;for(;_94<n;_94++){r=_8d[_94];if(r.start>_8f||_8e>_92.end){break;}}
var _95=_8e;var _96=_8f;for(var j=i;j<_94;j++){r=_8d[j];_95=Math.min(_95,r.start);_96=Math.max(_96,r.end);}
_8d.splice(i,_94-i,{start:_95,end:_96});return;}
if(_92.start>_8f){break;}}
_8d.splice(i,0,{start:_8e,end:_8f});};var _98=function(_99){var _9a=0;for(var i=0;i<_99.length;i++){var _9c=_99[i];_9a+=_9c.end-_9c.start;}
return _9a;};var _9d=function(c){return(c>="a"&&c<="z")||(c>="A"&&c<="Z")||c=="_";};var _9f=function(s,_a1){if(!_9d(s[_a1])){return null;}
for(var i=_a1-1;i>=0&&_9d(s[i]);i--){}
var _a3=i+1;var n=s.length;for(i=_a1+1;i<n&&_9d(s[i]);i++){}
return{start:_a3,end:i};};var _a5=function(s,_a7,_a8){var _a9;if(_a8){_a9=_9f(s,_a7);}else{if(_a7<=0){return _a7;}
_a9=_9f(s,_a7-1);}
if(!_a9){return _a7;}
if(_a8){if(_a9.start>=_a7-_8b){return _a9.start;}
if(_a9.end<=_a7+_8b){return _a9.end;}}else{if(_a9.end<=_a7+_8b){return _a9.end;}
if(_a9.start>=_a7-_8b){return _a9.start;}}
return _a7;};var _aa=function(s,_ac){var _ad=[];if(_ac){var _ae=0;var n=s.length;var _b0=0;do{_ac.lastIndex=_ae;var _b1=_ac.exec(s);if(_b1){if(_ae<_b1.index){var t=s.substring(_ae,_b1.index);_ad.push({text:t});}
_ad.push({text:_b1[0],isMatch:true});_ae=_b1.index+_b1[0].length;}else{_ad.push({text:s.substr(_ae)});break;}}while(true);}else{_ad.push({text:s});}
return _ad;};var _b3=function(_b4){var _b5=0;for(var i=0;i<_b4.length;i++){if(_b4[i].isMatch){_b5++;}}
return _b5;};var _b7=function(s,_b9,_ba,_bb,_bc){var _bd=Math.max(Math.floor(_bc/(_bb+1)),_8a);var _be=Math.max(_bd-(_ba-_b9),0);var _bf=Math.min(Math.floor(_ba+_be/3),s.length);var _c0=Math.max(_bf-_bd,0);_c0=_a5(s,_c0,true);_bf=_a5(s,_bf,false);return{start:_c0,end:_bf};};var _c1=function(_c2,s,_c4){var _c5=[];var _c6=_b3(_c2);var pos=0;for(var i=0;i<_c2.length;i++){var t=_c2[i];var _ca=t.text;if(t.isMatch){var _cb=_b7(s,pos,pos+_ca.length,_c6,_c4);_8c(_c5,_cb.start,_cb.end);}
pos+=_ca.length;}
return _c5;};var _cc=function(s,_ce,_cf){var _d0=_cf-_98(_ce);while(_d0>0){if(_ce.length==0){_8c(_ce,0,_a5(s,_cf,false));return;}else{var _d1=_ce[0];var _d2;var _d3;if(_d1.start==0){_d2=_d1.end;if(_ce.length>1){_d3=_ce[1].start;}else{_8c(_ce,_d2,_a5(s,_d2+_d0,false));return;}}else{_d2=0;_d3=_d1.start;}
var _d4=Math.min(_d3,_d2+_d0);_8c(_ce,_d2,_d4);_d0-=(_d4-_d2);}}};var _d5=function(_d6,s,_d8,_d9,_da){if(_d9.length==0){return;}
var _db=function(_dc,s,_de,_df,_e0){var t;var _e2;var pos=0;var i=0;var _e5=0;for(;i<_de.length;i++){t=_de[i];_e2=t.text;if(_df<pos+_e2.length){_e5=_df-pos;break;}
pos+=_e2.length;}
var _e6=_e0-_df;for(;i<_de.length&&_e6>0;i++){t=_de[i];_e2=t.text.substr(_e5);_e5=0;if(_e2.length>_e6){_e2=_e2.substr(0,_e6);}
if(t.isMatch){createTiddlyElement(_dc,"span",null,"marked",_e2);}else{createTiddlyText(_dc,_e2);}
_e6-=_e2.length;}
if(_e0<s.length){abego.createEllipsis(_dc);}};if(_d9[0].start>0){abego.createEllipsis(_d6);}
var _e7=_da;for(var i=0;i<_d9.length&&_e7>0;i++){var _e9=_d9[i];var len=Math.min(_e9.end-_e9.start,_e7);_db(_d6,s,_d8,_e9.start,_e9.start+len);_e7-=len;}};this.render=function(_eb,s,_ed,_ee){if(s.length<_ed){_ed=s.length;}
var _ef=_aa(s,_ee);var _f0=_c1(_ef,s,_ed);_cc(s,_f0,_ed);_d5(_eb,s,_ef,_f0,_ed);};};(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 _f2;var _f3;var _f4=function(_f5){_f2=_f5;};var _f6=function(){return _f2?_f2:[];};var _f7=function(){return _f2?_f2.length:0;};var _f8=4;var _f9=10;var _fa=2;var _fb=function(s,re){var m=s.match(re);return m?m.length:0;};var _ff=function(_100,_101){var _102=_101.getMarkRegExp();if(!_102){return 1;}
var _103=_100.title.match(_102);var _104=_103?_103.length:0;var _105=_fb(_100.getTags(),_102);var _106=_103?_103.join("").length:0;var _107=_100.title.length>0?_106/_100.title.length:0;var rank=_104*_f8+_105*_fa+_107*_f9+1;return rank;};var _109=function(_10a,_10b,_10c,_10d,_10e,_10f){_f3=null;var _110=_10a.reverseLookup("tags",_10f,false);try{var _111=[];if(config.options.chkSearchInTitle){_111.push("title");}
if(config.options.chkSearchInText){_111.push("text");}
if(config.options.chkSearchInTags){_111.push("tags");}
_f3=new abego.TiddlerQuery(_10b,_10c,_10d,_111,config.options.chkSearchExtendedFields);}
catch(e){return[];}
var _112=_f3.filter(_110);var _113=abego.YourSearch.getRankFunction();for(var i=0;i<_112.length;i++){var _115=_112[i];var rank=_113(_115,_f3);_115.searchRank=rank;}
if(!_10e){_10e="title";}
var _117=function(a,b){var _11a=a.searchRank-b.searchRank;if(_11a==0){if(a[_10e]==b[_10e]){return(0);}else{return(a[_10e]<b[_10e])?-1:+1;}}else{return(_11a>0)?-1:+1;}};_112.sort(_117);return _112;};var _11b=80;var _11c=50;var _11d=250;var _11e=50;var _11f=25;var _120=10;var _121="yourSearchResult";var _122="yourSearchResultItems";var _123;var _124;var _125;var _126;var _127;var _128=function(){if(version.extensions.YourSearchPlugin.styleSheetInited){return;}
version.extensions.YourSearchPlugin.styleSheetInited=true;setStylesheet(store.getTiddlerText("YourSearchStyleSheet"),"yourSearch");};var _129=function(){return _124!=null&&_124.parentNode==document.body;};var _12a=function(){if(_129()){document.body.removeChild(_124);}};var _12b=function(e){_12a();var _12d=this.getAttribute("tiddlyLink");if(_12d){var _12e=this.getAttribute("withHilite");var _12f=highlightHack;if(_12e&&_12e=="true"&&_f3){highlightHack=_f3.getMarkRegExp();}
story.displayTiddler(this,_12d);highlightHack=_12f;}
return(false);};var _130=function(){if(!_125){return;}
var root=_125;var _132=findPosX(root);var _133=findPosY(root);var _134=root.offsetHeight;var _135=_132;var _136=_133+_134;var _137=findWindowWidth();if(_137<_124.offsetWidth){_124.style.width=(_137-100)+"px";_137=findWindowWidth();}
var _138=_124.offsetWidth;if(_135+_138>_137){_135=_137-_138-30;}
if(_135<0){_135=0;}
_124.style.left=_135+"px";_124.style.top=_136+"px";_124.style.display="block";};var _139=function(){if(_124){window.scrollTo(0,ensureVisible(_124));}
if(_125){window.scrollTo(0,ensureVisible(_125));}};var _13a=function(){_130();_139();};var _13b;var _13c;var _13d=new abego.PageWiseRenderer();var _13e=function(_13f){this.itemHtml=store.getTiddlerText("YourSearchItemTemplate");if(!this.itemHtml){alertAndThrow("YourSearchItemTemplate not found");}
this.place=document.getElementById(_122);if(!this.place){this.place=createTiddlyElement(_13f,"div",_122);}};merge(_13e.prototype,{render:function(_140,_141,_142,_143){_13b=_143;_13c=_141;var item=createTiddlyElement(this.place,"div",null,"yourSearchItem");item.innerHTML=this.itemHtml;applyHtmlMacros(item,null);refreshElements(item,null);},endRendering:function(_145){_13c=null;}});var _146=function(){if(!_124||!_125){return;}
var html=store.getTiddlerText("YourSearchResultTemplate");if(!html){html="<b>Tiddler YourSearchResultTemplate not found</b>";}
_124.innerHTML=html;applyHtmlMacros(_124,null);refreshElements(_124,null);var _148=new _13e(_124);_13d.renderPage(_148);_13a();};_13d.getItemsPerPage=function(){var n=(config.options.chkPreviewText)?abego.toInt(config.options.txtItemsPerPageWithPreview,_120):abego.toInt(config.options.txtItemsPerPage,_11f);return(n>0)?n:1;};_13d.onPageChanged=function(){_146();};var _14a=function(){if(_125==null||!config.options.chkUseYourSearch){return;}
if((_125.value==_123)&&_123&&!_129()){if(_124&&(_124.parentNode!=document.body)){document.body.appendChild(_124);_13a();}else{abego.YourSearch.onShowResult(true);}}};var _14b=function(){_12a();_124=null;_123=null;};var _14c=function(self,e){while(e!=null){if(self==e){return true;}
e=e.parentNode;}
return false;};var _14f=function(e){if(e.target==_125){return;}
if(e.target==_126){return;}
if(_124&&_14c(_124,e.target)){return;}
_12a();};var _151=function(e){if(e.keyCode==27){_12a();}};addEvent(document,"click",_14f);addEvent(document,"keyup",_151);var _153=function(text,_155,_156){_123=text;_f4(_109(store,text,_155,_156,"title","excludeSearch"));abego.YourSearch.onShowResult();};var _157=function(_158,_159,_15a,_15b,_15c,_15d){_128();_123="";var _15e=null;var _15f=function(txt){if(config.options.chkUseYourSearch){_153(txt.value,config.options.chkCaseSensitiveSearch,config.options.chkRegExpSearch);}else{story.search(txt.value,config.options.chkCaseSensitiveSearch,config.options.chkRegExpSearch);}
_123=txt.value;};var _161=function(e){_15f(_125);return false;};var _163=function(e){if(!e){var e=window.event;}
_125=this;switch(e.keyCode){case 13:if(e.ctrlKey&&_127&&_129()){_127.onclick.apply(_127,[e]);}else{_15f(this);}
break;case 27:if(_129()){_12a();}else{this.value="";clearMessage();}
break;}
if(String.fromCharCode(e.keyCode)==this.accessKey||e.altKey){_14a();}
if(this.value.length<3&&_15e){clearTimeout(_15e);}
if(this.value.length>2){if(this.value!=_123){if(!config.options.chkUseYourSearch||config.options.chkSearchAsYouType){if(_15e){clearTimeout(_15e);}
var txt=this;_15e=setTimeout(function(){_15f(txt);},500);}}else{if(_15e){clearTimeout(_15e);}}}
if(this.value.length==0){_12a();}};var _166=function(e){this.select();clearMessage();_14a();};var args=_15c.parseParams("list",null,true);var _169=getFlag(args,"buttonAtRight");var _16a=getParam(args,"sizeTextbox",this.sizeTextbox);var btn;if(!_169){btn=createTiddlyButton(_158,this.label,this.prompt,_161);}
var txt=createTiddlyElement(_158,"input",null,null,null);if(_15a[0]){txt.value=_15a[0];}
txt.onkeyup=_163;txt.onfocus=_166;txt.setAttribute("size",_16a);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(_169){btn=createTiddlyButton(_158,this.label,this.prompt,_161);}
_125=txt;_126=btn;};var _16d=function(){_12a();var _16e=_f6();var n=_16e.length;if(n){var _170=[];for(var i=0;i<n;i++){_170.push(_16e[i].title);}
story.displayTiddlers(null,_170);}};var _172=function(_173,_174,_175,_176){invokeMacro(_173,"option",_174,_175,_176);var elem=_173.lastChild;var _178=elem.onclick;elem.onclick=function(e){var _17a=_178.apply(this,arguments);_146();return _17a;};return elem;};var _17b=function(s){var _17d=["''","{{{","}}}","//","<<<","/***","***/"];var _17e="";for(var i=0;i<_17d.length;i++){if(i!=0){_17e+="|";}
_17e+="("+_17d[i].escapeRegExp()+")";}
return s.replace(new RegExp(_17e,"mg"),"").trim();};var _180=function(){var i=_13b;return(i>=0&&i<=9)?(i<9?(i+1):0):-1;};var _182=new abego.LimitedTextRenderer();var _183=function(_184,s,_186){_182.render(_184,s,_186,_f3.getMarkRegExp());};var _187=TiddlyWiki.prototype.saveTiddler;TiddlyWiki.prototype.saveTiddler=function(_188,_189,_18a,_18b,_18c,tags,_18e){_187.apply(this,arguments);_14b();};var _18f=TiddlyWiki.prototype.removeTiddler;TiddlyWiki.prototype.removeTiddler=function(_190){_18f.apply(this,arguments);_14b();};config.macros.yourSearch={label:"yourSearch",prompt:"Gives access to the current/last YourSearch result",handler:function(_191,_192,_193,_194,_195,_196){if(_193.length==0){return;}
var name=_193[0];var func=config.macros.yourSearch.funcs[name];if(func){func(_191,_192,_193,_194,_195,_196);}},tests:{"true":function(){return true;},"false":function(){return false;},"found":function(){return _f7()>0;},"previewText":function(){return config.options.chkPreviewText;}},funcs:{itemRange:function(_199){if(_f7()){var _19a=_13d.getLastIndexOnPage();var s="%0 - %1".format([_13d.getFirstIndexOnPage()+1,_19a+1]);createTiddlyText(_199,s);}},count:function(_19c){createTiddlyText(_19c,_f7().toString());},query:function(_19d){if(_f3){createTiddlyText(_19d,_f3.toString());}},version:function(_19e){var t="YourSearch %0.%1.%2".format([version.extensions.YourSearchPlugin.major,version.extensions.YourSearchPlugin.minor,version.extensions.YourSearchPlugin.revision]);var e=createTiddlyElement(_19e,"a");e.setAttribute("href","http://tiddlywiki.abego-software.de/#YourSearchPlugin");e.innerHTML="<font color=\"black\" face=\"Arial, Helvetica, sans-serif\">"+t+"<font>";},copyright:function(_1a1){var e=createTiddlyElement(_1a1,"a");e.setAttribute("href","http://www.abego-software.de");e.innerHTML="<font color=\"black\" face=\"Arial, Helvetica, sans-serif\">&copy; 2005-2008 <b><font color=\"red\">abego</font></b> Software<font>";},newTiddlerButton:function(_1a3){if(_f3){var r=abego.parseNewTiddlerCommandLine(_f3.getQueryText());var btn=config.macros.newTiddler.createNewTiddlerButton(_1a3,r.title,r.params,"new tiddler","Create a new tiddler based on search text. (Shortcut: Ctrl-Enter; Separators: '.', '#')",null,"text");var _1a6=btn.onclick;btn.onclick=function(){_12a();_1a6.apply(this,arguments);};_127=btn;}},linkButton:function(_1a7,_1a8,_1a9,_1aa,_1ab,_1ac){if(_1a9<2){return;}
var _1ad=_1a9[1];var text=_1a9<3?_1ad:_1a9[2];var _1af=_1a9<4?text:_1a9[3];var _1b0=_1a9<5?null:_1a9[4];var btn=createTiddlyButton(_1a7,text,_1af,_12b,null,null,_1b0);btn.setAttribute("tiddlyLink",_1ad);},closeButton:function(_1b2,_1b3,_1b4,_1b5,_1b6,_1b7){var _1b8=createTiddlyButton(_1b2,"close","Close the Search Results (Shortcut: ESC)",_12a);},openAllButton:function(_1b9,_1ba,_1bb,_1bc,_1bd,_1be){var n=_f7();if(n==0){return;}
var _1c0=n==1?"open tiddler":"open all %0 tiddlers".format([n]);var _1c1=createTiddlyButton(_1b9,_1c0,"Open all found tiddlers (Shortcut: Alt-O)",_16d);_1c1.setAttribute("accessKey","O");},naviBar:function(_1c2,_1c3,_1c4,_1c5,_1c6,_1c7){_13d.addPageNavigation(_1c2);},"if":function(_1c8,_1c9,_1ca,_1cb,_1cc,_1cd){if(_1ca.length<2){return;}
var _1ce=_1ca[1];var _1cf=(_1ce=="not");if(_1cf){if(_1ca.length<3){return;}
_1ce=_1ca[2];}
var test=config.macros.yourSearch.tests[_1ce];var _1d1=false;try{if(test){_1d1=test(_1c8,_1c9,_1ca,_1cb,_1cc,_1cd)!=_1cf;}else{_1d1=(!eval(_1ce))==_1cf;}}
catch(ex){}
if(!_1d1){_1c8.style.display="none";}},chkPreviewText:function(_1d2,_1d3,_1d4,_1d5,_1d6,_1d7){var _1d8=_1d4.slice(1).join(" ");var elem=_172(_1d2,"chkPreviewText",_1d5,_1d7);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(_1da,_1db,_1dc,_1dd,_1de,_1df){var name=_1dc[0];var func=config.macros.foundTiddler.funcs[name];if(func){func(_1da,_1db,_1dc,_1dd,_1de,_1df);}},funcs:{title:function(_1e2,_1e3,_1e4,_1e5,_1e6,_1e7){if(!_13c){return;}
var _1e8=_180();var _1e9=_1e8>=0?"Open tiddler (Shortcut: Alt-%0)".format([_1e8.toString()]):"Open tiddler";var btn=createTiddlyButton(_1e2,null,_1e9,_12b,null);btn.setAttribute("tiddlyLink",_13c.title);btn.setAttribute("withHilite","true");_183(btn,_13c.title,_11b);if(_1e8>=0){btn.setAttribute("accessKey",_1e8.toString());}},tags:function(_1eb,_1ec,_1ed,_1ee,_1ef,_1f0){if(!_13c){return;}
_183(_1eb,_13c.getTags(),_11c);},text:function(_1f1,_1f2,_1f3,_1f4,_1f5,_1f6){if(!_13c){return;}
_183(_1f1,_17b(_13c.text),_11d);},field:function(_1f7,_1f8,_1f9,_1fa,_1fb,_1fc){if(!_13c){return;}
var name=_1f9[1];var len=_1f9.length>2?abego.toInt(_1f9[2],_11e):_11e;var v=store.getValue(_13c,name);if(v){_183(_1f7,_17b(v),len);}},number:function(_200,_201,_202,_203,_204,_205){var _206=_180();if(_206>=0){var text="%0)".format([_206.toString()]);createTiddlyElement(_200,"span",null,"shortcutNumber",text);}}}};var opts={chkUseYourSearch:true,chkPreviewText:true,chkSearchAsYouType:true,chkSearchInTitle:true,chkSearchInText:true,chkSearchInTags:true,chkSearchExtendedFields:true,txtItemsPerPage:_11f,txtItemsPerPageWithPreview:_120};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=_157;var _20a=function(){if(config.macros.search.handler!=_157){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(_20a,5000);abego.YourSearch.getStandardRankFunction=function(){return _ff;};abego.YourSearch.getRankFunction=function(){return abego.YourSearch.getStandardRankFunction();};abego.YourSearch.getCurrentTiddler=function(){return _13c;};abego.YourSearch.closeResult=function(){_12a();};abego.YourSearch.getFoundTiddlers=function(){return _f2;};abego.YourSearch.getQuery=function(){return _f3;};abego.YourSearch.onShowResult=function(_20b){highlightHack=_f3?_f3.getMarkRegExp():null;if(!_20b){_13d.setItems(_f6());}
if(!_124){_124=createTiddlyElement(document.body,"div",_121,"yourSearchResult");}else{if(_124.parentNode!=document.body){document.body.appendChild(_124);}}
_146();highlightHack=null;};})();}
//%/
/***
| Name:|allTagsExcept|
| Description:|show all tags but those listed |
| Version:|1.0|
| Date:|Sept 8, 2005|
| Author:|Clint Checketts|
usage: {{{<<allTagsExcept systemConfig systemTheme>>}}} This will show all tags but those listed (e.g. systemConfig and systemTheme)
<<allTagsExcept systemConfig systemTheme>>
revision note: cleaned up notes in code and created header area 06.06.10 MTP
***/
//{{{
version.extensions.allTagsExcept = {major: 0, minor: 1, revision: 0, date: new Date(2005,8,15)};
config.macros.allTagsExcept = {tooltip: "Show tiddlers tagged with '%0'",noTags: "There are no tags to display"};

config.macros.allTagsExcept.handler = function(place,macroName,params)
{
	var tags = store.getTags();
	var theTagList = createTiddlyElement(place,"ul",null,null,null);
	if(tags.length == 0)
		createTiddlyElement(theTagList,"li",null,"listTitle",this.noTags);
	for (var t=0; t<tags.length; t++) {
            var includeTag = true;
            for (var p=0;p<params.length; p++) if (tags[t][0] == params[p]) includeTag = false;
            if (includeTag){
		var theListItem =createTiddlyElement(theTagList,"li",null,null,null);
		var theTag = createTiddlyButton(theListItem,tags[t][0] + " (" + tags[t][1] + ")",this.tooltip.format([tags[t][0]]),onClickTag);
		theTag.setAttribute("tag",tags[t][0]);
           }
	}
}
//}}}
{{{<<allTags>>}}}
<<allTags>>
----
{{{<<allTags myExcludeTag>>}}}
<<allTags myExcludeTag>>
----
{{{<<allTags myExcludeTag sys>>}}}
<<allTags myExcludeTag sys>>
----
{{{<<allTags systemConfig T>>}}}
<<allTags systemConfig T>>
----
{{{<<allTags systemConfig>>}}}
<<allTags systemConfig>>

''Random Quotes and Thoughts''
<<QOTD Quotations 50000>>
''<script>return config.options.txtUserName</script>'s Wiki Experiments''
<<tiddler DateTime>>


/***
|Name:|extendTagButton.Tweak|
|Description:|Intercepts onClickTag between TaggerPlugin & ExtendTagPlugin to allow a exclude list for miniTag using bracketed space list in ExcludeFromTagList tiddler - Intended use is to suppress TagDB |
|Version:|1.0|
|Date:|10.08.08|
|Source:|TiddlyWikiDev Google Group|
|Author:|ELS for MTP|
***/
//{{{
var fn=onClickTag.toString(); 
fn=fn.replace( 
        /for \(r = 0; r < tagged.length; r\+\+\) \{/, 'var ex=store.getTiddlerText("ExcludeFromTagList","").readBracketedList();'+'for(r=0;r<tagged.length;r++) { if (ex.contains(tagged[r].title)) continue;'); 
eval("window.onClickTag="+fn);
//}}}
/***
|Name:|ExtentTagButtonPlugin|
|Description:|Adds a New tiddler button in the tag drop down|
|Version:|3.2 ($Rev: 3861 $)|
|Date:|$Date: 2008-03-08 10:53:09 +1000 (Sat, 08 Mar 2008) $|
|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");
	// Thanks 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: greenishgray
HeaderTop: #000
HeaderMid: #cf9
HeaderBottom: #445533
Background: #eeffcc
Foreground: #000
PrimaryPale: #bbcc99
PrimaryLight: #bbdd88
PrimaryMid: #445533
PrimaryDark: #ffc
SecondaryPale: #ffc
SecondaryLight: #99dd55
SecondaryMid: #cccccc
SecondaryDark: #445533
TertiaryPale: #bbcc99
TertiaryLight: #453
TertiaryMid: #9c6
TertiaryDark: #453
mailto:email1;email2;?subject=Test%20Message&body=Test%0dText

<<newReminder>><script>
	place.firstChild.firstChild.data ="reminder"; //Rename Macro
	place.firstChild.title="New Reminder"; //Modify Macro Hover
	jQuery('form').add('form select').css('fontSize', '9px');//Smaller select form
	jQuery('form').add('form input').css('fontSize', '9px');//Smaller input form
</script>

<<switchTheme width:auto>>
<<selectPalette>><script>place.lastChild.style.width="10em";place.lastChild.style.fontSize="8pt";</script>

!!!Theme / Palette Test
TiddlyWiki is a wiki-modeled client-side single-page application written by Jeremy Ruston that is designed to be used as a personal notebook. It is a single self-contained HTML file that includes CSS and JavaScript code. When the user downloads it to their PC, TiddlyWiki can save the entered information by overwriting itself on the user's disk, at the user's request. Following TiddlyWiki conventions, users can make a new entry, called a tiddler, in their local copy of the TiddlyWiki file and save it for future reference. Existing tiddlers can also be modified or deleted in the same way. Because it runs under most browsers and requires no installation, it can be easily used as a portable personal wiki.

[<IMG[images/fire.png]]
[>IMG[images/fire2.png]]
!!!Test Text for Fun
I love to play with my Wiki <<EncryptionDecryptAll>>

!heading 1
!!heading 2
!!!heading3
----
<<tag button>>
This is a link to a [[StyleSheet]] tiddler.

> This is a blockquote
> This is a blockquote
> This is a blockquote
!!!Sortable Table
| sortable |k
|column1|column2<<autosort>>|column3|h
| 1 | row1 | 31 |
| 2 | row4 | 41 |
| 3 | row2 | 96 |
| 4 | row5 | 12 |
| 5 | row3 | 14 |
!Code View
Link= [[Tricks]] Code={{{[[Tricks]]}}}

/***
My Code Here
***/
/*{{{*/
xx XX xx YY yy YY zz ZZ zz
/*}}}*/
<<newReminder>><script>place.firstChild.firstChild.data ="WtF";place.firstChild.title="WtF Hover";</script>
<<newJournal>><script>place.lastChild.firstChild.data ="WoW";place.lastChild.title="WoW Hover";</script>
http://groups.google.com/group/tiddlywiki/browse_thread/thread/b95de9cb062ad2a4/5e69a1d430f8a357?show_docid=5e69a1d430f8a357
----
I would like to have a script that can identify if any *list (<li>)
elements are present in a section, if not return *No Items, if so
return nothing. . .

!!!Section1
*list
*list
<script show>
var text=store.getTiddlerText('sciptlistsections##Section1');

match = text.match(/^[*|#]/im);
if (match != null) {
        // matched text: match[0]
        // match start: match.index
        // capturing group n: match[n]

	return ('*found list items');

} else {

        // Match attempt failed
        return ('*No Items')

}
</script>
!!!Section2
<script show>
var text=store.getTiddlerText('sciptlistsections##Section2');

match = text.match(/^[*|#]/im);
if (match != null) {
        // matched text: match[0]
        // match start: match.index
        // capturing group n: match[n]

	return ('*found list items');

} else {

        // Match attempt failed
        return ('*No Items')

}
</script>
@@display:none;
!!!End
@@
I am having a hard time figuring out how to identify if any *list
(<li>) items are present between sections

Thoughts or Guidance?

Mike 
----
If you read the content of the section a

var text ... should contain the text of the section.
In your case the else path would be of interest.

The following should be sensitive for
{{{*list and #list}}}
{{{
match = text.match(/^[*|#]/im);
if (match != null) {
        // matched text: match[0]
        // match start: match.index
        // capturing group n: match[n]
} else {

        // Match attempt failed

}
}}}
hope this helps
have fun
Mario 
----


<script>
var out = "" ;
for (var i=1; i<6; ++i)
{
 out += i + ".\n" ;
}

 return out ;
</script> 


<<switchTheme width:auto>>
<<selectPalette>><script>place.lastChild.style.width="10em";place.lastChild.style.fontSize="8pt";</script>
<script>
        var tag="Completed";
        var hdr="| Date | Body | Author |\n";
	var fmt="| %0 |%1: <<tiddler [[%1]]>>| %2 |\n"; 
	var tids=store.getTaggedTiddlers(tag,'modified').reverse(); ;
        var out=[hdr];
        for (var i=0; i<tids.length; i++) {
                var when=tids[i].created.formatString("DDD, MMM DDth,YYYY<br>0hh12:0mm:0ss am");
                var what=tids[i].title;
                var who=tids[i].modifier;
                out.push(fmt.format([when,what,who]));
        }
        return out.join('');
</script>
<script>
if('$1'!='$'+'1'){
        var tids=
        store.getTiddlers('modified','excludeLists').reverse();
        var num=0;
        var max='$2'=='$'+'2'?1:$2;
        for (var i=0; i<tids.length; i++){
                if(tids[i].tags.contains('$1')){
                        num++;
                        wikify('![['+tids[i].title+']]\n'+ store.getTiddlerText(tids[i].title),place);
                        if(num>=max)return;
                }
        }
        wikify('@@color:red;'+
                'No tiddler found tagging to \'$1\'!@@',place);
}

</script>
<script>
if('$1'!='$'+'1'){
        var tids=
        store.getTiddlers('modified','excludeLists').reverse();
        var num=0;
        var max='$2'=='$'+'2'?1:$2;
        for (var i=0; i<tids.length; i++){
                if(tids[i].tags.contains('$1')){
                        num++;
                        wikify('*[['+tids[i].title+']]',place);
                        if(num>=max)return;
                }
        }
if(num == 0) wikify('@@color:red;'+'No tiddler found tagging to [[ \$1\ ]]!@@',place);
//if(!num == 0) wikify('@@color:red;'+'Less tiddlers exist than specified!@@',place);
}
</script> 

[[CustomViewTemplate]]

<div macro="showWhenTaggedAll palette view" style='overflow: auto;'>
<span style="width:45%; float:left; padding:1em; 0 0 0.5em;"><span macro="paletteView"></span></span>
<span style="width:45%; float:right; padding:5em 1.5em 0 0;"><span macro="viewPalette"></span></span>
</div>

Any tiddler tagged <<tag palette>> + <<tag view>> will use PaletteViewMacro & ViewPalettePlugin on display
config.options.txtUserName="Mike";
config.options.txtBackupFolder="Backup";
config.options.chkAnimate=false;
config.options.chkSaveBackups=true;
config.options.chkAutoSave=false;
config.options.chkShowQuickEdit=true;
config.options.chkRandomTheme=true;
config.options.chkGenerateAnRssFeed   = false;

if (config.options.chkRandomTheme==false)
   config.options.txtTheme = "CustomTheme";