<!--{{{-->
<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>>
PageTemplate
|>|>|SiteTitle - SiteSubtitle|
|MainMenu|DefaultTiddlers<br><br><br><br>ViewTemplate<br><br>EditTemplate|SideBarOptions|
|~|~|OptionsPanel|
|~|~|AdvancedOptions|
|~|~|<<tiddler Configuration.SideBarTabs>>|

''StyleSheet:'' StyleSheetColors - StyleSheetLayout - StyleSheetPrint

SiteUrl
Blah, blah.
/***
|''Name:''|PlasticCalendarPlugin|
|''Description:''|This plugin creates a custom Gregorian calendar|
|''Version:''|1.3.1|
|''Date:''|Mar 13, 2007|
|''Source:''|http://www.math.ist.utl.pt/~psoares/addons.html|
|''Documentation:''|[[PlasticCalendarPlugin Documentation|PlasticCalendarPluginDoc]]|
|''Author:''|Paulo Soares|
|''License:''|[[Creative Commons Attribution-Share Alike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|''~CoreVersion:''|2.1.0|
***/
{{{
// --------------------------------------------------------------------
// Calendar
// --------------------------------------------------------------------

config.macros.calendar = {holidays: []};
config.macros.calendar.options = {
 // day week starts from (normally 0-Su or 1-Mo)
 calendarWeekStart: 0,
 calendarToday: "Today",
 calendarHoliday: "Holiday: ",
 calendarLongDateFormat: "0DD/0MM/YYYY",
 calendarShortDateFormat: "0DD/0MM",
 calendarTag: ["schedule"]
};

/***************************************************************************
** Internal functions
***************************************************************************/
var cldTag;

config.macros.calendar.calendarIsHoliday = function(date) {
 var cm = config.macros.calendar;
 var longHoliday = date.formatString(cm.options.calendarLongDateFormat);
 var shortHoliday = date.formatString(cm.options.calendarShortDateFormat);
 for(var i = 0; i < cm.holidays.length; i++) {
 if(cm.holidays[i][0] == longHoliday || cm.holidays[i][0] == shortHoliday) {
 return cm.holidays[i];
 }
 }
 return null;
}

config.macros.calendar.onClickOtherDay = function(e) {
 var day = this.getAttribute('tiddlylink');
 story.displayTiddler(null,day,DEFAULT_EDIT_TEMPLATE);
 for(var i=0; i<cldTag.length;i++){
 story.setTiddlerTag(day, cldTag[i], 0);
 }
 story.focusTiddler(day,"text");
}

config.macros.calendar.getPopupText = function(title) {
 var popup_entries = store.getTiddlerText(title).split("\n");
 var popup = popup_entries[0];
 if(popup_entries.length>1) popup += " ...";
 return popup;
}

config.macros.calendar.findCalendar = function(child) {
 var parent;
 while (child && child.parentNode) {
 parent = child.parentNode;
 if (parent.id == "calendarWrapper") {
 return parent;
 }
 child = parent;
 }
 return null;
}

config.macros.calendar.selectDate = function(e) {
 if (!e) var e = window.event;
 var cm = config.macros.calendar;
 var calendar = cm.findCalendar(this);
 if (calendar) {
 var d = this.getAttribute("date");
 if (d != null) cm.makeCalendar(calendar, new Date(new Number(d)));
 }
 e.cancelBubble = true;
 if (e.stopPropagation) e.stopPropagation();
 return false;
}

config.macros.calendar.makeCalendar = function(calendar, dt_current) {
 var cm = config.macros.calendar;
 var currentDay = new Date(new Number(calendar.getAttribute("currentDay")));
 var setControls = calendar.getAttribute("setControls");
 calendar.setAttribute("date", dt_current.valueOf());

 while (calendar.hasChildNodes())
 calendar.removeChild(calendar.firstChild);

if(setControls==1){
 // get same date in the previous year
 var dt_prev_year = new Date(dt_current);
 dt_prev_year.setFullYear(dt_prev_year.getFullYear() - 1);
 if (dt_prev_year.getDate() != dt_current.getDate())
 dt_prev_year.setDate(0);

 // get same date in the next year
 var dt_next_year = new Date(dt_current);
 dt_next_year.setFullYear(dt_next_year.getFullYear() + 1);
 if (dt_next_year.getDate() != dt_current.getDate())
 dt_next_year.setDate(0);

 // get same date in the previous month
 var dt_prev_month = new Date(dt_current);
 dt_prev_month.setMonth(dt_prev_month.getMonth() - 1);
 if (dt_prev_month.getDate() != dt_current.getDate())
 dt_prev_month.setDate(0);

 // get same date in the next month
 var dt_next_month = new Date(dt_current);
 dt_next_month.setMonth(dt_next_month.getMonth() + 1);
 if (dt_next_month.getDate() != dt_current.getDate())
 dt_next_month.setDate(0);
}

 // get first day to display in the grid for current month
 var dt_firstday = new Date(dt_current);
 dt_firstday.setDate(1);
 dt_firstday.setDate(1 - (7 + dt_firstday.getDay() - cm.options.calendarWeekStart) % 7);

 var area, header;
 var line, cell, i;

 // 1 - calendar header table
 // 2 - print weekdays titles
 // 3 - calendar days table 
calendar.cellPadding = 0;
calendar.cellSpacing = 0;
area = createTiddlyElement(calendar, "tbody");

 // 1 - calendar header table
 header = createTiddlyElement(area,"tr", "calendarHeader");
 header.cellPadding = 0;
 header.cellSpacing = 0;

if(setControls==1){ 
var headerValues = [
 [ "<<", "selectYear", dt_prev_year.valueOf() ],
 [ "<", "selectMonth", dt_prev_month.valueOf() ],
 [ config.messages.dates.months[dt_current.getMonth()] + ' ' + dt_current.getFullYear(),
 "selectToday", currentDay.valueOf() ],
 [ ">", "selectMonth", dt_next_month.valueOf() ],
 [ ">>", "selectYear", dt_next_year.valueOf() ]
 ];

 for (i = 0; i < headerValues.length; ++i) {
 var link = createTiddlyElement(header,"td", null, null, headerValues[i][0]);
 if(i==2) link.colSpan=3;
 link.onclick = cm.selectDate;
 link.setAttribute("date", headerValues[i][2]);
 }
} else {
 var link = createTiddlyElement(header,"td", null, null, 
config.messages.dates.months[dt_current.getMonth()] + ' ' + dt_current.getFullYear());
link.colSpan=7;
}

 // 2 - print weekdays titles
 line = createTiddlyElement(area, "tr", "weekNames");
 for (var n = 0; n < 7; ++n) {
 createTiddlyElement(line, "td", null, null, config.messages.dates.shortDays[(cm.options.calendarWeekStart + n)%7]);
 }

 // 3 - calendar days table
 var dt_current_day = new Date(dt_firstday);
 var day_class;
 var title;
 var holiday;
 var popup;
 var clickHandler;

 while (dt_current_day.getMonth() == dt_current.getMonth() ||
 dt_current_day.getMonth() == dt_firstday.getMonth()) {

 // print row header
 line = createTiddlyElement(area, "tr", "calendarLine", null, null);
 for (var n_current_wday = 0; n_current_wday < 7; ++n_current_wday) {
 title = dt_current_day.formatString(cm.options.calendarLongDateFormat);
 clickHandler = cm.onClickOtherDay;
 popup = null;
 holiday = cm.calendarIsHoliday(dt_current_day);

 if (holiday != null) {
 // holidays
 day_class = (holiday.length==3)? holiday[2]: "holiDay";
 popup = cm.options.calendarHoliday + holiday[1];
 } else if (dt_current_day.getDay() == 0 || dt_current_day.getDay() == 6) {
 // weekend days
 day_class = "weekDay";
 } else {
 // print working days of current month
 day_class = "workingDay";
 }

if(dt_current_day.getMonth() == dt_current.getMonth()){
 if (currentDay.valueOf() == dt_current_day.valueOf()) {
 // print current date
 if (store.tiddlerExists(title)){
 // day has a tiddler associated with it
 day_class += " currentscheduledDay";
 clickHandler = onClickTiddlerLink;
 popup = cm.options.calendarToday + ": "+ cm.getPopupText(title);
 } else {
 day_class += " currentDay";
 popup = cm.options.calendarToday;
}
}


 if (store.tiddlerExists(title) && store.getTiddler(title).isTagged(cldTag[0]))  {
 // day has a tiddler associated with it
 day_class += " scheduledDay";
 clickHandler = onClickTiddlerLink;
 popup = cm.getPopupText(title);
 }
}

 // extra formatting for days of previous or next month
 if (dt_current_day.getMonth() != dt_current.getMonth()) {
 day_class += " otherMonthDay";
 }

 var text = dt_current_day.getDate();
 var cell = createTiddlyElement(line, "td", null, day_class, text);
 cell.onclick=clickHandler;
 cell.setAttribute("date", dt_current_day.valueOf());
 cell.setAttribute("tiddlyLink", title);
 if(popup) cell.setAttribute("title", popup);
 dt_current_day.setDate(dt_current_day.getDate()+1);
 }
 }
}

config.macros.calendar.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
 var start_date = new Array();
 var date = new Date();
 var cldParams = paramString.parseParams('calendarParams', null, true);
 var cldYear = (cldParams[0].year)?parseFloat(cldParams[0].year[0]): date.getFullYear();
 var cldMonth = (cldParams[0].month)?parseFloat(cldParams[0].month[0]): date.getMonth();
 var n_months = (cldParams[0].numberMonths)?parseFloat(cldParams[0].numberMonths[0]): 1;
 var n_cols = (cldParams[0].numberColumns)?parseFloat(cldParams[0].numberColumns[0]): 3;
 cldTag = (cldParams[0].tag)?cldParams[0].tag[0].split("#"): config.macros.calendar.options.calendarTag;
 for(var i = 0; i < n_months; i++){
 start_date[i] = new Date(cldYear, cldMonth+i, 1);
 }
 var n_rows = Math.max(1,Math.ceil(n_months/n_cols));
 n_cols = Math.min(n_cols,n_months);
 var setControls=(n_months>1)? 0: 1;
 var currentDay = new Date();
 currentDay = new Date(currentDay.getFullYear(), currentDay.getMonth(), currentDay.getDate());
 var holder = createTiddlyElement(place, "table", null,"calendarHolder");
 var holderTable = createTiddlyElement(holder, "tbody");
 for(var i = 0; i < n_rows; i++){
 var holderLine = createTiddlyElement(holderTable, "tr");
 for(var j = 0; j < n_cols; j++){
 var holderCell = createTiddlyElement(holderLine, "td");
 if(n_cols*i+j+1<=n_months){
 var calendar = createTiddlyElement(holderCell, "table", "calendarWrapper");
 calendar.setAttribute("name", "calendarWrapper");
 calendar.setAttribute("setControls", setControls);
 calendar.setAttribute("currentDay", currentDay.valueOf());
 config.macros.calendar.makeCalendar(calendar, start_date[n_cols*i+j]);
 }
 }
 }
}

function refreshCalendars(hint) {
 var calendars = document.getElementsByName("calendarWrapper");
 var i, c;
 for (i = 0; i < calendars.length; ++i) {
 c = calendars.item(i);
 if (c.id == "calendarWrapper") {
 config.macros.calendar.makeCalendar(c, new Date(new Number(c.getAttribute("date"))));
 }
 }
}

store.addNotification(null, refreshCalendars);

setStylesheet("/***\n!Calendar Styles\n***/\n/*{{{*/\n .viewer .calendarHolder {\n margin-left: auto;\n margin-right: auto;\n border: none;\n}\n\n .viewer .calendarHolder table {\n border: none;\n margin: 0;\n}\n\n .viewer .calendarHolder tr {\n border: none;\n vertical-align: top;\n}\n\n .viewer .calendarHolder td {\n border: none;\n vertical-align: top;\n}\n\n .viewer #calendarWrapper {\n float: left;\n width: 21em;\n border: 2px solid #4682b4;\n cursor: pointer;\n}\n\n #calendarWrapper #calendarLine td {\n height: 2.5em;\n}\n\n #calendarWrapper tr {\n border:none;\n}\n\n #calendarWrapper td {\n text-align: center;\n vertical-align: middle;\n width: 14.28%;\n border:none;\n}\n\n #calendarWrapper #calendarHeader td{\n color: #ffffff;\n background-color: #4682b4;\n height: 2em;\n}\n\n #calendarWrapper #weekNames td {\n color: #ffffff;\n background-color: #87cefa;\n height: 2em;\n}\n\n #calendarWrapper .weekDay {\n background-color: #ccff99;\n}\n\n #calendarWrapper .holiDay {\n background-color: #9acd32;\n}\n\n #calendarWrapper .currentDay {\n border: solid #ff0000 2px;\n font-weight: bold;\n}\n\n #calendarWrapper .currentscheduledDay {\n border: solid #ff0000 2px;\n font-weight: bold;\n}\n\n #calendarWrapper .workingDay {\n background-color: #ffffff;\n}\n\n #calendarWrapper .scheduledDay {\n border: solid orange 2px;\n}\n\n #calendarWrapper .otherMonthDay {\n background-color: #999;\n}\n\n/*}}}*/","CalendarStyles");

config.shadowTiddlers.PlasticCalendarPluginDoc="The documentation is missing. It is available [[here|http://www.math.ist.utl.pt/~psoares/addons.html#PlasticCalendarPluginDoc]].";
}}}
/***
| Name:|Clock2|
| Author:|Simon Baird|
| Description:|A skinnable, sizeable analog clock|
| Source:|http://tiddlyspot.com/mptw/#Clock2|
| Requires:|Firefox 1.5.x or maybe Safari|
| Version:|1.0.3|
| Date:|4-Aug-2006|
!!Note
* Does not work in IE or Opera due to lack of canvas support.
* If you make a nice skin send it to me and I will include it here.
!!Ideas
* Can we support IE with this? http://sourceforge.net/projects/excanvas
* Skin should specify order of drawing so things can be on top of other things
* Fix it so we can have filled and/or stroked elements
* Skin should allow any number of moving and static elements
* Make download and example for non-TW use
* Make floating draggable?
!!Examples
{{{
<<clock2 fancy>><<clock2 120>>
<<clock2 chunkySwiss>> <<clock2 60 chunkySwiss noSeconds>><<clock2 '{
	outerBorder: { lineWidth: 60, radius:55, color: "#dd8877", alpha: 1 },
	smallIndicator: { lineWidth: 4, startAt: 80, endAt: 95, color: "white", alpha: 1 },
	largeIndicator: { lineWidth: 12, startAt: 77, endAt: 89, color: "#dd8877", alpha: 1 },
	hourHand: { lineWidth: 15, startAt: -15, endAt: 50, color: "white", alpha: 1 },
	minuteHand: { lineWidth: 10, startAt: 24, endAt: 200, color: "#771100", alpha: 0.6 },
	secondHand: { lineWidth: 3, startAt: 22, endAt: 83, color: "green", alpha: 0 },
	secondDecoration: { lineWidth: 1, startAt: 52, radius: 26, fillColor: "white", color: "red", alpha: 0.2 }
}'>>

}}}
<<clock2 fancy>><<clock2 120>>
<<clock2 chunkySwiss>> <<clock2 60 chunkySwiss noSeconds>><<clock2 '{
	outerBorder: { lineWidth: 60, radius:55, color: "#dd8877", alpha: 1 },
	smallIndicator: { lineWidth: 4, startAt: 80, endAt: 95, color: "white", alpha: 1 },
	largeIndicator: { lineWidth: 12, startAt: 77, endAt: 89, color: "#dd8877", alpha: 1 },
	hourHand: { lineWidth: 15, startAt: -15, endAt: 50, color: "white", alpha: 1 },
	minuteHand: { lineWidth: 10, startAt: 24, endAt: 200, color: "#771100", alpha: 0.6 },
	secondHand: { lineWidth: 3, startAt: 22, endAt: 83, color: "green", alpha: 0 },
	secondDecoration: { lineWidth: 1, startAt: 52, radius: 26, fillColor: "white", color: "red", alpha: 0.2 }
}'>>

See also BigClock.
!!Code
***/
//{{{

window.CoolClock = function(canvasId,displayRadius,skinId,showSecondHand) {
	return this.init(canvasId,displayRadius,skinId,showSecondHand);
}

CoolClock.config = {
	clockTracker: {},
	tickDelay: 1000,
	longTickDelay: 15000,
	defaultRadius: 85,
	renderRadius: 100,
	defaultSkin: "swissRail",
	skins:	{
		// try making your own...
		swissRail: {
			outerBorder: { lineWidth: 1, radius:95, color: "black", alpha: 1 },
			smallIndicator: { lineWidth: 2, startAt: 89, endAt: 93, color: "black", alpha: 1 },
			largeIndicator: { lineWidth: 4, startAt: 80, endAt: 93, color: "black", alpha: 1 },
			hourHand: { lineWidth: 8, startAt: -15, endAt: 50, color: "black", alpha: 1 },
			minuteHand: { lineWidth: 7, startAt: -15, endAt: 75, color: "black", alpha: 1 },
			secondHand: { lineWidth: 1, startAt: -20, endAt: 85, color: "red", alpha: 1 },
			secondDecoration: { lineWidth: 1, startAt: 70, radius: 4, fillColor: "red", color: "red", alpha: 1 }
		},
		chunkySwiss: {
			outerBorder: { lineWidth: 5, radius:97, color: "black", alpha: 1 },
			smallIndicator: { lineWidth: 4, startAt: 89, endAt: 93, color: "black", alpha: 1 },
			largeIndicator: { lineWidth: 8, startAt: 80, endAt: 93, color: "black", alpha: 1 },
			hourHand: { lineWidth: 12, startAt: -15, endAt: 60, color: "black", alpha: 1 },
			minuteHand: { lineWidth: 10, startAt: -15, endAt: 85, color: "black", alpha: 1 },
			secondHand: { lineWidth: 4, startAt: -20, endAt: 85, color: "red", alpha: 1 },
			secondDecoration: { lineWidth: 2, startAt: 70, radius: 8, fillColor: "red", color: "red", alpha: 1 }
		},
		fancy: {
			outerBorder: { lineWidth: 5, radius:95, color: "green", alpha: 0.7 },
			smallIndicator: { lineWidth: 1, startAt: 80, endAt: 93, color: "black", alpha: 0.4 },
			largeIndicator: { lineWidth: 1, startAt: 30, endAt: 93, color: "black", alpha: 0.5 },
			hourHand: { lineWidth: 8, startAt: -15, endAt: 50, color: "blue", alpha: 0.7 },
			minuteHand: { lineWidth: 7, startAt: -15, endAt: 92, color: "red", alpha: 0.7 },
			secondHand: { lineWidth: 10, startAt: 80, endAt: 85, color: "blue", alpha: 0.3 },
			secondDecoration: { lineWidth: 1, startAt: 30, radius: 50, fillColor: "blue", color: "red", alpha: 0.15 }
		}
	}
};

CoolClock.prototype = {
	init: function(canvasId,displayRadius,skinId,showSecondHand) {
		this.canvasId = canvasId;
		this.displayRadius = displayRadius || CoolClock.config.defaultRadius;
		this.skinId = skinId || CoolClock.config.defaultSkin;
		this.showSecondHand = typeof showSecondHand == "boolean" ? showSecondHand : true;
		this.tickDelay = CoolClock.config[ this.showSecondHand ? "tickDelay" : "longTickDelay"];

		this.canvas = document.getElementById(canvasId);
		this.canvas.setAttribute("width",this.displayRadius*2);
		this.canvas.setAttribute("height",this.displayRadius*2);

		this.renderRadius = CoolClock.config.renderRadius; 

		var scale = this.displayRadius / this.renderRadius;
		this.ctx = this.canvas.getContext("2d");
		this.ctx.scale(scale,scale);

		CoolClock.config.clockTracker[canvasId] = this;
		this.tick();
		return this;
	},

	fullCircle: function(skin) {
		this.fullCircleAt(this.renderRadius,this.renderRadius,skin);
	},

	fullCircleAt: function(x,y,skin) {
		with (this.ctx) {
			save();
			globalAlpha = skin.alpha;
			lineWidth = skin.lineWidth;
			arc(x, y, skin.radius, 0, 2*Math.PI, false);
			if (skin.fillColor) {
				fillStyle = skin.fillColor
				fill();
			}
			else {
				// XXX why not stroke and fill
				strokeStyle = skin.color;
				stroke();
			}
			restore();
		}
	},

	radialLineAtAngle: function(angleFraction,skin) {
		with (this.ctx) {
			save();
			translate(this.renderRadius,this.renderRadius);
			rotate(Math.PI * (2 * angleFraction - 0.5));
			globalAlpha = skin.alpha;
			strokeStyle = skin.color;
			lineWidth = skin.lineWidth;
			if (skin.radius) {
				this.fullCircleAt(skin.startAt,0,skin)
			}
			else {
				beginPath();
				moveTo(skin.startAt,0)
				lineTo(skin.endAt,0);
				stroke();
			}
			restore();
		}
	},

	render: function(hour,min,sec) {
		var skin = CoolClock.config.skins[this.skinId];
		this.ctx.clearRect(0,0,this.renderRadius*2,this.renderRadius*2);

		this.fullCircle(skin.outerBorder);

		for (var i=0;i<60;i++)
			this.radialLineAtAngle(i/60,skin[ i%5 ? "smallIndicator" : "largeIndicator"]);
				
		this.radialLineAtAngle((hour+min/60)/12,skin.hourHand);
		this.radialLineAtAngle((min+sec/60)/60,skin.minuteHand);
		if (this.showSecondHand) {
			this.radialLineAtAngle(sec/60,skin.secondHand);
			this.radialLineAtAngle(sec/60,skin.secondDecoration);
		}
	},


	nextTick: function() {
		setTimeout("CoolClock.config.clockTracker['"+this.canvasId+"'].tick()",this.tickDelay);
	},

	stillHere: function() {
		return document.getElementById(this.canvasId) != null;
	},

	refreshDisplay: function() {
		var now = new Date();
		this.render(now.getHours(),now.getMinutes(),now.getSeconds());
	},

	tick: function() {
		if (this.stillHere()) {
			this.refreshDisplay()
			this.nextTick();
		}
	}
}



config.macros.clock2 = {
	counter: 0,
	handler: function (place,macroName,params,wikifier,paramString,tiddler) {
		var size,skin,seconds,skinData;
		for (var i=0;i<params.length;i++)
			if (/^\d+$/.exec(params[i]))
				size = params[i];
			else if (params[i] == "noSeconds")
				seconds = false;
			else if (/^\{/.exec(params[i]))
				eval("skinData = " + params[i]);
			else
				skin = params[i];
		if (skinData) {
			CoolClock.config.skins.customSkin = skinData;
			skin = "customSkin";
		}
		var canvas = createTiddlyElement(place,"canvas","clockcanvas"+this.counter);
		var clock = new CoolClock("clockcanvas"+this.counter,size,skin,seconds);
		this.counter++;
	}
}

//}}}
Wrap the document you want to link to in double square brackets e.g. [[Project Overview]]. (You can see the code in the Edit view.)

You can also create a new document using the same technique.
!How to create a new document
*Create a new document by clicking on this button: ''<<newTiddler>>'' (also on the Top Menu)
**NB ''First create a new document title.''
!How to edit a document later on
*''Double-click'' to open a document - or use the menu at the top right of the notepad window where it says ''edit''
!How can I find my documents?
*Use the ''Search'' panel or the ''timeline'' ir the ''A-Z'' listing labelled ''All''
!How can I clear the screen of all documents except the one I am reading?
Click on the ''close others'' button - try it!
----
Click on ''Home'' to get back to the opening page and clear the screen.
----
[[Welcome]]
[[Project Overview]]
<<forEachTiddler>>
/***
|''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.
***/

Cick on DefaultTiddlers.
Add or change the order of the list. Each entry in the Default Tiddlers page loads automatically when you first start the Wiki or when you click on the Home button.
On ons 19 maj 2010 08:01:01 CET,  imported 4 tiddlers from
[[http://beginners.tiddlyspot.com/|http://beginners.tiddlyspot.com/]]:
<<<
#[[LoadRemoteFileThroughProxy]] - added
#[[PasswordOptionsPlugin]] - added
#[[TspotSetupPlugin]] - added
#[[UploadPlugin]] - added
<<<
/***
|''Name:''|LoadRemoteFileThroughProxy (previous LoadRemoteFileHijack)|
|''Description:''|When the TiddlyWiki file is located on the web (view over http) the content of [[SiteProxy]] tiddler is added in front of the file url. If [[SiteProxy]] does not exist "/proxy/" is added. |
|''Version:''|1.1.0|
|''Date:''|mar 17, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#LoadRemoteFileHijack|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0|
***/
//{{{
version.extensions.LoadRemoteFileThroughProxy = {
 major: 1, minor: 1, revision: 0, 
 date: new Date("mar 17, 2007"), 
 source: "http://tiddlywiki.bidix.info/#LoadRemoteFileThroughProxy"};

if (!window.bidix) window.bidix = {}; // bidix namespace
if (!bidix.core) bidix.core = {};

bidix.core.loadRemoteFile = loadRemoteFile;
loadRemoteFile = function(url,callback,params)
{
 if ((document.location.toString().substr(0,4) == "http") && (url.substr(0,4) == "http")){ 
 url = store.getTiddlerText("SiteProxy", "/proxy/") + url;
 }
 return bidix.core.loadRemoteFile(url,callback,params);
}
//}}}
<html><a href="javascript:;" onclick="story.closeAllTiddlers();restart();" style="font-weight:bold; color:white;">Home </a></html> 
<<newTiddler >> [[download|http://beginners.tiddlyspot.com/download]]
<!--- More ideas shamesslessly begged, borrowed or stolen from..... Simon Baird, Clint Checketts and Christine Hodges :)) --->
<!--{{{-->
<div class='header' macro="gradient vert #5c4894 #6b69ad">
    <div id='topMenu'>
       <span refresh='content' tiddler='SiteTitle'></span>
       <span refresh='content' tiddler='MainMenu'></span></div>
     </div>
</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>
<!--}}}-->
/***
|''Name:''|PasswordOptionPlugin|
|''Description:''|Extends TiddlyWiki options with non encrypted password option.|
|''Version:''|1.0.2|
|''Date:''|Apr 19, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#PasswordOptionPlugin|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0 (Beta 5)|
***/
//{{{
version.extensions.PasswordOptionPlugin = {
	major: 1, minor: 0, revision: 2, 
	date: new Date("Apr 19, 2007"),
	source: 'http://tiddlywiki.bidix.info/#PasswordOptionPlugin',
	author: 'BidiX (BidiX (at) bidix (dot) info',
	license: '[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D]]',
	coreVersion: '2.2.0 (Beta 5)'
};

config.macros.option.passwordCheckboxLabel = "Save this password on this computer";
config.macros.option.passwordInputType = "password"; // password | text
setStylesheet(".pasOptionInput {width: 11em;}\n","passwordInputTypeStyle");

merge(config.macros.option.types, {
	'pas': {
		elementType: "input",
		valueField: "value",
		eventName: "onkeyup",
		className: "pasOptionInput",
		typeValue: config.macros.option.passwordInputType,
		create: function(place,type,opt,className,desc) {
			// password field
			config.macros.option.genericCreate(place,'pas',opt,className,desc);
			// checkbox linked with this password "save this password on this computer"
			config.macros.option.genericCreate(place,'chk','chk'+opt,className,desc);			
			// text savePasswordCheckboxLabel
			place.appendChild(document.createTextNode(config.macros.option.passwordCheckboxLabel));
		},
		onChange: config.macros.option.genericOnChange
	}
});

merge(config.optionHandlers['chk'], {
	get: function(name) {
		// is there an option linked with this chk ?
		var opt = name.substr(3);
		if (config.options[opt]) 
			saveOptionCookie(opt);
		return config.options[name] ? "true" : "false";
	}
});

merge(config.optionHandlers, {
	'pas': {
 		get: function(name) {
			if (config.options["chk"+name]) {
				return encodeCookie(config.options[name].toString());
			} else {
				return "";
			}
		},
		set: function(name,value) {config.options[name] = decodeCookie(value);}
	}
});

// need to reload options to load passwordOptions
loadOptionsCookie();

/*
if (!config.options['pasPassword'])
	config.options['pasPassword'] = '';

merge(config.optionsDesc,{
		pasPassword: "Test password"
	});
*/
//}}}
!Things to do
<<forEachTiddler  where 'tiddler.tags.contains("ToDo")'  sortBy  'tiddler.title'>>
<<calendar  tag:'ToDo'>>
#''Timeline'' (on the right side bar) for a list of all then documents you have created
#''All'' is an A-Z document list (ignore the system files)
#Create a ''tag'' (in the space at the bottom of this "tiddler" when in Edit mode) to index your documents and do clever things later on
#''Close all'' (at the top of the tiddler - to close all documents except the one you are viewing
#''Home'' to get back to where you started
#Create a ToDo list using the calendar - click on a date
<<search>>
<<slider chkSliderToolsPanel SidebarTools '» Tools »' 'New tiddler, save changes etc..'>><<slider chkSliderOptionsPanel OptionsPanel '» Options »' 'Change TiddlyWiki advanced options'>>
<<closeAll>>
<<permaview>>
<<newTiddler>>
<<newJournal 'DD MMM YYYY'>>
<<saveChanges>>
and project management wiki.
<html><h2 style="font-weight:bold; color:white;">My Notebook</h2></html> 
/*{{{*/
.toolbar{float:right;}^
.toolbar .tiddlyLinkExisting{font-weight:normal;}
.toolbar{visibility:hidden;}
.selected .toolbar{visibility:visible;}
.tiddler {background: #fff;border-bottom: 2px solid #A7A7A7; border-top: 2px solid #A7A7A7; margin-bottom:10px;}
.headerForeground { display: none;}
#sidebar {width: 170px; background: #efefef;border-left: solid 2px #b8b9c7;border-top: solid 2px #d7d8e8;}
#sidebarTabs .tabContents {width: 158px; background: #eae9ee;font-weight: bold; color: #333 ;}
#sidebarOptions input { border: solid 2px #b8b9c7; }
#sidebarOptions .sliderPanel { background: #eee;}
#sidebarOptions a {;border: none;}
#sidebarOptions .sliderPanel a {border: none;color: #5c4894;}
#displayArea {margin: 1em 15.7em 0em 1em;border-left: solid 2px #b8b9c7;}
.viewer {line-height: 1.4em;padding-bottom: 1em;}
.viewer th, thead td {background: #5d4b97;border: 1px solid #666;color: #fff;}
.viewer .calendarHolder  {margin:15px;float:left; clear:right;}
.title {color: #000}
h1,h2,h3,h4,h5 {color: #fff;background: #6b69ad;}
a{ color: #700126;}
a:hover{ background: #6b69ad; color: #fff;font-weight: bold;}
.externalLink {	text-decoration: underline; color: #000083;}
body {	background: #d7d8e8;}
.popup { background: #6b69ad; border: 1px solid #04b;}
.popup li a:hover {background: #d7d8e8;color: #000;border: none;}
.popup li.disabled {color: #000;}
.button:hover {color: #fff;background: #6b69ad;
	border: 1px solid #d7d8e8;}
#topMenu { background: transparent; padding: 6px;margin-left: -5px;border-bottom: solid 3px  #5c4894;}
#topMenu .button,  #topMenu .tiddlyLink, tiddlyLinkExisting, #topMenu .externalLink
{
	color: #fff;
	text-align: center;
	font-weight: bold;
	font-size: 1.1em;
	text-decoration: none;
	letter-spacing: 1.5px;
	background: transparent;
	border-right: solid 1px #fff;
        padding: 5px 15px 8px 15px;
}
#topMenu a:hover {
	color: #700126;
	background: #d7d8e8;
}
#topMenu br {display: none; padding-right: 1em;}
#topMenu span .tiddlyLinkNonExisting {font-style:normal;}

/*}}}*/
/***
Description: Contains the stuff you need to use Tiddlyspot
Note, you also need UploadPlugin, PasswordOptionPlugin and LoadRemoteFileThroughProxy
from http://tiddlywiki.bidix.info for a complete working Tiddlyspot site.
***/
//{{{

// edit this if you are migrating sites or retrofitting an existing TW
config.tiddlyspotSiteId = 'beginners';

// make it so you can by default see edit controls via http
config.options.chkHttpReadOnly = false;
window.readOnly = false; // make sure of it (for tw 2.2)
window.showBackstage = true; // show backstage too

// disable autosave in d3
if (window.location.protocol != "file:")
	config.options.chkGTDLazyAutoSave = false;

// tweak shadow tiddlers to add upload button, password entry box etc
with (config.shadowTiddlers) {
	SiteUrl = 'http://'+config.tiddlyspotSiteId+'.tiddlyspot.com';
	SideBarOptions = SideBarOptions.replace(/(<<saveChanges>>)/,"$1<<tiddler TspotSidebar>>");
	OptionsPanel = OptionsPanel.replace(/^/,"<<tiddler TspotOptions>>");
	DefaultTiddlers = DefaultTiddlers.replace(/^/,"[[WelcomeToTiddlyspot]] ");
	MainMenu = MainMenu.replace(/^/,"[[WelcomeToTiddlyspot]] ");
}

// create some shadow tiddler content
merge(config.shadowTiddlers,{

'TspotOptions':[
 "tiddlyspot password:",
 "<<option pasUploadPassword>>",
 ""
].join("\n"),

'TspotControls':[
 "| tiddlyspot password:|<<option pasUploadPassword>>|",
 "| site management:|<<upload http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/store.cgi index.html . .  " + config.tiddlyspotSiteId + ">>//(requires tiddlyspot password)//<br>[[control panel|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/controlpanel]], [[download (go offline)|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/download]]|",
 "| links:|[[tiddlyspot.com|http://tiddlyspot.com/]], [[FAQs|http://faq.tiddlyspot.com/]], [[blog|http://tiddlyspot.blogspot.com/]], email [[support|mailto:support@tiddlyspot.com]] & [[feedback|mailto:feedback@tiddlyspot.com]], [[donate|http://tiddlyspot.com/?page=donate]]|"
].join("\n"),

'WelcomeToTiddlyspot':[
 "This document is a ~TiddlyWiki from tiddlyspot.com.  A ~TiddlyWiki is an electronic notebook that is great for managing todo lists, personal information, and all sorts of things.",
 "",
 "@@font-weight:bold;font-size:1.3em;color:#444; //What now?// &nbsp;&nbsp;@@ Before you can save any changes, you need to enter your password in the form below.  Then configure privacy and other site settings at your [[control panel|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/controlpanel]] (your control panel username is //" + config.tiddlyspotSiteId + "//).",
 "<<tiddler TspotControls>>",
 "See also GettingStarted.",
 "",
 "@@font-weight:bold;font-size:1.3em;color:#444; //Working online// &nbsp;&nbsp;@@ You can edit this ~TiddlyWiki right now, and save your changes using the \"save to web\" button in the column on the right.",
 "",
 "@@font-weight:bold;font-size:1.3em;color:#444; //Working offline// &nbsp;&nbsp;@@ A fully functioning copy of this ~TiddlyWiki can be saved onto your hard drive or USB stick.  You can make changes and save them locally without being connected to the Internet.  When you're ready to sync up again, just click \"upload\" and your ~TiddlyWiki will be saved back to tiddlyspot.com.",
 "",
 "@@font-weight:bold;font-size:1.3em;color:#444; //Help!// &nbsp;&nbsp;@@ Find out more about ~TiddlyWiki at [[TiddlyWiki.com|http://tiddlywiki.com]].  Also visit [[TiddlyWiki.org|http://tiddlywiki.org]] for documentation on learning and using ~TiddlyWiki. New users are especially welcome on the [[TiddlyWiki mailing list|http://groups.google.com/group/TiddlyWiki]], which is an excellent place to ask questions and get help.  If you have a tiddlyspot related problem email [[tiddlyspot support|mailto:support@tiddlyspot.com]].",
 "",
 "@@font-weight:bold;font-size:1.3em;color:#444; //Enjoy :)// &nbsp;&nbsp;@@ We hope you like using your tiddlyspot.com site.  Please email [[feedback@tiddlyspot.com|mailto:feedback@tiddlyspot.com]] with any comments or suggestions."
].join("\n"),

'TspotSidebar':[
 "<<upload http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/store.cgi index.html . .  " + config.tiddlyspotSiteId + ">><html><a href='http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/download' class='button'>download</a></html>"
].join("\n")

});
//}}}
| 19/05/2010 08:25:08 |  | [[/|http://beginners.tiddlyspot.com/]] | [[store.php|http://beginners.tiddlyspot.com/store.php]] | . | [[index.html | http://beginners.tiddlyspot.com/index.html]] | backup |
| 19/05/2010 08:25:35 |  | [[/|http://beginners.tiddlyspot.com/]] | [[store.cgi|http://beginners.tiddlyspot.com/store.cgi]] | . | [[index.html | http://beginners.tiddlyspot.com/index.html]] | backup |
/***
|''Name:''|UploadPlugin|
|''Description:''|Save to web a TiddlyWiki|
|''Version:''|4.1.3|
|''Date:''|Feb 24, 2008|
|''Source:''|http://tiddlywiki.bidix.info/#UploadPlugin|
|''Documentation:''|http://tiddlywiki.bidix.info/#UploadPluginDoc|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0|
|''Requires:''|PasswordOptionPlugin|
***/
//{{{
version.extensions.UploadPlugin = {
	major: 4, minor: 1, revision: 3,
	date: new Date("Feb 24, 2008"),
	source: 'http://tiddlywiki.bidix.info/#UploadPlugin',
	author: 'BidiX (BidiX (at) bidix (dot) info',
	coreVersion: '2.2.0'
};

//
// Environment
//

if (!window.bidix) window.bidix = {}; // bidix namespace
bidix.debugMode = false;	// true to activate both in Plugin and UploadService
	
//
// Upload Macro
//

config.macros.upload = {
// default values
	defaultBackupDir: '',	//no backup
	defaultStoreScript: "store.php",
	defaultToFilename: "index.html",
	defaultUploadDir: ".",
	authenticateUser: true	// UploadService Authenticate User
};
	
config.macros.upload.label = {
	promptOption: "Save and Upload this TiddlyWiki with UploadOptions",
	promptParamMacro: "Save and Upload this TiddlyWiki in %0",
	saveLabel: "save to web", 
	saveToDisk: "save to disk",
	uploadLabel: "upload"	
};

config.macros.upload.messages = {
	noStoreUrl: "No store URL in parmeters or options",
	usernameOrPasswordMissing: "Username or password missing"
};

config.macros.upload.handler = function(place,macroName,params) {
	if (readOnly)
		return;
	var label;
	if (document.location.toString().substr(0,4) == "http") 
		label = this.label.saveLabel;
	else
		label = this.label.uploadLabel;
	var prompt;
	if (params[0]) {
		prompt = this.label.promptParamMacro.toString().format([this.destFile(params[0], 
			(params[1] ? params[1]:bidix.basename(window.location.toString())), params[3])]);
	} else {
		prompt = this.label.promptOption;
	}
	createTiddlyButton(place, label, prompt, function() {config.macros.upload.action(params);}, null, null, this.accessKey);
};

config.macros.upload.action = function(params)
{
		// for missing macro parameter set value from options
		if (!params) params = {};
		var storeUrl = params[0] ? params[0] : config.options.txtUploadStoreUrl;
		var toFilename = params[1] ? params[1] : config.options.txtUploadFilename;
		var backupDir = params[2] ? params[2] : config.options.txtUploadBackupDir;
		var uploadDir = params[3] ? params[3] : config.options.txtUploadDir;
		var username = params[4] ? params[4] : config.options.txtUploadUserName;
		var password = config.options.pasUploadPassword; // for security reason no password as macro parameter	
		// for still missing parameter set default value
		if ((!storeUrl) && (document.location.toString().substr(0,4) == "http")) 
			storeUrl = bidix.dirname(document.location.toString())+'/'+config.macros.upload.defaultStoreScript;
		if (storeUrl.substr(0,4) != "http")
			storeUrl = bidix.dirname(document.location.toString()) +'/'+ storeUrl;
		if (!toFilename)
			toFilename = bidix.basename(window.location.toString());
		if (!toFilename)
			toFilename = config.macros.upload.defaultToFilename;
		if (!uploadDir)
			uploadDir = config.macros.upload.defaultUploadDir;
		if (!backupDir)
			backupDir = config.macros.upload.defaultBackupDir;
		// report error if still missing
		if (!storeUrl) {
			alert(config.macros.upload.messages.noStoreUrl);
			clearMessage();
			return false;
		}
		if (config.macros.upload.authenticateUser && (!username || !password)) {
			alert(config.macros.upload.messages.usernameOrPasswordMissing);
			clearMessage();
			return false;
		}
		bidix.upload.uploadChanges(false,null,storeUrl, toFilename, uploadDir, backupDir, username, password); 
		return false; 
};

config.macros.upload.destFile = function(storeUrl, toFilename, uploadDir) 
{
	if (!storeUrl)
		return null;
		var dest = bidix.dirname(storeUrl);
		if (uploadDir && uploadDir != '.')
			dest = dest + '/' + uploadDir;
		dest = dest + '/' + toFilename;
	return dest;
};

//
// uploadOptions Macro
//

config.macros.uploadOptions = {
	handler: function(place,macroName,params) {
		var wizard = new Wizard();
		wizard.createWizard(place,this.wizardTitle);
		wizard.addStep(this.step1Title,this.step1Html);
		var markList = wizard.getElement("markList");
		var listWrapper = document.createElement("div");
		markList.parentNode.insertBefore(listWrapper,markList);
		wizard.setValue("listWrapper",listWrapper);
		this.refreshOptions(listWrapper,false);
		var uploadCaption;
		if (document.location.toString().substr(0,4) == "http") 
			uploadCaption = config.macros.upload.label.saveLabel;
		else
			uploadCaption = config.macros.upload.label.uploadLabel;
		
		wizard.setButtons([
				{caption: uploadCaption, tooltip: config.macros.upload.label.promptOption, 
					onClick: config.macros.upload.action},
				{caption: this.cancelButton, tooltip: this.cancelButtonPrompt, onClick: this.onCancel}
				
			]);
	},
	options: [
		"txtUploadUserName",
		"pasUploadPassword",
		"txtUploadStoreUrl",
		"txtUploadDir",
		"txtUploadFilename",
		"txtUploadBackupDir",
		"chkUploadLog",
		"txtUploadLogMaxLine"		
	],
	refreshOptions: function(listWrapper) {
		var opts = [];
		for(i=0; i<this.options.length; i++) {
			var opt = {};
			opts.push();
			opt.option = "";
			n = this.options[i];
			opt.name = n;
			opt.lowlight = !config.optionsDesc[n];
			opt.description = opt.lowlight ? this.unknownDescription : config.optionsDesc[n];
			opts.push(opt);
		}
		var listview = ListView.create(listWrapper,opts,this.listViewTemplate);
		for(n=0; n<opts.length; n++) {
			var type = opts[n].name.substr(0,3);
			var h = config.macros.option.types[type];
			if (h && h.create) {
				h.create(opts[n].colElements['option'],type,opts[n].name,opts[n].name,"no");
			}
		}
		
	},
	onCancel: function(e)
	{
		backstage.switchTab(null);
		return false;
	},
	
	wizardTitle: "Upload with options",
	step1Title: "These options are saved in cookies in your browser",
	step1Html: "<input type='hidden' name='markList'></input><br>",
	cancelButton: "Cancel",
	cancelButtonPrompt: "Cancel prompt",
	listViewTemplate: {
		columns: [
			{name: 'Description', field: 'description', title: "Description", type: 'WikiText'},
			{name: 'Option', field: 'option', title: "Option", type: 'String'},
			{name: 'Name', field: 'name', title: "Name", type: 'String'}
			],
		rowClasses: [
			{className: 'lowlight', field: 'lowlight'} 
			]}
};

//
// upload functions
//

if (!bidix.upload) bidix.upload = {};

if (!bidix.upload.messages) bidix.upload.messages = {
	//from saving
	invalidFileError: "The original file '%0' does not appear to be a valid TiddlyWiki",
	backupSaved: "Backup saved",
	backupFailed: "Failed to upload backup file",
	rssSaved: "RSS feed uploaded",
	rssFailed: "Failed to upload RSS feed file",
	emptySaved: "Empty template uploaded",
	emptyFailed: "Failed to upload empty template file",
	mainSaved: "Main TiddlyWiki file uploaded",
	mainFailed: "Failed to upload main TiddlyWiki file. Your changes have not been saved",
	//specific upload
	loadOriginalHttpPostError: "Can't get original file",
	aboutToSaveOnHttpPost: 'About to upload on %0 ...',
	storePhpNotFound: "The store script '%0' was not found."
};

bidix.upload.uploadChanges = function(onlyIfDirty,tiddlers,storeUrl,toFilename,uploadDir,backupDir,username,password)
{
	var callback = function(status,uploadParams,original,url,xhr) {
		if (!status) {
			displayMessage(bidix.upload.messages.loadOriginalHttpPostError);
			return;
		}
		if (bidix.debugMode) 
			alert(original.substr(0,500)+"\n...");
		// Locate the storeArea div's 
		var posDiv = locateStoreArea(original);
		if((posDiv[0] == -1) || (posDiv[1] == -1)) {
			alert(config.messages.invalidFileError.format([localPath]));
			return;
		}
		bidix.upload.uploadRss(uploadParams,original,posDiv);
	};
	
	if(onlyIfDirty && !store.isDirty())
		return;
	clearMessage();
	// save on localdisk ?
	if (document.location.toString().substr(0,4) == "file") {
		var path = document.location.toString();
		var localPath = getLocalPath(path);
		saveChanges();
	}
	// get original
	var uploadParams = new Array(storeUrl,toFilename,uploadDir,backupDir,username,password);
	var originalPath = document.location.toString();
	// If url is a directory : add index.html
	if (originalPath.charAt(originalPath.length-1) == "/")
		originalPath = originalPath + "index.html";
	var dest = config.macros.upload.destFile(storeUrl,toFilename,uploadDir);
	var log = new bidix.UploadLog();
	log.startUpload(storeUrl, dest, uploadDir,  backupDir);
	displayMessage(bidix.upload.messages.aboutToSaveOnHttpPost.format([dest]));
	if (bidix.debugMode) 
		alert("about to execute Http - GET on "+originalPath);
	var r = doHttp("GET",originalPath,null,null,username,password,callback,uploadParams,null);
	if (typeof r == "string")
		displayMessage(r);
	return r;
};

bidix.upload.uploadRss = function(uploadParams,original,posDiv) 
{
	var callback = function(status,params,responseText,url,xhr) {
		if(status) {
			var destfile = responseText.substring(responseText.indexOf("destfile:")+9,responseText.indexOf("\n", responseText.indexOf("destfile:")));
			displayMessage(bidix.upload.messages.rssSaved,bidix.dirname(url)+'/'+destfile);
			bidix.upload.uploadMain(params[0],params[1],params[2]);
		} else {
			displayMessage(bidix.upload.messages.rssFailed);			
		}
	};
	// do uploadRss
	if(config.options.chkGenerateAnRssFeed) {
		var rssPath = uploadParams[1].substr(0,uploadParams[1].lastIndexOf(".")) + ".xml";
		var rssUploadParams = new Array(uploadParams[0],rssPath,uploadParams[2],'',uploadParams[4],uploadParams[5]);
		var rssString = generateRss();
		// no UnicodeToUTF8 conversion needed when location is "file" !!!
		if (document.location.toString().substr(0,4) != "file")
			rssString = convertUnicodeToUTF8(rssString);	
		bidix.upload.httpUpload(rssUploadParams,rssString,callback,Array(uploadParams,original,posDiv));
	} else {
		bidix.upload.uploadMain(uploadParams,original,posDiv);
	}
};

bidix.upload.uploadMain = function(uploadParams,original,posDiv) 
{
	var callback = function(status,params,responseText,url,xhr) {
		var log = new bidix.UploadLog();
		if(status) {
			// if backupDir specified
			if ((params[3]) && (responseText.indexOf("backupfile:") > -1))  {
				var backupfile = responseText.substring(responseText.indexOf("backupfile:")+11,responseText.indexOf("\n", responseText.indexOf("backupfile:")));
				displayMessage(bidix.upload.messages.backupSaved,bidix.dirname(url)+'/'+backupfile);
			}
			var destfile = responseText.substring(responseText.indexOf("destfile:")+9,responseText.indexOf("\n", responseText.indexOf("destfile:")));
			displayMessage(bidix.upload.messages.mainSaved,bidix.dirname(url)+'/'+destfile);
			store.setDirty(false);
			log.endUpload("ok");
		} else {
			alert(bidix.upload.messages.mainFailed);
			displayMessage(bidix.upload.messages.mainFailed);
			log.endUpload("failed");			
		}
	};
	// do uploadMain
	var revised = bidix.upload.updateOriginal(original,posDiv);
	bidix.upload.httpUpload(uploadParams,revised,callback,uploadParams);
};

bidix.upload.httpUpload = function(uploadParams,data,callback,params)
{
	var localCallback = function(status,params,responseText,url,xhr) {
		url = (url.indexOf("nocache=") < 0 ? url : url.substring(0,url.indexOf("nocache=")-1));
		if (xhr.status == 404)
			alert(bidix.upload.messages.storePhpNotFound.format([url]));
		if ((bidix.debugMode) || (responseText.indexOf("Debug mode") >= 0 )) {
			alert(responseText);
			if (responseText.indexOf("Debug mode") >= 0 )
				responseText = responseText.substring(responseText.indexOf("\n\n")+2);
		} else if (responseText.charAt(0) != '0') 
			alert(responseText);
		if (responseText.charAt(0) != '0')
			status = null;
		callback(status,params,responseText,url,xhr);
	};
	// do httpUpload
	var boundary = "---------------------------"+"AaB03x";	
	var uploadFormName = "UploadPlugin";
	// compose headers data
	var sheader = "";
	sheader += "--" + boundary + "\r\nContent-disposition: form-data; name=\"";
	sheader += uploadFormName +"\"\r\n\r\n";
	sheader += "backupDir="+uploadParams[3] +
				";user=" + uploadParams[4] +
				";password=" + uploadParams[5] +
				";uploaddir=" + uploadParams[2];
	if (bidix.debugMode)
		sheader += ";debug=1";
	sheader += ";;\r\n"; 
	sheader += "\r\n" + "--" + boundary + "\r\n";
	sheader += "Content-disposition: form-data; name=\"userfile\"; filename=\""+uploadParams[1]+"\"\r\n";
	sheader += "Content-Type: text/html;charset=UTF-8" + "\r\n";
	sheader += "Content-Length: " + data.length + "\r\n\r\n";
	// compose trailer data
	var strailer = new String();
	strailer = "\r\n--" + boundary + "--\r\n";
	data = sheader + data + strailer;
	if (bidix.debugMode) alert("about to execute Http - POST on "+uploadParams[0]+"\n with \n"+data.substr(0,500)+ " ... ");
	var r = doHttp("POST",uploadParams[0],data,"multipart/form-data; ;charset=UTF-8; boundary="+boundary,uploadParams[4],uploadParams[5],localCallback,params,null);
	if (typeof r == "string")
		displayMessage(r);
	return r;
};

// same as Saving's updateOriginal but without convertUnicodeToUTF8 calls
bidix.upload.updateOriginal = function(original, posDiv)
{
	if (!posDiv)
		posDiv = locateStoreArea(original);
	if((posDiv[0] == -1) || (posDiv[1] == -1)) {
		alert(config.messages.invalidFileError.format([localPath]));
		return;
	}
	var revised = original.substr(0,posDiv[0] + startSaveArea.length) + "\n" +
				store.allTiddlersAsHtml() + "\n" +
				original.substr(posDiv[1]);
	var newSiteTitle = getPageTitle().htmlEncode();
	revised = revised.replaceChunk("<title"+">","</title"+">"," " + newSiteTitle + " ");
	revised = updateMarkupBlock(revised,"PRE-HEAD","MarkupPreHead");
	revised = updateMarkupBlock(revised,"POST-HEAD","MarkupPostHead");
	revised = updateMarkupBlock(revised,"PRE-BODY","MarkupPreBody");
	revised = updateMarkupBlock(revised,"POST-SCRIPT","MarkupPostBody");
	return revised;
};

//
// UploadLog
// 
// config.options.chkUploadLog :
//		false : no logging
//		true : logging
// config.options.txtUploadLogMaxLine :
//		-1 : no limit
//      0 :  no Log lines but UploadLog is still in place
//		n :  the last n lines are only kept
//		NaN : no limit (-1)

bidix.UploadLog = function() {
	if (!config.options.chkUploadLog) 
		return; // this.tiddler = null
	this.tiddler = store.getTiddler("UploadLog");
	if (!this.tiddler) {
		this.tiddler = new Tiddler();
		this.tiddler.title = "UploadLog";
		this.tiddler.text = "| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |";
		this.tiddler.created = new Date();
		this.tiddler.modifier = config.options.txtUserName;
		this.tiddler.modified = new Date();
		store.addTiddler(this.tiddler);
	}
	return this;
};

bidix.UploadLog.prototype.addText = function(text) {
	if (!this.tiddler)
		return;
	// retrieve maxLine when we need it
	var maxLine = parseInt(config.options.txtUploadLogMaxLine,10);
	if (isNaN(maxLine))
		maxLine = -1;
	// add text
	if (maxLine != 0) 
		this.tiddler.text = this.tiddler.text + text;
	// Trunck to maxLine
	if (maxLine >= 0) {
		var textArray = this.tiddler.text.split('\n');
		if (textArray.length > maxLine + 1)
			textArray.splice(1,textArray.length-1-maxLine);
			this.tiddler.text = textArray.join('\n');		
	}
	// update tiddler fields
	this.tiddler.modifier = config.options.txtUserName;
	this.tiddler.modified = new Date();
	store.addTiddler(this.tiddler);
	// refresh and notifiy for immediate update
	story.refreshTiddler(this.tiddler.title);
	store.notify(this.tiddler.title, true);
};

bidix.UploadLog.prototype.startUpload = function(storeUrl, toFilename, uploadDir,  backupDir) {
	if (!this.tiddler)
		return;
	var now = new Date();
	var text = "\n| ";
	var filename = bidix.basename(document.location.toString());
	if (!filename) filename = '/';
	text += now.formatString("0DD/0MM/YYYY 0hh:0mm:0ss") +" | ";
	text += config.options.txtUserName + " | ";
	text += "[["+filename+"|"+location + "]] |";
	text += " [[" + bidix.basename(storeUrl) + "|" + storeUrl + "]] | ";
	text += uploadDir + " | ";
	text += "[[" + bidix.basename(toFilename) + " | " +toFilename + "]] | ";
	text += backupDir + " |";
	this.addText(text);
};

bidix.UploadLog.prototype.endUpload = function(status) {
	if (!this.tiddler)
		return;
	this.addText(" "+status+" |");
};

//
// Utilities
// 

bidix.checkPlugin = function(plugin, major, minor, revision) {
	var ext = version.extensions[plugin];
	if (!
		(ext  && 
			((ext.major > major) || 
			((ext.major == major) && (ext.minor > minor))  ||
			((ext.major == major) && (ext.minor == minor) && (ext.revision >= revision))))) {
			// write error in PluginManager
			if (pluginInfo)
				pluginInfo.log.push("Requires " + plugin + " " + major + "." + minor + "." + revision);
			eval(plugin); // generate an error : "Error: ReferenceError: xxxx is not defined"
	}
};

bidix.dirname = function(filePath) {
	if (!filePath) 
		return;
	var lastpos;
	if ((lastpos = filePath.lastIndexOf("/")) != -1) {
		return filePath.substring(0, lastpos);
	} else {
		return filePath.substring(0, filePath.lastIndexOf("\\"));
	}
};

bidix.basename = function(filePath) {
	if (!filePath) 
		return;
	var lastpos;
	if ((lastpos = filePath.lastIndexOf("#")) != -1) 
		filePath = filePath.substring(0, lastpos);
	if ((lastpos = filePath.lastIndexOf("/")) != -1) {
		return filePath.substring(lastpos + 1);
	} else
		return filePath.substring(filePath.lastIndexOf("\\")+1);
};

bidix.initOption = function(name,value) {
	if (!config.options[name])
		config.options[name] = value;
};

//
// Initializations
//

// require PasswordOptionPlugin 1.0.1 or better
bidix.checkPlugin("PasswordOptionPlugin", 1, 0, 1);

// styleSheet
setStylesheet('.txtUploadStoreUrl, .txtUploadBackupDir, .txtUploadDir {width: 22em;}',"uploadPluginStyles");

//optionsDesc
merge(config.optionsDesc,{
	txtUploadStoreUrl: "Url of the UploadService script (default: store.php)",
	txtUploadFilename: "Filename of the uploaded file (default: in index.html)",
	txtUploadDir: "Relative Directory where to store the file (default: . (downloadService directory))",
	txtUploadBackupDir: "Relative Directory where to backup the file. If empty no backup. (default: ''(empty))",
	txtUploadUserName: "Upload Username",
	pasUploadPassword: "Upload Password",
	chkUploadLog: "do Logging in UploadLog (default: true)",
	txtUploadLogMaxLine: "Maximum of lines in UploadLog (default: 10)"
});

// Options Initializations
bidix.initOption('txtUploadStoreUrl','');
bidix.initOption('txtUploadFilename','');
bidix.initOption('txtUploadDir','');
bidix.initOption('txtUploadBackupDir','');
bidix.initOption('txtUploadUserName','');
bidix.initOption('pasUploadPassword','');
bidix.initOption('chkUploadLog',true);
bidix.initOption('txtUploadLogMaxLine','10');


// Backstage
merge(config.tasks,{
	uploadOptions: {text: "upload", tooltip: "Change UploadOptions and Upload", content: '<<uploadOptions>>'}
});
config.backstageTasks.push("uploadOptions");


//}}}

<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::ViewToolbar]]'></div>
<div class='title' macro='view title'></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>
<!--}}}-->
config.options.chkInsertTabs = true; // tab inserts a tab when editing a tiddler
config.options.chkAnimate = false; // default true
config.options.txtUserName = ""; // default "YourName"
config.options.chkSaveBackups = false; // default true
config.options.chkAutoSave = true; // default false
config.options.chkSaveEmptyTemplate = false; // default false
config.options.txtBackupFolder = "backup"; // default ""
config.options.txtMaxEditRows = "70"; // default "50"
This is your personal wiki notepad where you can store ''notes'', ''images'', ''web site links'' and ''email links'' that will launch your default email program. The original program notes are here: http://www.tiddlywiki.com.

#Enter your username for signing your edits: <<option txtUserName>>
#[[Create new documents|CreateDocument]]
#[[Quick Start]]
#[[How to create auto-start items]]
#[[Create links to other documents]]
#Change the site [[Title|SiteTitle]] and [[Subtitle|SiteSubtitle]]
/***
|''Name:''|YourSearchPlugin|
|''Version:''|2.1.1 (2007-03-11)|
|''Source:''|http://tiddlywiki.abego-software.de/#YourSearchPlugin ([[del.icio.us|http://del.icio.us/post?url=http://tiddlywiki.abego-software.de/index.html%23YourSearchPlugin]])|
|''Author:''|UdoBorkowski (ub [at] abego-software [dot] de)|
|''Licence:''|[[BSD open source license (abego Software)|http://www.abego-software.de/legal/apl-v10.html]]|
|''Copyright:''|&copy; 2005-2006 [[abego Software|http://www.abego-software.de]]|
|''~CoreVersion:''|2.1.0|
|''Browser:''|Firefox 1.0.4+; Firefox 1.5; ~InternetExplorer 6.0|
!About YourSearch
YourSearch gives you a bunch of new features to simplify and speed up your daily searches in TiddlyWiki. It seamlessly integrates into the standard TiddlyWiki search: just start typing into the 'search' field and explore!

For more information see [[Help|YourSearch Help]].
!Compatibility
This plugin requires TiddlyWiki 2.1. 
Check the [[archive|http://tiddlywiki.abego-software.de/archive]] for ~YourSearchPlugins supporting older versions of TiddlyWiki.
!Source Code
***/
/***
This plugin's source code is compressed (and hidden). Use this [[link|http://tiddlywiki.abego-software.de/archive/YourSearchPlugin/Plugin-YourSearch-src.2.1.1.js]] to get the readable source code.
***/
///%
if(!version.extensions.YourSearchPlugin){version.extensions.YourSearchPlugin={major:2,minor:1,revision:1,source:"http://tiddlywiki.abego-software.de/#YourSearchPlugin",licence:"[[BSD open source license (abego Software)|http://www.abego-software.de/legal/apl-v10.html]]",copyright:"Copyright (c) abego Software GmbH, 2005-2007 (www.abego-software.de)"};if(!window.abego){window.abego={};}if(!Array.forEach){Array.forEach=function(_1,_2,_3){for(var i=0,len=_1.length;i<len;i++){_2.call(_3,_1[i],i,_1);}};Array.prototype.forEach=function(_5,_6){for(var i=0,len=this.length;i<len;i++){_5.call(_6,this[i],i,this);}};}abego.toInt=function(s,_9){if(!s){return _9;}var n=parseInt(s);return (n==NaN)?_9:n;};abego.createEllipsis=function(_b){var e=createTiddlyElement(_b,"span");e.innerHTML="&hellip;";};abego.shallowCopy=function(_d){if(!_d){return _d;}var _e={};for(var n in _d){_e[n]=_d[n];}return _e;};abego.copyOptions=function(_10){return !_10?{}:abego.shallowCopy(_10);};abego.countStrings=function(_11,s){if(!s){return 0;}var len=s.length;var n=0;var _15=0;while(1){var i=_11.indexOf(s,_15);if(i<0){return n;}n++;_15=i+len;}return n;};abego.getBracedText=function(_17,_18,_19){if(!_18){_18=0;}var re=/\{([^\}]*)\}/gm;re.lastIndex=_18;var m=re.exec(_17);if(m){var s=m[1];var _1d=abego.countStrings(s,"{");if(!_1d){if(_19){_19.lastIndex=re.lastIndex;}return s;}var len=_17.length;for(var i=re.lastIndex;i<len&&_1d;i++){var c=_17.charAt(i);if(c=="{"){_1d++;}else{if(c=="}"){_1d--;}}}if(!_1d){if(_19){_19.lastIndex=i-1;}return _17.substring(m.index+1,i-1);}}};abego.select=function(_21,_22,_23,_24){if(!_24){_24=[];}_21.forEach(function(t){if(_22.call(_23,t)){_24.push(t);}});return _24;};abego.TiddlerFilterTerm=function(_26,_27){if(!_27){_27={};}var _28=_26;if(!_27.textIsRegExp){_28=_26.escapeRegExp();if(_27.fullWordMatch){_28="\\b"+_28+"\\b";}}var _29=new RegExp(_28,"m"+(_27.caseSensitive?"":"i"));this.tester=new abego.MultiFieldRegExpTester(_29,_27.fields,_27.withExtendedFields);};abego.TiddlerFilterTerm.prototype.test=function(_2a){return this.tester.test(_2a);};abego.parseNewTiddlerCommandLine=function(s){var m=/(.*?)\.(?:\s+|$)([^#]*)(#.*)?/.exec(s);if(!m){m=/([^#]*)()(#.*)?/.exec(s);}if(m){var r;if(m[3]){var s2=m[3].replace(/#/g,"");r=s2.parseParams("tag");}else{r=[[]];}var _2f=m[2]?m[2].trim():"";r.push({name:"text",value:_2f});r[0].text=[_2f];return {title:m[1].trim(),params:r};}else{return {title:s.trim(),params:[[]]};}};abego.parseTiddlerFilterTerm=function(_30,_31,_32){var re=/\s*(?:(?:\{([^\}]*)\})|(?:(=)|([#%!])|(?:(\w+)\s*\:(?!\/\/))|(?:(?:("(?:(?:\\")|[^"])+")|(?:\/((?:(?:\\\/)|[^\/])+)\/)|(\w+\:\/\/[^\s]+)|([^\s\)\-\"]+)))))/mg;var _34={"!":"title","%":"text","#":"tags"};var _35={};var _36;re.lastIndex=_31;while(1){var i=re.lastIndex;var m=re.exec(_30);if(!m||m.index!=i){throw "Word or String literal expected";}if(m[1]){var _39={};var _3a=abego.getBracedText(_30,0,_39);if(!_3a){throw "Invalid {...} syntax";}var f=Function("tiddler","return ("+_3a+");");return {func:f,lastIndex:_39.lastIndex,markRE:null};}if(m[2]){_36=true;}else{if(m[3]){_35[_34[m[3]]]=1;}else{if(m[4]){_35[m[4]]=1;}else{var _3c=m[6];var _3d=m[5]?window.eval(m[5]):m[6]?m[6]:m[7]?m[7]:m[8];var _3e=abego.copyOptions(_3e);_3e.fullWordMatch=_36;_3e.textIsRegExp=_3c;var _3f=[];for(var n in _35){_3f.push(n);}if(_3f.length==0){_3e.fields=_3e.defaultFields;}else{_3e.fields=_3f;_3e.withExtendedFields=false;}var _41=new abego.TiddlerFilterTerm(_3d,_3e);var _42=_3c?_3d:_3d.escapeRegExp();if(_42&&_36){_42="\\b"+_42+"\\b";}return {func:function(_43){return _41.test(_43);},lastIndex:re.lastIndex,markRE:_42?"(?:"+_42+")":null};}}}}};abego.BoolExp=function(s,_45,_46){this.s=s;var _47=_46&&_46.defaultOperationIs_OR;var _48=/\s*(?:(\-|not)|(\())/gi;var _49=/\s*\)/g;var _4a=/\s*(?:(and|\&\&)|(or|\|\|))/gi;var _4b=/\s*[^\)\s]/g;var _4c=/\s*(\-|not)?(\s*\()?/gi;var _4d;var _4e=function(_4f){_4c.lastIndex=_4f;var m=_4c.exec(s);var _51;var _52;if(m&&m.index==_4f){_4f=_4c.lastIndex;_51=m[1];if(m[2]){var e=_4d(_4f);_49.lastIndex=e.lastIndex;if(!_49.exec(s)){throw "Missing ')'";}_52={func:e.func,lastIndex:_49.lastIndex,markRE:e.markRE};}}if(!_52){_52=_45(s,_4f,_46);}if(_51){_52.func=(function(f){return function(_55){return !f(_55);};})(_52.func);_52.markRE=null;}return _52;};_4d=function(_56){var _57=_4e(_56);while(1){var l=_57.lastIndex;_4a.lastIndex=l;var m=_4a.exec(s);var _5a;var _5b;if(m&&m.index==l){_5a=!m[1];_5b=_4e(_4a.lastIndex);}else{try{_5b=_4e(l);}catch(e){return _57;}_5a=_47;}_57.func=(function(_5c,_5d,_5e){return _5e?function(_5f){return _5c(_5f)||_5d(_5f);}:function(_60){return _5c(_60)&&_5d(_60);};})(_57.func,_5b.func,_5a);_57.lastIndex=_5b.lastIndex;if(!_57.markRE){_57.markRE=_5b.markRE;}else{if(_5b.markRE){_57.markRE=_57.markRE+"|"+_5b.markRE;}}}};var _61=_4d(0);this.evalFunc=_61.func;if(_61.markRE){this.markRegExp=new RegExp(_61.markRE,_46.caseSensitive?"mg":"img");}};abego.BoolExp.prototype.exec=function(){return this.evalFunc.apply(this,arguments);};abego.BoolExp.prototype.getMarkRegExp=function(){return this.markRegExp;};abego.BoolExp.prototype.toString=function(){return this.s;};abego.MultiFieldRegExpTester=function(re,_63,_64){this.re=re;this.fields=_63?_63:["title","text","tags"];this.withExtendedFields=_64;};abego.MultiFieldRegExpTester.prototype.test=function(_65){var re=this.re;for(var i=0;i<this.fields.length;i++){var s=store.getValue(_65,this.fields[i]);if(typeof s=="string"&&re.test(s)){return this.fields[i];}}if(this.withExtendedFields){return store.forEachField(_65,function(_69,_6a,_6b){return typeof _6b=="string"&&re.test(_6b)?_6a:null;},true);}return null;};abego.TiddlerQuery=function(_6c,_6d,_6e,_6f,_70){if(_6e){this.regExp=new RegExp(_6c,_6d?"mg":"img");this.tester=new abego.MultiFieldRegExpTester(this.regExp,_6f,_70);}else{this.expr=new abego.BoolExp(_6c,abego.parseTiddlerFilterTerm,{defaultFields:_6f,caseSensitive:_6d,withExtendedFields:_70});}this.getQueryText=function(){return _6c;};this.getUseRegExp=function(){return _6e;};this.getCaseSensitive=function(){return _6d;};this.getDefaultFields=function(){return _6f;};this.getWithExtendedFields=function(){return _70;};};abego.TiddlerQuery.prototype.test=function(_71){if(!_71){return false;}if(this.regExp){return this.tester.test(_71);}return this.expr.exec(_71);};abego.TiddlerQuery.prototype.filter=function(_72){return abego.select(_72,this.test,this);};abego.TiddlerQuery.prototype.getMarkRegExp=function(){if(this.regExp){return "".search(this.regExp)>=0?null:this.regExp;}return this.expr.getMarkRegExp();};abego.TiddlerQuery.prototype.toString=function(){return (this.regExp?this.regExp:this.expr).toString();};abego.PageWiseRenderer=function(){this.firstIndexOnPage=0;};merge(abego.PageWiseRenderer.prototype,{setItems:function(_73){this.items=_73;this.setFirstIndexOnPage(0);},getMaxPagesInNavigation:function(){return 10;},getItemsCount:function(_74){return this.items?this.items.length:0;},getCurrentPageIndex:function(){return Math.floor(this.firstIndexOnPage/this.getItemsPerPage());},getLastPageIndex:function(){return Math.floor((this.getItemsCount()-1)/this.getItemsPerPage());},setFirstIndexOnPage:function(_75){this.firstIndexOnPage=Math.min(Math.max(0,_75),this.getItemsCount()-1);},getFirstIndexOnPage:function(){this.firstIndexOnPage=Math.floor(this.firstIndexOnPage/this.getItemsPerPage())*this.getItemsPerPage();return this.firstIndexOnPage;},getLastIndexOnPage:function(){return Math.min(this.getFirstIndexOnPage()+this.getItemsPerPage()-1,this.getItemsCount()-1);},onPageChanged:function(_76,_77){},renderPage:function(_78){if(_78.beginRendering){_78.beginRendering(this);}try{if(this.getItemsCount()){var _79=this.getLastIndexOnPage();var _7a=-1;for(var i=this.getFirstIndexOnPage();i<=_79;i++){_7a++;_78.render(this,this.items[i],i,_7a);}}}finally{if(_78.endRendering){_78.endRendering(this);}}},addPageNavigation:function(_7c){if(!this.getItemsCount()){return;}var _7d=this;var _7e=function(e){if(!e){var e=window.event;}var _81=abego.toInt(this.getAttribute("page"),0);var _82=_7d.getCurrentPageIndex();if(_81==_82){return;}var _83=_81*_7d.getItemsPerPage();_7d.setFirstIndexOnPage(_83);_7d.onPageChanged(_81,_82);};var _84;var _85=this.getCurrentPageIndex();var _86=this.getLastPageIndex();if(_85>0){_84=createTiddlyButton(_7c,"Previous","Go to previous page (Shortcut: Alt-'<')",_7e,"prev");_84.setAttribute("page",(_85-1).toString());_84.setAttribute("accessKey","<");}for(var i=-this.getMaxPagesInNavigation();i<this.getMaxPagesInNavigation();i++){var _88=_85+i;if(_88<0){continue;}if(_88>_86){break;}var _89=(i+_85+1).toString();var _8a=_88==_85?"currentPage":"otherPage";_84=createTiddlyButton(_7c,_89,"Go to page %0".format([_89]),_7e,_8a);_84.setAttribute("page",(_88).toString());}if(_85<_86){_84=createTiddlyButton(_7c,"Next","Go to next page (Shortcut: Alt-'>')",_7e,"next");_84.setAttribute("page",(_85+1).toString());_84.setAttribute("accessKey",">");}}});abego.LimitedTextRenderer=function(){var _8b=40;var _8c=4;var _8d=function(_8e,_8f,_90){var n=_8e.length;if(n==0){_8e.push({start:_8f,end:_90});return;}var i=0;for(;i<n;i++){var _93=_8e[i];if(_93.start<=_90&&_8f<=_93.end){var r;var _95=i+1;for(;_95<n;_95++){r=_8e[_95];if(r.start>_90||_8f>_93.end){break;}}var _96=_8f;var _97=_90;for(var j=i;j<_95;j++){r=_8e[j];_96=Math.min(_96,r.start);_97=Math.max(_97,r.end);}_8e.splice(i,_95-i,{start:_96,end:_97});return;}if(_93.start>_90){break;}}_8e.splice(i,0,{start:_8f,end:_90});};var _99=function(_9a){var _9b=0;for(var i=0;i<_9a.length;i++){var _9d=_9a[i];_9b+=_9d.end-_9d.start;}return _9b;};var _9e=function(c){return (c>="a"&&c<="z")||(c>="A"&&c<="Z")||c=="_";};var _a0=function(s,_a2){if(!_9e(s[_a2])){return null;}for(var i=_a2-1;i>=0&&_9e(s[i]);i--){}var _a4=i+1;var n=s.length;for(i=_a2+1;i<n&&_9e(s[i]);i++){}return {start:_a4,end:i};};var _a6=function(s,_a8,_a9){var _aa;if(_a9){_aa=_a0(s,_a8);}else{if(_a8<=0){return _a8;}_aa=_a0(s,_a8-1);}if(!_aa){return _a8;}if(_a9){if(_aa.start>=_a8-_8c){return _aa.start;}if(_aa.end<=_a8+_8c){return _aa.end;}}else{if(_aa.end<=_a8+_8c){return _aa.end;}if(_aa.start>=_a8-_8c){return _aa.start;}}return _a8;};var _ab=function(s,_ad){var _ae=[];if(_ad){var _af=0;var n=s.length;var _b1=0;do{_ad.lastIndex=_af;var _b2=_ad.exec(s);if(_b2){if(_af<_b2.index){var t=s.substring(_af,_b2.index);_ae.push({text:t});}_ae.push({text:_b2[0],isMatch:true});_af=_b2.index+_b2[0].length;}else{_ae.push({text:s.substr(_af)});break;}}while(true);}else{_ae.push({text:s});}return _ae;};var _b4=function(_b5){var _b6=0;for(var i=0;i<_b5.length;i++){if(_b5[i].isMatch){_b6++;}}return _b6;};var _b8=function(s,_ba,_bb,_bc,_bd){var _be=Math.max(Math.floor(_bd/(_bc+1)),_8b);var _bf=Math.max(_be-(_bb-_ba),0);var _c0=Math.min(Math.floor(_bb+_bf/3),s.length);var _c1=Math.max(_c0-_be,0);_c1=_a6(s,_c1,true);_c0=_a6(s,_c0,false);return {start:_c1,end:_c0};};var _c2=function(_c3,s,_c5){var _c6=[];var _c7=_b4(_c3);var pos=0;for(var i=0;i<_c3.length;i++){var t=_c3[i];var _cb=t.text;if(t.isMatch){var _cc=_b8(s,pos,pos+_cb.length,_c7,_c5);_8d(_c6,_cc.start,_cc.end);}pos+=_cb.length;}return _c6;};var _cd=function(s,_cf,_d0){var _d1=_d0-_99(_cf);while(_d1>0){if(_cf.length==0){_8d(_cf,0,_a6(s,_d0,false));return;}else{var _d2=_cf[0];var _d3;var _d4;if(_d2.start==0){_d3=_d2.end;if(_cf.length>1){_d4=_cf[1].start;}else{_8d(_cf,_d3,_a6(s,_d3+_d1,false));return;}}else{_d3=0;_d4=_d2.start;}var _d5=Math.min(_d4,_d3+_d1);_8d(_cf,_d3,_d5);_d1-=(_d5-_d3);}}};var _d6=function(_d7,s,_d9,_da,_db){if(_da.length==0){return;}var _dc=function(_dd,s,_df,_e0,_e1){var t;var _e3;var pos=0;var i=0;var _e6=0;for(;i<_df.length;i++){t=_df[i];_e3=t.text;if(_e0<pos+_e3.length){_e6=_e0-pos;break;}pos+=_e3.length;}var _e7=_e1-_e0;for(;i<_df.length&&_e7>0;i++){t=_df[i];_e3=t.text.substr(_e6);_e6=0;if(_e3.length>_e7){_e3=_e3.substr(0,_e7);}if(t.isMatch){createTiddlyElement(_dd,"span",null,"marked",_e3);}else{createTiddlyText(_dd,_e3);}_e7-=_e3.length;}if(_e1<s.length){abego.createEllipsis(_dd);}};if(_da[0].start>0){abego.createEllipsis(_d7);}var _e8=_db;for(var i=0;i<_da.length&&_e8>0;i++){var _ea=_da[i];var len=Math.min(_ea.end-_ea.start,_e8);_dc(_d7,s,_d9,_ea.start,_ea.start+len);_e8-=len;}};this.render=function(_ec,s,_ee,_ef){if(s.length<_ee){_ee=s.length;}var _f0=_ab(s,_ef);var _f1=_c2(_f0,s,_ee);_cd(s,_f1,_ee);_d6(_ec,s,_f0,_f1,_ee);};};(function(){function alertAndThrow(msg){alert(msg);throw msg;}if(version.major<2||(version.major==2&&version.minor<1)){alertAndThrow("YourSearchPlugin requires TiddlyWiki 2.1 or newer.\n\nCheck the archive for YourSearch plugins\nsupporting older versions of TiddlyWiki.\n\nArchive: http://tiddlywiki.abego-software.de/archive");}abego.YourSearch={};var _f3;var _f4;var _f5=function(_f6){_f3=_f6;};var _f7=function(){return _f3?_f3:[];};var _f8=function(){return _f3?_f3.length:0;};var _f9=4;var _fa=10;var _fb=2;var _fc=function(s,re){var m=s.match(re);return m?m.length:0;};var _100=function(_101,_102){var _103=_102.getMarkRegExp();if(!_103){return 1;}var _104=_101.title.match(_103);var _105=_104?_104.length:0;var _106=_fc(_101.getTags(),_103);var _107=_104?_104.join("").length:0;var _108=_101.title.length>0?_107/_101.title.length:0;var rank=_105*_f9+_106*_fb+_108*_fa+1;return rank;};var _10a=function(_10b,_10c,_10d,_10e,_10f,_110){_f4=null;var _111=_10b.reverseLookup("tags",_110,false);try{var _112=[];if(config.options.chkSearchInTitle){_112.push("title");}if(config.options.chkSearchInText){_112.push("text");}if(config.options.chkSearchInTags){_112.push("tags");}_f4=new abego.TiddlerQuery(_10c,_10d,_10e,_112,config.options.chkSearchExtendedFields);}catch(e){return [];}var _113=_f4.filter(_111);var _114=abego.YourSearch.getRankFunction();for(var i=0;i<_113.length;i++){var _116=_113[i];var rank=_114(_116,_f4);_116.searchRank=rank;}if(!_10f){_10f="title";}var _118=function(a,b){var _11b=a.searchRank-b.searchRank;if(_11b==0){if(a[_10f]==b[_10f]){return (0);}else{return (a[_10f]<b[_10f])?-1:+1;}}else{return (_11b>0)?-1:+1;}};_113.sort(_118);return _113;};var _11c=80;var _11d=50;var _11e=250;var _11f=50;var _120=25;var _121=10;var _122="yourSearchResult";var _123="yourSearchResultItems";var _124;var _125;var _126;var _127;var _128;var _129=function(){if(version.extensions.YourSearchPlugin.styleSheetInited){return;}version.extensions.YourSearchPlugin.styleSheetInited=true;setStylesheet(store.getTiddlerText("YourSearchStyleSheet"),"yourSearch");};var _12a=function(){return _125!=null&&_125.parentNode==document.body;};var _12b=function(){if(_12a()){document.body.removeChild(_125);}};var _12c=function(e){_12b();var _12e=this.getAttribute("tiddlyLink");if(_12e){var _12f=this.getAttribute("withHilite");var _130=highlightHack;if(_12f&&_12f=="true"&&_f4){highlightHack=_f4.getMarkRegExp();}story.displayTiddler(this,_12e);highlightHack=_130;}return (false);};var _131=function(){if(!_126){return;}var root=_126;var _133=findPosX(root);var _134=findPosY(root);var _135=root.offsetHeight;var _136=_133;var _137=_134+_135;var _138=findWindowWidth();if(_138<_125.offsetWidth){_125.style.width=(_138-100)+"px";_138=findWindowWidth();}var _139=_125.offsetWidth;if(_136+_139>_138){_136=_138-_139-30;}if(_136<0){_136=0;}_125.style.left=_136+"px";_125.style.top=_137+"px";_125.style.display="block";};var _13a=function(){if(_125){window.scrollTo(0,ensureVisible(_125));}if(_126){window.scrollTo(0,ensureVisible(_126));}};var _13b=function(){_131();_13a();};var _13c;var _13d;var _13e=new abego.PageWiseRenderer();var _13f=function(_140){this.itemHtml=store.getTiddlerText("YourSearchItemTemplate");if(!this.itemHtml){alertAndThrow("YourSearchItemTemplate not found");}this.place=document.getElementById(_123);if(!this.place){this.place=createTiddlyElement(_140,"div",_123);}};merge(_13f.prototype,{render:function(_141,_142,_143,_144){_13c=_144;_13d=_142;var item=createTiddlyElement(this.place,"div",null,"yourSearchItem");item.innerHTML=this.itemHtml;applyHtmlMacros(item,null);refreshElements(item,null);},endRendering:function(_146){_13d=null;}});var _147=function(){if(!_125||!_126){return;}var html=store.getTiddlerText("YourSearchResultTemplate");if(!html){html="<b>Tiddler YourSearchResultTemplate not found</b>";}_125.innerHTML=html;applyHtmlMacros(_125,null);refreshElements(_125,null);var _149=new _13f(_125);_13e.renderPage(_149);_13b();};_13e.getItemsPerPage=function(){var n=(config.options.chkPreviewText)?abego.toInt(config.options.txtItemsPerPageWithPreview,_121):abego.toInt(config.options.txtItemsPerPage,_120);return (n>0)?n:1;};_13e.onPageChanged=function(){_147();};var _14b=function(){if(_126==null||!config.options.chkUseYourSearch){return;}if((_126.value==_124)&&_124&&!_12a()){if(_125&&(_125.parentNode!=document.body)){document.body.appendChild(_125);_13b();}else{abego.YourSearch.onShowResult(true);}}};var _14c=function(){_12b();_125=null;_124=null;};var _14d=function(self,e){while(e!=null){if(self==e){return true;}e=e.parentNode;}return false;};var _150=function(e){if(e.target==_126){return;}if(e.target==_127){return;}if(_125&&_14d(_125,e.target)){return;}_12b();};var _152=function(e){if(e.keyCode==27){_12b();}};addEvent(document,"click",_150);addEvent(document,"keyup",_152);var _154=function(text,_156,_157){_124=text;_f5(_10a(store,text,_156,_157,"title","excludeSearch"));abego.YourSearch.onShowResult();};var _158=function(_159,_15a,_15b,_15c,_15d,_15e){_129();_124="";var _15f=null;var _160=function(txt){if(config.options.chkUseYourSearch){_154(txt.value,config.options.chkCaseSensitiveSearch,config.options.chkRegExpSearch);}else{story.search(txt.value,config.options.chkCaseSensitiveSearch,config.options.chkRegExpSearch);}_124=txt.value;};var _162=function(e){_160(_126);return false;};var _164=function(e){if(!e){var e=window.event;}_126=this;switch(e.keyCode){case 13:if(e.ctrlKey&&_128&&_12a()){_128.onclick.apply(_128,[e]);}else{_160(this);}break;case 27:if(_12a()){_12b();}else{this.value="";clearMessage();}break;}if(String.fromCharCode(e.keyCode)==this.accessKey||e.altKey){_14b();}if(this.value.length<3&&_15f){clearTimeout(_15f);}if(this.value.length>2){if(this.value!=_124){if(!config.options.chkUseYourSearch||config.options.chkSearchAsYouType){if(_15f){clearTimeout(_15f);}var txt=this;_15f=setTimeout(function(){_160(txt);},500);}}else{if(_15f){clearTimeout(_15f);}}}if(this.value.length==0){_12b();}};var _168=function(e){this.select();clearMessage();_14b();};var args=_15d.parseParams("list",null,true);var _16b=getFlag(args,"buttonAtRight");var _16c=getParam(args,"sizeTextbox",this.sizeTextbox);var btn;if(!_16b){btn=createTiddlyButton(_159,this.label,this.prompt,_162);}var txt=createTiddlyElement(_159,"input",null,null,null);if(_15b[0]){txt.value=_15b[0];}txt.onkeyup=_164;txt.onfocus=_168;txt.setAttribute("size",_16c);txt.setAttribute("accessKey",this.accessKey);txt.setAttribute("autocomplete","off");if(config.browser.isSafari){txt.setAttribute("type","search");txt.setAttribute("results","5");}else{txt.setAttribute("type","text");}if(_16b){btn=createTiddlyButton(_159,this.label,this.prompt,_162);}_126=txt;_127=btn;};var _16f=function(){_12b();var _170=_f7();var n=_170.length;if(n){var _172=[];for(var i=0;i<n;i++){_172.push(_170[i].title);}story.displayTiddlers(null,_172);}};var _174=function(_175,_176,_177,_178){invokeMacro(_175,"option",_176,_177,_178);var elem=_175.lastChild;var _17a=elem.onclick;elem.onclick=function(e){var _17c=_17a.apply(this,arguments);_147();return _17c;};return elem;};var _17d=function(s){var _17f=["''","{{{","}}}","//","<<<","/***","***/"];var _180="";for(var i=0;i<_17f.length;i++){if(i!=0){_180+="|";}_180+="("+_17f[i].escapeRegExp()+")";}return s.replace(new RegExp(_180,"mg"),"").trim();};var _182=function(){var i=_13c;return (i>=0&&i<=9)?(i<9?(i+1):0):-1;};var _184=new abego.LimitedTextRenderer();var _185=function(_186,s,_188){_184.render(_186,s,_188,_f4.getMarkRegExp());};var _189=TiddlyWiki.prototype.saveTiddler;TiddlyWiki.prototype.saveTiddler=function(_18a,_18b,_18c,_18d,_18e,tags,_190){_189.apply(this,arguments);_14c();};var _191=TiddlyWiki.prototype.removeTiddler;TiddlyWiki.prototype.removeTiddler=function(_192){_191.apply(this,arguments);_14c();};config.macros.yourSearch={label:"yourSearch",prompt:"Gives access to the current/last YourSearch result",handler:function(_193,_194,_195,_196,_197,_198){if(_195.length==0){return;}var name=_195[0];var func=config.macros.yourSearch.funcs[name];if(func){func(_193,_194,_195,_196,_197,_198);}},tests:{"true":function(){return true;},"false":function(){return false;},"found":function(){return _f8()>0;},"previewText":function(){return config.options.chkPreviewText;}},funcs:{itemRange:function(_19b){if(_f8()){var _19c=_13e.getLastIndexOnPage();var s="%0 - %1".format([_13e.getFirstIndexOnPage()+1,_19c+1]);createTiddlyText(_19b,s);}},count:function(_19e){createTiddlyText(_19e,_f8().toString());},query:function(_19f){if(_f4){createTiddlyText(_19f,_f4.toString());}},version:function(_1a0){var t="YourSearch %0.%1.%2".format([version.extensions.YourSearchPlugin.major,version.extensions.YourSearchPlugin.minor,version.extensions.YourSearchPlugin.revision]);var e=createTiddlyElement(_1a0,"a");e.setAttribute("href","http://tiddlywiki.abego-software.de/#YourSearchPlugin");e.innerHTML="<font color=\"black\" face=\"Arial, Helvetica, sans-serif\">"+t+"<font>";},copyright:function(_1a3){var e=createTiddlyElement(_1a3,"a");e.setAttribute("href","http://www.abego-software.de");e.innerHTML="<font color=\"black\" face=\"Arial, Helvetica, sans-serif\">&copy; 2005-2006 <b><font color=\"red\">abego</font></b> Software<font>";},newTiddlerButton:function(_1a5){if(_f4){var r=abego.parseNewTiddlerCommandLine(_f4.getQueryText());var btn=config.macros.newTiddler.createNewTiddlerButton(_1a5,r.title,r.params,"new tiddler","Create a new tiddler based on search text. (Shortcut: Ctrl-Enter; Separators: '.', '#')",null,"text");var _1a8=btn.onclick;btn.onclick=function(){_12b();_1a8.apply(this,arguments);};_128=btn;}},linkButton:function(_1a9,_1aa,_1ab,_1ac,_1ad,_1ae){if(_1ab<2){return;}var _1af=_1ab[1];var text=_1ab<3?_1af:_1ab[2];var _1b1=_1ab<4?text:_1ab[3];var _1b2=_1ab<5?null:_1ab[4];var btn=createTiddlyButton(_1a9,text,_1b1,_12c,null,null,_1b2);btn.setAttribute("tiddlyLink",_1af);},closeButton:function(_1b4,_1b5,_1b6,_1b7,_1b8,_1b9){var _1ba=createTiddlyButton(_1b4,"close","Close the Search Results (Shortcut: ESC)",_12b);},openAllButton:function(_1bb,_1bc,_1bd,_1be,_1bf,_1c0){var n=_f8();if(n==0){return;}var _1c2=n==1?"open tiddler":"open all %0 tiddlers".format([n]);var _1c3=createTiddlyButton(_1bb,_1c2,"Open all found tiddlers (Shortcut: Alt-O)",_16f);_1c3.setAttribute("accessKey","O");},naviBar:function(_1c4,_1c5,_1c6,_1c7,_1c8,_1c9){_13e.addPageNavigation(_1c4);},"if":function(_1ca,_1cb,_1cc,_1cd,_1ce,_1cf){if(_1cc.length<2){return;}var _1d0=_1cc[1];var _1d1=(_1d0=="not");if(_1d1){if(_1cc.length<3){return;}_1d0=_1cc[2];}var test=config.macros.yourSearch.tests[_1d0];var _1d3=false;try{if(test){_1d3=test(_1ca,_1cb,_1cc,_1cd,_1ce,_1cf)!=_1d1;}else{_1d3=(!eval(_1d0))==_1d1;}}catch(ex){}if(!_1d3){_1ca.style.display="none";}},chkPreviewText:function(_1d4,_1d5,_1d6,_1d7,_1d8,_1d9){var _1da=_1d6.slice(1).join(" ");var elem=_174(_1d4,"chkPreviewText",_1d7,_1d9);elem.setAttribute("accessKey","P");elem.title="Show text preview of found tiddlers (Shortcut: Alt-P)";return elem;}}};config.macros.foundTiddler={label:"foundTiddler",prompt:"Provides information on the tiddler currently processed on the YourSearch result page",handler:function(_1dc,_1dd,_1de,_1df,_1e0,_1e1){var name=_1de[0];var func=config.macros.foundTiddler.funcs[name];if(func){func(_1dc,_1dd,_1de,_1df,_1e0,_1e1);}},funcs:{title:function(_1e4,_1e5,_1e6,_1e7,_1e8,_1e9){if(!_13d){return;}var _1ea=_182();var _1eb=_1ea>=0?"Open tiddler (Shortcut: Alt-%0)".format([_1ea.toString()]):"Open tiddler";var btn=createTiddlyButton(_1e4,null,_1eb,_12c,null);btn.setAttribute("tiddlyLink",_13d.title);btn.setAttribute("withHilite","true");_185(btn,_13d.title,_11c);if(_1ea>=0){btn.setAttribute("accessKey",_1ea.toString());}},tags:function(_1ed,_1ee,_1ef,_1f0,_1f1,_1f2){if(!_13d){return;}_185(_1ed,_13d.getTags(),_11d);},text:function(_1f3,_1f4,_1f5,_1f6,_1f7,_1f8){if(!_13d){return;}_185(_1f3,_17d(_13d.text),_11e);},field:function(_1f9,_1fa,_1fb,_1fc,_1fd,_1fe){if(!_13d){return;}var name=_1fb[1];var len=_1fb.length>2?abego.toInt(_1fb[2],_11f):_11f;var v=store.getValue(_13d,name);if(v){_185(_1f9,_17d(v),len);}},number:function(_202,_203,_204,_205,_206,_207){var _208=_182();if(_208>=0){var text="%0)".format([_208.toString()]);createTiddlyElement(_202,"span",null,"shortcutNumber",text);}}}};var opts={chkUseYourSearch:true,chkPreviewText:true,chkSearchAsYouType:true,chkSearchInTitle:true,chkSearchInText:true,chkSearchInTags:true,chkSearchExtendedFields:true,txtItemsPerPage:_120,txtItemsPerPageWithPreview:_121};for(var n in opts){if(config.options[n]==undefined){config.options[n]=opts[n];}}config.shadowTiddlers.AdvancedOptions+="\n<<option chkUseYourSearch>> Use 'Your Search' //([[more options|YourSearch Options]]) ([[help|YourSearch Help]])// ";config.shadowTiddlers["YourSearch Help"]="!Field Search\nWith the Field Search you can restrict your search to certain fields of a tiddler, e.g"+" only search the tags or only the titles. The general form is //fieldname//'':''//textToSearch// (e."+"g. {{{title:intro}}}). In addition one-character shortcuts are also supported for the standard field"+"s {{{title}}}, {{{text}}} and {{{tags}}}:\n|!What you want|!What you type|!Example|\n|Search ''titles "+"only''|start word with ''!''|{{{!jonny}}} (shortcut for {{{title:jonny}}})|\n|Search ''contents/text "+"only''|start word with ''%''|{{{%football}}} (shortcut for {{{text:football}}})|\n|Search ''tags only"+"''|start word with ''#''|{{{#Plugin}}} (shortcut for {{{tags:Plugin}}})|\n\nUsing this feature you may"+" also search the extended fields (\"Metadata\") introduced with TiddlyWiki 2.1, e.g. use {{{priority:1"+"}}} to find all tiddlers with the priority field set to \"1\".\n\nYou may search a word in more than one"+" field. E.g. {{{!#Plugin}}} (or {{{title:tags:Plugin}}} in the \"long form\") finds tiddlers containin"+"g \"Plugin\" either in the title or in the tags (but does not look for \"Plugin\" in the text). \n\n!Boole"+"an Search\nThe Boolean Search is useful when searching for multiple words.\n|!What you want|!What you "+"type|!Example|\n|''All words'' must exist|List of words|{{{jonny jeremy}}} (or {{{jonny and jeremy}}}"+")|\n|''At least one word'' must exist|Separate words by ''or''|{{{jonny or jeremy}}}|\n|A word ''must "+"not exist''|Start word with ''-''|{{{-jonny}}} (or {{{not jonny}}})|\n\n''Note:'' When you specify two"+" words, separated with a space, YourSearch finds all tiddlers that contain both words, but not neces"+"sarily next to each other. If you want to find a sequence of word, e.g. '{{{John Brown}}}', you need"+" to put the words into quotes. I.e. you type: {{{\"john brown\"}}}.\n\nUsing parenthesis you may change "+"the default \"left to right\" evaluation of the boolean search. E.g. {{{not (jonny or jeremy)}}} finds"+" all tiddlers that contain neither \"jonny\" nor \"jeremy. In contrast to this {{{not jonny or jeremy}}"+"} (i.e. without parenthesis) finds all tiddlers that either don't contain \"jonny\" or that contain \"j"+"eremy\".\n\n!'Exact Word' Search\nBy default a search result all matches that 'contain' the searched tex"+"t. E.g. if you search for {{{Task}}} you will get all tiddlers containing 'Task', but also '~Complet"+"edTask', '~TaskForce' etc.\n\nIf you only want to get the tiddlers that contain 'exactly the word' you"+" need to prefix it with a '='. E.g. typing '=Task' will find the tiddlers that contain the word 'Tas"+"k', ignoring words that just contain 'Task' as a substring.\n\n!~CaseSensitiveSearch and ~RegExpSearch"+"\nThe standard search options ~CaseSensitiveSearch and ~RegExpSearch are fully supported by YourSearc"+"h. However when ''~RegExpSearch'' is on Filtered and Boolean Search are disabled.\n\nIn addition you m"+"ay do a \"regular expression\" search even with the ''~RegExpSearch'' set to false by directly enterin"+"g the regular expression into the search field, framed with {{{/.../}}}. \n\nExample: {{{/m[ae][iy]er/"+"}}} will find all tiddlers that contain either \"maier\", \"mayer\", \"meier\" or \"meyer\".\n\n!~JavaScript E"+"xpression Filtering\nIf you are familiar with JavaScript programming and know some TiddlyWiki interna"+"ls you may also use JavaScript expression for the search. Just enter a JavaScript boolean expression"+" into the search field, framed with {{{ { ... } }}}. In the code refer to the variable tiddler and e"+"valuate to {{{true}}} when the given tiddler should be included in the result. \n\nExample: {{{ { tidd"+"ler.modified > new Date(\"Jul 4, 2005\")} }}} returns all tiddler modified after July 4th, 2005.\n\n!Com"+"bined Search\nYou are free to combine the various search options. \n\n''Examples''\n|!What you type|!Res"+"ult|\n|{{{!jonny !jeremy -%football}}}|all tiddlers with both {{{jonny}}} and {{{jeremy}}} in its tit"+"les, but no {{{football}}} in content.|\n|{{{#=Task}}}|All tiddlers tagged with 'Task' (the exact wor"+"d). Tags named '~CompletedTask', '~TaskForce' etc. are not considered.|\n\n!Access Keys\nYou are encour"+"aged to use the access keys (also called \"shortcut\" keys) for the most frequently used operations. F"+"or quick reference these shortcuts are also mentioned in the tooltip for the various buttons etc.\n\n|"+"!Key|!Operation|\n|{{{Alt-F}}}|''The most important keystroke'': It moves the cursor to the search in"+"put field so you can directly start typing your query. Pressing {{{Alt-F}}} will also display the pr"+"evious search result. This way you can quickly display multiple tiddlers using \"Press {{{Alt-F}}}. S"+"elect tiddler.\" sequences.|\n|{{{ESC}}}|Closes the [[YourSearch Result]]. When the [[YourSearch Resul"+"t]] is already closed and the cursor is in the search input field the field's content is cleared so "+"you start a new query.|\n|{{{Alt-1}}}, {{{Alt-2}}},... |Pressing these keys opens the first, second e"+"tc. tiddler from the result list.|\n|{{{Alt-O}}}|Opens all found tiddlers.|\n|{{{Alt-P}}}|Toggles the "+"'Preview Text' mode.|\n|{{{Alt-'<'}}}, {{{Alt-'>'}}}|Displays the previous or next page in the [[Your"+"Search Result]].|\n|{{{Return}}}|When you have turned off the 'as you type' search mode pressing the "+"{{{Return}}} key actually starts the search (as does pressing the 'search' button).|\n\n//If some of t"+"hese shortcuts don't work for you check your browser if you have other extensions installed that alr"+"eady \"use\" these shortcuts.//";config.shadowTiddlers["YourSearch Options"]="|>|!YourSearch Options|\n|>|<<option chkUseYourSearch>> Use 'Your Search'|\n|!|<<option chkPreviewText"+">> Show Text Preview|\n|!|<<option chkSearchAsYouType>> 'Search As You Type' Mode (No RETURN required"+" to start search)|\n|!|Default Search Filter:<<option chkSearchInTitle>>Title ('!') <<option chk"+"SearchInText>>Text ('%') <<option chkSearchInTags>>Tags ('#') <<option chkSearchExtendedFiel"+"ds>>Extended Fields<html><br><font size=\"-2\">The fields of a tiddlers that are searched when you don"+"'t explicitly specify a filter in the search text <br>(Explictly specify fields using one or more '!"+"', '%', '#' or 'fieldname:' prefix before the word/text to find).</font></html>|\n|!|Number of items "+"on search result page: <<option txtItemsPerPage>>|\n|!|Number of items on search result page with pre"+"view text: <<option txtItemsPerPageWithPreview>>|\n";config.shadowTiddlers["YourSearchStyleSheet"]="/***\n!~YourSearchResult Stylesheet\n***/\n/*{{{*/\n.yourSearchResult {\n\tposition: absolute;\n\twidth: 800"+"px;\n\n\tpadding: 0.2em;\n\tlist-style: none;\n\tmargin: 0;\n\n\tbackground: #ffd;\n\tborder: 1px solid DarkGra"+"y;\n}\n\n/*}}}*/\n/***\n!!Summary Section\n***/\n/*{{{*/\n.yourSearchResult .summary {\n\tborder-bottom-width:"+" thin;\n\tborder-bottom-style: solid;\n\tborder-bottom-color: #999999;\n\tpadding-bottom: 4px;\n}\n\n.yourSea"+"rchRange, .yourSearchCount, .yourSearchQuery {\n\tfont-weight: bold;\n}\n\n.yourSearchResult .summary ."+"button {\n\tfont-size: 10px;\n\n\tpadding-left: 0.3em;\n\tpadding-right: 0.3em;\n}\n\n.yourSearchResult .summa"+"ry .chkBoxLabel {\n\tfont-size: 10px;\n\n\tpadding-right: 0.3em;\n}\n\n/*}}}*/\n/***\n!!Items Area\n***/\n/*{{{*"+"/\n.yourSearchResult .marked {\n\tbackground: none;\n\tfont-weight: bold;\n}\n\n.yourSearchItem {\n\tmargin-to"+"p: 2px;\n}\n\n.yourSearchNumber {\n\tcolor: #808080;\n}\n\n\n.yourSearchTags {\n\tcolor: #008000;\n}\n\n.yourSearc"+"hText {\n\tcolor: #808080;\n\tmargin-bottom: 6px;\n}\n\n/*}}}*/\n/***\n!!Footer\n***/\n/*{{{*/\n.yourSearchFoote"+"r {\n\tmargin-top: 8px;\n\tborder-top-width: thin;\n\tborder-top-style: solid;\n\tborder-top-color: #999999;"+"\n}\n\n.yourSearchFooter a:hover{\n\tbackground: none;\n\tcolor: none;\n}\n/*}}}*/\n/***\n!!Navigation Bar\n***/"+"\n/*{{{*/\n.yourSearchNaviBar a {\n\tfont-size: 16px;\n\tmargin-left: 4px;\n\tmargin-right: 4px;\n\tcolor: bla"+"ck;\n\ttext-decoration: underline;\n}\n\n.yourSearchNaviBar a:hover {\n\tbackground-color: none;\n}\n\n.yourSe"+"archNaviBar .prev {\n\tfont-weight: bold;\n\tcolor: blue;\n}\n\n.yourSearchNaviBar .currentPage {\n\tcolor: #"+"FF0000;\n\tfont-weight: bold;\n\ttext-decoration: none;\n}\n\n.yourSearchNaviBar .next {\n\tfont-weight: bold"+";\n\tcolor: blue;\n}\n/*}}}*/\n";config.shadowTiddlers["YourSearchResultTemplate"]="<!--\n{{{\n-->\n<span macro=\"yourSearch if found\">\n<!-- The Summary Header ============================"+"================ -->\n<table class=\"summary\" border=\"0\" width=\"100%\" cellspacing=\"0\" cellpadding=\"0\">"+"<tbody>\n <tr>\n\t<td align=\"left\">\n\t\tYourSearch Result <span class=\"yourSearchRange\" macro=\"yourSearc"+"h itemRange\"></span>\n\t\t&nbsp;of&nbsp;<span class=\"yourSearchCount\" macro=\"yourSearch count\"></span>\n"+"\t\tfor&nbsp;<span class=\"yourSearchQuery\" macro=\"yourSearch query\"></span>\n\t</td>\n\t<td class=\"yourSea"+"rchButtons\" align=\"right\">\n\t\t<span macro=\"yourSearch chkPreviewText\"></span><span class=\"chkBoxLabel"+"\">preview text</span>\n\t\t<span macro=\"yourSearch newTiddlerButton\"></span>\n\t\t<span macro=\"yourSearch openAllButton\"></span>\n\t\t<span macro=\"yourSearch lin"+"kButton 'YourSearch Options' options 'Configure YourSearch'\"></span>\n\t\t<span macro=\"yourSearch linkB"+"utton 'YourSearch Help' help 'Get help how to use YourSearch'\"></span>\n\t\t<span macro=\"yourSearch clo"+"seButton\"></span>\n\t</td>\n </tr>\n</tbody></table>\n\n<!-- The List of Found Tiddlers ================="+"=========================== -->\n<div id=\"yourSearchResultItems\" itemsPerPage=\"25\" itemsPerPageWithPr"+"eview=\"10\"></div>\n\n<!-- The Footer (with the Navigation) ==========================================="+"= -->\n<table class=\"yourSearchFooter\" border=\"0\" width=\"100%\" cellspacing=\"0\" cellpadding=\"0\"><tbody"+">\n <tr>\n\t<td align=\"left\">\n\t\tResult page: <span class=\"yourSearchNaviBar\" macro=\"yourSearch naviBar"+"\"></span>\n\t</td>\n\t<td align=\"right\"><span macro=\"yourSearch version\"></span>, <span macro=\"yourSearc"+"h copyright\"></span>\n\t</td>\n </tr>\n</tbody></table>\n<!-- end of the 'tiddlers found' case ========="+"================================== -->\n</span>\n\n\n<!-- The \"No tiddlers found\" case ================="+"========================== -->\n<span macro=\"yourSearch if not found\">\n<table class=\"summary\" border="+"\"0\" width=\"100%\" cellspacing=\"0\" cellpadding=\"0\"><tbody>\n <tr>\n\t<td align=\"left\">\n\t\tYourSearch Resu"+"lt: No tiddlers found for <span class=\"yourSearchQuery\" macro=\"yourSearch query\"></span>.\n\t</td>\n\t<t"+"d class=\"yourSearchButtons\" align=\"right\">\n\t\t<span macro=\"yourSearch newTiddlerButton\"></span>\n\t\t<span macro=\"yourSearch linkButton 'YourSearch Options'"+" options 'Configure YourSearch'\"></span>\n\t\t<span macro=\"yourSearch linkButton 'YourSearch Help' help"+" 'Get help how to use YourSearch'\"></span>\n\t\t<span macro=\"yourSearch closeButton\"></span>\n\t</td>\n <"+"/tr>\n</tbody></table>\n</span>\n\n\n<!--\n}}}\n-->\n";config.shadowTiddlers["YourSearchItemTemplate"]="<!--\n{{{\n-->\n<span class='yourSearchNumber' macro='foundTiddler number'></span>\n<span class='yourSea"+"rchTitle' macro='foundTiddler title'/></span>&nbsp;-&nbsp;\n<span class='yourSearchTags' macro='found"+"Tiddler field tags 50'/></span>\n<span macro=\"yourSearch if previewText\"><div class='yourSearchText' macro='fo"+"undTiddler field text 250'/></div></span>\n<!--\n}}}\n-->";config.shadowTiddlers["YourSearch"]="<<tiddler [[YourSearch Help]]>>";config.shadowTiddlers["YourSearch Result"]="The popup-like window displaying the result of a YourSearch query.";config.macros.search.handler=_158;var _20c=function(){if(config.macros.search.handler!=_158){alert("Message from YourSearchPlugin:\n\n\nAnother plugin has disabled the 'Your Search' features.\n\n\nYou may "+"disable the other plugin or change the load order of \nthe plugins (by changing the names of the tidd"+"lers)\nto enable the 'Your Search' features.");}};setTimeout(_20c,5000);abego.YourSearch.getStandardRankFunction=function(){return _100;};abego.YourSearch.getRankFunction=function(){return abego.YourSearch.getStandardRankFunction();};abego.YourSearch.getCurrentTiddler=function(){return _13d;};abego.YourSearch.closeResult=function(){_12b();};abego.YourSearch.getFoundTiddlers=function(){return _f3;};abego.YourSearch.getQuery=function(){return _f4;};abego.YourSearch.onShowResult=function(_20d){highlightHack=_f4?_f4.getMarkRegExp():null;if(!_20d){_13e.setItems(_f7());}if(!_125){_125=createTiddlyElement(document.body,"div",_122,"yourSearchResult");}else{if(_125.parentNode!=document.body){document.body.appendChild(_125);}}_147();highlightHack=null;};})();}
//%/
<<version>>