Testing TiddlyWiki Themes

is loading ...

Requires Javascript.

Testing different TW Themes for file: & http: - a reusable non-linear personal web notebook
<!--{{{-->
<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>>
if(window.location.protocol =="http:") {
jQuery("body").addClass("onlineMode");
}
[[User Options]] +++
[[Extended Options]] -
[[Search Options]] -
<<fontSize "font-size:">> -
[[Editing Options]] -
===

[[Tiddler Administration]] +++
[[Recent Tiddlers]] -
[[Main Menu|MainMenu]] -
[[Setup Menu]] -
[[Administrative Menu]] -
[[Template snippets]] -
[[Basic Tiddler Lists]] -
[[Formatting Tiddlers]] +++
[[Formatting Text]] --
[[iframe template]] --
[[Headers & Outlines]] --
[[Tiddly Links]] --
[[Tables]] --
[[Images]] --
===

[[Tiddler Lists]] +++
[[Basic Tiddler Lists]] -
[[Alphabetical Tiddlers]] -
[[Recent Tiddlers]] -
[[Tiddler Timelines]] +++
[[Tiddler Timeline]] -
[[Reverse Timeline]] -
[[Event Timeline]] -
===

[[Shadow Tiddlers]] -
[[Missing Tiddlers]] -
[[Imported Tiddlers]] -
[[Included TiddlyWikis]] -
===

[[Menus]] +++
[[Main Menu|MainMenu]] -
[[Administrative Menu]] -
[[Hover Menu|HoverMenu]] -
[[Setup Menu]] -
===

[[Default Tiddlers|DefaultTiddlers]] -
[[Import Tiddlers]] -
[[Plugin Macros]] -
[[Templates & Stylesheets]] 
[[Themes]] -
[[PageTemplate]] -
[[ViewTemplate]] -
[[EditTemplate]] -
[[StyleSheet]] -
[[MainMenuStyles]] -
[[TagglyTaggingStyles]] -
[[Colour Palette]] -

===

{{center{
[img[http://www.climatechange3.net/cc3-logo-75x75.png][Climate Change 3.0]]
[img[http://www.climatechange3.net/tiddlywiki-logo-100x51.jpg][TiddlyWiki]]
<<version>>
}}}
[[Administrative Menu]] - attached to base of the [[Main Menu|MainMenu]]
<<tiddler "Administrative Menu">>
<<list all>>
<<tabs txtMainTab Timeline Timeline TabTimeline Alphabetical 'All tiddlers' TabAll Tags 'All tags' TabTags  Missing 'Missing tiddlers' TabMoreMissing Orphans 'Orphaned tiddlers' TabMoreOrphans Shadowed 'Shadowed tiddlers' TabMoreShadowed>>
/***
|Name|''timeline''|h
|Author|[[Saq Imtiaz]]|
|Version|0.5 bet|
|Description|A replacement for the core timeline macro that offers more features|
|Source|http://lewcid.googlepages.com/lewcid.html#BetterTimelineMacro|
|TW Version|2.x|
***/
/***
!!!Features:
*list tiddlers with only specific tag
*exclude tiddlers with a particular tag
*limit entries to any number of days, for example one week
*specify a start date for the timeline, only tiddlers after that date will be listed.

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

!!!Syntax:
{{{<<timeline better:true>>}}}
''the param better:true enables the advanced features, without it you will get the old timeline behaviour.''

additonal params:
(use only the ones you want)
{{{<<timeline better:true  onlyTag:Tag1 excludeTag:Tag2 sortBy:modified/created firstDay:YYYYMMDD maxDays:7 maxEntries:30>>}}}

''explanation of syntax:''
onlyTag: only tiddlers with this tag will be listed. Default is to list all tiddlers.
excludeTag: tiddlers with this tag will not be listed.
sortBy: sort tiddlers by date modified or date created. Possible values are modified or created.
firstDay: useful for starting timeline from a specific date. Example: 20060701 for 1st of July, 2006
maxDays: limits timeline to include only tiddlers from the specified number of days. If you use a value of 7 for example, only tiddlers from the last 7 days will be listed.
maxEntries: limit the total number of entries in the timeline.


!!!History:
*28-07-06: ver 0.5 beta, first release

!!!Code
***/
//{{{
// Return the tiddlers as a sorted array
TiddlyWiki.prototype.getTiddlers = function(field,excludeTag,includeTag)
{
          var results = [];
          this.forEachTiddler(function(title,tiddler)
          {
          if(excludeTag == undefined || tiddler.tags.find(excludeTag) == null)
                        if(includeTag == undefined || tiddler.tags.find(includeTag)!=null)
                                      results.push(tiddler);
          });
          if(field)
                   results.sort(function (a,b) {if(a[field] == b[field]) return(0); else return (a[field] < b[field]) ? -1 : +1; });
          return results;
}



//this function by Udo
function getParam(params, name, defaultValue)
{
          if (!params)
          return defaultValue;
          var p = params[0][name];
          return p ? p[0] : defaultValue;
}

window.old_timeline_handler= config.macros.timeline.handler;
config.macros.timeline.handler = function(place,macroName,params,wikifier,paramString,tiddler)
{
          var args = paramString.parseParams("list",null,true);
          var betterMode = getParam(args, "better", "false");
          if (betterMode == 'true')
          {
          var sortBy = getParam(args,"sortBy","modified");
          var excludeTag = getParam(args,"excludeTag",undefined);
          var includeTag = getParam(args,"onlyTag",undefined);
          var tiddlers = store.getTiddlers(sortBy,excludeTag,includeTag);
          var firstDayParam = getParam(args,"firstDay",undefined);
          var firstDay = (firstDayParam!=undefined)? firstDayParam: "00010101";
          var lastDay = "";
          var field= sortBy;
          var maxDaysParam = getParam(args,"maxDays",undefined);
          var maxDays = (maxDaysParam!=undefined)? maxDaysParam*24*60*60*1000: (new Date()).getTime() ;
          var maxEntries = getParam(args,"maxEntries",undefined);
          var last = (maxEntries!=undefined) ? tiddlers.length-Math.min(tiddlers.length,parseInt(maxEntries)) : 0;
          for(var t=tiddlers.length-1; t>=last; t--)
                  {
                  var tiddler = tiddlers[t];
                  var theDay = tiddler[field].convertToLocalYYYYMMDDHHMM().substr(0,8);
                  if ((theDay>=firstDay)&& (tiddler[field].getTime()> (new Date()).getTime() - maxDays))
                     {
                     if(theDay != lastDay)
                               {
                               var theDateList = document.createElement("ul");
                               place.appendChild(theDateList);
                               createTiddlyElement(theDateList,"li",null,"listTitle",tiddler[field].formatString(this.dateFormat));
                               lastDay = theDay;
                               }
                  var theDateListItem = createTiddlyElement(theDateList,"li",null,"listLink",null);
                  theDateListItem.appendChild(createTiddlyLink(place,tiddler.title,true));
                  }
                  }
          }

          else
              {
              window.old_timeline_handler.apply(this,arguments);
              }
}
//}}}
/***
|Name|BreadcrumbsPluginInfo|
|Author|Eric Shulman|
|Source|http://www.TiddlyTools.com/#BreadcrumbsPlugin|
|Documentation|http://www.TiddlyTools.com/#BreadcrumbsPluginInfo|
|Version|2.1.0|
|License|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides|Story.prototype.displayTiddler,TiddlyWiki.prototype.removeTiddler|
|Description|Documentation for BreadcrumbsPlugin|
This plugin provides a list of links to all tiddlers opened during the session, creating a "trail of breadcrumbs" from one tiddler to the next, allowing you to quickly navigate to any previously viewed tiddler, or select 'home' to reset the display to the initial set of tiddlers that were open at the start of the session (i.e., when the document was loaded into the browser).
!!!!!Usage
<<<
syntax:
{{{
<<breadcrumbs homeSeparator crumbSeparator>>
}}}
By default, the breadcrumbs are displayed as a continuous, //horizontal// word-wrapped line of text, using default character sequences for ''homeSeparator'' (" | ") and ''crumbSeparator'' (" > ").  The //optional// ''homeSeparator'' and ''crumbSeparator'' macro parameters allow you to specify alternative separators.  For example, to display the breadcrumbs //vertically// (in a stack, rather than a row), set the separator values to use {{{[[<br>]]}}}... and, to display a horizontal line as the home separator, use {{{[[<html><hr></html>]]}}}.
<<<
!!!!!Examples:
<<<
{{{
<<breadcrumbs>>
}}}
<<breadcrumbs>>
{{{
<<breadcrumbs [[<html><hr></html>]] [[<br>]]>>
}}}
<<breadcrumbs [[<html><hr></html>]] [[<br>]]>>
<<<
!!!!!Customization
<<<
Using CSS and a few of the plugin configuration options (see below), you can make the breadcrumbs display resemble browser tabs by adding the following to your [[StyleSheet]]:
{{{
.breadCrumbs { border-bottom:1px solid; }
.breadCrumbs a {
	border: 1px solid; padding: 0px 1em;
	-moz-border-radius-topleft:.5em; -moz-border-radius-topright:.5em;
	-webkit-border-top-left-radius:.5em; -webkit-border-top-right-radius:.5em;
}
}}}
and this in [[ConfigTweaks]] (tagged with systemConfig, of course):
{{{
config.options.chkShowStartupBreadcrumbs=true;
config.options.chkBreadcrumbsLimitOpenTiddlers=true;
config.options.txtBreadcrumbsLimitOpenTiddlers=1;
config.macros.breadcrumbs.homeSeparator=" ";
config.macros.breadcrumbs.crumbSeparator=" ";
}}}
<<<
!!!!!Configuration
<<<
__''display placement:''__
<<option chkCreateDefaultBreadcrumbs>> automatically create breadcrumbs display (if needed)
{{{<<option chkCreateDefaultBreadcrumbs>>}}}
>By default, the plugin automatically creates the "breadCrumbs" display element at the top of the story column, just above the tiddlerDisplay area.  To manually control the display and placement of the breadcrumbs display, you can define a DIV with class="breadCrumbs" in a custom [[PageTemplate]] or embed the {{{<<breadcrumbs>>}}} macro in specific tiddler content.
>
>For example, to add the breadcrumbs below the mainMenu, change this:
{{{
<div id='mainMenu' refresh='content' tiddler='MainMenu'></div>
}}}
>to:
{{{
<div id='mainMenu'>
	<div refresh='content' tiddler='MainMenu'></div>
	<div id='breadCrumbs' class='breadCrumbs'></div>
</div>
}}}
>You can also block automatic creation of the breadcrumbs display by setting
{{{
config.options.chkCreateDefaultBreadcrumbs=false;
}}}
>in a [[CookieJar]]/[[ConfigTweaks]] plugin tiddler.

__''other settings:''__
<<option chkShowBreadcrumbs>> show/hide breadcrumbs display
{{{<<option chkShowBreadcrumbs>>}}}
>This checkbox toggles the visibility of the breadcrumbs display.  However, the display is not updated until the next crumb is added (or a previous crumb is clicked on).  For immediate effect, the [[ToggleBreadcrumbs]] script uses [[InlineJavascriptPlugin]] to synchronize the checkbox setting and the breadcrumbs display.
<<option chkReorderBreadcrumbs>> re-order breadcrumbs when visiting a previously viewed tiddler
{{{<<option chkReorderBreadcrumbs>>}}}
>When visiting a previously viewed tiddler, the title of the most-recently displayed tiddler is simply moved to the end of the list and individual breadcrumbs are not removed from the list unless the underlying tiddler is deleted.  When ''re-ordering'' is disabled, the breadcrumbs list is ''trimmed'' so that all crumbs following that tiddler are removed from the list.
<<option chkBreadcrumbsHideHomeLink>> omit 'Home' link from breadcrumbs display
{{{<<option chkBreadcrumbsHideHomeLink>>}}}
>Enabling this option suppresses the automatic display of the "Home" link (and home separator).  To manually add the home link elsewhere in your document, use the following HTML:
{{{
<html><a href="javascript:;" onclick="config.macros.breadcrumbs.home()">home</a></html>
}}}
<<option chkBreadcrumbsSave>> prompt to save breadcrumbs when 'Home' link is pressed
{{{<<option chkBreadcrumbsSave>>}}}
>Whenever you press the 'home' button, you can be prompted to save the current breadcrumbs in a tiddler as a space-separated list of tiddler links (default title="SavedBreadcrumbs").  
<<option chkShowStartupBreadcrumbs>> show breadcrumbs for 'startup' tiddlers
{{{<<option chkShowStartupBreadcrumbs>>}}}
>Breadcrumbs are usually only added for tiddlers that are opened after the document has been loaded, and not for tiddlers displayed during initial startup (e.g., [[DefaultTiddlers]]).  Enabling this option displays breadcrumbs for all viewed tiddlers, regardless of when they are opened.
<<option chkBreadcrumbsReverse>> show breadcrumbs in reverse order
{{{<<option chkBreadcrumbsReverse>>}}}
>As tiddlers are displayed, breadcrumbs are usually added to the //end// of the list.  Enabling this option displays breadcrumbs in reverse order, so that the most recently visited tiddlers are listed first.
<<option chkBreadcrumbsLimit>> limit breadcrumbs display to {{twochar{<<option txtBreadcrumbsLimit>>}}} items
{{{<<option chkBreadcrumbsLimit>>}}} and {{{<<option txtBreadcrumbsLimit>>}}}
>By default, breadcrumbs are displayed for all tiddlers that have been visited (unless the list is being 'trimmed' by disabling the chkReorderBreadcrumbs option above).  Enabling this option limits the display of the list to a maximum specified number of breadcrumbs.
<<option chkBreadcrumbsLimitOpenTiddlers>> limit open tiddlers to {{twochar{<<option txtBreadcrumbsLimitOpenTiddlers>>}}} items
{{{<<option chkBreadcrumbsLimitOpenTiddlers>>}}} and {{{<<option txtBreadcrumbsLimitOpenTiddlers>>}}}
>By default, tiddlers remain open (e.g., displayed in the story column) until you explicitly close them.  When this option is enabled, only the most recently opened tiddlers will remain open: ''any tiddlers in excess of the specified limit are automatically closed.''  //Note: for 'data safety', if a tiddler is being edited, you will be asked for permission to "save-and-close" that tiddler or leave it open (even if that would exceed the specified limit).//
<<<
!!!!!Revisions
<<<
2009.03.22 [2.1.0] added 'save breadcrumbs to tiddler' feature
2008.05.01 [2.0.0] added 'limit open tiddlers' feature (with safety check for tiddler in edit mode)
2008.04.06 [1.9.1] corrected 'limit' logic so that //last// N crumbs are shown instead of //first// N crumbs.  Also, added chkBreadcrumbsHideHomeLink
2008.04.04 [1.9.0] added chkBreadcrumbsReverse and chk/txtBreadcrumbsLimit
2008.03.29 [1.8.4] in displayTiddler(), get title from tiddler object (if needed).  Fixes errors caused when calling function passes a tiddler *object* instead of a tiddler *title*
2008.03.24 [1.8.3] include shadow tiddlers in breadcrumbs list.  Also changed settings so that "reordering" breadcrumbs is the default, instead of "trimming" the list
2007.12.04 [*.*.*] update for TW2.3.0: replaced deprecated core functions, regexps, and macros
2007.10.26 [1.8.2] documentation cleanup
2007.10.18 [1.8.1] in GetAreas(), use try/catch to avoid "Bad NPObject as private data" fatal error caused when embedded QuickTime player element is accessed by hasClass() function.
2007.10.02 [1.8.0] major documentation and code cleanup.  Moved config.breadCrumbs.* to config.macros.breadcrumbs.* to consolidate objects.  Also, fixed homeSeparator and crumbSeparator default handling.
2007.10.02 [1.7.0] added config.options.chkShowStartupBreadcrumbs option
2007.09.16 [1.6.1] in getAreas(), removed errant use of 'place' (was causing fatal error when creating default breadcrumbs display element).  Also, added chkCreateDefaultBreadcrumbs configuration setting to enable/disable automatic creation of a default breadcrumbs display.
2007.09.16 [1.6.0] re-wrote refresh() to enable multiple display instances, by finding elements with "breadCrumbs" classname.  Fallback to fixed ID (="breadCrumbs") is still used for backward-compatibility.  move rendering code from refresh() to separate render() function, and added definition for {{{<<breadCrumbs>>}}} macro to support embedding breadcrumbs displays in tiddler content.
2007.09.15 [1.5.9.1] updated documentation
2007.09.15 [1.5.9] defined homeSeparator (" | ") and crumbSeparator (" > ") as object properties so that they can be redefined as desired for different layouts (e.g., using 'newline' for the crumbSeparator will arrange crumbs in a column rather than a row.
2007.06.21 [1.5.8.1] in home(), return false to prevent IE from attempting to navigate away...
2007.05.26 [1.5.8] added support for {{{<<option chkReorderBreadcrumbs>>}}} to toggle trim vs. re-order behavior when visiting previously viewed tiddlers
2007.05.25 [1.5.7] added support for {{{<<option chkShowBreadcrumbs>>}}} to toggle //display// of breadcrumbs
2007.05.24 [1.5.6] in refresh(), remove non-existing tiddler titles from crumb list.  Also, hijack removeTiddler() so crumbs can be updated after tiddler is deleted.
2007.04.11 [1.5.5] added optional params to previousTiddler macro handler() to allow alternative label and tooltip text (instead of default "back")
2007.03.02 [1.5.4] in refresh(), for TW2.2, look for "storyDisplay" instead of "tiddlerDisplay" but keep fallback to "tiddlerDisplay" for TW2.1 or earlier
2007.02.24 [1.5.3] changed from hijack of onClickTiddlerLink to hijack of displayTiddler() so that ALL displayed tiddlers are recorded in the crumbs, including programmatically displayed tiddlers opened by macros, scripts, etc., (such as [[GotoPlugin]], among many others) in addition to those opened by clicks on links.
2007.02.24 [1.5.2.0] eliminated global space clutter by moving function and data declarations so they are contained inside config.breadCrumbs object.
2007.02.06 [1.5.1] added "previousTiddler" macro (for use in sidebar)
2007.02.05 [1.5.0] added "previousTiddler" toolbar command (aka, "back")
2006.08.04 [1.4.0.1] change spaces to tabs
2006.08.04 [1.4.0] modified from 1.4.0 distro: in refresh(), set {{{display:none/block}}} instead of {{{visibility:hidden/visible}}}.  In home(), check for valid crumbArea before setting style.
2006.08.02 [1.4.0] Fixed bug, the redefined onClickTiddlerLink_orig_breadCrumbs works incorrectly on IE
2006.07.20 [1.3.0] Runs compatibly with TW 2.1.0 (rev #403+)
2006.02.07 [1.2.0] change global array breadCrumbs to config.breadCrumbs by Eric's suggestion
2006.02.04 [1.1.0] JSLint checked
2006.02.01 [1.0.0] initial release
<<<
/***
| Name:|CloseOnCancelPlugin|
| Description:|Closes the tiddler if you click new tiddler then cancel. Default behaviour is to leave it open|
| Version:|6.9.3|
| Date:|30-Sep-2006|
| Source:|http://mptw.tiddlyspot.com/#CloseOnCancelPlugin|
| Author:|Simon Baird <simon.baird@gmail.com>|
| CoreVersion:|2.1.x|
***/
//{{{
merge(config.commands.cancelTiddler,{

	handler_orig_closeUnsaved: config.commands.cancelTiddler.handler,

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

});

//}}}

Foreground: #000
Background: #fff
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
The [[ColorPalette]] tiddler is used in TiddlyWiki to define a set of colours - fifteen by default - whose names are then used in the [[StyleSheetColors]] tiddler. This system allow one to easily change the entire colour scheme of a TiddlyWiki site far more quickly than if one were to have change the colour for each style element.

|Background |#fff |@@bgcolor(#000000):color(#ffffff):Background@@ |@@bgcolor(#ffffff): &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @@|
|Foreground |#000 |@@color(#000000):Foreground@@ |@@bgcolor(#000000): &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @@|
|PrimaryPale |#8cf |@@color(#88ccff):~PrimaryPale@@ |@@bgcolor(#88ccff): &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @@|
|PrimaryLight |#18f |@@color(#1188ff):~PrimaryLight@@ |@@bgcolor(#1188ff): &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @@|
|PrimaryMid |#04b |@@color(#0044bb):~PrimaryMid@@ |@@bgcolor(#0044bb): &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @@|
|PrimaryDark |#017 |@@color(#001177):~PrimaryDark@@ |@@bgcolor(#001177): &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @@|
|SecondaryPale |#ffc |@@color(#ffffcc):~SecondaryPale@@ |@@bgcolor(#ffffcc): &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @@|
|SecondaryLight |#fe7 |@@color(#ffee77):~SecondaryLight@@ |@@bgcolor(#ffee77): &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @@|
|SecondaryMid |#db4 |@@color(#ddbb44):~SecondaryMid@@ |@@bgcolor(#ddbb44): &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @@|
|SecondaryDark  |#841 |@@color(#884411):~SecondaryDark@@ |@@bgcolor(#884411): &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @@|
|TertiaryPale |#eee |@@color(#eeeeee):~TertiaryPale@@ |@@bgcolor(#eeeeee): &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @@|
|TertiaryLight  |#ccc |@@color(#cccccc):~TertiaryLight@@ |@@bgcolor(#cccccc): &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @@|
|TertiaryMid |#999 |@@color(#999999):~TertiaryMid@@ |@@bgcolor(#999999): &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @@|
|TertiaryDark |#666 |@@color(#666666):~TertiaryDark@@ |@@bgcolor(#666666): &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @@|
|Error |#f77 |@@color(#ff7777):Error@@ |@@bgcolor(#ff7777): &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @@|
/*{{{*/
.large {
font-size:120%;
font-weight:bold;
}
.larger {
font-size:130%;
font-weight:bold;
}
.medium-large {
font-size:110%;
font-weight:bold;
}
.small {
font-size:85%;
font-weight:normal;
}
.smaller {
font-size:70%;
font-weight:normal;
}
.right {
text-align:right;
align:right;
}
.center {
text-align:center;
align:center;
}
.iframe {
font-size:85%;
}
.border-right {
padding-right:10px;
}
/* ''Header Levels'' */

h1, h2, h3, h4, h5 {
font-weight: bold;
text-decoration: none;
}

h1 {font-size: 1.35em;}
h2 {font-size: 1.25em;}
h3 {font-size: 1.1em;}
h4 {font-size: 1em;}
h5 {font-size: .9em;}

/*}}}*/
/* ''Borderless Table'' /*
/*{{{*/
.cleartable table {
border: 0;
}
/*}}}*/
config.options.chkDisableNonExistingWikiLinks=true;
config.options.chkSearchTitles=true;
config.options.chkSearchText=false;
config.options.chkSearchTags=false;
config.options.txtTheme="OnlineTheme";
/***
|''Name:''|CryptoFunctionsPlugin|
|''Description:''|Support for cryptographic functions|
***/
//{{{
if(!version.extensions.CryptoFunctionsPlugin) {
version.extensions.CryptoFunctionsPlugin = {installed:true};

//--
//-- Crypto functions and associated conversion routines
//--

// Crypto "namespace"
function Crypto() {}

// Convert a string to an array of big-endian 32-bit words
Crypto.strToBe32s = function(str)
{
	var be = Array();
	var len = Math.floor(str.length/4);
	var i, j;
	for(i=0, j=0; i<len; i++, j+=4) {
		be[i] = ((str.charCodeAt(j)&0xff) << 24)|((str.charCodeAt(j+1)&0xff) << 16)|((str.charCodeAt(j+2)&0xff) << 8)|(str.charCodeAt(j+3)&0xff);
	}
	while (j<str.length) {
		be[j>>2] |= (str.charCodeAt(j)&0xff)<<(24-(j*8)%32);
		j++;
	}
	return be;
};

// Convert an array of big-endian 32-bit words to a string
Crypto.be32sToStr = function(be)
{
	var str = "";
	for(var i=0;i<be.length*32;i+=8)
		str += String.fromCharCode((be[i>>5]>>>(24-i%32)) & 0xff);
	return str;
};

// Convert an array of big-endian 32-bit words to a hex string
Crypto.be32sToHex = function(be)
{
	var hex = "0123456789ABCDEF";
	var str = "";
	for(var i=0;i<be.length*4;i++)
		str += hex.charAt((be[i>>2]>>((3-i%4)*8+4))&0xF) + hex.charAt((be[i>>2]>>((3-i%4)*8))&0xF);
	return str;
};

// Return, in hex, the SHA-1 hash of a string
Crypto.hexSha1Str = function(str)
{
	return Crypto.be32sToHex(Crypto.sha1Str(str));
};

// Return the SHA-1 hash of a string
Crypto.sha1Str = function(str)
{
	return Crypto.sha1(Crypto.strToBe32s(str),str.length);
};

// Calculate the SHA-1 hash of an array of blen bytes of big-endian 32-bit words
Crypto.sha1 = function(x,blen)
{
	// Add 32-bit integers, wrapping at 32 bits
	add32 = function(a,b)
	{
		var lsw = (a&0xFFFF)+(b&0xFFFF);
		var msw = (a>>16)+(b>>16)+(lsw>>16);
		return (msw<<16)|(lsw&0xFFFF);
	};
	// Add five 32-bit integers, wrapping at 32 bits
	add32x5 = function(a,b,c,d,e)
	{
		var lsw = (a&0xFFFF)+(b&0xFFFF)+(c&0xFFFF)+(d&0xFFFF)+(e&0xFFFF);
		var msw = (a>>16)+(b>>16)+(c>>16)+(d>>16)+(e>>16)+(lsw>>16);
		return (msw<<16)|(lsw&0xFFFF);
	};
	// Bitwise rotate left a 32-bit integer by 1 bit
	rol32 = function(n)
	{
		return (n>>>31)|(n<<1);
	};

	var len = blen*8;
	// Append padding so length in bits is 448 mod 512
	x[len>>5] |= 0x80 << (24-len%32);
	// Append length
	x[((len+64>>9)<<4)+15] = len;
	var w = Array(80);

	var k1 = 0x5A827999;
	var k2 = 0x6ED9EBA1;
	var k3 = 0x8F1BBCDC;
	var k4 = 0xCA62C1D6;

	var h0 = 0x67452301;
	var h1 = 0xEFCDAB89;
	var h2 = 0x98BADCFE;
	var h3 = 0x10325476;
	var h4 = 0xC3D2E1F0;

	for(var i=0;i<x.length;i+=16) {
		var j,t;
		var a = h0;
		var b = h1;
		var c = h2;
		var d = h3;
		var e = h4;
		for(j = 0;j<16;j++) {
			w[j] = x[i+j];
			t = add32x5(e,(a>>>27)|(a<<5),d^(b&(c^d)),w[j],k1);
			e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
		}
		for(j=16;j<20;j++) {
			w[j] = rol32(w[j-3]^w[j-8]^w[j-14]^w[j-16]);
			t = add32x5(e,(a>>>27)|(a<<5),d^(b&(c^d)),w[j],k1);
			e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
		}
		for(j=20;j<40;j++) {
			w[j] = rol32(w[j-3]^w[j-8]^w[j-14]^w[j-16]);
			t = add32x5(e,(a>>>27)|(a<<5),b^c^d,w[j],k2);
			e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
		}
		for(j=40;j<60;j++) {
			w[j] = rol32(w[j-3]^w[j-8]^w[j-14]^w[j-16]);
			t = add32x5(e,(a>>>27)|(a<<5),(b&c)|(d&(b|c)),w[j],k3);
			e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
		}
		for(j=60;j<80;j++) {
			w[j] = rol32(w[j-3]^w[j-8]^w[j-14]^w[j-16]);
			t = add32x5(e,(a>>>27)|(a<<5),b^c^d,w[j],k4);
			e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
		}

		h0 = add32(h0,a);
		h1 = add32(h1,b);
		h2 = add32(h2,c);
		h3 = add32(h3,d);
		h4 = add32(h4,e);
	}
	return Array(h0,h1,h2,h3,h4);
};


}
//}}}
/*{{{*/
.clear table {
border: 0;
}
.principles {
font-family:comic sans ms;
}
.principles table {
border:0;
}
.principles td
font-size:130%
font-weight:bold;
border: 0;
)
.principles td.td
font-size:100%
font-weight:normal;
)
.accentuate {
font-weight:85;
color:red;
}

/*}}}*/
/***
|Name|HoverMenuPlugin|
|Created by|[[Saq Imtiaz]]|
|Location|http://tw.lewcid.org/#HoverMenuPlugin|
|Version|1.11|
|Requires|~TW2.x|
|Description: |Provides a hovering menu on the edge of the screen for commonly used commands, that scrolls with the page. |
|Demo: |Observe the hovering menu on the right edge of the screen. |
|Installation: |Copy the contents of this tiddler to your TW, tag with systemConfig, save and reload your TW. |
To customize your HoverMenu, edit the HoverMenu shadow tiddler.

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

The menu has an id of hoverMenu, in case you want to style the buttons in it using css.

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

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

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

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

!Code
***/

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

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

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

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

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

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


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

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

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

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

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

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

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

     return false;
}

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

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

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

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

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

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

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

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

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

window.isChild = function(e,parentId) {
        while (e != null) {
                var parent = document.getElementById(parentId);
                if (parent == e) return true;
                e = e.parentNode;
                }
        return false;
};
//}}}


[[Welcome]]
/***
|''Name:''|DeprecatedFunctionsPlugin|
|''Description:''|Support for deprecated functions removed from core|
***/
//{{{
if(!version.extensions.DeprecatedFunctionsPlugin) {
version.extensions.DeprecatedFunctionsPlugin = {installed:true};

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

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

// @Deprecated: Use enclosedTextHelper and this.lookaheadRegExp instead
config.formatterHelpers.monospacedByLineHelper = function(w)
{
	var lookaheadRegExp = new RegExp(this.lookahead,"mg");
	lookaheadRegExp.lastIndex = w.matchStart;
	var lookaheadMatch = lookaheadRegExp.exec(w.source);
	if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
		var text = lookaheadMatch[1];
		if(config.browser.isIE)
			text = text.replace(/\n/g,"\r");
		createTiddlyElement(w.output,"pre",null,null,text);
		w.nextMatch = lookaheadRegExp.lastIndex;
	}
};

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

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

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

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

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

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

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

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

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

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

}
//}}}
/***
|''Name:''|DisableWikiLinksPlugin|
|''Source:''|http://www.TiddlyTools.com/#DisableWikiLinksPlugin|
|''Author:''|Eric Shulman - ELS Design Studios|
|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|''~CoreVersion:''|2.0.10|

This plugin allows you to disable TiddlyWiki's automatic WikiWord linking behavior, so that WikiWords embedded in tiddler content will be rendered as regular text, instead of being automatically converted to tiddler links.  To create a tiddler link when automatic linking is disabled, you must enclose the link text within {{{[[...]]}}}.

You can also block automatic WikiWord linking behavior only for non-existing tiddler titles, while still automatically linking WikiWords that correspond to existing tiddlers titles or shadow tiddler titles.

You can also block specific selected WikiWords from being automatically linked by listing them in [[DisableWikiLinksList]], separated by whitespace.  This tiddler is optional and, when present, causes the listed words to always be excluded, even if automatic linking of other WikiWords is being permitted.  

Note: WikiWords contained in default ''shadow'' tiddlers will be automatically linked unless you select an additional checkbox option lets you disable these automatic links as well, though this is not recommended, since it can make it more difficult to access some TiddlyWiki standard default content (such as AdvancedOptions or SideBarTabs)

!!!!!Configuration
<<<
Self-contained control panel:
<<option chkDisableNonExistingWikiLinks>> Disable automatic WikiWord links for non-existing tiddlers
<<option chkDisableWikiLinks>> Disable ALL automatic WikiWord tiddler links
<<option chkAllowLinksFromShadowTiddlers>> ... except for WikiWords contained in shadow tiddlers
<<<
!!!!!Installation
<<<
import (or copy/paste) the following tiddlers into your document:
''DisableWikiLinksPlugin'' (tagged with <<tag systemConfig>>)
<<<
!!!!!Revision History
<<<
''2006.12.31 [1.4.0]'' in formatter, test for chkDisableNonExistingWikiLinks
''2006.12.09 [1.3.0]'' in formatter, test for excluded wiki words specified in DisableWikiLinksList
''2006.12.09 [1.2.2]'' fix logic in autoLinkWikiWords() (was allowing links TO shadow tiddlers, even when chkDisableWikiLinks is TRUE).  
''2006.12.09 [1.2.1]'' revised logic for handling links in shadow content
''2006.12.08 [1.2.0]'' added hijack of Tiddler.prototype.autoLinkWikiWords so regular (non-bracketed) WikiWords won't be added to the missing list
''2006.05.24 [1.1.0]'' added option to NOT bypass automatic wikiword links when displaying default shadow content (default is to auto-link shadow content)
''2006.02.05 [1.0.1]'' wrapped wikifier hijack in init function to eliminate globals and avoid FireFox 1.5.0.1 crash bug when referencing globals
''2005.12.09 [1.0.0]'' initial release
<<<
!!!!!Credits
<<<
This feature was developed by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]]
<<<
!!!!!Code
***/
//{{{
version.extensions.disableWikiLinks= {major: 1, minor: 4, revision: 0, date: new Date(2006,12,31)};

if (config.options.chkDisableNonExistingWikiLinks==undefined) config.options.chkDisableNonExistingWikiLinks= false;
if (config.options.chkDisableWikiLinks==undefined) config.options.chkDisableWikiLinks= false;
if (config.options.chkAllowLinksFromShadowTiddlers==undefined) config.options.chkAllowLinksFromShadowTiddlers=true;

// find the formatter for wikiLink and replace handler with 'pass-thru' rendering
initDisableWikiLinksFormatter();
function initDisableWikiLinksFormatter() {
	for (var i=0; i<config.formatters.length && config.formatters[i].name!="wikiLink"; i++);
	config.formatters[i].coreHandler=config.formatters[i].handler;
	config.formatters[i].handler=function(w) {
		// supress any leading "~" (if present)
		var skip=(w.matchText.substr(0,1)==config.textPrimitives.unWikiLink)?1:0;
		var title=w.matchText.substr(skip);
		var exists=store.tiddlerExists(title);
		var inShadow=w.tiddler && store.isShadowTiddler(w.tiddler.title);

		// check for specific excluded wiki words
		var t=store.getTiddlerText("DisableWikiLinksList")
		if (t && t.length && t.indexOf(w.matchText)!=-1)
			{ w.outputText(w.output,w.matchStart+skip,w.nextMatch); return; }

		// if not disabling links from shadows (default setting)
		if (config.options.chkAllowLinksFromShadowTiddlers && inShadow)
			return this.coreHandler(w);

		// check for non-existing non-shadow tiddler
		if (config.options.chkDisableNonExistingWikiLinks && !exists)
			{ w.outputText(w.output,w.matchStart+skip,w.nextMatch); return; }

		// if not enabled, just do standard WikiWord link formatting
		if (!config.options.chkDisableWikiLinks)
			return this.coreHandler(w);

		// just return text without linking
		w.outputText(w.output,w.matchStart+skip,w.nextMatch)
	}
}

Tiddler.prototype.coreAutoLinkWikiWords = Tiddler.prototype.autoLinkWikiWords;
Tiddler.prototype.autoLinkWikiWords = function()
{
	// DEBUG alert("processing: "+this.title);
	// if all automatic links are not disabled, just return results from core function
	if (!config.options.chkDisableWikiLinks)
		return this.coreAutoLinkWikiWords.apply(this,arguments);
	return false;
}
//}}}
<!--{{{-->
<div class='toolbar' macro='toolbar +saveTiddler -cancelTiddler deleteTiddler jump'></div>
<div class='title' macro='view title'></div>
<div class='editor' macro='edit title'></div>
<div class='editor' macro='edit text'></div>
<div class='editor' macro='edit tags'></div>
<div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser'></span></div>
<div class='toolbar' macro='toolbar +saveTiddler -cancelTiddler deleteTiddler jump'></div>
<!--}}}-->
/***
|Name|ExportTiddlersPlugin|
|Source|http://www.TiddlyTools.com/#ExportTiddlersPlugin|
|Version|2.4.1|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <<br>>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|select and extract tiddlers from your ~TiddlyWiki documents and save them to a local file|

When many people edit copies of the same TiddlyWiki document, the ability to easily copy and share these changes so they can then be redistributed to the entire group is very important.  This ability is also very useful when moving your own tiddlers from document to document (e.g., when upgrading to the latest version of TiddlyWiki, or 'pre-loading' your favorite stylesheets into a new 'empty' TiddlyWiki document.)

ExportTiddlersPlugin let you ''select and extract tiddlers from your ~TiddlyWiki documents and save them to a local file'' or a remote server (requires installation of compatible server-side scripting, still under development...).  An interactive control panel lets you specify a destination, and then select which tiddlers to export.  A convenient 'selection filter' helps you pick desired tiddlers by specifying a combination of modification dates, tags, or tiddler text to be matched or excluded.  ''Tiddler data can be output as ~TiddlyWiki "storeArea ~DIVs" that can be imported into another ~TiddlyWiki or as ~RSS-compatible XML that can be published for RSS syndication.''

!!!!!Inline interface (live)
<<<
<<exportTiddlers inline>>
<<<
!!!!!Usage
<<<
Optional "special tiddlers" used by this plugin:
* SiteUrl^^
URL for official server-published version of document being viewed (used in XML export)
default: //none//^^
* SiteHost^^
host name/address for remote server (e.g., "www.server.com" or "192.168.1.27")
default: //none//^^
* SitePost^^
remote path/filename for submitting changes (e.g., "/cgi-bin/submit.cgi")
default: //none//^^
* SiteParams^^
arguments (if any) for server-side receiving script
default: //none//^^
* SiteNotify^^
addresses (if any) for sending automatic server-side email notices
default: //none//^^
* SiteID^^
username or other authorization identifier for login-controlled access to remote server
default: current TiddlyWiki username (e.g., "YourName")^^
* SiteDate^^
stored date/time stamp for most recent published version of document
default: current document.modified value (i.e., the 'file date')^^
<<<
!!!!!Example
<<<
<<exportTiddlers>>
<<<
!!!!!Installation
<<<
Import (or copy/paste) the following tiddlers into your document:
''ExportTiddlersPlugin'' (tagged with <<tag systemConfig>>)

create/edit ''SideBarOptions'': (sidebar menu items) 
^^Add {{{<<exportTiddlers>>}}} macro^^
<<<
!!!!!Revision History
<<<
''2007.07.16 [2.4.1]'' in exportTWHeader(), reset HTML source 'markup' so installed markup is NOT copied to new file.
''2007.06.30 [2.4.0]'' added "select related tiddlers" feature.  Recursively scans the tiddler links[] info to find all tiddlers referenced by any of the currently selected tiddler, and then selects them all (including the original tiddlers).  ''//Theoretically//'', selecting all related tiddlers should ensure that the exported file contains all tiddlers needed to properly render all of the originally selected tiddlers.
''2007.04.19 [2.3.0]'' in exportData(), pass SiteURL value as param to saveToRss().  Fixes 'undefined' appearing in tiddler link in XML output.  Also, in refreshExportList(), added 'sort by tags'.  Also, added 'group select'... selecting a heading (date,author,tag) auto-selects all tiddlers in that group.
''2007.03.02 [2.2.6]'' in onClickExportButton(), when selecting open tiddlers for TW2.2, look for "storyDisplay" instead of "tiddlerDisplay" but keep fallback to "tiddlerDisplay" for TW2.1 or earlier
''2007.03.01 [2.2.5]'' removed hijack of store.saveChanges() (was catching save on http:, but there are other solutions that do a much better job of handling save to server.
|please see [[ExportTiddlersPluginHistory]] for additional revision details|
''2005.10.09 [0.0.0]'' development started
<<<
!!!!!Credits
<<<
This feature was developed by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]]
<<<
!!!!!Code
***/
// // version
//{{{
version.extensions.exportTiddlers = {major: 2, minor: 4, revision: 1, date: new Date(2007,7,16)};
//}}}

// // macro handler
//{{{
config.macros.exportTiddlers = {
	label: "export tiddlers",
	prompt: "Copy selected tiddlers to an export document",
	newdefault: "export.html",
	datetimefmt: "0MM/0DD/YYYY 0hh:0mm:0ss" // for "filter date/time" edit fields
};

config.macros.exportTiddlers.handler = function(place,macroName,params) {
	if (params[0]!="inline")
		{ createTiddlyButton(place,this.label,this.prompt,onClickExportMenu); return; }
	var panel=createExportPanel(place);
	panel.style.position="static";
	panel.style.display="block";
}

function createExportPanel(place) {
	var panel=document.getElementById("exportPanel");
	if (panel) { panel.parentNode.removeChild(panel); }
	setStylesheet(config.macros.exportTiddlers.css,"exportTiddlers");
	panel=createTiddlyElement(place,"span","exportPanel",null,null)
	panel.innerHTML=config.macros.exportTiddlers.html;
	exportShowPanel(document.location.protocol);
	exportInitFilter();
	refreshExportList(0);
	return panel;
}

function onClickExportMenu(e)
{
	if (!e) var e = window.event;
	var parent=resolveTarget(e).parentNode;
	var panel = document.getElementById("exportPanel");
	if (panel==undefined || panel.parentNode!=parent)
		panel=createExportPanel(parent);
	var isOpen = panel.style.display=="block";
	if(config.options.chkAnimate)
		anim.startAnimating(new Slider(panel,!isOpen,e.shiftKey || e.altKey,"none"));
	else
		panel.style.display = isOpen ? "none" : "block" ;
	if (panel.style.display!="none") refreshExportList(0); // update list when panel is made visible
	e.cancelBubble = true;
	if (e.stopPropagation) e.stopPropagation();
	return(false);
}
//}}}

// // IE needs explicit scoping for functions called by browser events
//{{{
window.onClickExportMenu=onClickExportMenu;
window.onClickExportButton=onClickExportButton;
window.exportShowPanel=exportShowPanel;
window.exportShowFilterFields=exportShowFilterFields;
window.refreshExportList=refreshExportList;
//}}}

// // CSS for floating export control panel
//{{{
config.macros.exportTiddlers.css = '\
#exportPanel {\
	display: none; position:absolute; z-index:12; width:35em; right:105%; top:6em;\
	background-color: #eee; color:#000; font-size: 8pt; line-height:110%;\
	border:1px solid black; border-bottom-width: 3px; border-right-width: 3px;\
	padding: 0.5em; margin:0em; -moz-border-radius:1em;\
}\
#exportPanel a, #exportPanel td a { color:#009; display:inline; margin:0px; padding:1px; }\
#exportPanel table { width:100%; border:0px; padding:0px; margin:0px; font-size:8pt; line-height:110%; background:transparent; }\
#exportPanel tr { border:0px;padding:0px;margin:0px; background:transparent; }\
#exportPanel td { color:#000; border:0px;padding:0px;margin:0px; background:transparent; }\
#exportPanel select { width:98%;margin:0px;font-size:8pt;line-height:110%;}\
#exportPanel input  { width:98%;padding:0px;margin:0px;font-size:8pt;line-height:110%; }\
#exportPanel textarea  { width:98%;padding:0px;margin:0px;overflow:auto;font-size:8pt; }\
#exportPanel .box { border:1px solid black; padding:3px; margin-bottom:5px; background:#f8f8f8; -moz-border-radius:5px; }\
#exportPanel .topline { border-top:2px solid black; padding-top:3px; margin-bottom:5px; }\
#exportPanel .rad { width:auto;border:0 }\
#exportPanel .chk { width:auto;border:0 }\
#exportPanel .btn { width:auto; }\
#exportPanel .btn1 { width:98%; }\
#exportPanel .btn2 { width:48%; }\
#exportPanel .btn3 { width:32%; }\
#exportPanel .btn4 { width:24%; }\
#exportPanel .btn5 { width:19%; }\
';
//}}}

// // HTML for export control panel interface
//{{{
config.macros.exportTiddlers.html = '\
<!-- output target and format -->\
<table cellpadding="0" cellspacing="0"><tr><td width=50%>\
	export to\
	<select size=1 id="exportTo" onchange="exportShowPanel(this.value);">\
	<option value="file:" SELECTED>this computer</option>\
	<option value="http:">web server (http)</option>\
	<option value="https:">secure web server (https)</option>\
	<option value="ftp:">file server (ftp)</option>\
	</select>\
</td><td width=50%>\
	output format\
	<select id="exportFormat" size=1>\
	<option value="DIV">TiddlyWiki export file</option>\
	<option value="TW">TiddlyWiki document</option>\
	<option value="XML">RSS feed (XML)</option>\
	</select>\
</td></tr></table>\
\
<!-- export to local file  -->\
<div id="exportLocalPanel" style="margin-top:5px;">\
local path/filename<br>\
<input type="text" id="exportFilename" size=40 style="width:93%"><input \
	type="button" id="exportBrowse" value="..." title="select or enter a local folder/file..." style="width:5%" \
	onclick="this.previousSibling.value=window.promptForExportFilename(this);">\
<!--<input type="file" id="exportFilename" size=57 style="width:100%"><br>-->\
</div><!--panel-->\
\
<!-- export to http server -->\
<div id="exportHTTPPanel" style="display:none;margin-top:5px;">\
<table><tr><td align=left>\
	server location, script, and parameters<br>\
</td><td align=right>\
	<input type="checkbox" class="chk" id="exportNotify"\
		onClick="document.getElementById(\'exportSetNotifyPanel\').style.display=this.checked?\'block\':\'none\'"> notify\
</td></tr></table>\
<input type="text" id="exportHTTPServerURL" onfocus="this.select()"><br>\
<div id="exportSetNotifyPanel" style="display:none">\
	send email notices to<br>\
	<input type="text" id="exportNotifyTo" onfocus="this.select()"><br>\
</div>\
</div><!--panel-->\
\
<!-- export to ftp server -->\
<div id="exportFTPPanel" style="display:none;margin-top:5px;">\
<table cellpadding="0" cellspacing="0" width="32%"><tr valign="top"><td>\
	host server<br>\
	<input type="text" id="exportFTPHost" onfocus="this.select()"><br>\
</td><td width="32%">\
	username<br>\
	<input type="text" id="exportFTPID" onfocus="this.select()"><br>\
</td><td width="32%">\
	password<br>\
	<input type="password" id="exportFTPPW" onfocus="this.select()"><br>\
</td></tr></table>\
FTP path/filename<br>\
<input type="text" id="exportFTPFilename" onfocus="this.select()"><br>\
</div><!--panel-->\
\
<!-- notes -->\
notes<br>\
<textarea id="exportNotes" rows=3 cols=40 style="height:4em;margin-bottom:5px;" onfocus="this.select()"></textarea> \
\
<!-- list of tiddlers -->\
<table><tr align="left"><td>\
	select:\
	<a href="JavaScript:;" id="exportSelectAll"\
		onclick="onClickExportButton(this)" title="select all tiddlers">\
		&nbsp;all&nbsp;</a>\
	<a href="JavaScript:;" id="exportSelectChanges"\
		onclick="onClickExportButton(this)" title="select tiddlers changed since last save">\
		&nbsp;changes&nbsp;</a> \
	<a href="JavaScript:;" id="exportSelectOpened"\
		onclick="onClickExportButton(this)" title="select tiddlers currently being displayed">\
		&nbsp;opened&nbsp;</a> \
	<a href="JavaScript:;" id="exportSelectRelated"\
		onclick="onClickExportButton(this)" title="select all tiddlers related (by link or transclusion) to the currently selected tiddlers">\
		&nbsp;related&nbsp;</a> \
	<a href="JavaScript:;" id="exportToggleFilter"\
		onclick="onClickExportButton(this)" title="show/hide selection filter">\
		&nbsp;filter&nbsp;</a>  \
</td><td align="right">\
	<a href="JavaScript:;" id="exportListSmaller"\
		onclick="onClickExportButton(this)" title="reduce list size">\
		&nbsp;&#150;&nbsp;</a>\
	<a href="JavaScript:;" id="exportListLarger"\
		onclick="onClickExportButton(this)" title="increase list size">\
		&nbsp;+&nbsp;</a>\
</td></tr></table>\
<select id="exportList" multiple size="10" style="margin-bottom:5px;"\
	onchange="refreshExportList(this.selectedIndex)">\
</select><br>\
</div><!--box-->\
\
<!-- selection filter -->\
<div id="exportFilterPanel" style="display:none">\
<table><tr align="left"><td>\
	selection filter\
</td><td align="right">\
	<a href="JavaScript:;" id="exportHideFilter"\
		onclick="onClickExportButton(this)" title="hide selection filter">hide</a>\
</td></tr></table>\
<div class="box">\
<input type="checkbox" class="chk" id="exportFilterStart" value="1"\
	onclick="exportShowFilterFields(this)"> starting date/time<br>\
<table cellpadding="0" cellspacing="0"><tr valign="center"><td width="50%">\
	<select size=1 id="exportFilterStartBy" onchange="exportShowFilterFields(this);">\
		<option value="0">today</option>\
		<option value="1">yesterday</option>\
		<option value="7">a week ago</option>\
		<option value="30">a month ago</option>\
		<option value="site">SiteDate</option>\
		<option value="file">file date</option>\
		<option value="other">other (mm/dd/yyyy hh:mm)</option>\
	</select>\
</td><td width="50%">\
	<input type="text" id="exportStartDate" onfocus="this.select()"\
		onchange="document.getElementById(\'exportFilterStartBy\').value=\'other\';">\
</td></tr></table>\
<input type="checkbox" class="chk" id="exportFilterEnd" value="1"\
	onclick="exportShowFilterFields(this)"> ending date/time<br>\
<table cellpadding="0" cellspacing="0"><tr valign="center"><td width="50%">\
	<select size=1 id="exportFilterEndBy" onchange="exportShowFilterFields(this);">\
		<option value="0">today</option>\
		<option value="1">yesterday</option>\
		<option value="7">a week ago</option>\
		<option value="30">a month ago</option>\
		<option value="site">SiteDate</option>\
		<option value="file">file date</option>\
		<option value="other">other (mm/dd/yyyy hh:mm)</option>\
	</select>\
</td><td width="50%">\
	<input type="text" id="exportEndDate" onfocus="this.select()"\
		onchange="document.getElementById(\'exportFilterEndBy\').value=\'other\';">\
</td></tr></table>\
<input type="checkbox" class="chk" id=exportFilterTags value="1"\
	onclick="exportShowFilterFields(this)"> match tags<br>\
<input type="text" id="exportTags" onfocus="this.select()">\
<input type="checkbox" class="chk" id=exportFilterText value="1"\
	onclick="exportShowFilterFields(this)"> match titles/tiddler text<br>\
<input type="text" id="exportText" onfocus="this.select()">\
</div> <!--box-->\
</div> <!--panel-->\
\
<!-- action buttons -->\
<div style="text-align:center">\
<input type=button class="btn3" onclick="onClickExportButton(this)"\
	id="exportFilter" value="apply filter">\
<input type=button class="btn3" onclick="onClickExportButton(this)"\
	id="exportStart" value="export tiddlers">\
<input type=button class="btn3" onclick="onClickExportButton(this)"\
	id="exportClose" value="close">\
</div><!--center-->\
';
//}}}

// // initialize interface
// // exportShowPanel(which)
//{{{
function exportShowPanel(which) {
	var index=0; var panel='exportLocalPanel';
	switch (which) {
		case 'file:':
		case undefined:
			index=0; panel='exportLocalPanel'; break;
		case 'http:':
			index=1; panel='exportHTTPPanel'; break;
		case 'https:':
			index=2; panel='exportHTTPPanel'; break;
		case 'ftp:':
			index=3; panel='exportFTPPanel'; break;
		default:
			alert("Sorry, export to "+which+" is not yet available");
			break;
	}
	exportInitPanel(which);
	document.getElementById('exportTo').selectedIndex=index;
	document.getElementById('exportLocalPanel').style.display='none';
	document.getElementById('exportHTTPPanel').style.display='none';
	document.getElementById('exportFTPPanel').style.display='none';
	document.getElementById(panel).style.display='block';
}
//}}}

// // exportInitPanel(which)
//{{{
function exportInitPanel(which) {
	switch (which) {
		case "file:": // LOCAL EXPORT PANEL: file/path:
			// ** no init - security issues in IE **
			break;
		case "http:": // WEB EXPORT PANEL
		case "https:": // SECURE WEB EXPORT PANEL
			// url
			if (store.tiddlerExists("unawiki_download")) {
				var theURL=store.getTiddlerText("unawiki_download");
				theURL=theURL.replace(/\[\[download\|/,'').replace(/\]\]/,'');
				var title=(store.tiddlerExists("unawiki_host"))?"unawiki_host":"SiteHost";
				var theHost=store.getTiddlerText(title);
				if (!theHost || !theHost.length) theHost=document.location.host;
				if (!theHost || !theHost.length) theHost=title;
			}
			// server script/params
			var title=(store.tiddlerExists("unawiki_host"))?"unawiki_host":"SiteHost";
			var theHost=store.getTiddlerText(title);
			if (!theHost || !theHost.length) theHost=document.location.host;
			if (!theHost || !theHost.length) theHost=title;
			// get POST
			var title=(store.tiddlerExists("unawiki_post"))?"unawiki_post":"SitePost";
			var thePost=store.getTiddlerText(title);
			if (!thePost || !thePost.length) thePost="/"+title;
			// get PARAMS
			var title=(store.tiddlerExists("unawiki_params"))?"unawiki_params":"SiteParams";
			var theParams=store.getTiddlerText(title);
			if (!theParams|| !theParams.length) theParams=title;
			var serverURL = which+"//"+theHost+thePost+"?"+theParams;
			document.getElementById("exportHTTPServerURL").value=serverURL;
			// get NOTIFY
			var theAddresses=store.getTiddlerText("SiteNotify");
			if (!theAddresses|| !theAddresses.length) theAddresses="SiteNotify";
			document.getElementById("exportNotifyTo").value=theAddresses;
			break;
		case "ftp:": // FTP EXPORT PANEL
			// host
			var siteHost=store.getTiddlerText("SiteHost");
			if (!siteHost || !siteHost.length) siteHost=document.location.host;
			if (!siteHost || !siteHost.length) siteHost="SiteHost";
			document.getElementById("exportFTPHost").value=siteHost;
			// username
			var siteID=store.getTiddlerText("SiteID");
			if (!siteID || !siteID.length) siteID=config.options.txtUserName;
			document.getElementById("exportFTPID").value=siteID;
			// password
			document.getElementById("exportFTPPW").value="";
			// file/path
			document.getElementById("exportFTPFilename").value="";
			break;
	}
}
//}}}

// // exportInitFilter()
//{{{
function exportInitFilter() {
	// start date
	document.getElementById("exportFilterStart").checked=false;
	document.getElementById("exportStartDate").value="";
	// end date
	document.getElementById("exportFilterEnd").checked=false;
	document.getElementById("exportEndDate").value="";
	// tags
	document.getElementById("exportFilterTags").checked=false;
	document.getElementById("exportTags").value="";
	// text
	document.getElementById("exportFilterText").checked=false;
	document.getElementById("exportText").value="";
	// show/hide filter input fields
	exportShowFilterFields();
}
//}}}

// // exportShowFilterFields(which)
//{{{
function exportShowFilterFields(which) {
	var show;

	show=document.getElementById('exportFilterStart').checked;
	document.getElementById('exportFilterStartBy').style.display=show?"block":"none";
	document.getElementById('exportStartDate').style.display=show?"block":"none";
	var val=document.getElementById('exportFilterStartBy').value;
	document.getElementById('exportStartDate').value
		=getFilterDate(val,'exportStartDate').formatString(config.macros.exportTiddlers.datetimefmt);
	 if (which && (which.id=='exportFilterStartBy') && (val=='other'))
		document.getElementById('exportStartDate').focus();

	show=document.getElementById('exportFilterEnd').checked;
	document.getElementById('exportFilterEndBy').style.display=show?"block":"none";
	document.getElementById('exportEndDate').style.display=show?"block":"none";
	var val=document.getElementById('exportFilterEndBy').value;
	document.getElementById('exportEndDate').value
		=getFilterDate(val,'exportEndDate').formatString(config.macros.exportTiddlers.datetimefmt);
	 if (which && (which.id=='exportFilterEndBy') && (val=='other'))
		document.getElementById('exportEndDate').focus();

	show=document.getElementById('exportFilterTags').checked;
	document.getElementById('exportTags').style.display=show?"block":"none";

	show=document.getElementById('exportFilterText').checked;
	document.getElementById('exportText').style.display=show?"block":"none";
}
//}}}

// // onClickExportButton(which): control interactions
//{{{
function onClickExportButton(which)
{
	// DEBUG alert(which.id);
	var theList=document.getElementById('exportList'); if (!theList) return;
	var count = 0;
	var total = store.getTiddlers('title').length;
	switch (which.id)
		{
		case 'exportFilter':
			count=filterExportList();
			var panel=document.getElementById('exportFilterPanel');
			if (count==-1) { panel.style.display='block'; break; }
			document.getElementById("exportStart").disabled=(count==0);
			clearMessage(); displayMessage("filtered "+formatExportMessage(count,total));
			if (count==0) { alert("No tiddlers were selected"); panel.style.display='block'; }
			break;
		case 'exportStart':
			exportTiddlers();
			break;
		case 'exportHideFilter':
		case 'exportToggleFilter':
			var panel=document.getElementById('exportFilterPanel')
			panel.style.display=(panel.style.display=='block')?'none':'block';
			break;
		case 'exportSelectChanges':
			var lastmod=new Date(document.lastModified);
			for (var t = 0; t < theList.options.length; t++) {
				if (theList.options[t].value=="") continue;
				var tiddler=store.getTiddler(theList.options[t].value); if (!tiddler) continue;
				theList.options[t].selected=(tiddler.modified>lastmod);
				count += (tiddler.modified>lastmod)?1:0;
			}
			document.getElementById("exportStart").disabled=(count==0);
			clearMessage(); displayMessage(formatExportMessage(count,total));
			if (count==0) alert("There are no unsaved changes");
			break;
		case 'exportSelectAll':
			for (var t = 0; t < theList.options.length; t++) {
				if (theList.options[t].value=="") continue;
				theList.options[t].selected=true;
				count += 1;
			}
			document.getElementById("exportStart").disabled=(count==0);
			clearMessage(); displayMessage(formatExportMessage(count,count));
			break;
		case 'exportSelectOpened':
			for (var t = 0; t < theList.options.length; t++) theList.options[t].selected=false;
			var tiddlerDisplay = document.getElementById("tiddlerDisplay"); // for TW2.1-
			if (!tiddlerDisplay) tiddlerDisplay = document.getElementById("storyDisplay"); // for TW2.2+
			for (var t=0;t<tiddlerDisplay.childNodes.length;t++) {
				var tiddler=tiddlerDisplay.childNodes[t].id.substr(7);
				for (var i = 0; i < theList.options.length; i++) {
					if (theList.options[i].value!=tiddler) continue;
					theList.options[i].selected=true; count++; break;
				}
			}
			document.getElementById("exportStart").disabled=(count==0);
			clearMessage(); displayMessage(formatExportMessage(count,total));
			if (count==0) alert("There are no tiddlers currently opened");
			break;
		case 'exportSelectRelated':
			// recursively build list of related tiddlers
			function getRelatedTiddlers(tid,tids) {
				var t=store.getTiddler(tid); if (!t || tids.contains(tid)) return tids;
				tids.push(t.title);
				if (!t.linksUpdated) t.changed();
				for (var i=0; i<t.links.length; i++)
					if (t.links[i]!=tid) tids=getRelatedTiddlers(t.links[i],tids);
				return tids;
			}
			// for all currently selected tiddlers, gather up the related tiddlers (including self) and select them as well
			var tids=[];
			for (var i=0; i<theList.options.length; i++)
				if (theList.options[i].selected) tids=getRelatedTiddlers(theList.options[i].value,tids);
			// select related tiddlers (includes original selected tiddlers)
			for (var i=0; i<theList.options.length; i++)
				theList.options[i].selected=tids.contains(theList.options[i].value);
			clearMessage(); displayMessage(formatExportMessage(tids.length,total));
			break;
		case 'exportListSmaller':	// decrease current listbox size
			var min=5;
			theList.size-=(theList.size>min)?1:0;
			break;
		case 'exportListLarger':	// increase current listbox size
			var max=(theList.options.length>25)?theList.options.length:25;
			theList.size+=(theList.size<max)?1:0;
			break;
		case 'exportClose':
			document.getElementById('exportPanel').style.display='none';
			break;
		}
}
//}}}

// // list display
//{{{
function formatExportMessage(count,total)
{
	var txt=total+' tiddler'+((total!=1)?'s':'')+" - ";
	txt += (count==0)?"none":(count==total)?"all":count;
	txt += " selected for export";
	return txt;
}

function refreshExportList(selectedIndex)
{
	var theList  = document.getElementById("exportList");
	var sort;
	if (!theList) return;
	// get the sort order
	if (!selectedIndex)   selectedIndex=0;
	if (selectedIndex==0) sort='modified';
	if (selectedIndex==1) sort='title';
	if (selectedIndex==2) sort='modified';
	if (selectedIndex==3) sort='modifier';
	if (selectedIndex==4) sort='tags';

	// unselect headings and count number of tiddlers actually selected
	for (var t=0,count=0; t < theList.options.length; t++) {
		if (!theList.options[t].selected) continue;
		if (theList.options[t].value!="")
			count++;
		else { // if heading is selected, deselect it, and then select and count all in section
			theList.options[t].selected=false;
			for ( t++; t<theList.options.length && theList.options[t].value!=""; t++) {
				theList.options[t].selected=true;
				count++;
			}
		}
	}

	// disable "export" button if no tiddlers selected
	document.getElementById("exportStart").disabled=(count==0);
	// show selection count
	var tiddlers = store.getTiddlers('title');
	if (theList.options.length) { clearMessage(); displayMessage(formatExportMessage(count,tiddlers.length)); }

	// if a [command] item, reload list... otherwise, no further refresh needed
	if (selectedIndex>4)  return;

	// clear current list contents
	while (theList.length > 0) { theList.options[0] = null; }
	// add heading and control items to list
	var i=0;
	var indent=String.fromCharCode(160)+String.fromCharCode(160);
	theList.options[i++]=
		new Option(tiddlers.length+" tiddlers in document", "",false,false);
	theList.options[i++]=
		new Option(((sort=="title"        )?">":indent)+' [by title]', "",false,false);
	theList.options[i++]=
		new Option(((sort=="modified")?">":indent)+' [by date]', "",false,false);
	theList.options[i++]=
		new Option(((sort=="modifier")?">":indent)+' [by author]', "",false,false);
	theList.options[i++]=
		new Option(((sort=="tags"	)?">":indent)+' [by tags]', "",false,false);
	// output the tiddler list
	switch(sort)
		{
		case "title":
			for(var t = 0; t < tiddlers.length; t++)
				theList.options[i++] = new Option(tiddlers[t].title,tiddlers[t].title,false,false);
			break;
		case "modifier":
		case "modified":
			var tiddlers = store.getTiddlers(sort);
			// sort descending for newest date first
			tiddlers.sort(function (a,b) {if(a[sort] == b[sort]) return(0); else return (a[sort] > b[sort]) ? -1 : +1; });
			var lastSection = "";
			for(var t = 0; t < tiddlers.length; t++)
				{
				var tiddler = tiddlers[t];
				var theSection = "";
				if (sort=="modified") theSection=tiddler.modified.toLocaleDateString();
				if (sort=="modifier") theSection=tiddler.modifier;
				if (theSection != lastSection)
					{
					theList.options[i++] = new Option(theSection,"",false,false);
					lastSection = theSection;
					}
				theList.options[i++] = new Option(indent+indent+tiddler.title,tiddler.title,false,false);
				}
			 break;
		case "tags":
			var theTitles = {}; // all tiddler titles, hash indexed by tag value
			var theTags = new Array();
			for(var t=0; t<tiddlers.length; t++) {
				var title=tiddlers[t].title;
				var tags=tiddlers[t].tags;
				if (!tags || !tags.length) {
					if (theTitles["untagged"]==undefined) { theTags.push("untagged"); theTitles["untagged"]=new Array(); }
					theTitles["untagged"].push(title);
				}
				else for(var s=0; s<tags.length; s++) {
					if (theTitles[tags[s]]==undefined) { theTags.push(tags[s]); theTitles[tags[s]]=new Array(); }
					theTitles[tags[s]].push(title);
				}
			}
			theTags.sort();
			for(var tagindex=0; tagindex<theTags.length; tagindex++) {
				var theTag=theTags[tagindex];
				theList.options[i++]=new Option(theTag,"",false,false);
				for(var t=0; t<theTitles[theTag].length; t++)
					theList.options[i++]=new Option(indent+indent+theTitles[theTag][t],theTitles[theTag][t],false,false);
			}
			break;
		}
	theList.selectedIndex=selectedIndex;		  // select current control item
}
//}}}

// // list filtering
//{{{
function getFilterDate(val,id)
{
	var result=0;
	switch (val) {
		case 'site':
			var timestamp=store.getTiddlerText("SiteDate");
			if (!timestamp) timestamp=document.lastModified;
			result=new Date(timestamp);
			break;
		case 'file':
			result=new Date(document.lastModified);
			break;
		case 'other':
			result=new Date(document.getElementById(id).value);
			break;
		default: // today=0, yesterday=1, one week=7, two weeks=14, a month=31
			var now=new Date(); var tz=now.getTimezoneOffset()*60000; now-=tz;
			var oneday=86400000;
			if (id=='exportStartDate')
				result=new Date((Math.floor(now/oneday)-val)*oneday+tz);
			else
				result=new Date((Math.floor(now/oneday)-val+1)*oneday+tz-1);
			break;
	}
	// DEBUG alert('getFilterDate('+val+','+id+')=='+result+"\nnow="+now);
	return result;
}

function filterExportList()
{
	var theList  = document.getElementById("exportList"); if (!theList) return -1;

	var filterStart=document.getElementById("exportFilterStart").checked;
	var val=document.getElementById("exportFilterStartBy").value;
	var startDate=getFilterDate(val,'exportStartDate');

	var filterEnd=document.getElementById("exportFilterEnd").checked;
	var val=document.getElementById("exportFilterEndBy").value;
	var endDate=getFilterDate(val,'exportEndDate');

	var filterTags=document.getElementById("exportFilterTags").checked;
	var tags=document.getElementById("exportTags").value;

	var filterText=document.getElementById("exportFilterText").checked;
	var text=document.getElementById("exportText").value;

	if (!(filterStart||filterEnd||filterTags||filterText)) {
		alert("Please set the selection filter");
		document.getElementById('exportFilterPanel').style.display="block";
		return -1;
	}
	if (filterStart&&filterEnd&&(startDate>endDate)) {
		var msg="starting date/time:\n"
		msg+=startDate.toLocaleString()+"\n";
		msg+="is later than ending date/time:\n"
		msg+=endDate.toLocaleString()
		alert(msg);
		return -1;
	}

	// scan list and select tiddlers that match all applicable criteria
	var total=0;
	var count=0;
	for (var i=0; i<theList.options.length; i++) {
		// get item, skip non-tiddler list items (section headings)
		var opt=theList.options[i]; if (opt.value=="") continue;
		// get tiddler, skip missing tiddlers (this should NOT happen)
		var tiddler=store.getTiddler(opt.value); if (!tiddler) continue; 
		var sel=true;
		if ( (filterStart && tiddler.modified<startDate)
		|| (filterEnd && tiddler.modified>endDate)
		|| (filterTags && !matchTags(tiddler,tags))
		|| (filterText && (tiddler.text.indexOf(text)==-1) && (tiddler.title.indexOf(text)==-1)))
			sel=false;
		opt.selected=sel;
		count+=sel?1:0;
		total++;
	}
	return count;
}
//}}}

//{{{
function matchTags(tiddler,cond)
{
	if (!cond||!cond.trim().length) return false;

	// build a regex of all tags as a big-old regex that 
	// OR's the tags together (tag1|tag2|tag3...) in length order
	var tgs = store.getTags();
	if ( tgs.length == 0 ) return results ;
	var tags = tgs.sort( function(a,b){return (a[0].length<b[0].length)-(a[0].length>b[0].length);});
	var exp = "(" + tags.join("|") + ")" ;
	exp = exp.replace( /(,[\d]+)/g, "" ) ;
	var regex = new RegExp( exp, "ig" );

	// build a string such that an expression that looks like this: tag1 AND tag2 OR NOT tag3
	// turns into : /tag1/.test(...) && /tag2/.test(...) || ! /tag2/.test(...)
	cond = cond.replace( regex, "/$1\\|/.test(tiddlerTags)" );
	cond = cond.replace( /\sand\s/ig, " && " ) ;
	cond = cond.replace( /\sor\s/ig, " || " ) ;
	cond = cond.replace( /\s?not\s/ig, " ! " ) ;

	// if a boolean uses a tag that doesn't exist - it will get left alone 
	// (we only turn existing tags into actual tests).
	// replace anything that wasn't found as a tag, AND, OR, or NOT with the string "false"
	// if the tag doesn't exist then /tag/.test(...) will always return false.
	cond = cond.replace( /(\s|^)+[^\/\|&!][^\s]*/g, "false" ) ;

	// make a string of the tags in the tiddler and eval the 'cond' string against that string 
	// if it's TRUE then the tiddler qualifies!
	var tiddlerTags = (tiddler.tags?tiddler.tags.join("|"):"")+"|" ;
	try { if ( eval( cond ) ) return true; }
	catch( e ) { displayMessage("Error in tag filter '" + e + "'" ); }
	return false;
}
//}}}

// // output data formatting
// // exportHeader(format)
//{{{
function exportHeader(format)
{
	switch (format) {
		case "TW":	return exportTWHeader();
		case "DIV":	return exportDIVHeader();
		case "XML":	return exportXMLHeader();
	}
}
//}}}

// // exportFooter(format)
//{{{
function exportFooter(format)
{
	switch (format) {
		case "TW":	return exportDIVFooter();
		case "DIV":	return exportDIVFooter();
		case "XML":	return exportXMLFooter();
	}
}
//}}}

// // exportTWHeader()
//{{{
function exportTWHeader()
{
	// Get the URL of the document
	var originalPath = document.location.href;
	// Check we were loaded from a file URL
	if(originalPath.substr(0,5) != "file:")
		{ alert(config.messages.notFileUrlError); return; }
	// 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"),"\\");
	// Load the original file
	var original = loadFile(localPath);
	if(original == null)
		{ alert(config.messages.cantSaveError); return; }
	// reset existing HTML source markup
	original=updateMarkupBlock(original,"PRE-HEAD");
	original=updateMarkupBlock(original,"POST-HEAD");
	original=updateMarkupBlock(original,"PRE-BODY");
	original=updateMarkupBlock(original,"POST-BODY");
	// Locate the storeArea div's
	var posOpeningDiv = original.indexOf(startSaveArea);
	var posClosingDiv = original.lastIndexOf(endSaveArea);
	if((posOpeningDiv == -1) || (posClosingDiv == -1))
		{ alert(config.messages.invalidFileError.format([localPath])); return; }
	return original.substr(0,posOpeningDiv+startSaveArea.length)
}
//}}}

// // exportDIVHeader()
//{{{
function exportDIVHeader()
{
	var out=[];
	var now = new Date();
	var title = convertUnicodeToUTF8(wikifyPlain("SiteTitle").htmlEncode());
	var subtitle = convertUnicodeToUTF8(wikifyPlain("SiteSubtitle").htmlEncode());
	var user = convertUnicodeToUTF8(config.options.txtUserName.htmlEncode());
	var twver = version.major+"."+version.minor+"."+version.revision;
	var pver = version.extensions.exportTiddlers.major+"."
		+version.extensions.exportTiddlers.minor+"."+version.extensions.exportTiddlers.revision;
	out.push("<html><body>");
	out.push("<style type=\"text/css\">");
	out.push("#storeArea {display:block;margin:1em;}");
	out.push("#storeArea div");
	out.push("{padding:0.5em;margin:1em;border:2px solid black;height:10em;overflow:auto;}");
	out.push("#javascriptWarning");
	out.push("{width:100%;text-align:left;background-color:#eeeeee;padding:1em;}");
	out.push("</style>");
	out.push("<div id=\"javascriptWarning\">");
	out.push("TiddlyWiki export file<br>");
	out.push("Source"+": <b>"+convertUnicodeToUTF8(document.location.href)+"</b><br>");
	out.push("Title: <b>"+title+"</b><br>");
	out.push("Subtitle: <b>"+subtitle+"</b><br>");
	out.push("Created: <b>"+now.toLocaleString()+"</b> by <b>"+user+"</b><br>");
	out.push("TiddlyWiki "+twver+" / "+"ExportTiddlersPlugin "+pver+"<br>");
	out.push("Notes:<hr><pre>"+document.getElementById("exportNotes").value.replace(regexpNewLine,"<br>")+"</pre>");
	out.push("</div>");
	out.push("<div id=\"storeArea\">");
	return out;
}
//}}}

// // exportDIVFooter()
//{{{
function exportDIVFooter()
{
	var out=[];
	out.push("</div><!--POST-BODY-START-->\n<!--POST-BODY-END--></body></html>");
	return out;
}
//}}}

// // exportXMLHeader()
//{{{
function exportXMLHeader()
{
	var out=[];
	var now = new Date();
	var u = store.getTiddlerText("SiteUrl",null);
	var title = convertUnicodeToUTF8(wikifyPlain("SiteTitle").htmlEncode());
	var subtitle = convertUnicodeToUTF8(wikifyPlain("SiteSubtitle").htmlEncode());
	var user = convertUnicodeToUTF8(config.options.txtUserName.htmlEncode());
	var twver = version.major+"."+version.minor+"."+version.revision;
	var pver = version.extensions.exportTiddlers.major+"."
		+version.extensions.exportTiddlers.minor+"."+version.extensions.exportTiddlers.revision;
	out.push("<" + "?xml version=\"1.0\"?" + ">");
	out.push("<rss version=\"2.0\">");
	out.push("<channel>");
	out.push("<title>" + title + "</title>");
	if(u) out.push("<link>" + convertUnicodeToUTF8(u.htmlEncode()) + "</link>");
	out.push("<description>" + subtitle + "</description>");
	out.push("<language>en-us</language>");
	out.push("<copyright>Copyright " + now.getFullYear() + " " + user + "</copyright>");
	out.push("<pubDate>" + now.toGMTString() + "</pubDate>");
	out.push("<lastBuildDate>" + now.toGMTString() + "</lastBuildDate>");
	out.push("<docs>http://blogs.law.harvard.edu/tech/rss</docs>");
	out.push("<generator>TiddlyWiki "+twver+" plus ExportTiddlersPlugin "+pver+"</generator>");
	return out;
}
//}}}

// // exportXMLFooter()
//{{{
function exportXMLFooter()
{
	var out=[];
	out.push("</channel></rss>");
	return out;
}
//}}}

// // exportData()
//{{{
function exportData(theList,theFormat)
{
	// scan export listbox and collect DIVs or XML for selected tiddler content
	var out=[];
	for (var i=0; i<theList.options.length; i++) {
		// get item, skip non-selected items and section headings
		var opt=theList.options[i]; if (!opt.selected||(opt.value=="")) continue;
		// get tiddler, skip missing tiddlers (this should NOT happen)
		var thisTiddler=store.getTiddler(opt.value); if (!thisTiddler) continue; 
		if (theFormat=="TW")	out.push(convertUnicodeToUTF8(thisTiddler.saveToDiv()));
		if (theFormat=="DIV")	out.push(convertUnicodeToUTF8(thisTiddler.title+"\n"+thisTiddler.saveToDiv()));
		if (theFormat=="XML")	out.push(convertUnicodeToUTF8(thisTiddler.saveToRss(store.getTiddlerText("SiteUrl",""))));
	}
	return out;
}
//}}}

// // exportTiddlers(): output selected data to local or server
//{{{
function exportTiddlers()
{
	var theList  = document.getElementById("exportList"); if (!theList) return;

	// get the export settings
	var theProtocol = document.getElementById("exportTo").value;
	var theFormat = document.getElementById("exportFormat").value;

	// assemble output: header + tiddlers + footer
	var theData=exportData(theList,theFormat);
	var count=theData.length;
	var out=[]; var txt=out.concat(exportHeader(theFormat),theData,exportFooter(theFormat)).join("\n");
	var msg="";
	switch (theProtocol) {
		case "file:":
			var theTarget = document.getElementById("exportFilename").value.trim();
			if (!theTarget.length) msg = "A local path/filename is required\n";
			if (!msg && saveFile(theTarget,txt))
				msg=count+" tiddler"+((count!=1)?"s":"")+" exported to local file";
			else if (!msg)
				msg+="An error occurred while saving to "+theTarget;
			break;
		case "http:":
		case "https:":
			var theTarget = document.getElementById("exportHTTPServerURL").value.trim();
			if (!theTarget.length) msg = "A server URL is required\n";
			if (document.getElementById('exportNotify').checked)
				theTarget+="&notify="+encodeURIComponent(document.getElementById('exportNotifyTo').value);
			if (document.getElementById('exportNotes').value.trim().length)
				theTarget+="&notes="+encodeURIComponent(document.getElementById('exportNotes').value);
			if (!msg && exportPost(theTarget+encodeURIComponent(txt)))
				msg=count+" tiddler"+((count!=1)?"s":"")+" exported to "+theProtocol+" server";
			else if (!msg)
				msg+="An error occurred while saving to "+theTarget;
			break;
		case "ftp:":
		default:
			msg="Sorry, export to "+theLocation+" is not yet available";
			break;
	}
	clearMessage(); displayMessage(msg,theTarget);
}
//}}}

// // exportPost(url): cross-domain post uses hidden iframe to submit url and capture responses
//{{{
function exportPost(url)
{
	var f=document.getElementById("exportFrame"); if (f) document.body.removeChild(f);
	f=document.createElement("iframe"); f.id="exportFrame";
	f.style.width="0px"; f.style.height="0px"; f.style.border="0px";
	document.body.appendChild(f);
	var d=f.document;
	if (f.contentDocument) d=f.contentDocument; // For NS6
	else if (f.contentWindow) d=f.contentWindow.document; // For IE5.5 and IE6
 	d.location.replace(url);
 	return true;
}
//}}}

// // promptForFilename(msg,path,file) uses platform/browser specific functions to get local filespec
//{{{
function promptForExportFilename(here)
{
	var msg=here.title; // use tooltip as dialog box message
	var path=getLocalPath(document.location.href);
	var slashpos=path.lastIndexOf("/"); if (slashpos==-1) slashpos=path.lastIndexOf("\\"); 
	if (slashpos!=-1) path = path.substr(0,slashpos+1); // remove filename from path, leave the trailing slash
	var file=config.macros.exportTiddlers.newdefault;
	var result="";
	if(window.Components) { // moz
		try {
			netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
			var nsIFilePicker = window.Components.interfaces.nsIFilePicker;
			var picker = Components.classes['@mozilla.org/filepicker;1'].createInstance(nsIFilePicker);
			picker.init(window, msg, nsIFilePicker.modeSave);
			var thispath = Components.classes['@mozilla.org/file/local;1'].createInstance(Components.interfaces.nsILocalFile);
			thispath.initWithPath(path);
			picker.displayDirectory=thispath;
			picker.defaultExtension='html';
			picker.defaultString=file;
			picker.appendFilters(nsIFilePicker.filterAll|nsIFilePicker.filterText|nsIFilePicker.filterHTML);
			if (picker.show()!=nsIFilePicker.returnCancel) var result=picker.file.persistentDescriptor;
		}
		catch(e) { alert('error during local file access: '+e.toString()) }
	}
	else { // IE
		try { // XP only
			var s = new ActiveXObject('UserAccounts.CommonDialog');
			s.Filter='All files|*.*|Text files|*.txt|HTML files|*.htm;*.html|';
			s.FilterIndex=3; // default to HTML files;
			s.InitialDir=path;
			s.FileName=file;
			if (s.showOpen()) var result=s.FileName;
		}
		catch(e) { var result=prompt(msg,path+file); } // fallback for non-XP IE
	}
	return result;
}
//}}}
|''Selection'' |''Description'' |''Name'' |
|>|>| ''Saving & editing options'' |
|<<option txtUserName>> |Username for signing your edits |txtUserName |
|<<option chkAnimate>>|Enable animations |chkAnimate |
|<<option chkAutoSave>>|Automatically save changes |chkAutoSave |
|<<option txtFileSystemCharSet>>|Default character set for saving changes (Firefox/Mozilla only) |txtFileSystemCharSet |
|<<option chkConfirmDelete>>|Require confirmation before deleting tiddlers |chkConfirmDelete |
|<<option chkForceMinorUpdate>>|Don't update modifier username and date when editing tiddlers |chkForceMinorUpdate |
|<<option chkHttpReadOnly>>|Hide editing features when viewed over HTTP |chkHttpReadOnly |
|<<option chkGenerateAnRssFeed>>|Generate an RSS feed when saving changes |chkGenerateAnRssFeed |
|<<option chkSaveBackups>>|Keep backup file when saving changes |chkSaveBackups |
|<<option txtBackupFolder>>|Name of folder to use for backups |txtBackupFolder |
|<<option chkSaveEmptyTemplate>>|Generate an empty template when saving changes |chkSaveEmptyTemplate |
|<<option chkSaveFromWebAttemptLocalIO>>|(unknown) |chkSaveFromWebAttemptLocalIO |
|<<option chkSaveFromWebPreFetch>>|(unknown) |chkSaveFromWebPreFetch |
|<<option txtSaveFromWebScriptURL>>|(unknown) |txtSaveFromWebScriptURL |
|<<option txtSaveFromWebSourceFile>>|(unknown) |txtSaveFromWebSourceFile |
|<<option txtSaveFromWebTargetFilename>>|Save from Web Target filename |txtSaveFromWebTargetFilename |
|<<option chkBackstage>>|//Display backstage ?// |chkBackstage |
|>|>| ''Search options'' |
|<<option chkSearchList>>|(unknown) |chkSearchList |
|<<option chkSearchTags>>|Search in tags |chkSearchTags |
|<<option chkSearchText>>|Search in tiddler text  |chkSearchText |
|<<option chkSearchTitles>>|(Search in tiddler titles |chkSearchTitles |
|<<option chkSearchTitlesFirst>>|Search in tiddler title first |chkSearchTitlesFirst |
|<<option chkHoldSearches>>|Hold search results |chkHoldSearches |
|<<option chkCaseSensitiveSearch>>|Case-sensitive searching |chkCaseSensitiveSearch |
|<<option chkSearchIncremental>>|Incremental Search |chkSearchIncremental |
|<<option chkRegExpSearch>>|Enable regular expressions for searches |chkRegExpSearch |
|<<option chkDisplayStartupTime>>|(unknown) |chkDisplayStartupTime |
|>|>|''More options'' |
|<<option txtFontSize>>|//Font size ?// |txtFontSize |
|<<option chkImportReport>>|Create Import Report (ImportTiddlersPlugin) |chkImportReport |
|<<option chkInsertTabs>>|Use the tab key to insert tab characters instead of moving between fields |chkInsertTabs |
|<<option txtMainTab>>|(unknown) |txtMainTab |
|<<option txtMaxEditRows>>|Maximum number of rows in edit boxes |txtMaxEditRows |
|<<option txtMoreTab>>|(unknown) |txtMoreTab |
|<<option chkOpenInNewWindow>>|Open external links in a new window |chkOpenInNewWindow |
|<<option txtRelatedTiddlersExclude>>|(unknown) |txtRelatedTiddlersExclude |
|<<option chkRelatedTiddlersShowList>>|Show related tiddlers |chkRelatedTiddlersShowList |
|<<option chkRelatedTiddlersShowTree>>|Show related tiddler tree |chkRelatedTiddlersShowTree |
|<<option chkRelatedTiddlersZoom>>|Related tiddler zoom |chkRelatedTiddlersZoom |
|<<option chkSinglePageMode>>|(unknown) |chkSinglePageMode |
|<<option chkSortTags>>|(unknown) |chkSortTags |
|<<option txtTheme>>|(unknown) |txtTheme |
|<<option chkToggleLinks>>|Clicking on links to open tiddlers causes them to close |chkToggleLinks |
|<<option chkUsePreForStorage>>|(unknown) |chkUsePreForStorage |
|<<option chkDebugLazySliderDefer>>|//Debug Lazy Slider Defer ?// |chkDebugLazySliderDefer |
|<<option chkDebugLazySliderRender>>|(unknown) |chkDebugLazySliderRender |
//{{{
//  WebSnapr - Preview Bubble Javascript
//  Written by Juan Xavier Larrea
//  Adapted for TW by Saq Imtiaz
// requires [[this image|bg.png]]

function applyStyleString(obj,str) {
	if(document.all && !window.opera) {
		obj.style.setAttribute("cssText",str);
	} else {
		obj.setAttribute("style",str);
	}
}

// Point this variable to the correct location of the bg.png file
var bubbleImagePath = 'bg.png';

function getElementsByClassName(oElm, strTagName, strClassName){
    var arrElements = (strTagName == "*" && oElm.all)? oElm.all : oElm.getElementsByTagName(strTagName);
    var arrReturnElements = new Array();
    strClassName = strClassName.replace(/\-/g, "\\-");
    var oRegExp = new RegExp("(^|\\s)" + strClassName + "(\\s|$)");
    var oElement;
    for(var i=0; i<arrElements.length; i++){
        oElement = arrElements[i];      
        if(oRegExp.test(oElement.className)){
            arrReturnElements.push(oElement);
        }   
    }
    return (arrReturnElements)
}

function bindBubbles(e){
    lbActions=getElementsByClassName(document,"a","externalLink");
    for(i=0;i<lbActions.length;i++){
        addEvent(lbActions[i],"mouseover",attachBubble,false);
        addEvent(lbActions[i],"mouseout",detachBubble,false);
        lbActions[i].title = '';
        }
}

function attachBubble(_b){
    var _c;
    if(_b["srcElement"]){
        _c=_b["srcElement"];
    }else{
        _c=_b["target"];
    }
    if (_c.href == undefined){
	    _c=_c.parentNode;
     }
    var _d=_c.href;
    var _e=findPosX(_c) +5;
    var _f=findPosY(_c) +17;  
    var _10=document.createElement("div");
    document.getElementsByTagName("body")[0].appendChild(_10);
    _10.className="previewbubble";
    applyStyleString(_10,"text-align: center; z-index: 99999; position: absolute; top: "+_f+"px ; left: "+_e+"px ;  width: 240px; height: 190px; padding: 0; margin: 0;");
    if (config.browser.isIE)
        _10.style.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + bubbleImagePath + "',sizingMethod='image')";
   else
       _10.style.background= "url("+ bubbleImagePath +") no-repeat";
   var img=document.createElement("img");
   _10.appendChild(img);

    applyStyleString(img,"padding-top: 0; padding-left: 0; padding-right: 0; padding-bottom: 0; margin-top: 27px; margin-left: 12px; margin-bottom: 0; margin-right: 0; border: 0");
    img.setAttribute("src","http://images.websnapr.com/?url="+_d);
    img.setAttribute("width",202);
    img.setAttribute("height",152);
    img.setAttribute("alt","Snapshot");
}

function detachBubble(_12){
    lbActions=getElementsByClassName(document,"div","previewbubble");
    for(i=0;i<lbActions.length;i++){
        lbActions[i].parentNode.removeChild(lbActions[i]);
    }
}

old_websnapr_refreshTiddler = Story.prototype.refreshTiddler;
Story.prototype.refreshTiddler = function(title,template,force)
{
    var tiddlerElem = old_websnapr_refreshTiddler.apply(this,arguments);
    bindBubbles();
    return tiddlerElem;
}
//}}}
/***
|''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.
***/

/*{{{*/
.header {
position: relative;
background: cc2-t-150x88.png center repeat;
}
.header a:hover {
	background: transparent;
}
.headerShadow {
	position: relative;
	padding: 1.5em 0em 1em 1em;
	left: -1px;
	top: -1px;
}
.headerForeground {
position: absolute;
padding: 1.5em 0em 1em 1em;
left: 0px;
top: 0px;
}
.headerShadow .left,
.headerShadow .right {
    position: absolute;
    top:5px;
    left:5px;
}
.headerShadow .right {
    right: 0;
}
.headerShadow .invisible {
display: non:
}
.headerForeground .left,
.headerForeground .right {
    display: none;
}
.header .siteTitle {
font-size: 2.5em;
position:absolute;
margin-left:80px;
margin-right:3px;
color: #ffffff;
}

.header .siteSubtitle {
font-size: 1.3em;
position:absolute;
margin-left:80px;
margin-right:3px;
color: #ffffff;
}

.headerShadow {
	color: [[ColorPalette::SecondaryLight]];
}

.headerShadow a {
	font-weight: normal;
	color: [[ColorPalette::Backround]];
}

.headerForeground {
	color: [[ColorPalette::Background]];
}

.headerForeground a {
	font-weight: normal;
}
/*}}}*/
/***
| Name:|HideWhenPlugin|
| Description:|Allows conditional inclusion/exclusion in templates|
| Version:|6.1.2|
| Date:|20-Oct-2006|
| Source:|http://mptw.tiddlyspot.com/#HideWhenPlugin|
| Author:|Simon Baird <simon.baird@gmail.com>|
For use in ViewTemplate and EditTemplate. Eg
{{{<div macro="showWhenTagged Task">[[TaskToolbar]]</div>}}}
{{{<div macro="showWhen tiddler.modifier == 'BartSimpson'"><img src="bart.gif"/></div>}}}
***/
//{{{

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

merge(config.macros,{

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

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

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

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

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

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

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

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

});

//}}}

<<tiddler HoverMenu>>
<<top>>
@@border:0;padding:0;margin:0;[[?|TWHelp-SearchResults]]@@
<<jump j '' top>>
<<fullscreen>>

<<fontSize>>



{{admin{
<<newTiddler ">><<renameButton n>>
<<newTiddler text:{{store.getTiddlerText("iframe template","")}}>><<renameButton i 'Create a new iframe tiddler'>>
<<newTiddler text:{{store.getTiddlerText("foreach template","")}}>><<renameButton c 'Create a new category tiddler'>>
<<newTiddler text:{{store.getTiddlerText("picasa template","")}} title:"New Album" tag:"picasa album" >><<renameButton a 'Create a new photo album'>>
<<newTiddler text:{{store.getTiddlerText("youtube template","")}} title:"New YouTube" tag:youtube>><<renameButton y 'Create a new youtube tiddler'>>
<<saveChanges>><<renameButton s 'Save TiddlyWiki'>>
}}}
/*{{{*/
#hoverMenu .imgLink, #hoverMenu .imgLink:hover {border:none; padding:0px; float:right; margin-bottom:2px; margin-top:0px;}
#hoverMenu .button, #hoverMenu .tiddlyLink {border:none; font-weight:bold; background:[[ColorPalette::SecondaryDark]]; color:[[ColorPalette::SecondaryLight]]; padding:0 5px; float:right; margin-bottom:3px;}
#hoverMenu .button:hover, #hoverMenu .tiddlyLink:hover {font-weight:bold; border:none; color:[[ColorPalette::SecondaryDark]]; background:[[ColorPalette::SecondaryMid]]; padding:0 5px; float:right; margin-bottom:4px;}
#hoverMenu .button {width:100%; text-align:center}#hoverMenu { position:absolute; width:7px;}
@media print #hoverMenu .imgLink, #hoverMenu .imgLink:hover, #hoverMenu .button, #hoverMenu .tiddlyLink, #hoverMenu .button:hover, #hoverMenu .tiddlyLink:hover, #hoverMenu .button {display: none;}

/*}}}*/
The ''Import Tiddlers'' tiddler uses the [[ImportTiddlers|ImportTiddlersPlugin]] plugin macro that allows you to import tiddlers from other TiddlyWiki pages, with the syntax {{{<<importTiddlers inline>>}}}.

<<importTiddlers inline>>
/***
|Name|ImportTiddlersPlugin|
|Source|http://www.TiddlyTools.com/#ImportTiddlersPlugin|
|Documentation|http://www.TiddlyTools.com/#ImportTiddlersPluginInfo|
|Version|4.3.1|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides|config.macros.importTiddlers.handler|
|Description|interactive controls for import/export with filtering.|
This plugin lets you selectively combine tiddlers from any two TiddlyWiki documents.  An interactive control panel lets you pick a document to import from, and then select which tiddlers to import, with prompting for skip, rename, merge or replace actions when importing tiddlers that match existing titles.  Automatically add tags to imported tiddlers so they are easy to find later on.  Generates a detailed report of import 'history' in ImportedTiddlers.
!!!!!Documentation
<<<
see [[ImportTiddlersPluginInfo]] for details
<<<
!!!!!interactive control panel:
<<<
<<tiddler ImportTiddlers>>
{{clear{
^^(see [[ImportTiddlers]] shadow tiddler)^^}}}
<<<
!!!!!Installation Notes
<<<
* As of 6/27/2007, "patch" functions that provide backward-compatibility with TW2.1.x and earlier have been split into a separate [[ImportTiddlersPluginPatch]] tiddler to reduce installation overhead for //this// plugin.  You only need to install the additional plugin tiddler when using ImportTiddlersPlugin in documents using TW2.1.x or earlier.
* As of 3/21/2007, the interactive {{{<<importTiddlers>>}}} and non-interactive {{{<<loadTiddlers>>}}} macro definitions and related code have been split into separate [[ImportTiddlersPlugin]] and [[LoadTiddlersPlugin]] to permit selective installation of either the interactive and/or non-interactive macro functions.
* Quick Installation Tip: If you are using an unmodified version of TiddlyWiki (core release version <<version>>), you can get a new, empty TiddlyWiki with the Import Tiddlers plugin pre-installed (''[[download from here|TW+ImportExport.html]]''), and then simply import all your content from your old document into this new, empty document.
<<<
!!!!!Revisions
<<<
2008.06.29 [4.3.1] More layout/animation work for simpler sequential interaction.  Code reduction/cleanup
|please see [[ImportTiddlersPluginInfo]] for additional revision details|
2005.07.20 [1.0.0] Initial Release
<<<
!!!!!Code
***/
// // ''MACRO DEFINITION''
//{{{
// Version
version.extensions.importTiddlers = {major: 4, minor: 3, revision: 0, date: new Date(2008,6,28)};

// add ImportTiddlerPlugin controls to built-in backstage import task
if (config.tasks) { // TW2.2 or above
	config.tasks.importTask.content="Use ~TiddlyWiki built-in importer (below) or, ";
	config.tasks.importTask.content+="<<importTiddlers link 'Use ImportTiddlersPlugin control panel...'>>\n";
	config.tasks.importTask.content+="<<importTiddlers core>>"
}

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

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

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

merge(config.macros.importTiddlers,{
	label: "import tiddlers",
	prompt: "Copy tiddlers from another document",
	openMsg: "Opening %0",
	openErrMsg: "Could not open %0 - error=%1",
	readMsg: "Read %0 bytes from %1",
	foundMsg: "Found %0 tiddlers in %1",
	filterMsg: "Filtered %0 tiddlers matching '%1'",
	summaryMsg: "%0 tiddler%1 in the list",
	summaryFilteredMsg: "%0 of %1 tiddler%2 in the list",
	plural: "s are",
	single: " is",
	countMsg: "%0 tiddlers selected for import",
	processedMsg: "Processed %0 tiddlers",
	importedMsg: "Imported %0 of %1 tiddlers from %2",
	loadText: "please load a document...",
	closeText: "close",	// text for close button when file is loaded
	doneText: "done",	// text for close button when file is not loaded
	startText: "import",	// text for import button
	stopText: "stop",	// text for import button while importing
	local: true,		// default to import from local file
	src: "",		// path/filename or URL of document to import (retrieved from SiteUrl tiddler)
	proxy: "",		// URL for remote proxy script (retrieved from SiteProxy tiddler)
	useProxy: false,	// use specific proxy script in front of remote URL
	inbound: null,		// hash-indexed array of tiddlers from other document
	newTags: "",		// text of tags added to imported tiddlers
	addTags: true,		// add new tags to imported tiddlers
	listsize: 20,		// # of lines to show in imported tiddler list
	importTags: true,	// include tags from remote source document when importing a tiddler
	keepTags: true,		// retain existing tags when replacing a tiddler
	sync: false,		// add 'server' fields to imported tiddlers (for sync function)
	lastFilter: "",		// most recent filter (URL hash) applied
	lastAction: null,	// most recent collision button performed
	index: 0,		// current processing index in import list
	sort: ""		// sort order for imported tiddler listbox
});

if (config.macros.importTiddlers.coreHandler==undefined)
	config.macros.importTiddlers.coreHandler=config.macros.importTiddlers.handler; // save built-in handler
config.macros.importTiddlers.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
	if (!params[0] || params[0].toLowerCase()=='core') { // default to built in
		if (config.macros.importTiddlers.coreHandler)
			config.macros.importTiddlers.coreHandler.apply(this,arguments);
		else 
			createTiddlyButton(place,this.label,this.prompt,onClickImportMenu);
	} else if (params[0]=='link') { // show link to floating panel
		createTiddlyButton(place,params[1]||this.label,params[2]||this.prompt,onClickImportMenu);
	} else if (params[0]=='inline') {// show panel as INLINE tiddler content
		createImportPanel(place);
		document.getElementById("importPanel").style.position="static";
		document.getElementById("importPanel").style.display="block";
	} else if (config.macros.loadTiddlers)
		config.macros.loadTiddlers.handler(place,macroName,params); // any other params: loadtiddlers
}

// // ''INTERFACE DEFINITION''
// // Handle link click to create/show/hide control panel
//{{{
function onClickImportMenu(e)
{
	if (!e) var e = window.event;
	var parent=resolveTarget(e).parentNode;
	var panel = document.getElementById("importPanel");
	if (panel==undefined || panel.parentNode!=parent)
		panel=createImportPanel(parent);
	var isOpen = panel.style.display=="block";
	if(config.options.chkAnimate)
		anim.startAnimating(new Slider(panel,!isOpen,e.shiftKey || e.altKey,"none"));
	else
		panel.style.display = isOpen ? "none" : "block" ;
	e.cancelBubble = true;
	if (e.stopPropagation) e.stopPropagation();
	return(false);
}
//}}}

// // Create control panel: HTML, CSS
//{{{
function createImportPanel(place) {
	var cmi=config.macros.importTiddlers; // abbreviation
	var panel=document.getElementById("importPanel");
	if (panel) { panel.parentNode.removeChild(panel); }
	setStylesheet(cmi.css,"importTiddlers");
	panel=createTiddlyElement(place,"span","importPanel",null,null)
	panel.innerHTML=cmi.html;
	refreshImportList();
	var siteURL=store.getTiddlerText("SiteUrl"); if (!siteURL) siteURL="";
	document.getElementById("importSourceURL").value=siteURL;
	cmi.src=siteURL;
	var siteProxy=store.getTiddlerText("SiteProxy"); if (!siteProxy) siteProxy="SiteProxy";
	document.getElementById("importSiteProxy").value=siteProxy;
	cmi.proxy=siteProxy;
	if (config.browser.isGecko) { // FF3 FIXUP
		document.getElementById("fileImportSource").style.display="none";
		document.getElementById("importLocalPanelFix").style.display="block";
	}
	return panel;
}
//}}}

// // CSS
//{{{
config.macros.importTiddlers.css = '\
#importPanel {\
	display: none; position:absolute; z-index:11; width:35em; right:105%; top:3em;\
	background-color: #eee; color:#000; font-size: 8pt; line-height:110%;\
	border:1px solid black; border-bottom-width: 3px; border-right-width: 3px;\
	padding: 0.5em; margin:0em; -moz-border-radius:1em;\
}\
#importPanel a, #importPanel td a { color:#009; display:inline; margin:0px; padding:1px; }\
#importPanel table { width:100%; border:0px; padding:0px; margin:0px; font-size:8pt; line-height:110%; background:transparent; }\
#importPanel tr { border:0px;padding:0px;margin:0px; background:transparent; }\
#importPanel td { color:#000; border:0px;padding:0px;margin:0px; background:transparent; }\
#importPanel select { width:100%;margin:0px;font-size:8pt;line-height:110%;}\
#importPanel input  { width:98%;padding:0px;margin:0px;font-size:8pt;line-height:110%}\
#importPanel .box { border:1px solid #000; background-color:#eee; padding:3px 5px; margin-bottom:5px; -moz-border-radius:5px;}\
#importPanel .topline { border-top:1px solid #999; padding-top:2px; margin-top:2px; }\
#importPanel .rad { width:auto; }\
#importPanel .chk { width:auto; margin:1px;border:0; }\
#importPanel .btn { width:auto; }\
#importPanel .btn1 { width:98%; }\
#importPanel .btn2 { width:48%; }\
#importPanel .btn3 { width:32%; }\
#importPanel .btn4 { width:23%; }\
#importPanel .btn5 { width:19%; }\
#importPanel .importButton { padding: 0em; margin: 0px; font-size:8pt; }\
#importPanel .importListButton { padding:0em 0.25em 0em 0.25em; color: #000000; display:inline }\
#backstagePanel #importPanel { left:10%; right:auto; }\
';
//}}}

// // HTML 
//{{{
config.macros.importTiddlers.html = '\
<!-- source and report -->\
<table><tr><td align=left>\
	import from\
	<input type="radio" class="rad" name="importFrom" id="importFromFile" value="file" CHECKED\
		onclick="onClickImportButton(this,event)" title="show file controls"> local file\
	<input type="radio" class="rad" name="importFrom" id="importFromWeb"  value="http"\
		onclick="onClickImportButton(this,event)" title="show web controls"> web server\
</td><td align=right>\
	<input type=checkbox class="chk" id="chkImportReport" checked\
		onClick="config.options[\'chkImportReport\']=this.checked;"> create report\
</td></tr></table>\
\
<div class="box" id="importSourcePanel" style="margin:.5em">\
<div id="importLocalPanel" style="display:block;margin-bottom:2px;"><!-- import from local file  -->\
enter or browse for source path/filename<br>\
<input type="file" id="fileImportSource" size=57 style="width:100%"\
	onKeyUp="config.macros.importTiddlers.src=this.value"\
	onChange="config.macros.importTiddlers.src=this.value;document.getElementById(\'importLoad\').onclick()">\
<div id="importLocalPanelFix" style="display:none"><!-- FF3 FIXUP -->\
	<input type="text" id="fileImportSourceFix" style="width:90%"\
		title="Enter a path/file to import"\
		onKeyUp="config.macros.importTiddlers.src=this.value"\
		onChange="config.macros.importTiddlers.src=this.value; document.getElementById(\'importLoad\').onclick()">\
	<input type="button" id="fileImportSourceFixButton" style="width:7%" value="..."\
		title="Select a path/file to import"\
		onClick="var r=config.macros.importTiddlers.askForFilename(this); if (!r||!r.length) return;\
			document.getElementById(\'fileImportSourceFix\').value=r;\
			config.macros.importTiddlers.src=r;\
			document.getElementById(\'importLoad\').onclick()">\
</div><!--end FF3 FIXUP-->\
</div><!--end local-->\
<div id="importHTTPPanel" style="display:none;margin-bottom:2px;"><!-- import from http server -->\
<table><tr><td align=left>\
	enter a URL or <a href="javascript:;" id="importSelectFeed"\
		onclick="onClickImportButton(this,event)" title="select a pre-defined \'systemServer\' URL">\
		select a server</a><br>\
</td><td align=right>\
	<input type="checkbox" class="chk" id="importUsePassword"\
		onClick="config.macros.importTiddlers.usePassword=this.checked;\
			config.macros.importTiddlers.showPanel(\'importIDPWPanel\',this.checked,true);">password\
	<input type="checkbox" class="chk" id="importUseProxy"\
		onClick="config.macros.importTiddlers.useProxy=this.checked;\
			config.macros.importTiddlers.showPanel(\'importSiteProxy\',this.checked,true);">proxy\
</td></tr></table>\
<input type="text" id="importSiteProxy" style="display:none;margin-bottom:1px" onfocus="this.select()" value="SiteProxy"\
	onKeyUp="config.macros.importTiddlers.proxy=this.value"\
	onChange="config.macros.importTiddlers.proxy=this.value;">\
<input type="text" id="importSourceURL" onfocus="this.select()" value="SiteUrl"\
	onKeyUp="config.macros.importTiddlers.src=this.value"\
	onChange="config.macros.importTiddlers.src=this.value;">\
<div id="importIDPWPanel" style="text-align:center;margin-top:2px;display:none";>\
username: <input type=text id="txtImportID" style="width:25%" \
	onChange="config.options.txtRemoteUsername=this.value;">\
 password: <input type=password id="txtImportPW" style="width:25%" \
	onChange="config.options.txtRemotePassword=this.value;">\
</div><!--end idpw-->\
</div><!--end http-->\
</div><!--end source-->\
\
<div class="box" id="importSelectPanel" style="display:none;margin:.5em;">\
<table><tr><td align=left>\
select:\
<a href="javascript:;" id="importSelectAll"\
	onclick="onClickImportButton(this);return false;" title="SELECT all tiddlers">\
	all</a>\
&nbsp;<a href="javascript:;" id="importSelectNew"\
	onclick="onClickImportButton(this);return false;" title="SELECT tiddlers not already in destination document">\
	added</a>\
&nbsp;<a href="javascript:;" id="importSelectChanges"\
	onclick="onClickImportButton(this);return false;" title="SELECT tiddlers that have been updated in source document">\
	changes</a>\
&nbsp;<a href="javascript:;" id="importSelectDifferences"\
	onclick="onClickImportButton(this);return false;" title="SELECT tiddlers that have been added or are different from existing tiddlers">\
	differences</a>\
</td><td align=right>\
<a href="javascript:;" id="importListSmaller"\
	onclick="onClickImportButton(this);return false;" title="SHRINK list size">\
	&nbsp;&#150;&nbsp;</a>\
<a href="javascript:;" id="importListLarger"\
	onclick="onClickImportButton(this);return false;" title="GROW list size">\
	&nbsp;+&nbsp;</a>\
<a href="javascript:;" id="importListMaximize"\
	onclick="onClickImportButton(this);return false;" title="MAXIMIZE/RESTORE list size">\
	&nbsp;=&nbsp;</a>\
</td></tr></table>\
<select id="importList" size=8 multiple\
	onchange="setTimeout(\'refreshImportList(\'+this.selectedIndex+\')\',1)">\
	<!-- NOTE: delay refresh so list is updated AFTER onchange event is handled -->\
</select>\
<div style="text-align:center">\
	<a href="javascript:;"\
		title="click for help using filters..."\
		onclick="alert(\'A filter consists of one or more space-separated combinations of:\\n\\ntiddler titles\\ntag:[[tagvalue]]\\ntag:[[tag expression]] (requires MatchTagsPlugin)\\nstory:[[TiddlerName]]\\nsearch:[[searchtext]]\\n\\nUse a blank filter for all tiddlers.\')"\
	>filter</a>\
	<input type="text" id="importLastFilter" style="margin-bottom:1px; width:65%"\
		title="Enter a combination of one or more filters. Use a blank filter for all tiddlers."\
		onfocus="this.select()" value=""\
		onKeyUp="config.macros.importTiddlers.lastFilter=this.value"\
		onChange="config.macros.importTiddlers.lastFilter=this.value;">\
	<input type="button" id="importApplyFilter" style="width:20%" value="apply"\
		title="filter list of tiddlers to include only those that match certain criteria"\
		onclick="onClickImportButton(this)">\
	</div>\
</div><!--end select-->\
\
<div class="box" id="importOptionsPanel" style="text-align:center;margin:.5em;display:none;">\
	apply tags: <input type=checkbox class="chk" id="chkImportTags" checked\
		onClick="config.macros.importTiddlers.importTags=this.checked;">from source&nbsp;\
	<input type=checkbox class="chk" id="chkKeepTags" checked\
		onClick="config.macros.importTiddlers.keepTags=this.checked;">keep existing&nbsp;\
	<input type=checkbox class="chk" id="chkAddTags" \
		onClick="config.macros.importTiddlers.addTags=this.checked;\
			config.macros.importTiddlers.showPanel(\'txtNewTags\',this.checked,true);\
			if (this.checked) document.getElementById(\'txtNewTags\').focus();">add tags<br>\
	<input type=text id="txtNewTags" style="margin-top:4px;display:none;" size=15\ onfocus="this.select()" \
		title="enter tags to be added to imported tiddlers" \
		onKeyUp="config.macros.importTiddlers.newTags=this.value;\
		document.getElementById(\'chkAddTags\').checked=this.value.length>0;" autocomplete=off>\
	<nobr><input type=checkbox class="chk" id="chkSync" \
		onClick="config.macros.importTiddlers.sync=this.checked;">\
		link imported tiddlers to source document (for sync later)</nobr>\
</div><!--end options-->\
\
<div id="importButtonPanel" style="text-align:center">\
	<input type=button id="importLoad"	class="importButton btn3" value="open"\
		title="load listbox with tiddlers from source document"\
		onclick="onClickImportButton(this)">\
	<input type=button id="importOptions"	class="importButton btn3" value="options..."\
		title="set options for tags, sync, etc."\
		onclick="onClickImportButton(this)">\
	<input type=button id="importStart"	class="importButton btn3" value="import"\
		title="start/stop import of selected source tiddlers into current document"\
		onclick="onClickImportButton(this)">\
	<input type=button id="importClose"	class="importButton btn3" value="done"\
		title="clear listbox or hide control panel"\
		onclick="onClickImportButton(this)">\
</div>\
\
<div class="none" id="importCollisionPanel" style="display:none;margin:.5em 0 .5em .5em;">\
	<table><tr><td style="width:65%" align="left">\
		<table><tr><td align=left>\
			tiddler already exists:\
		</td><td align=right>\
			<input type=checkbox class="chk" id="importApplyToAll" \
			onclick="document.getElementById(\'importRename\').disabled=this.checked;"\
			checked>apply to all\
		</td></tr></table>\
		<input type=text id="importNewTitle" size=15 autocomplete=off">\
	</td><td style="width:34%" align="center">\
		<input type=button id="importMerge"\
			class="importButton" style="width:47%" value="merge"\
			title="append the incoming tiddler to the existing tiddler"\
			onclick="onClickImportButton(this)"><!--\
		--><input type=button id="importSkip"\
			class="importButton" style="width:47%" value="skip"\
			title="do not import this tiddler"\
			onclick="onClickImportButton(this)"><!--\
		--><br><input type=button id="importRename"\
			class="importButton" style="width:47%" value="rename"\
			title="rename the incoming tiddler"\
			onclick="onClickImportButton(this)"><!--\
		--><input type=button id="importReplace"\
			class="importButton" style="width:47%" value="replace"\
			title="discard the existing tiddler"\
			onclick="onClickImportButton(this)">\
	</td></tr></table>\
</div><!--end collision-->\
';
//}}}

// // Control interactions
//{{{
function onClickImportButton(which,event)
{
	var cmi=config.macros.importTiddlers; // abbreviation

	var list = document.getElementById('importList');
	if (!list) return;
	var thePanel = document.getElementById('importPanel');
	var theCollisionPanel = document.getElementById('importCollisionPanel');
	var theNewTitle = document.getElementById('importNewTitle');
	var count=0;
	switch (which.id)
		{
		case 'importFromFile':	// show local panel
		case 'importFromWeb':	// show HTTP panel
			cmi.local=(which.id=='importFromFile');
			cmi.showPanel('importLocalPanel',cmi.local);
			cmi.showPanel('importHTTPPanel',!cmi.local);
			break;
		case 'importOptions':	// show/hide options panel
			cmi.showPanel('importOptionsPanel',document.getElementById('importOptionsPanel').style.display=='none');
			break;
		case 'fileImportSource':
		case 'importLoad':		// load import source into hidden frame
			importReport();		// if an import was in progress, generate a report
			cmi.inbound=null;	// clear the imported tiddler buffer
			refreshImportList();	// reset/resize the listbox
			if (cmi.src=="") break;
			// Load document, read it's DOM and fill the list
			cmi.loadRemoteFile(cmi.src,cmi.filterTiddlerList);
			break;
		case 'importSelectFeed':	// select a pre-defined systemServer feed URL
			var p=Popup.create(which); if (!p) return;
			var tids=store.getTaggedTiddlers('systemServer');
			if (!tids.length)
				createTiddlyText(createTiddlyElement(p,'li'),'no pre-defined server feeds');
			for (var t=0; t<tids.length; t++) {
				var u=store.getTiddlerSlice(tids[t].title,"URL");
				var d=store.getTiddlerSlice(tids[t].title,"Description");
				if (!d||!d.length) d=store.getTiddlerSlice(tids[t].title,"description");
				if (!d||!d.length) d=u;
				createTiddlyButton(createTiddlyElement(p,'li'),tids[t].title,d,
					function(){
						var u=this.getAttribute('url');
						document.getElementById('importSourceURL').value=u;
						config.macros.importTiddlers.src=u;
						document.getElementById('importLoad').onclick();
					},
					null,null,null,{url:u});
			}
			Popup.show(p,false);
			event.cancelBubble = true;
			if (event.stopPropagation) event.stopPropagation();
			return(false);
			// create popup with feed list
			// onselect, insert feed URL into input field.
			break;
		case 'importSelectAll':		// select all tiddler list items (i.e., not headings)
			importReport();		// if an import was in progress, generate a report
			for (var t=0,count=0; t < list.options.length; t++) {
				if (list.options[t].value=="") continue;
				list.options[t].selected=true;
				count++;
			}
			clearMessage(); displayMessage(cmi.countMsg.format([count]));
			document.getElementById('importStart').disabled=!count;
			break;
		case 'importSelectNew':		// select tiddlers not in current document
			importReport();		// if an import was in progress, generate a report
			for (var t=0,count=0; t < list.options.length; t++) {
				list.options[t].selected=false;
				if (list.options[t].value=="") continue;
				list.options[t].selected=!store.tiddlerExists(list.options[t].value);
				count+=list.options[t].selected?1:0;
			}
			clearMessage(); displayMessage(cmi.countMsg.format([count]));
			document.getElementById('importStart').disabled=!count;
			break;
		case 'importSelectChanges':		// select tiddlers that are updated from existing tiddlers
			importReport();		// if an import was in progress, generate a report
			for (var t=0,count=0; t < list.options.length; t++) {
				list.options[t].selected=false;
				if (list.options[t].value==""||!store.tiddlerExists(list.options[t].value)) continue;
				for (var i=0; i<cmi.inbound.length; i++) // find matching inbound tiddler
					{ var inbound=cmi.inbound[i]; if (inbound.title==list.options[t].value) break; }
				list.options[t].selected=(inbound.modified-store.getTiddler(list.options[t].value).modified>0); // updated tiddler
				count+=list.options[t].selected?1:0;
			}
			clearMessage(); displayMessage(cmi.countMsg.format([count]));
			document.getElementById('importStart').disabled=!count;
			break;
		case 'importSelectDifferences':		// select tiddlers that are new or different from existing tiddlers
			importReport();		// if an import was in progress, generate a report
			for (var t=0,count=0; t < list.options.length; t++) {
				list.options[t].selected=false;
				if (list.options[t].value=="") continue;
				if (!store.tiddlerExists(list.options[t].value)) { list.options[t].selected=true; count++; continue; }
				for (var i=0; i<cmi.inbound.length; i++) // find matching inbound tiddler
					{ var inbound=cmi.inbound[i]; if (inbound.title==list.options[t].value) break; }
				list.options[t].selected=(inbound.modified-store.getTiddler(list.options[t].value).modified!=0); // changed tiddler
				count+=list.options[t].selected?1:0;
			}
			clearMessage(); displayMessage(cmi.countMsg.format([count]));
			document.getElementById('importStart').disabled=!count;
			break;
		case 'importApplyFilter':	// filter list to include only matching tiddlers
			importReport();		// if an import was in progress, generate a report
			clearMessage();
			if (!cmi.all) // no tiddlers loaded = "0 selected"
				{ displayMessage(cmi.countMsg.format([0])); return false; }
			var hash=document.getElementById('importLastFilter').value;
			cmi.inbound=cmi.filterByHash("#"+hash,cmi.all);
			refreshImportList();	// reset/resize the listbox
			break;
		case 'importStart':		// initiate the import processing
			importReport();		// if an import was in progress, generate a report
			document.getElementById('importApplyToAll').checked=false;
			document.getElementById('importStart').value=cmi.stopText;
			if (cmi.index>0) cmi.index=-1; // stop processing
			else cmi.index=importTiddlers(0); // or begin processing
			importStopped();
			break;
		case 'importClose':		// unload imported tiddlers or hide the import control panel
			// if imported tiddlers not loaded, close the import control panel
			if (!cmi.inbound) { thePanel.style.display='none'; break; }
			importReport();		// if an import was in progress, generate a report
			cmi.inbound=null;	// clear the imported tiddler buffer
			refreshImportList();	// reset/resize the listbox
			break;
		case 'importSkip':	// don't import the tiddler
			cmi.lastAction=which;
			var theItem	= list.options[cmi.index];
			for (var j=0;j<cmi.inbound.length;j++)
			if (cmi.inbound[j].title==theItem.value) break;
			var theImported = cmi.inbound[j];
			theImported.status='skipped after asking';			// mark item as skipped
			theCollisionPanel.style.display='none';
			cmi.index=importTiddlers(cmi.index+1);	// resume with NEXT item
			importStopped();
			break;
		case 'importRename':		// change name of imported tiddler
			cmi.lastAction=which;
			var theItem		= list.options[cmi.index];
			for (var j=0;j<cmi.inbound.length;j++)
			if (cmi.inbound[j].title==theItem.value) break;
			var theImported		= cmi.inbound[j];
			theImported.status	= 'renamed from '+theImported.title;	// mark item as renamed
			theImported.set(theNewTitle.value,null,null,null,null);		// change the tiddler title
			theItem.value		= theNewTitle.value;			// change the listbox item text
			theItem.text		= theNewTitle.value;			// change the listbox item text
			theCollisionPanel.style.display='none';
			cmi.index=importTiddlers(cmi.index);	// resume with THIS item
			importStopped();
			break;
		case 'importMerge':	// join existing and imported tiddler content
			cmi.lastAction=which;
			var theItem	= list.options[cmi.index];
			for (var j=0;j<cmi.inbound.length;j++)
			if (cmi.inbound[j].title==theItem.value) break;
			var theImported	= cmi.inbound[j];
			var theExisting	= store.getTiddler(theItem.value);
			var theText	= theExisting.text+'\n----\n^^merged from: ';
			theText		+='[['+cmi.src+'#'+theItem.value+'|'+cmi.src+'#'+theItem.value+']]^^\n';
			theText		+='^^'+theImported.modified.toLocaleString()+' by '+theImported.modifier+'^^\n'+theImported.text;
			var theDate	= new Date();
			var theTags	= theExisting.getTags()+' '+theImported.getTags();
			theImported.set(null,theText,null,theDate,theTags);
			theImported.status   = 'merged with '+theExisting.title;	// mark item as merged
			theImported.status  += ' - '+theExisting.modified.formatString("MM/DD/YYYY 0hh:0mm:0ss");
			theImported.status  += ' by '+theExisting.modifier;
			theCollisionPanel.style.display='none';
			cmi.index=importTiddlers(cmi.index);	// resume with this item
			importStopped();
			break;
		case 'importReplace':		// substitute imported tiddler for existing tiddler
			cmi.lastAction=which;
			var theItem		  = list.options[cmi.index];
			for (var j=0;j<cmi.inbound.length;j++)
			if (cmi.inbound[j].title==theItem.value) break;
			var theImported     = cmi.inbound[j];
			var theExisting	  = store.getTiddler(theItem.value);
			theImported.status  = 'replaces '+theExisting.title;		// mark item for replace
			theImported.status += ' - '+theExisting.modified.formatString("MM/DD/YYYY 0hh:0mm:0ss");
			theImported.status += ' by '+theExisting.modifier;
			theCollisionPanel.style.display='none';
			cmi.index=importTiddlers(cmi.index);	// resume with THIS item
			importStopped();
			break;
		case 'importListSmaller':		// decrease current listbox size, minimum=5
			if (list.options.length==1) break;
			list.size-=(list.size>5)?1:0;
			cmi.listsize=list.size;
			break;
		case 'importListLarger':		// increase current listbox size, maximum=number of items in list
			if (list.options.length==1) break;
			list.size+=(list.size<list.options.length)?1:0;
			cmi.listsize=list.size;
			break;
		case 'importListMaximize':	// toggle listbox size between current and maximum
			if (list.options.length==1) break;
			list.size=(list.size==list.options.length)?cmi.listsize:list.options.length;
			break;
		}
}
//}}}

// // toggle panel
//{{{
config.macros.importTiddlers.showPanel=function(place,show,skipAnim) {
	if (typeof place == "string") var place=document.getElementById(place);
	if (!place||!place.style) return;
	if(!skipAnim && anim && config.options.chkAnimate) anim.startAnimating(new Slider(place,show,false,"none"));
	else place.style.display=show?"block":"none";
}
//}}}

// // refresh listbox
//{{{
function refreshImportList(selectedIndex)
{
	var cmi=config.macros.importTiddlers; // abbreviation

	var list  = document.getElementById("importList");
	if (!list) return;
	// if nothing to show, reset list content and size
	if (!cmi.inbound) 
	{
		while (list.length > 0) { list.options[0] = null; }
		list.options[0]=new Option(cmi.loadText,"",false,false);
		list.size=cmi.listsize;

		// toggle buttons and panels
		document.getElementById('importLoad').disabled=false;
		document.getElementById('importLoad').style.display='inline';
		document.getElementById('importStart').disabled=true;
		document.getElementById('importOptions').disabled=true;
		document.getElementById('importOptions').style.display='none';
		document.getElementById('fileImportSource').disabled=false;
		document.getElementById('importFromFile').disabled=false;
		document.getElementById('importFromWeb').disabled=false;
		document.getElementById('importStart').value=cmi.startText;
		document.getElementById('importClose').value=cmi.doneText;
		document.getElementById('importSelectPanel').style.display='none';
		document.getElementById('importOptionsPanel').style.display='none';
		return;
	}
	// there are inbound tiddlers loaded...
	// toggle buttons and panels
	document.getElementById('importLoad').disabled=true;
	document.getElementById('importLoad').style.display='none';
	document.getElementById('importOptions').style.display='inline';
	document.getElementById('importOptions').disabled=false;
	document.getElementById('fileImportSource').disabled=true;
	document.getElementById('importFromFile').disabled=true;
	document.getElementById('importFromWeb').disabled=true;
	document.getElementById('importClose').value=cmi.closeText;
	if (document.getElementById('importSelectPanel').style.display=='none')
		cmi.showPanel('importSelectPanel',true);

	// get the sort order
	if (!selectedIndex)   selectedIndex=0;
	if (selectedIndex==0) cmi.sort='title';		// heading
	if (selectedIndex==1) cmi.sort='title';
	if (selectedIndex==2) cmi.sort='modified';
	if (selectedIndex==3) cmi.sort='tags';
	if (selectedIndex>3) {
		// display selected tiddler count
		for (var t=0,count=0; t < list.options.length; t++) {
			if (!list.options[t].selected) continue;
			if (list.options[t].value!="")
				count+=1;
			else { // if heading is selected, deselect it, and then select and count all in section
				list.options[t].selected=false;
				for ( t++; t<list.options.length && list.options[t].value!=""; t++) {
					list.options[t].selected=true;
					count++;
				}
			}
		}
		clearMessage(); displayMessage(cmi.countMsg.format([count]));
	}
	document.getElementById('importStart').disabled=!count;
	if (selectedIndex>3) return; // no refresh needed

	// get the alphasorted list of tiddlers
	var tiddlers=cmi.inbound;
	tiddlers.sort(function (a,b) {if(a['title'] == b['title']) return(0); else return (a['title'] < b['title']) ? -1 : +1; });
	// clear current list contents
	while (list.length > 0) { list.options[0] = null; }
	// add heading and control items to list
	var i=0;
	var indent=String.fromCharCode(160)+String.fromCharCode(160);
	if (cmi.all.length==tiddlers.length)
		var summary=cmi.summaryMsg.format([tiddlers.length,(tiddlers.length!=1)?cmi.plural:cmi.single]);
	else
		var summary=cmi.summaryFilteredMsg.format([tiddlers.length,cmi.all.length,(cmi.all.length!=1)?cmi.plural:cmi.single]);
	list.options[i++]=new Option(summary,"",false,false);
	list.options[i++]=new Option(((cmi.sort=="title"   )?">":indent)+' [by title]',"",false,false);
	list.options[i++]=new Option(((cmi.sort=="modified")?">":indent)+' [by date]',"",false,false);
	list.options[i++]=new Option(((cmi.sort=="tags")?">":indent)+' [by tags]',"",false,false);
	// output the tiddler list
	switch(cmi.sort) {
		case "title":
			for(var t = 0; t < tiddlers.length; t++)
				list.options[i++] = new Option(tiddlers[t].title,tiddlers[t].title,false,false);
			break;
		case "modified":
			// sort descending for newest date first
			tiddlers.sort(function (a,b) {if(a['modified'] == b['modified']) return(0); else return (a['modified'] > b['modified']) ? -1 : +1; });
			var lastSection = "";
			for(var t = 0; t < tiddlers.length; t++) {
				var tiddler = tiddlers[t];
				var theSection = tiddler.modified.toLocaleDateString();
				if (theSection != lastSection) {
					list.options[i++] = new Option(theSection,"",false,false);
					lastSection = theSection;
				}
				list.options[i++] = new Option(indent+indent+tiddler.title,tiddler.title,false,false);
			}
			break;
		case "tags":
			var theTitles = {}; // all tiddler titles, hash indexed by tag value
			var theTags = new Array();
			for(var t=0; t<tiddlers.length; t++) {
				var title=tiddlers[t].title;
				var tags=tiddlers[t].tags;
				if (!tags || !tags.length) {
					if (theTitles["untagged"]==undefined) { theTags.push("untagged"); theTitles["untagged"]=new Array(); }
					theTitles["untagged"].push(title);
				}
				else for(var s=0; s<tags.length; s++) {
					if (theTitles[tags[s]]==undefined) { theTags.push(tags[s]); theTitles[tags[s]]=new Array(); }
					theTitles[tags[s]].push(title);
				}
			}
			theTags.sort();
			for(var tagindex=0; tagindex<theTags.length; tagindex++) {
				var theTag=theTags[tagindex];
				list.options[i++]=new Option(theTag,"",false,false);
				for(var t=0; t<theTitles[theTag].length; t++)
					list.options[i++]=new Option(indent+indent+theTitles[theTag][t],theTitles[theTag][t],false,false);
			}
			break;
		}
	list.selectedIndex=selectedIndex;		  // select current control item
	if (list.size<cmi.listsize) list.size=cmi.listsize;
	if (list.size>list.options.length) list.size=list.options.length;
}

config.macros.importTiddlers.filterTiddlerList=function(success,params,txt,src,xhr) {
	var cmi=config.macros.importTiddlers; // abbreviation
	var src=src.replace(/%20/g," ");
	if (!success) { displayMessage(cmi.openErrMsg.format([src,xhr.status])); return; }
	cmi.all = cmi.readTiddlersFromHTML(txt);
	var count=cmi.all?cmi.all.length:0;
	var querypos=src.lastIndexOf("?"); if (querypos!=-1) src=src.substr(0,querypos);
	displayMessage(cmi.foundMsg.format([count,src]));
	cmi.inbound=cmi.filterByHash(params,cmi.all); // use full URL including hash (if any)
	document.getElementById("importLastFilter").value=cmi.lastFilter;
	window.refreshImportList(0);
}

config.macros.importTiddlers.filterByHash=function(src,tiddlers)
{
	var hashpos=src.lastIndexOf("#"); if (hashpos==-1) return tiddlers;
	var hash=src.substr(hashpos+1); if (!hash.length) return tiddlers;
	var tids=[];
	var params=hash.parseParams("anon",null,true,false,false);
	for (var p=1; p<params.length; p++) {
		switch (params[p].name) {
			case "anon":
			case "open":
				tids.pushUnique(params[p].value);
				break;
			case "tag":
				if (store.getMatchingTiddlers) { // for boolean expressions - see MatchTagsPlugin
					var r=store.getMatchingTiddlers(params[p].value,null,tiddlers);
					for (var t=0; t<r.length; t++) tids.pushUnique(r[t].title);
				} else for (var t=0; t<tiddlers.length; t++)
					if (tiddlers[t].isTagged(params[p].value))
						tids.pushUnique(tiddlers[t].title);
				break;
			case "story":
				for (var t=0; t<tiddlers.length; t++)
					if (tiddlers[t].title==params[p].value) {
						tiddlers[t].changed();
						for (var s=0; s<tiddlers[t].links.length; s++)
							tids.pushUnique(tiddlers[t].links[s]);
						break;
					}
				break;
			case "search":
				for (var t=0; t<tiddlers.length; t++)
					if (tiddlers[t].text.indexOf(params[p].value)!=-1)
						tids.pushUnique(tiddlers[t].title);
				break;
		}
	}
	var matches=[];
	for (var t=0; t<tiddlers.length; t++)
		if (tids.contains(tiddlers[t].title))
			matches.push(tiddlers[t]);
	displayMessage(config.macros.importTiddlers.filterMsg.format([matches.length,hash]));
	config.macros.importTiddlers.lastFilter=hash;
	return matches;
}
//}}}

// // re-entrant processing for handling import with interactive collision prompting
//{{{
function importTiddlers(startIndex)
{
	var cmi=config.macros.importTiddlers; // abbreviation

	if (!cmi.inbound) return -1;

	var list = document.getElementById('importList');
	if (!list) return;
	var t;
	// if starting new import, reset import status flags
	if (startIndex==0)
		for (var t=0;t<cmi.inbound.length;t++)
			cmi.inbound[t].status="";
	for (var i=startIndex; i<list.options.length; i++)
		{
		// if list item is not selected or is a heading (i.e., has no value), skip it
		if ((!list.options[i].selected) || ((t=list.options[i].value)==""))
			continue;
		for (var j=0;j<cmi.inbound.length;j++)
			if (cmi.inbound[j].title==t) break;
		var inbound = cmi.inbound[j];
		var theExisting = store.getTiddler(inbound.title);
		// avoid redundant import for tiddlers that are listed multiple times (when 'by tags')
		if (inbound.status=="added")
			continue;
		// don't import the "ImportedTiddlers" history from the other document...
		if (inbound.title=='ImportedTiddlers')
			continue;
		// if tiddler exists and import not marked for replace or merge, stop importing
		if (theExisting && (inbound.status.substr(0,7)!="replace") && (inbound.status.substr(0,5)!="merge"))
			return i;
		// assemble tags (remote + existing + added)
		var newTags = "";
		if (cmi.importTags)
			newTags+=inbound.getTags()	// import remote tags
		if (cmi.keepTags && theExisting)
			newTags+=" "+theExisting.getTags(); // keep existing tags
		if (cmi.addTags && cmi.newTags.trim().length)
			newTags+=" "+cmi.newTags; // add new tags
		inbound.set(null,null,null,null,newTags.trim());
		// set the status to 'added' (if not already set by the 'ask the user' UI)
		inbound.status=(inbound.status=="")?'added':inbound.status;
		// set sync fields
		if (cmi.sync) {
			if (!inbound.fields) inbound.fields={}; // for TW2.1.x backward-compatibility
			inbound.fields["server.page.revision"]=inbound.modified.convertToYYYYMMDDHHMM();
			inbound.fields["server.type"]="file";
			inbound.fields["server.host"]=(cmi.local?"file://":"")+cmi.src;
		}
		// do the import!
		store.suspendNotifications();
		store.saveTiddler(inbound.title, inbound.title, inbound.text, inbound.modifier, inbound.modified, inbound.tags, inbound.fields, true, inbound.created);
                store.fetchTiddler(inbound.title).created = inbound.created; // force creation date to imported value (needed for TW2.1.x and earlier)
		store.resumeNotifications();
		}
	return(-1);	// signals that we really finished the entire list
}
//}}}

//{{{
function importStopped()
{
	var cmi=config.macros.importTiddlers; // abbreviation
	var list = document.getElementById('importList');
	var theNewTitle = document.getElementById('importNewTitle');
	if (!list) return;
	if (cmi.index==-1){ 
		document.getElementById('importStart').value=cmi.startText;
		importReport();		// import finished... generate the report
	} else {
		// import collision...
		// show the collision panel and set the title edit field
		document.getElementById('importStart').value=cmi.stopText;
		cmi.showPanel('importCollisionPanel',true);
		theNewTitle.value=list.options[cmi.index].value;
		if (document.getElementById('importApplyToAll').checked
			&& cmi.lastAction
			&& cmi.lastAction.id!="importRename") {
			onClickImportButton(cmi.lastAction);
		}
	}
}
//}}}

// // ''REPORT GENERATOR''
//{{{
function importReport()
{
	var cmi=config.macros.importTiddlers; // abbreviation
	if (!cmi.inbound) return;

	// if import was not completed, the collision panel will still be open... close it now.
	var panel=document.getElementById('importCollisionPanel'); if (panel) panel.style.display='none';

	// get the alphasorted list of tiddlers
	var tiddlers = cmi.inbound;
	// gather the statistics
	var count=0; var total=0;
	for (var t=0; t<tiddlers.length; t++) {
		if (!tiddlers[t].status || !tiddlers[t].status.trim().length) continue;
		if (tiddlers[t].status.substr(0,7)!="skipped") count++;
		total++;
	}
	// generate a report
	if (total) displayMessage(cmi.processedMsg.format([total]));
	if (count && config.options.chkImportReport) {
		// get/create the report tiddler
		var theReport = store.getTiddler('ImportedTiddlers');
		if (!theReport) { theReport= new Tiddler(); theReport.title = 'ImportedTiddlers'; theReport.text  = ""; }
		// format the report content
		var now = new Date();
		var newText = "On "+now.toLocaleString()+", "+config.options.txtUserName
		newText +=" imported "+count+" tiddler"+(count==1?"":"s")+" from\n[["+cmi.src+"|"+cmi.src+"]]:\n";
		if (cmi.addTags && cmi.newTags.trim().length)
			newText += "imported tiddlers were tagged with: \""+cmi.newTags+"\"\n";
		newText += "<<<\n";
		for (var t=0; t<tiddlers.length; t++) if (tiddlers[t].status) newText += "#[["+tiddlers[t].title+"]] - "+tiddlers[t].status+"\n";
		newText += "<<<\n";
		// update the ImportedTiddlers content and show the tiddler
		theReport.text	 = newText+((theReport.text!="")?'\n----\n':"")+theReport.text;
		theReport.modifier = config.options.txtUserName;
		theReport.modified = new Date();
                store.saveTiddler(theReport.title, theReport.title, theReport.text, theReport.modifier, theReport.modified, theReport.tags, theReport.fields);
		story.displayTiddler(null,theReport.title,1,null,null,false);
		story.refreshTiddler(theReport.title,1,true);
	}

	// reset status flags
	for (var t=0; t<cmi.inbound.length; t++) cmi.inbound[t].status="";

	// mark document as dirty and let display update as needed
	if (count) { store.setDirty(true); store.notifyAll(); }

	// always show final message when tiddlers were actually loaded
	if (count) displayMessage(cmi.importedMsg.format([count,tiddlers.length,cmi.src.replace(/%20/g," ")]));
}
//}}}

// // File and XMLHttpRequest I/O
//{{{
config.macros.importTiddlers.askForFilename=function(here) {
	var msg=here.title; // use tooltip as dialog box message
	var path=getLocalPath(document.location.href);
	var slashpos=path.lastIndexOf("/"); if (slashpos==-1) slashpos=path.lastIndexOf("\\"); 
	if (slashpos!=-1) path = path.substr(0,slashpos+1); // remove filename from path, leave the trailing slash
	var file="";
	var result="";
	if(window.Components) { // moz
		try {
			netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
			var nsIFilePicker = window.Components.interfaces.nsIFilePicker;
			var picker = Components.classes['@mozilla.org/filepicker;1'].createInstance(nsIFilePicker);
			picker.init(window, msg, nsIFilePicker.modeOpen);
			var thispath = Components.classes['@mozilla.org/file/local;1'].createInstance(Components.interfaces.nsILocalFile);
			thispath.initWithPath(path);
			picker.displayDirectory=thispath;
			picker.defaultExtension='html';
			picker.defaultString=file;
			picker.appendFilters(nsIFilePicker.filterAll|nsIFilePicker.filterText|nsIFilePicker.filterHTML);
			if (picker.show()!=nsIFilePicker.returnCancel) var result=picker.file.persistentDescriptor;
		}
		catch(e) { alert('error during local file access: '+e.toString()) }
	}
	else { // IE
		try { // XPSP2 IE only
			var s = new ActiveXObject('UserAccounts.CommonDialog');
			s.Filter='All files|*.*|Text files|*.txt|HTML files|*.htm;*.html|';
			s.FilterIndex=3; // default to HTML files;
			s.InitialDir=path;
			s.FileName=file;
			if (s.showOpen()) var result=s.FileName;
		}
		catch(e) {  // fallback
			var result=prompt(msg,path+file);
		}
	}
	return result;
}

config.macros.importTiddlers.fileExists=function(theFile) {
	var found=false;
	if(window.Components) {
		try { netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); }
		catch(e) { return false; } // security access denied
		var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
		try { file.initWithPath(theFile); }
		catch(e) { return false; } // invalid directory
		found = file.exists();
	}
	else { // use ActiveX FSO object for MSIE 
		var fso = new ActiveXObject("Scripting.FileSystemObject");
		found = fso.FileExists(theFile)
	}
	return found;
}

config.macros.importTiddlers.loadRemoteFile = function(src,callback) {
	if (src==undefined || !src.length) return null; // filename is required
	var original=src; // URL as specified
	var hashpos=src.indexOf("#"); if (hashpos!=-1) src=src.substr(0,hashpos); // URL with #... suffix removed (needed for IE)
	clearMessage();
	displayMessage(this.openMsg.format([src.replace(/%20/g," ")]));
	if (src.substr(0,5)!="http:" && src.substr(0,5)!="file:") { // if src is relative (i.e., not a URL)
		if (!this.fileExists(src)) { // if file cannot be found, might be relative path.. try fixup
			var pathPrefix=document.location.href;  // get current document path and trim off filename
			var slashpos=pathPrefix.lastIndexOf("/"); if (slashpos==-1) slashpos=pathPrefix.lastIndexOf("\\"); 
			if (slashpos!=-1 && slashpos!=pathPrefix.length-1) pathPrefix=pathPrefix.substr(0,slashpos+1);
			src=pathPrefix+src;
			if (pathPrefix.substr(0,5)!="http:") src=getLocalPath(src);
		}
	}
	if (src.substr(0,5)!="http:" && src.substr(0,5)!="file:") { // if not remote URL, read from local filesystem
		var txt=loadFile(src);
		if ((txt==null)||(txt==false)) // file didn't load
			{ displayMessage(config.macros.importTiddlers.openErrMsg.format([src.replace(/%20/g," "),"(filesystem error)"])); }
		else {
			displayMessage(config.macros.importTiddlers.readMsg.format([txt.length,src.replace(/%20/g," ")]));
			if (callback) callback(true,original,convertUTF8ToUnicode(txt),src,null);
		}
	}
	else {
		var name=config.options.txtRemoteUsername; var pass=config.options.txtRemotePassword;
		var xhr=doHttp("GET",src,null,null,name,pass,callback,original,null)
		if (!xhr) displayMessage(config.macros.importTiddlers.openErrMsg.format([src,"(XMLHTTPRequest error)"]));
	}
}

config.macros.importTiddlers.readTiddlersFromHTML=function(html)
{
	var remoteStore=new TiddlyWiki();
	remoteStore.importTiddlyWiki(html);
	return remoteStore.getTiddlers("title");	
}
//}}}
//{{{
config.formatters.unshift( {
    name: "inlinesliders",
    match: "\\+\\+\\+\\+|\\<slider",
    lookaheadRegExp: /(?:\+\+\+\+|<slider) (\w*)(?:>?)\n((?:.|\n)*?)\n(?:====|<\/slider>)/mg,
    handler: function(w)
    {
        this.lookaheadRegExp.lastIndex = w.matchStart;
        var lookaheadMatch = this.lookaheadRegExp.exec(w.source)
        if(lookaheadMatch && lookaheadMatch.index == w.matchStart )
            {
            var btn = createTiddlyButton(w.output,lookaheadMatch[1] + " "+"\u00BB",lookaheadMatch[1],this.onClickSlider,"button sliderButton");
	        var panel = createTiddlyElement(w.output,"div",null,"sliderPanel");
	        panel.style.display = "none";
            wikify(lookaheadMatch[2],panel);
            w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
            }
    },
    onClickSlider : function(e)
    {
        if(!e) var e = window.event;
	    var n = this.nextSibling;
        n.style.display = (n.style.display=="none") ? "block" : "none";
        return false;
    }
})
//}}}
/***
|//Name://|~IntelliTaggerPlugin|
|//Version://|1.0.0 |
|//Date:// |26 April 2006 - 2006-04-26|
|//Tags://|tagging intellitagger plugin 'abego software' intelligence 'key words'|
|//Type://|plugin|
|//Source://|http://tiddlywiki.abego-software.de/#IntelliTaggerPlugin|
|//Author://|Udo Borkowski (ub [at] abego-software [dot] de)|
|//Documentation://|[[IntelliTaggerPlugin Documentation|http://tiddlywiki.abego-software.de/doc/IntelliTagger.pdf]] (pdf)|
|//Source Code://|[[IntelliTaggerPlugin SourceCode|[http://tiddlywiki.abego-software.de/#IntelliTaggerPlugin SourceCode]]|
|//Licence://|[[BSD open source license (abego Software)|http://tiddlywiki.abego-software.de/#BSD open source license (abego Software)]]|
|//~TiddlyWiki://|Version 2.0.8 or better|
|//Browser://|Firefox 1.5.0.2 or better|
***/
// /%
if(!version.extensions.IntelliTaggerPlugin){if(!window.abego){window.abego={};}if(!abego.internal){abego.internal={};}abego.alertAndThrow=function(s){alert(s);throw s;};if(version.major<2){abego.alertAndThrow("Use TiddlyWiki 2.0.8 or better to run the IntelliTagger Plugin.");}version.extensions.IntelliTaggerPlugin={major:1,minor:0,revision:0,date:new Date(2006,3,26),type:"plugin",source:"http://tiddlywiki.abego-software.de/#IntelliTaggerPlugin",documentation:"[[IntelliTaggerPlugin Documentation]]",sourcecode:"[[IntelliTaggerPlugin SourceCode]]",author:"Udo Borkowski (ub [at] abego-software [dot] de)",licence:"[[BSD open source license (abego Software)]]",tiddlywiki:"Version 2.0.8 or better",browser:"Firefox 1.5.0.2 or better"};abego.isPopupOpen=function(_2){return _2&&_2.parentNode==document.body;};abego.openAsPopup=function(_3){if(_3.parentNode!=document.body){document.body.appendChild(_3);}};abego.closePopup=function(_4){if(abego.isPopupOpen(_4)){document.body.removeChild(_4);}};abego.getWindowRect=function(){return {left:findScrollX(),top:findScrollY(),height:findWindowHeight(),width:findWindowWidth()};};abego.moveElement=function(_5,_6,_7){_5.style.left=_6+"px";_5.style.top=_7+"px";};abego.centerOnWindow=function(_8){if(_8.style.position!="absolute"){throw "abego.centerOnWindow: element must have absolute position";}var _9=abego.getWindowRect();abego.moveElement(_8,_9.left+(_9.width-_8.offsetWidth)/2,_9.top+(_9.height-_8.offsetHeight)/2);};abego.isDescendantOrSelf=function(_a,e){while(e){if(_a==e){return true;}e=e.parentNode;}return false;};abego.toSet=function(_c){var _d={};for(var i=0;i<_c.length;i++){_d[_c[i]]=true;}return _d;};abego.filterStrings=function(_f,_10,_11){var _12=[];for(var i=0;i<_f.length&&(_11===undefined||_12.length<_11);i++){var s=_f[i];if(s.match(_10)){_12.push(s);}}return _12;};abego.arraysAreEqual=function(a,b){var n=a.length;if(n!=b.length){return false;}for(var i=0;i<n;i++){if(a[i]!=b[i]){return false;}}return true;};abego.moveBelowAndClip=function(_19,_1a){if(!_1a){return;}var _1b=findPosX(_1a);var _1c=findPosY(_1a);var _1d=_1a.offsetHeight;var _1e=_1b;var _1f=_1c+_1d;var _20=findWindowWidth();if(_20<_19.offsetWidth){_19.style.width=(_20-100)+"px";}var _21=_19.offsetWidth;if(_1e+_21>_20){_1e=_20-_21-30;}if(_1e<0){_1e=0;}_19.style.left=_1e+"px";_19.style.top=_1f+"px";_19.style.display="block";};abego.compareStrings=function(a,b){return (a==b)?0:(a<b)?-1:1;};abego.sortIgnoreCase=function(arr){var _25=[];var n=arr.length;for(var i=0;i<n;i++){var s=arr[i];_25.push([s.toString().toLowerCase(),s]);}_25.sort(function(a,b){return (a[0]==b[0])?0:(a[0]<b[0])?-1:1;});for(i=0;i<n;i++){arr[i]=_25[i][1];}};abego.getTiddlerField=function(_2b,_2c,_2d){var _2e=document.getElementById(_2b.idPrefix+_2c);var e=null;if(_2e!=null){var _30=_2e.getElementsByTagName("*");for(var t=0;t<_30.length;t++){var c=_30[t];if(c.tagName.toLowerCase()=="input"||c.tagName.toLowerCase()=="textarea"){if(!e){e=c;}if(c.getAttribute("edit")==_2d){e=c;}}}}return e;};abego.setRange=function(_33,_34,end){if(_33.setSelectionRange){_33.setSelectionRange(_34,end);var max=0+_33.scrollHeight;var len=_33.textLength;var top=max*_34/len,bot=max*end/len;_33.scrollTop=Math.min(top,(bot+top-_33.clientHeight)/2);}else{if(_33.createTextRange!=undefined){var _39=_33.createTextRange();_39.collapse();_39.moveEnd("character",end);_39.moveStart("character",_34);_39.select();}else{_33.select();}}};abego.internal.TagManager=function(){var _3a=null;var _3b=function(){if(_3a){return;}_3a={};store.forEachTiddler(function(_3c,_3d){for(var i=0;i<_3d.tags.length;i++){var tag=_3d.tags[i];var _40=_3a[tag];if(!_40){_40=_3a[tag]={count:0,tiddlers:{}};}_40.tiddlers[_3d.title]=true;_40.count+=1;}});};var _41=TiddlyWiki.prototype.saveTiddler;TiddlyWiki.prototype.saveTiddler=function(_42,_43,_44,_45,_46,_47){var _48=this.fetchTiddler(_42);var _49=_48?_48.tags:[];var _4a=(typeof _47=="string")?_47.readBracketedList():_47;_41.apply(this,arguments);if(!abego.arraysAreEqual(_49,_4a)){abego.internal.getTagManager().reset();}};var _4b=TiddlyWiki.prototype.removeTiddler;TiddlyWiki.prototype.removeTiddler=function(_4c){var _4d=this.fetchTiddler(_4c);var _4e=_4d&&_4d.tags.length>0;_4b.apply(this,arguments);if(_4e){abego.internal.getTagManager().reset();}};this.reset=function(){_3a=null;};this.getTiddlersWithTag=function(tag){_3b();var _50=_3a[tag];return _50?_50.tiddlers:null;};this.getAllTags=function(_51){_3b();var _52=[];for(var i in _3a){_52.push(i);}for(i=0;_51&&i<_51.length;i++){_52.pushUnique(_51[i],true);}abego.sortIgnoreCase(_52);return _52;};this.getTagInfos=function(){_3b();var _54=[];for(var _55 in _3a){_54.push([_55,_3a[_55]]);}return _54;};var _56=function(a,b){var a1=a[1];var b1=b[1];var d=b[1].count-a[1].count;return d!=0?d:abego.compareStrings(a[0].toLowerCase(),b[0].toLowerCase());};this.getSortedTagInfos=function(){_3b();var _5c=this.getTagInfos();_5c.sort(_56);return _5c;};this.getPartnerRankedTags=function(_5d){var _5e={};for(var i=0;i<_5d.length;i++){var _60=this.getTiddlersWithTag(_5d[i]);for(var _61 in _60){var _62=store.getTiddler(_61);if(!(_62 instanceof Tiddler)){continue;}for(var j=0;j<_62.tags.length;j++){var tag=_62.tags[j];var c=_5e[tag];_5e[tag]=c?c+1:1;}}}var _66=abego.toSet(_5d);var _67=[];for(var n in _5e){if(!_66[n]){_67.push(n);}}_67.sort(function(a,b){var d=_5e[b]-_5e[a];return d!=0?d:abego.compareStrings(a.toLowerCase(),b.toLowerCase());});return _67;};};abego.internal.getTagManager=function(){if(!abego.internal.gTagManager){abego.internal.gTagManager=new abego.internal.TagManager();}return abego.internal.gTagManager;};(function(){var _6c=2;var _6d=1;var _6e=30;var _6f;var _70;var _71;var _72;var _73;var _74;if(!abego.IntelliTagger){abego.IntelliTagger={};}var _75=function(){return _70;};var _76=function(tag){return _73[tag];};var _78=function(s){var i=s.lastIndexOf(" ");return (i>=0)?s.substr(0,i):"";};var _7b=function(_7c){var s=_7c.value;var len=s.length;return (len>0&&s[len-1]!=" ");};var _7f=function(_80){var s=_80.value;var len=s.length;if(len>0&&s[len-1]!=" "){_80.value+=" ";}};var _83=function(tag,_85,_86){if(_7b(_85)){_85.value=_78(_85.value);}story.setTiddlerTag(_86.title,tag,0);_7f(_85);abego.IntelliTagger.assistTagging(_85,_86);};var _87=function(n){if(_74){if(_74.length>n){return _74[n];}n-=_74.length;}return (_72&&_72.length>n)?_72[n]:null;};var _89=function(n,_8b,_8c){var _8d=_87(n);if(_8d){_83(_8d,_8b,_8c);}};var _8e=function(_8f){var pos=_8f.value.lastIndexOf(" ");var _91=(pos>=0)?_8f.value.substr(++pos,_8f.value.length):_8f.value;return new RegExp(_91.escapeRegExp(),"i");};var _92=function(_93,_94){var _95=0;for(var i=0;i<_93.length;i++){if(_94[_93[i]]){_95++;}}return _95;};var _97=function(_98,_99,_9a){var _9b=1;var c=_98[_99];for(var i=_99+1;i<_98.length;i++){if(_98[i][1].count==c){if(_98[i][0].match(_9a)){_9b++;}}else{break;}}return _9b;};var _9e=function(_9f,_a0){var _a1=abego.internal.getTagManager().getSortedTagInfos();var _a2=[];var _a3=0;for(var i=0;i<_a1.length;i++){var c=_a1[i][1].count;if(c!=_a3){if(_a0&&(_a2.length+_97(_a1,i,_9f)>_a0)){break;}_a3=c;}if(c==1){break;}var s=_a1[i][0];if(s.match(_9f)){_a2.push(s);}}return _a2;};var _a7=function(_a8,_a9){return abego.filterStrings(abego.internal.getTagManager().getAllTags(_a9),_a8);};var _aa=function(){if(!_6f){return;}var _ab=store.getTiddlerText("IntelliTaggerMainTemplate");if(!_ab){_ab="<b>Tiddler IntelliTaggerMainTemplate not found</b>";}_6f.innerHTML=_ab;applyHtmlMacros(_6f,null);refreshElements(_6f,null);};var _ac=function(e){if(!e){var e=window.event;}var tag=this.getAttribute("tag");if(_71){_71.call(this,tag,e);}return false;};var _af=function(_b0,_b1,_b2,_b3){if(!_b1){return;}var _b4=_b3?abego.toSet(_b3):{};var n=_b1.length;for(var i=0;i<n;i++){var tag=_b1[i];if(_b4[tag]){continue;}if(i>0){createTiddlyElement(_b0,"span",null,"tagSeparator"," | ");}var _b8="";var _b9=_b0;if(_b2<10){_b9=createTiddlyElement(_b0,"span",null,"numberedSuggestion");_b2++;var key=_b2<10?""+(_b2):"0";createTiddlyElement(_b9,"span",null,"suggestionNumber",key+") ");var _bb=_b2==1?"Ctrl-Space or ":"";_b8=" (Shortcut: %1Alt-%0)".format([key,_bb]);}var _bc=config.views.wikified.tag.tooltip.format([tag]);var _bd=(_76(tag)?"Remove tag '%0'%1":"Add tag '%0'%1").format([tag,_b8]);var _be="%0; Shift-Click: %1".format([_bd,_bc]);var btn=createTiddlyButton(_b9,tag,_be,_ac,_76(tag)?"currentTag":null);btn.setAttribute("tag",tag);}};var _c0=function(){if(_6f){window.scrollTo(0,ensureVisible(_6f));}if(_75()){window.scrollTo(0,ensureVisible(_75()));}};var _c1=function(e){if(!e){var e=window.event;}if(!_6f){return;}var _c3=resolveTarget(e);if(_c3==_75()){return;}if(abego.isDescendantOrSelf(_6f,_c3)){return;}abego.IntelliTagger.close();};addEvent(document,"click",_c1);var _c4=Story.prototype.gatherSaveFields;Story.prototype.gatherSaveFields=function(e,_c6){_c4.apply(this,arguments);var _c7=_c6.tags;if(_c7){_c6.tags=_c7.trim();}};var _c8=function(_c9){story.focusTiddler(_c9,"tags");var _ca=abego.getTiddlerField(story,_c9,"tags");if(_ca){var len=_ca.value.length;abego.setRange(_ca,len,len);window.scrollTo(0,ensureVisible(_ca));}};var _cc=config.macros.edit.handler;config.macros.edit.handler=function(_cd,_ce,_cf,_d0,_d1,_d2){_cc.apply(this,arguments);var _d3=_cf[0];if((_d2 instanceof Tiddler)&&_d3=="tags"){var _d4=_cd.lastChild;_d4.onfocus=function(e){abego.IntelliTagger.assistTagging(_d4,_d2);setTimeout(function(){_c8(_d2.title);},100);};_d4.onkeyup=function(e){if(!e){var e=window.event;}if(e.altKey&&!e.ctrlKey&&!e.metaKey&&(e.keyCode>=48&&e.keyCode<=57)){_89(e.keyCode==48?9:e.keyCode-49,_d4,_d2);}else{if(e.ctrlKey&&e.keyCode==32){_89(0,_d4,_d2);}}setTimeout(function(){abego.IntelliTagger.assistTagging(_d4,_d2);},100);return false;};_7f(_d4);}};var _d7=function(e){if(!e){var e=window.event;}var _d9=resolveTarget(e);var _da=_d9.getAttribute("tiddler");if(_da){story.displayTiddler(_d9,_da,"IntelliTaggerEditTagsTemplate",false);_c8(_da);}return false;};var _db=config.macros.tags.handler;config.macros.tags.handler=function(_dc,_dd,_de,_df,_e0,_e1){_db.apply(this,arguments);abego.IntelliTagger.createEditTagsButton(_e1,createTiddlyElement(_dc.lastChild,"li"));};var _e2=function(){if(_6f&&_70&&!abego.isDescendantOrSelf(document,_70)){abego.IntelliTagger.close();}};setInterval(_e2,100);abego.IntelliTagger.displayTagSuggestions=function(_e3,_e4,_e5,_e6,_e7){_72=_e3;_73=abego.toSet(_e4);_74=_e5;_70=_e6;_71=_e7;if(!_6f){_6f=createTiddlyElement(document.body,"div",null,"intelliTaggerSuggestions");_6f.style.position="absolute";}_aa();abego.openAsPopup(_6f);if(_75()){var w=_75().offsetWidth;if(_6f.offsetWidth<w){_6f.style.width=(w-2*(_6c+_6d))+"px";}abego.moveBelowAndClip(_6f,_75());}else{abego.centerOnWindow(_6f);}_c0();};abego.IntelliTagger.assistTagging=function(_e9,_ea){var _eb=_8e(_e9);var s=_e9.value;if(_7b(_e9)){s=_78(s);}var _ed=s.readBracketedList();var _ee=_ed.length>0?abego.filterStrings(abego.internal.getTagManager().getPartnerRankedTags(_ed),_eb,_6e):_9e(_eb,_6e);abego.IntelliTagger.displayTagSuggestions(_a7(_eb,_ed),_ed,_ee,_e9,function(tag,e){if(e.shiftKey){onClickTag.call(this,e);}else{_83(tag,_e9,_ea);}});};abego.IntelliTagger.close=function(){abego.closePopup(_6f);_6f=null;return false;};abego.IntelliTagger.createEditTagsButton=function(_f1,_f2,_f3,_f4,_f5,id,_f7){if(!_f3){_f3="[edit]";}if(!_f4){_f4="Edit the tags";}if(!_f5){_f5="editTags";}var _f8=createTiddlyButton(_f2,_f3,_f4,_d7,_f5,id,_f7);_f8.setAttribute("tiddler",(_f1 instanceof Tiddler)?_f1.title:String(_f1));return _f8;};config.macros.intelliTagger={label:"intelliTagger",handler:function(_f9,_fa,_fb,_fc,_fd,_fe){var _ff=_fd.parseParams("list",null,true);var _100=_ff[0]["action"];for(var i=0;_100&&i<_100.length;i++){var _102=_100[i];var _103=config.macros.intelliTagger.subhandlers[_102];if(!_103){abego.alertAndThrow("Unsupported action '%0'".format([_102]));}_103(_f9,_fa,_fb,_fc,_fd,_fe);}},subhandlers:{showTags:function(_104,_105,_106,_107,_108,_109){_af(_104,_72,_74?_74.length:0,_74);},showFavorites:function(_10a,_10b,_10c,_10d,_10e,_10f){_af(_10a,_74,0);},closeButton:function(_110,_111,_112,_113,_114,_115){var _116=createTiddlyButton(_110,"close","Close the suggestions",abego.IntelliTagger.close);},version:function(_117){var t="IntelliTagger %0.%1.%2".format([version.extensions.IntelliTaggerPlugin.major,version.extensions.IntelliTaggerPlugin.minor,version.extensions.IntelliTaggerPlugin.revision]);var e=createTiddlyElement(_117,"a");e.setAttribute("href","http://tiddlywiki.abego-software.de/#IntelliTaggerPlugin");e.innerHTML="<font color=\"black\" face=\"Arial, Helvetica, sans-serif\">"+t+"<font>";},copyright:function(_11a){var e=createTiddlyElement(_11a,"a");e.setAttribute("href","http://tiddlywiki.abego-software.de");e.innerHTML="<font color=\"black\" face=\"Arial, Helvetica, sans-serif\">&copy; 2006 <b><font color=\"red\">abego</font></b> Software<font>";}}};})();config.shadowTiddlers["IntelliTaggerStyleSheet"]="/***\n"+"!~IntelliTagger Stylesheet\n"+"***/\n"+"/*{{{*/\n"+".intelliTaggerSuggestions {\n"+"\tposition: absolute;\n"+"\twidth: 600px;\n"+"\n"+"\tpadding: 2px;\n"+"\tlist-style: none;\n"+"\tmargin: 0;\n"+"\n"+"\tbackground: #eeeeee;\n"+"\tborder: 1px solid DarkGray;\n"+"}\n"+"\n"+".intelliTaggerSuggestions .currentTag   {\n"+"\tfont-weight: bold;\n"+"}\n"+"\n"+".intelliTaggerSuggestions .suggestionNumber {\n"+"\tcolor: #808080;\n"+"}\n"+"\n"+".intelliTaggerSuggestions .numberedSuggestion{\n"+"\twhite-space: nowrap;\n"+"}\n"+"\n"+".intelliTaggerSuggestions .intelliTaggerFooter {\n"+"\tmargin-top: 4px;\n"+"\tborder-top-width: thin;\n"+"\tborder-top-style: solid;\n"+"\tborder-top-color: #999999;\n"+"}\n"+".intelliTaggerSuggestions .favorites {\n"+"\tborder-bottom-width: thin;\n"+"\tborder-bottom-style: solid;\n"+"\tborder-bottom-color: #999999;\n"+"\tpadding-bottom: 2px;\n"+"}\n"+"\n"+".intelliTaggerSuggestions .normalTags {\n"+"\tpadding-top: 2px;\n"+"}\n"+"\n"+".intelliTaggerSuggestions .intelliTaggerFooter .button {\n"+"\tfont-size: 10px;\n"+"\n"+"\tpadding-left: 0.3em;\n"+"\tpadding-right: 0.3em;\n"+"}\n"+"\n"+"/*}}}*/\n";config.shadowTiddlers["IntelliTaggerMainTemplate"]="<!--\n"+"{{{\n"+"-->\n"+"<div class=\"favorites\" macro=\"intelliTagger action: showFavorites\"></div>\n"+"<div class=\"normalTags\" macro=\"intelliTagger action: showTags\"></div>\n"+"<!-- The Footer (with the Navigation) ============================================ -->\n"+"<table class=\"intelliTaggerFooter\" border=\"0\" width=\"100%\" cellspacing=\"0\" cellpadding=\"0\"><tbody>\n"+"  <tr>\n"+"\t<td align=\"left\">\n"+"\t\t<span macro=\"intelliTagger action: closeButton\"></span>\n"+"\t</td>\n"+"\t<td align=\"right\">\n"+"\t\t<span macro=\"intelliTagger action: version\"></span>, <span macro=\"intelliTagger action: copyright \"></span>\n"+"\t</td>\n"+"  </tr>\n"+"</tbody></table>\n"+"<!--\n"+"}}}\n"+"-->\n";config.shadowTiddlers["IntelliTaggerEditTagsTemplate"]="<!--\n"+"{{{\n"+"-->\n"+"<div class='toolbar' macro='toolbar +saveTiddler -cancelTiddler'></div>\n"+"<div class='title' macro='view title'></div>\n"+"<div class='tagged' macro='tags'></div>\n"+"<div class='viewer' macro='view text wikified'></div>\n"+"<div class='toolbar' macro='toolbar +saveTiddler -cancelTiddler'></div>\n"+"<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser'></span></div>\n"+"<!--\n"+"}}}\n"+"-->\n";config.shadowTiddlers["BSD open source license (abego Software)"]="See [[Licence|http://tiddlywiki.abego-software.de/#%5B%5BBSD%20open%20source%20license%5D%5D]].";config.shadowTiddlers["IntelliTaggerPlugin Documentation"]="[[Documentation on abego Software website|http://tiddlywiki.abego-software.de/doc/IntelliTagger.pdf]].";config.shadowTiddlers["IntelliTaggerPlugin SourceCode"]="[[Plugin source code on abego Software website|http://tiddlywiki.abego-software.de/src/Plugin-IntelliTagger-src.js]]";setStylesheet(store.getTiddlerText("IntelliTaggerStyleSheet"),"intelliTagger");}
//%/
|''Name'' |LocalTheme |
|''Description'' |Theme for viewing this page on a local drive |
|>|Templates, Styles & Palette |
|PageTemplate |PageTemplate |
|ViewTemplate |ViewTemplate |
|EditTemplate |EditTemplate |
|StyleSheet |StyleSheet |
|ColorPalette |ColorPalette |
.admin {
display: none;
}
/*{{{*/
#mainMenu {
position: absolute;
left: 0;
width: 16em;
text-align: right;
line-height: 1.6em;
padding-left: 0.2em;
padding-right: 0.5em;
padding-top: 0.5em;
font-size: 85%;
}

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

#mainMenu table {
text-align: right;
width: 100%;
}
/*}}}*/
{{large{
[[Welcome]]
}}}
<<tiddler "Search Box">> <<tiddler "Navigation Menu">>
{{admin{
[[Main Menu|MainMenu]]
[[Setup Menu]]
[[Default Tiddlers]]
[[Recent Tiddlers]]
[[Administrative Menu]]
[[Import Tiddlers]]
[[Plugin Macros]]
[[Templates & Style Sheets]]
<<tiddler "Administrative Menu">>
}}}
/*{{{*/
#mainMenu {
font-family:'Arial Narrow', 'sans serif';
position: absolute;
left: 0;
width: 16em;
text-align: right;
line-height: 1.6em;
padding-left: 0.2em;
padding-right: 0.5em;
padding-top: 0.5em;
font-size: 85%;
}

#mainMenu .tiddlyLinkExisting, 
#mainMenu .tiddlyLinkNonExisting,
#sidebarTabs .tiddlyLinkNonExisting{
font-weight: normal;
font-style: normal;
}
#mainMenu .highlight {
background: [[ColorPalette::SecondaryLight]]
}
#mainMenu table {
text-align: right;
width: 100%;
}
#mainMenu .center {
align:center;
text-align:center;
}
/*}}}*/
<!--{{{-->
<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml' />
<!--}}}-->


<style type="text/css">#contentWrapper {display:none;}</style><div id="SplashScreen" style="border: 3px solid #ccc; display: block; text-align: center; width: 320px; margin: 100px auto; padding: 50px; color:#000; font-size: 28px; font-family:Tahoma; background-color:#eee;"><b>Testing TiddlyWiki Themes</b><p>is loading<blink> ...</blink><br><br><span style="font-size: 14px; color:red;">Requires Javascript.</span></div>
''Menus'' - and the versatility of menus - - if understood and used creatively and systematically - play a key role in TiddlyPerfect site - and open up a plethora of opportunities to organize, present, and find the wealth of information that can live in the structured tiddlers of a TiddlyPerfect world. In a digital knowledge-based universe, the use of digital tools that offer you  clear and simple hierarchical user-defined menus can play an invaluable role in easing one's journey in a digital world.

The [[NestedSlidersPlugin]], written by [[Udo Borkowski]] plays a vital role in [[TiddlyPerfect Menus]] - allowing the easy expansion or collapsing of  multi-level menus.

* [[Main Menu|MainMenu]] 
* [[Administrative Menus]]
** [[Head Menu]]
** [[Hover Menu|HoverMenu]] 
** [[Nesting Menus]]
* [[Changing Menus]]
* [[DataPerfect Menus]] 
* [[Browser Menus]] 
* [[Designing Menus]]
* [[Building Menus]]
* [[Desktop Menus]] 
* [[Digital Navigation]]
* [[Learning Menus]]
<<list missing>>
/***
| Name:|''monkeyTagger''|
| Created by:|SaqImtiaz|
| Location:|http://lewcid.googlepages.com/lewcid.html|
| Version:|0.9 (08-Apr-2006)|
| Requires:|~TW2.07|

!About:
*an adaptation of TagAdderMacro for monkeyGTD and tagglytagging user, but could be useful to just about anyone!
*{{{<<monkeyTagger Project>>}}} gives a drop down list of all tags, tagged with Project.
*The list allows toggling of tags on the current tiddler.
*logging options for task management.

!Demo:
<<monkeyTagger Status>>

!Installation:
*Copy this tiddler to your TW with the systemConfig tag
*either copy the following to your ViewTemplate:
{{{<div class='tagged' macro='monkeyTagger tagToTrack'></div>}}}
or
*better yet, define your own toolbar class and add as many as you need to create a nice toolbar.
Eg:
{{{<div class='toolbar' >
<span style="padding-right:0.15em;" macro='monkeyTagger Project'></span>
<span style="padding-right:0.15em;" macro='monkeyTagger Status'></span>
<span macro='toolbar -closeTiddler closeOthers +editTiddler permalink references jump'></span>
</div>}}}
 (adjust padding to taste)

!Usage:

''Syntax:''
|>|{{{<<monkeyTagger source:"sourcetag" label:"customlabel" logging:"true/false" anchor:"anchortext"  arrow:"true/false">>}}}|
|label:|quoted text to use as a customlabel|
|arrow:|add arrow to custom label, values are "true" or "false"|
|anchor:|quoted text to specify where to add logging text|
|logging:|enable logging of tags added (for task management), values are "true" or "false"|

the only parameter you ''have'' to pass is the source. When passing only one parameter, you can write either something like:
{{{<<monkeyTagger "Project">>}}} or {{{<<monkeyTagger source:"Project">>}}} for <<monkeyTagger Project>>
All other parameters are optional, and can be written in any order.

''Defaults:''
|label:|default label if not specified = source tag + arrow|
|arrow:|true |
|logging:|false |
|anchor:|none used by default, logging text added to end of tiddler |

''Examples:''
|custom label| {{{<<monkeyTagger source:"Project" label:"customlabel">>}}} |<<monkeyTagger source:"Project" label:"customlabel">>|
|custom label without arrow| {{{<<monkeyTagger source:"Project" label:"customlabel" arrow:"false">>}}} |<<monkeyTagger source:"Project" label:"customlabel" arrow:"false">>|
|logging enabled| {{{<<monkeyTagger source:"Project" logging:"true"}}} |<<monkeyTagger source:"Project" logging:"true">>|
|logging enabled with anchor text|{{{<<monkeyTagger source:"Project" logging:"true" anchor:"anchortext"}}} |<<monkeyTagger source:"Project" logging:"true" anchor:"anchortext">>|

''Tips:''
*Make sure your anchor text doesn't occur more than once in every tiddler, as the first instance will be used.
*I recommend using something like {{{/%StatusLog%/}}} as an invisible anchor.
*Use a tag based template, and add monkeyTagger macro's with logging enabled to the toolbar in just your taskmanagement templates.

!To Do:
*add sorting options if requested.
*''add exclude tag feature''!

!History
*Version 0.9: 
**changed to named parameters to make it more user friendly
**added option to disable/enable dropdown arrow in custom labels
**added logging option with anchor text.

!CODE
***/
//{{{

config.macros.monkeyTagger= {};
//config.macros.monkeyTagger.dropdownchar = (document.all?"▼":"▾"); // the fat one is the only one that works in IE
config.macros.monkeyTagger.dropdownchar = "▼"; // uncomment previous line and comment this for smaller version in FF
config.macros.monkeyTagger.handler = function(place,macroName,params,wikifier,paramString,tiddler)
{
 var nAV = paramString.parseParams('test', null, true);

 if ((nAV[0].arrow)&&(nAV[0].arrow[0])=='false')
    var arrow=': ';
 else
     var arrow=': '+ config.macros.monkeyTagger.dropdownchar;

 if((nAV[0].source)&&(nAV[0].source[0])!='.')
        {var tagToTrack = nAV[0].source[0]}
 else if(params[0]&&(params[0]!='.'))
      {var tagToTrack = params[0]}
 else
       {return false;};
 var monkeylabel = ((nAV[0].label)&&(nAV[0].label[0])!='.')?nAV[0].label[0]+arrow: tagToTrack+arrow;
 var logmode = ((nAV[0].logging)&&(nAV[0].logging[0])!='.')?nAV[0].logging[0]: "false";
 if ((nAV[0].anchor)&&(nAV[0].anchor[0])!='.')
    var anchor = nAV[0].anchor[0];
 var monkeytooltip=tagToTrack + ' :';


     if(tiddler instanceof Tiddler)
                {var title = tiddler.title;
                
                var addcomment = function(tiddler,newTag){
                    var now = new Date();
                    var timeFormat= 'DD/0MM/YY 0hh:0mm';
                    var formattednow= now.formatString(timeFormat);
                    var txt="\n*''"+tagToTrack+"'' set as ''"+newTag+"'' on "+formattednow;
                    if (anchor && anchor!='.')
                       {var pos=tiddler.text.indexOf(anchor);
                       if (pos!=-1) {pos=pos + anchor.length}
                       else if (pos==-1) {pos=tiddler.text.length}}
                    else if (!anchor){var pos = tiddler.text.length;};

                    tiddler.set(null,tiddler.text.substr(0,pos)+txt+tiddler.text.substr(pos));
                    story.refreshTiddler(tiddler.title,null,true);
                    return false;
}

                var ontagclick = function(e) {
                    if (!e) var e = window.event;
                    var tag = this.getAttribute("tag");
                    var t=store.getTiddler(title);
                    if (!t || !t.tags) return;
                    if (t.tags.find(tag)==null)
                       {t.tags.push(tag)
                         if (logmode=="true"){addcomment(t,tag);}}
                    else
                        {t.tags.splice(t.tags.find(tag),1)};
                    story.saveTiddler(title);
                    story.refreshTiddler(title,null,true);
                    return false;
                    };
                var onclick = function(e) {
                    if (!e) var e = window.event;
                    var popup = Popup.create(this);
                    var thistiddler=store.getTiddler(title);

                    var taggedarray = new Array();
                    var tagslabel = new Array();

                    var taggedtiddlers = store.getTaggedTiddlers(tagToTrack);
                    for (var t=0; t<taggedtiddlers.length; t++){
                        var taggedtitle= ((taggedtiddlers[t]).title);
                        taggedarray.push(taggedtitle);}

                    for (var t=0; t<taggedarray.length; t++){
                        var temptag = taggedarray[t];
                        if (thistiddler.tags.find(temptag)==null)
                           {var temptag='[ ] '+ temptag;
                           tagslabel.push(temptag);}
                        else
                            {var temptag ='[x] '+ temptag;
                            tagslabel.push(temptag);}
                            }

                   if(tagslabel.length == 0)
                          createTiddlyText(createTiddlyElement(popup,"li"),('no '+tagToTrack));
                          for (var t=0; t<tagslabel.length; t++)
                          {
                          var theTag = createTiddlyButton(createTiddlyElement(popup,"li"),tagslabel[t],("toggle '"+ ([taggedarray[t]]))+"'",ontagclick);
                          theTag.setAttribute("tag",taggedarray[t]);
                          }
       Popup.show(popup,false);
       e.cancelBubble = true;
       if (e.stopPropagation) e.stopPropagation();
       return(false);
};
 //createTiddlyButton(place,monkeylabel,monkeylabel,onclick);

var createdropperButton = function(place){
var sp = createTiddlyElement(place,"span",null,"monkeytaggerbutton");
var theDropDownBtn = createTiddlyButton(sp,monkeylabel,monkeytooltip,onclick);
};

createdropperButton(place);
 }
};
setStylesheet(
 ".toolbar .monkeytaggerbutton {margin-right:0em; border:0px solid #fff; padding:0px; padding-right:0px; padding-left:0px;}\n"+
 ".monkeytaggerbutton a.button {padding:2px; padding-left:2px; padding-right:2px;}\n"+
// ".monkeytaggerbutton {font-size:130%;}\n"+
//".monkeytaggerbutton .button {color:#703;}\n"+
 "",
"MonkeyTaggerStyles");

//}}}
//{{{
config.macros.saveRss = {};
config.macros.saveRss.handler = function(place)
{
	if(!readOnly)
		createTiddlyButton(place,'save rss','save rss',function(e){saveMultiRss();return false;});
}

window.getRssMarkers = function()
{
    var s = [];
    myregexp=/\|(?:.*?)\|(?:.*?)\|(.*?)\|(?:.*?)\|(.*?)\|/g;
    while((m = myregexp.exec(store.getTiddlerText("MultiRssConfig"))) != null)
         s.push("<link rel='alternate' type='application/rss+xml' title='%0' href='%1'>".format([m[1].trim(),m[2].trim()]));
    return s.splice(1,s.length).join("\n");
}

updateMarkupBlock_old_multirss = window.updateMarkupBlock;
window.updateMarkupBlock = function (s,blockName,tiddlerName)
{
    s = updateMarkupBlock_old_multirss.apply(this,arguments);
    if (blockName == "PRE-HEAD")
        s = lewcidRSSAddToMarkupBlock(s);
    return s;
}

window.lewcidRSSAddToMarkupBlock = function (s)
{
    var pos = s.indexOf("<!--PRE-HEAD-END-->");
    return ( s.substring(0,pos).replace("<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml'>","") + "\n" + getRssMarkers() + "\n" + s.substring(pos) );
}

TiddlyWiki.prototype.rssgetTiddlers = function(field,includeTag,excludeTag)
{
          var results = [];
          this.forEachTiddler(function(title,tiddler)
          {
          if(excludeTag == undefined || excludeTag == '' || tiddler.tags.find(excludeTag) == null)
                        if(includeTag == undefined || includeTag == '' || tiddler.tags.find(includeTag)!=null)
                                      results.push(tiddler);
          });
          if(field)
                   results.sort(function (a,b) {if(a[field] == b[field]) return(0); else return (a[field] < b[field]) ? -1 : +1; });
          return results;
}

window.generateRss = function (tiddlers,title,subtitle)
{
	var s = [];
	var d = new Date();
	var u = store.getTiddlerText("SiteUrl");
	s.push("<" + "?xml version=\"1.0\"?" + ">");
	s.push("<rss version=\"2.0\">");
	s.push("<channel>");
	s.push("<title" + ">" + ((title && title != '') ? wikifyPlain("SiteTitle").htmlEncode()+ " | "+ title: wikifyPlain("SiteTitle").htmlEncode()) + "</title" + ">");
	if(u)
		s.push("<link>" + u.htmlEncode() + "</link>");
	s.push("<description>" + ((subtitle && subtitle != '')? subtitle : wikifyPlain("SiteSubtitle").htmlEncode()) + "</description>");
	s.push("<language>en-us</language>");
	s.push("<copyright>Copyright " + d.getFullYear() + " " + config.options.txtUserName.htmlEncode() + "</copyright>");
	s.push("<pubDate>" + d.toGMTString() + "</pubDate>");
	s.push("<lastBuildDate>" + d.toGMTString() + "</lastBuildDate>");
	s.push("<docs>http://blogs.law.harvard.edu/tech/rss</docs>");
	s.push("<generator>TiddlyWiki " + version.major + "." + version.minor + "." + version.revision + "</generator>");
	if (!tiddlers)
        var tiddlers = store.getTiddlers("modified","excludeLists");
	var n = config.numRssItems > tiddlers.length ? 0 : tiddlers.length-config.numRssItems;
	for (var t=tiddlers.length-1; t>=n; t--)
		s.push(tiddlers[t].saveToRss(u));
	s.push("</channel>");
	s.push("</rss>");
	return s.join("\n");
}


old_multiRss_saveChanges = window.saveChanges;
window.saveChanges = function(onlyIfDirty)
{
    var rssStatus = config.options.chkGenerateAnRssFeed;
    config.options.chkGenerateAnRssFeed = false;
    old_multiRss_saveChanges.apply(this,arguments);
    config.options.chkGenerateAnRssFeed = rssStatus;
    if(config.options.chkGenerateAnRssFeed)
        saveMultiRss();
}

window.saveMultiRss = function()
{
      var rssIndex = store.getTiddlerText("MultiRssConfig").split("\n");
      rssIndex = rssIndex.splice(1,rssIndex.length);
      for (var i=0; i<rssIndex.length; i++)
          {
          var rss = rssIndex[i].split("|");
          var localPath = getLocalPath(document.location.toString());
          var rssPath = getRssPath(localPath)+ (rss[5].trim());
          var rssSave = saveFile(rssPath,convertUnicodeToUTF8(generateRss(store.rssgetTiddlers("modified",rss[1].trim(),rss[2].trim()),rss[3].trim(),rss[4].trim())));
          if(rssSave)
              displayMessage(config.messages.rssSaved,"file://" + rssPath);
          else
              alert(config.messages.rssFailed);
          }
}

window.getRssPath = function(str) {
    var slash = (str.indexOf('/')!=-1)? '/':'\\';
    return str.substring(0,str.lastIndexOf(slash) + 1);
}

config.shadowTiddlers.MultiRssConfig = "| !includeTag | !excludeTag | !title | !description | !filename |\n| rss | |rss only| this feed has rss tiddlers only | rss-feed.xml |\n|  systemConfig| |plugins| tiddlywiki plugins only |plugins.xml|\n| | systemConfig excludeRSS| Main RSS feed | everything but plugins | rss.xml|";
//}}}
<<jump>><<renameButton 'jump to an open tiddler'>>
<<closeAll>><<renameButton 'close all tiddlers'>>
<<permaview>>
<<newDocument ask print>><<renameButton 'print open tiddlers'>>
{{admin{
<<newTiddler "New Tiddler" >>
<<newTiddler text:{{store.getTiddlerText("foreach template","")}}>><<renameButton 'new category tiddler'>>
<<newTiddler text:{{store.getTiddlerText("iframe template","")}}>><<renameButton 'new iframe'>>
<<newTiddler text:{{store.getTiddlerText("picasa template","")}} title:"New Album" tag:"picasa album" >><<renameButton 'new album'>>
<<newTiddler text:{{store.getTiddlerText("youtube template","")}} title:"New YouTube" tag:youtube>><<renameButton 'new youtube'>>
<<saveChanges>>
<<option txtUserName>>
}}}
/***
|''Name:''|NestedSlidersPlugin|
|''Source:''|http://www.TiddlyTools.com/#NestedSlidersPlugin|
|''Author:''|Eric Shulman - ELS Design Studios|
|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|''~CoreVersion:''|2.0.10|

Quickly make any tiddler content into an expandable 'slider' panel, without needing to create a separate tiddler to contain the slider content.  Optional syntax allows ''default to open'', ''custom button label/tooltip'' and ''automatic blockquote formatting.''

You can also 'nest' these sliders as deep as you like (see complex nesting example below), so that expandable 'tree-like' hierarchical displays can be created.  This is most useful when converting existing in-line text content to create in-line annotations, footnotes, context-sensitive help, or other subordinate information displays.

For more details, please click on a section headline below:
++++!!!!![Configuration]>
Debugging messages for 'lazy sliders' deferred rendering:
<<option chkDebugLazySliderDefer>> show debugging alert when deferring slider rendering
<<option chkDebugLazySliderRender>> show debugging alert when deferred slider is actually rendered
===
++++!!!!![Usage and Options]>
When installed, this plugin adds new wiki syntax for embedding 'slider' panels directly into tiddler content.  Use {{{+++}}} and {{{===}}} to delimit the slider content.  Additional optional syntax elements let you specify
*default to open
** closed  {{{+++}}} and  {{{===}}}
** open {{{++++}}} and {{{===}}}
>> mark the start and end of the slider definition, respectively.  When the extra {{{+}}} is used, the slider will be open when initially displayed.
*cookiename: {{{(cookiename)}}} - saves the slider opened/closed state, and restores this state whenever the slider is re-rendered.
*heading level
*floater: (with optional CSS width value)
*mouse auto rollover: {{{*}}} ^^ automatically opens/closes slider on "rollover" as well as when clicked^^
*custom class/label/tooltip/accesskey: {{{{{class{[label=key|tooltip]}}}}}} ^^uses custom label/tooltip/accesskey.  {{{{{class{...}}}}}}, {{{=key}}} and {{{|tooltip}}} are optional.  'class' is any valid CSS class name, used to style the slider label text.  'key' must be a ''single letter only''.  Default labels/tootips are: ">" (more) and "<" (less), with no default access key assignment.^^
*automatic blockquote:  {{{">"}}} //(without the quotes)// ^^automatically adds blockquote formatting to slider content^^
*deferred rendering
The complete syntax, using all options, is:
//{{{
++++(cookiename)!!!!!^width^*{{class{[label=key|tooltip]}}}>...
content goes here
===
//}}}

* {{{!}}} through {{{!!!!!}}}^^
displays the slider label using a formatted headline (Hn) style instead of a button/link style^^
* {{{^width^}}} (or just {{{^}}})^^
makes the slider 'float' on top of other content rather than shifting that content downward.  'width' must be a valid CSS value (e.g., "30em", "180px", "50%", etc.).  If omitted, the default width is "auto" (i.e., fit to content)^^

* 
*
* {{{"..."}}} //(without the quotes)//^^
defers rendering of closed sliders until the first time they are opened.  //Note: deferred rendering may produce unexpected results in some cases.  Use with care.//^^

//Note: to make slider definitions easier to read and recognize when editing a tiddler, newlines immediately following the {{{+++}}} 'start slider' or preceding the {{{===}}} 'end slider' sequence are automatically suppressed so that excess whitespace is eliminated from the output.//
===
++++!!!!![Examples]>
simple in-line slider: 
{{{
+++
   content
===
}}}
+++
   content
===
----
use a custom label and tooltip: 
{{{
+++[label|tooltip]
   content
===
}}}
+++[label|tooltip]
   content
===
----
content automatically blockquoted: 
{{{
+++>
   content
===
}}}
+++>
   content
===
----
all options combined //(default open, cookie, heading, sized floater, rollover, class, label/tooltip/key, blockquoted, deferred)//
{{{
++++(testcookie)!!!^30em^*{{big{[label=Z|click or press Alt-Z to open]}}}>...
   content
===
}}}
++++(testcookie)!!!^30em^*{{big{[label=Z|click or press Alt-Z to open]}}}>...
   content
===
----
complex nesting example:
{{{
+++^[get info...=I|click for information or press Alt-I]
   put some general information here, plus a floating slider with more specific info:
   +++^10em^[view details...|click for details]
      put some detail here, which could include a rollover with a +++^25em^*[glossary definition]explaining technical terms===
   ===
===
}}}
+++^[get info...=I|click for information or press Alt-I]
   put some general information here, plus a floating slider with more specific info:
   +++^10em^[view details...|click for details]
      put some detail here, which could include a rollover with a +++^25em^*[glossary definition]explaining technical terms===
   ===
===
===
!!!!!Installation
<<<
import (or copy/paste) the following tiddlers into your document:
''NestedSlidersPlugin'' (tagged with <<tag systemConfig>>)
<<<
!!!!!Revision History
<<<
''2006.07.28 - 2.0.0'' added custom class syntax around label/tip/key syntax: {{{{{classname{[label=key|tip]}}}}}}
''2006.07.25 - 1.9.3'' when parsing slider, save default open/closed state in button element, then in onClickNestedSlider(), if slider state matches saved default, instead of saving cookie, delete it.  Significantly reduces the 'cookie overhead' when default slider states are used.
''2006.06.29 - 1.9.2'' in onClickNestedSlider(), when setting focus to first control, skip over type="hidden"
''2006.06.22 - 1.9.1'' added panel.defaultPanelWidth to save requested panel width, even after resizing has changed the style value
''2006.05.11 - 1.9.0'' added optional '^width^' syntax for floating sliders and '=key' syntax for setting an access key on a slider label
''2006.05.09 - 1.8.0'' in onClickNestedSlider(), when showing panel, set focus to first child input/textarea/select element
''2006.04.24 - 1.7.8'' in adjustSliderPos(), if floating panel is contained inside another floating panel, subtract offset of containing panel to find correct position
''2006.02.16 - 1.7.7'' corrected deferred rendering to account for use-case where show/hide state is tracked in a cookie
''2006.02.15 - 1.7.6'' in adjustSliderPos(), ensure that floating panel is positioned completely within the browser window (i.e., does not go beyond the right edge of the browser window)
''2006.02.04 - 1.7.5'' add 'var' to unintended global variable declarations to avoid FireFox 1.5.0.1 crash bug when assigning to globals
''2006.01.18 - 1.7.4'' only define adjustSliderPos() function if it has not already been provided by another plugin.  This lets other plugins 'hijack' the function even when they are loaded first.
''2006.01.16 - 1.7.3'' added adjustSliderPos(place,btn,panel,panelClass) function to permit specialized logic for placement of floating panels.  While it provides improved placement for many uses of floating panels, it exhibits a relative offset positioning error when used within *nested* floating panels.  Short-term workaround is to only adjust the position for 'top-level' floaters.
''2006.01.16 - 1.7.2'' added button property to slider panel elements so that slider panel can tell which button it belongs to.  Also, re-activated and corrected animation handling so that nested sliders aren't clipped by hijacking Slider.prototype.stop so that "overflow:hidden" can be reset to "overflow:visible" after animation ends
''2006.01.14 - 1.7.1'' added optional "^" syntax for floating panels.  Defines new CSS class, ".floatingPanel", as an alternative for standard in-line ".sliderPanel" styles.
''2006.01.14 - 1.7.0'' added optional "*" syntax for rollover handling to show/hide slider without requiring a click (Based on a suggestion by tw4efl)
''2006.01.03 - 1.6.2'' When using optional "!" heading style, instead of creating a clickable "Hn" element, create an "A" element inside the "Hn" element.  (allows click-through in SlideShowPlugin, which captures nearly all click events, except for hyperlinks)
''2005.12.15 - 1.6.1'' added optional "..." syntax to invoke deferred ('lazy') rendering for initially hidden sliders
removed checkbox option for 'global' application of lazy sliders
''2005.11.25 - 1.6.0'' added optional handling for 'lazy sliders' (deferred rendering for initially hidden sliders)
''2005.11.21 - 1.5.1'' revised regular expressions: if present, a single newline //preceding// and/or //following// a slider definition will be suppressed so start/end syntax can be place on separate lines in the tiddler 'source' for improved readability.  Similarly, any whitespace (newlines, tabs, spaces, etc.) trailing the 'start slider' syntax or preceding the 'end slider' syntax is also suppressed.
''2005.11.20 - 1.5.0'' added (cookiename) syntax for optional tracking and restoring of slider open/close state
''2005.11.11 - 1.4.0'' added !!!!! syntax to render slider label as a header (Hn) style instead of a button/link style
''2005.11.07 - 1.3.0'' removed alternative syntax {{{(((}}} and {{{)))}}} (so they can be used by other
formatting extensions) and simplified/improved regular expressions to trim multiple excess newlines
''2005.11.05 - 1.2.1'' changed name to NestedSlidersPlugin
more documentation
''2005.11.04 - 1.2.0'' added alternative character-mode syntax {{{(((}}} and {{{)))}}}
tweaked "eat newlines" logic for line-mode {{{+++}}} and {{{===}}} syntax
''2005.11.03 - 1.1.1'' fixed toggling of default tooltips ("more..." and "less...") when a non-default button label is used
code cleanup, added documentation
''2005.11.03 - 1.1.0'' changed delimiter syntax from {{{(((}}} and {{{)))}}} to {{{+++}}} and {{{===}}}
changed name to EasySlidersPlugin
''2005.11.03 - 1.0.0'' initial public release
<<<
!!!!!Credits
<<<
This feature was implemented by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]] with initial research and suggestions from RodneyGomes, GeoffSlocock, and PaulPetterson.
<<<
!!!!!Code
***/
//{{{
version.extensions.nestedSliders = {major: 2, minor: 0, revision: 0, date: new Date(2006,7,28)};
//}}}

//{{{
// options for deferred rendering of sliders that are not initially displayed
if (config.options.chkDebugLazySliderDefer==undefined) config.options.chkDebugLazySliderDefer=false;
if (config.options.chkDebugLazySliderRender==undefined) config.options.chkDebugLazySliderRender=false;

// default styles for 'floating' class
setStylesheet(".floatingPanel { position:absolute; z-index:10; padding:0.5em; margin:0em; \
	background-color:#eee; color:#000; border:1px solid #000; text-align:left; }","floatingPanelStylesheet");
//}}}

//{{{
config.formatters.push( {
	name: "nestedSliders",
	match: "\\n?\\+{3}",
	terminator: "\\s*\\={3}\\n?",
	lookahead: "\\n?\\+{3}(\\+)?(\\([^\\)]*\\))?(\\!*)?(\\^(?:[^\\^\\*\\[\\>]*\\^)?)?(\\*)?(?:\\{\\{([\\w]+[\\s\\w]*)\\{)?(\\[[^\\]]*\\])?(?:\\}{3})?(\\>)?(\\.\\.\\.)?\\s*",
	handler: function(w)
		{
			// defopen=lookaheadMatch[1]
			// cookiename=lookaheadMatch[2]
			// header=lookaheadMatch[3]
			// panelwidth=lookaheadMatch[4]
			// rollover=lookaheadMatch[5]
			// class=lookaheadMatch[6]
			// label=lookaheadMatch[7]
			// blockquote=lookaheadMatch[8]
			// deferred=lookaheadMatch[9]

			 lookaheadRegExp = new RegExp(this.lookahead,"mg");
			lookaheadRegExp.lastIndex = w.matchStart;
			var lookaheadMatch = lookaheadRegExp.exec(w.source)
			if(lookaheadMatch && lookaheadMatch.index == w.matchStart)
			{
				// location for rendering button and panel
				var place=w.output;

				// default to closed, no cookie, no accesskey
				var show="none"; var title=">"; var tooltip="show"; var cookie=""; var key="";

				// extra "+", default to open
				if (lookaheadMatch[1])
					{ show="block"; title="<"; tooltip="hide"; }

				// cookie, use saved open/closed state
				if (lookaheadMatch[2]) {
					cookie=lookaheadMatch[2].trim().slice(1,-1);
					cookie="chkSlider"+cookie;
					if (config.options[cookie]==undefined)
						{ config.options[cookie] = (show=="block") }
					if (config.options[cookie])
						{ show="block"; title="<"; tooltip="hide"; }
					else
						{ show="none"; title=">"; tooltip="show"; }
				}

				// parse custom label/tooltip/accesskey: [label=X|tooltip]
				if (lookaheadMatch[7]) {
					title = lookaheadMatch[7].trim().slice(1,-1);
					var pos=title.indexOf("|");
					if (pos!=-1) { tooltip = title.substr(pos+1,title.length); title=title.substr(0,pos); }
					if (title.substr(title.length-2,1)=="=") { key=title.substr(title.length-1,1); title=title.slice(0,-2); }
					if (pos==-1) tooltip += " "+title; // default tooltip: "show/hide <title>"
				}

				// create the button
				if (lookaheadMatch[3]) { // use "Hn" header format instead of button/link
					var lvl=(lookaheadMatch[3].length>6)?6:lookaheadMatch[3].length;
					var btn = createTiddlyElement(createTiddlyElement(place,"h"+lvl,null,null,null),"a",null,lookaheadMatch[6],title);
					btn.onclick=onClickNestedSlider;
					btn.setAttribute("href","javascript:;");
					btn.setAttribute("title",tooltip);
				}
				else
					var btn = createTiddlyButton(place,title,tooltip,onClickNestedSlider,lookaheadMatch[6]);

				// set extra button attributes
				btn.sliderCookie = cookie; // save the cookiename (if any) in the button object
				btn.defOpen=lookaheadMatch[1]!=null; // save default open/closed state (boolean)
				btn.keyparam=key; // save the access key letter ("" if none)
				if (key.length) {
					btn.setAttribute("accessKey",key); // init access key
					btn.onfocus=function(){this.setAttribute("accessKey",this.keyparam);}; // **reclaim** access key on focus
				}

				// "non-click" MouseOver open/close slider
				if (lookaheadMatch[5]) btn.onmouseover=onClickNestedSlider;

				// create slider panel
				var panelClass=lookaheadMatch[4]?"floatingPanel":"sliderPanel";
				var panel=createTiddlyElement(place,"div",null,panelClass,null);
				panel.button = btn; // so the slider panel know which button it belongs to
				panel.defaultPanelWidth=(lookaheadMatch[4] && lookaheadMatch[4].length>2)?lookaheadMatch[4].slice(1,-1):""; // save requested panel size
				btn.sliderPanel=panel;
				panel.style.display = show;
				panel.style.width=panel.defaultPanelWidth;

				// render slider (or defer until shown) 
				w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
				if ((show=="block")||!lookaheadMatch[9]) {
					// render now if panel is supposed to be shown or NOT deferred rendering
					w.subWikify(lookaheadMatch[8]?createTiddlyElement(panel,"blockquote"):panel,this.terminator);
					// align slider/floater position with button
					adjustSliderPos(place,btn,panel,panelClass);
				}
				else {
					var src = w.source.substr(w.nextMatch);
					var endpos=findMatchingDelimiter(src,"+++","===");
					panel.setAttribute("raw",src.substr(0,endpos));
					panel.setAttribute("blockquote",lookaheadMatch[8]?"true":"false");
					panel.setAttribute("rendered","false");
					w.nextMatch += endpos+3;
					if (w.source.substr(w.nextMatch,1)=="\n") w.nextMatch++;
					if (config.options.chkDebugLazySliderDefer) alert("deferred '"+title+"':\n\n"+panel.getAttribute("raw"));
				}
			}
		}
	}
)

// TBD: ignore 'quoted' delimiters (e.g., "{{{+++foo===}}}" isn't really a slider)
function findMatchingDelimiter(src,starttext,endtext) {
	var startpos = 0;
	var endpos = src.indexOf(endtext);
	// check for nested delimiters
	while (src.substring(startpos,endpos-1).indexOf(starttext)!=-1) {
		// count number of nested 'starts'
		var startcount=0;
		var temp = src.substring(startpos,endpos-1);
		var pos=temp.indexOf(starttext);
		while (pos!=-1)  { startcount++; pos=temp.indexOf(starttext,pos+starttext.length); }
		// set up to check for additional 'starts' after adjusting endpos
		startpos=endpos+endtext.length;
		// find endpos for corresponding number of matching 'ends'
		while (startcount && endpos!=-1) {
			endpos = src.indexOf(endtext,endpos+endtext.length);
			startcount--;
		}
	}
	return (endpos==-1)?src.length:endpos;
}
//}}}

//{{{
window.onClickNestedSlider=function(e)
{
	if (!e) var e = window.event;
	var theTarget = resolveTarget(e);
	var theLabel = theTarget.firstChild.data;
	var theSlider = theTarget.sliderPanel
	var isOpen = theSlider.style.display!="none";
	// if using default button labels, toggle labels
	if (theLabel==">") theTarget.firstChild.data = "<";
	else if (theLabel=="<") theTarget.firstChild.data = ">";
	// if using default tooltips, toggle tooltips
	if (theTarget.getAttribute("title")=="show")
		theTarget.setAttribute("title","hide");
	else if (theTarget.getAttribute("title")=="hide")
		theTarget.setAttribute("title","show");
	if (theTarget.getAttribute("title")=="show "+theLabel)
		theTarget.setAttribute("title","hide "+theLabel);
	else if (theTarget.getAttribute("title")=="hide "+theLabel)
		theTarget.setAttribute("title","show "+theLabel);
	// deferred rendering (if needed)
	if (theSlider.getAttribute("rendered")=="false") {
		if (config.options.chkDebugLazySliderRender)
			alert("rendering '"+theLabel+"':\n\n"+theSlider.getAttribute("raw"));
		var place=theSlider;
		if (theSlider.getAttribute("blockquote")=="true")
			place=createTiddlyElement(place,"blockquote");
		wikify(theSlider.getAttribute("raw"),place);
		theSlider.setAttribute("rendered","true");
	}
	// show/hide the slider
	if(config.options.chkAnimate)
		anim.startAnimating(new Slider(theSlider,!isOpen,e.shiftKey || e.altKey,"none"));
	else
		theSlider.style.display = isOpen ? "none" : "block";
	// reset to default width (might have been changed via plugin code)
	theSlider.style.width=theSlider.defaultPanelWidth;
	// align slider/floater position with target button
	if (!isOpen) adjustSliderPos(theSlider.parentNode,theTarget,theSlider,theSlider.className);
	// if showing panel, set focus to first 'focus-able' element in panel
	if (theSlider.style.display!="none") {
		var ctrls=theSlider.getElementsByTagName("*");
		for (var c=0; c<ctrls.length; c++) {
			var t=ctrls[c].tagName.toLowerCase();
			if ((t=="input" && ctrls[c].type!="hidden") || t=="textarea" || t=="select")
				{ ctrls[c].focus(); break; }
		}
	}
	if (this.sliderCookie && this.sliderCookie.length) {
		config.options[this.sliderCookie]=!isOpen;
		if (config.options[this.sliderCookie]!=this.defOpen)
			saveOptionCookie(this.sliderCookie);
		else { // remove cookie if slider is in default display state
			var ex=new Date(); ex.setTime(ex.getTime()-1000);
			document.cookie = this.sliderCookie+"=novalue; path=/; expires="+ex.toGMTString();
		}
	}
	return false;
}

// hijack animation handler 'stop' handler so overflow is visible after animation has completed
Slider.prototype.coreStop = Slider.prototype.stop;
Slider.prototype.stop = function() { this.coreStop(); this.element.style.overflow = "visible"; }

// adjust panel position based on button position
if (window.adjustSliderPos==undefined) window.adjustSliderPos=function(place,btn,panel,panelClass) {
	if (panelClass=="floatingPanel") {
		var left=0;
		var top=btn.offsetHeight; 
		if (place.style.position!="relative") {
			var left=findPosX(btn);
			var top=findPosY(btn)+btn.offsetHeight;
			var p=place; while (p && p.className!='floatingPanel') p=p.parentNode;
			if (p) { left-=findPosX(p); top-=findPosY(p); }
		}
		if (left+panel.offsetWidth > getWindowWidth()) left=getWindowWidth()-panel.offsetWidth-10;
		panel.style.left=left+"px"; panel.style.top=top+"px";
	}
}

function getWindowWidth() {
	if(document.width!=undefined)
		return document.width; // moz (FF)
	if(document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) )
		return document.documentElement.clientWidth; // IE6
	if(document.body && ( document.body.clientWidth || document.body.clientHeight ) )
		return document.body.clientWidth; // IE4
	if(window.innerWidth!=undefined)
		return window.innerWidth; // IE - general
	return 0; // unknown
}
//}}}
/***
|Name|NewDocumentPlugin|
|Source|http://www.TiddlyTools.com/#NewDocumentPlugin|
|Version|1.7.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|Quickly create new TiddlyWiki documents from your existing document, with just one click|

Use the {{{<<newDocument>>}}} macro to place a "new document" link into your sidebar/mainmenu/any tiddler (wherever you like).  Select this command to automatically create a "new.html" document containing a specific set of tagged tiddlers.  Optional parameters let you specify an alternate path/filename for the new file, or different tags to match.  You can also indicate "ask" for either parameter, which will  trigger a prompt for input when the command is selected.

!!!!!Usage
<<<
{{{<<newDocument label:text prompt:text filename tag tag tag...>>}}}
{{{<<newDocument label:text prompt:text filename all>>}}}
{{{<<newDocument label:text prompt:text filename snap ID>>}}}
{{{<<newDocument label:text prompt:text filename snap here>>}}}
{{{<<newDocument label:text prompt:text nofile print ID>>}}}
{{{<<newDocument label:text prompt:text nofile print here>>}}}
 where:
* ''label:text'' defines //optional// alternative link text (replaces default "new document" display)
* ''prompt:text'' defines //optional// alternative tooltip text for 'mouseover' prompting (replaces default hard-coded tooltip text)
* ''filename'' is any local path-and-filename.  If no parameters are provided, the default is to create the file "new.html" in the current directory.  If a filename is provided without a path (i.e., there is no "/" in the input), then the current directory is also assumed.  Otherwise, this parameter is expected to contain the complete path and filename needed to write the file to your local hard disk.  If ''ask'' is used in place of the filename parameter then, when the command link is selected, a message box will be automatically displayed so you can select/enter the path and filename.
* ''tag tag tag...'' is a list of one or more space-separated tags (use quotes or {{{[[]]}}} around tags that contain spaces).  The new document will include all tiddlers that match at least one of the tags in the list.  The default is to include tiddlers tagged with <<tag includeNew>>.    The special value ''all'' may be used to match every tiddler (even those without tags).   If ''ask'' is used in place of the tags then, when the command link is selected, a message box will be automatically displayed so you can enter the desired tags at that time.
* When you use the keyword ''snap'' in place of the tags, you can generate a file containing the //rendered//  CSS-and-HTML that is currently being displayed in browser.  By default, the snapshop uses the 'contentWrapper' DOM element ID to automatically include all the TiddlyWiki elements, such as the sidebars and header, in addition to the center 'story' column containing the tiddler content.
* When you use the keyword ''print'' in place of the tags, a snapshot is generated, but the contents are not written to a file.  Instead, they are displayed in a separate browser tab/window, and the print dialog for that tab/window is automatically invoked.
* You can limit the snapshot to capture only a portion of the rendered TiddlyWiki elements by specifiying an optional alternate DOM element ID, such as "displayArea" (the entire center 'story' column) or even just a single tiddler (e.g., "tidderMyTiddlerTitle", assuming that "MyTiddlerTitle" is currently displayed).  Only the portions of the document that are contained //within// the specified DOM element will be transcribed to the resulting snapshot file.  If ''ask'' is used in place of a DOM element ID, you will be prompted to enter the ID (default is "contentWrapper") when the snapshot is being taken.  This allows you to easily enter the ID of any currently displayed tiddler to make quick snapshots of specific tiddlers.  If ''here'' is used in place of a DOM element ID, the current tiddler id is used.

Note: as of version 1.4.0 of this plugin, support for selecting tiddlers by using tag *expressions* has been replaced with simpler, more efficient "containsAny()" logic.  To create new ~TiddlyWiki documents that contain only those tiddlers selected with advanced AND/OR/NOT Boolean expressions, you can use the filtering features provided by the ExportTiddlersPlugin (see www.TiddlyTools.com/#ExportTiddlersPlugin).
<<<
!!!!!Examples:
<<<
{{{<<newDocument>>}}}
equivalent to {{{<<newDocument new.htm includeNew systemTiddlers>>}}}
creates default "new.html" containing tiddlers tagged with either<<tag includeNew>>or<<tag systemTiddlers>>
try it: <<newDocument>>

{{{<<newDocument empty.html systemTiddlers>>}}}
creates "empty.html" containing only tiddlers tagged with<<tag systemTiddlers>>
//(reproduces old-style (pre 2.0.2) empty file)//
try it: <<newDocument empty.html systemTiddlers>>

{{{<<newDocument "label:create Import/Export starter" ask importexport>>}}}
save importexport tiddlers to a new file, prompts for path/file
try it: <<newDocument "label:create Import/Export starter" ask importexport>>

{{{<<newDocument ask ask>>}}}
prompts for path/file, prompts for tags to match
try it: <<newDocument ask ask>>

{{{<<newDocument ask all>>}}}
save all current TiddlyWiki contents to a new file, prompts for path/file
try it: <<newDocument ask all>>

{{{<<newDocument ask snap>>}}}
generates snapshot of currently displayed document, prompts for path/file
try it: <<newDocument ask snap>>

{{{<<newDocument ask snap here>>}}}
generates snapshot of this tiddler ONLY, prompts for path/file
try it: <<newDocument ask snap here>>

{{{<<newDocument ask print here>>}}}
prints a snapshot of this tiddler ONLY
try it: <<newDocument nofile print here>>

<<<
!!!!!Installation
<<<
Import (or copy/paste) the following tiddlers into your document:
''NewDocumentPlugin'' (tagged with <<tag systemConfig>>)
<<<
!!!!!Revision History
<<<
''2007.12.04 [*.*.*]'' update for TW2.3.0: replaced deprecated core functions, regexps, and macros
''2007.03.30 [1.7.0]'' added support for "print" param as alternative for "snap".  When "print" is used, the filename is ignored and ouput is directed to another browser tab/window, where the print dialog is then automatically triggered.
''2007.03.30 [1.6.1]'' added support for "here" keyword for current tiddler elementID and "prompt:text" param for specifying tooltip text
''2007.02.12 [1.6.0]'' in onClickNewDocument(), reset HTML source 'markup'
''2006.10.23 [1.5.1]'' in onClickNewDocument(), get saved parameter value for snapID instead of using default "contentWrapper" (oops!)
''2006.10.18 [1.5.0]'' new optional param for 'snap'... specify alternative DOM element ID (default is still "contentWrapper").  Based on a suggestion from Xavier Verges.
''2006.08.03 [1.4.3]'' in promptForFilename(), for IE (WinXP only), added handling for UserAccounts.CommonDialog
''2006.07.29 [1.4.2]'' in onClickNewDocument(), okmsg display is now linked to newly created file
''2006.07.24 [1.4.1]'' in promptForFilename(), check for nsIFilePicker.returnCancel to allow nsIFilePicker.returnOK **OR** nsIFilePicker.returnReplace to be processed.
''2006.05.23 [1.4.0]'' due to very poor performance, support for tag *expressions* has been removed, in favor of a simpler "containsAny()" scan for tags.
''2006.04.09 [1.3.6]'' in onClickNewDocument, added call to convertUnicodeToUTF8() to better handle international characters.
''2006.03.15 [1.3.5]'' added nsIFilePicker() handler for selecting filename in moz-based browsers.  IE and other non-moz browsers still use simple prompt() dialog
''2006.03.15 [1.3.0]'' added "label:text" param for custom link text.  added special "all" filter parameter for "save as..." handling (writes all tiddlers to output file)
''2006.03.09 [1.2.0]'' added special "snap" filter parameter to generate and write "snapshot" files containing static HTML+CSS for currently rendered document.
''2006.02.24 [1.1.2]'' Fix incompatiblity with TW 2.0.5 by removing custom definition of getLocalPath() (which is now part of TW core)
''2006.02.03 [1.1.1]'' concatentate 'extra' params so that tag expressions don't have to be quoted.   moved all text to 'formatted' string definitions for easier translation.
''2006.02.03 [1.1.0]'' added support for tag EXPRESSIONS.  plus improved documentation and code cleanup
''2006.02.03 [1.0.0]'' Created.
<<<
!!!!!Credits
<<<
This feature was developed by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]]
<<<
!!!!!Code
***/
//{{{
version.extensions.newDocument = {major: 1, minor: 7, revision: 0, date: new Date(2007,3,30)};

config.macros.newDocument = {
	newlabel: "new document",
	newprompt: "Create a new TiddlyWiki 'starter' document",
	newdefault: "new.html",
	allparam: "all",
	saveaslabel: "save as...",
	saveasprompt: "Save current TiddlyWiki to a different file",
	printparam: "print",
	snapparam: "snap",
	snaplabel: "create a snapshot",
	snapprompt: "Create a 'snapshot' of the current TiddlyWiki display",
	snapdefault: "snapshot.html",
	snapID: "contentWrapper",
	snapIDprompt: "Please enter a DOM element ID for the desired content",
	snapIDerrmsg: "Unrecognized document element ID: '%0'",
	askparam: "ask",
	hereparam: "here",
	labelparam: "label:",
	promptparam: "prompt:",
	fileprompt: "Please enter a filename",
	filter: "includeNew",
	filterprompt: "Match one or more tags:\n(space-separated, use [[...]] around tags containing spaces)",
	filtererrmsg: "Error in tag filter '%0'",
	snapmsg: "Document snapshot written to %1",
	okmsg: "%0 tiddlers written to %1",
	failmsg: "An error occurred while creating %0"
};

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

	var path=getLocalPath(document.location.href);
	var slashpos=path.lastIndexOf("/"); if (slashpos==-1) slashpos=path.lastIndexOf("\\"); 
	if (slashpos!=-1) path = path.substr(0,slashpos+1); // remove filename from path, leave the trailing slash

	if (params[0] && params[0].substr(0,config.macros.newDocument.labelparam.length)==config.macros.newDocument.labelparam)
		var label=params.shift().substr(config.macros.newDocument.labelparam.length)
	if (params[0] && params[0].substr(0,config.macros.newDocument.promptparam.length)==config.macros.newDocument.promptparam)
		var prompt=params.shift().substr(config.macros.newDocument.promptparam.length)
	var filename=params.shift(); if (!filename) filename=config.macros.newDocument.newdefault;
	if (params[0]==config.macros.newDocument.snapparam || params[0]==config.macros.newDocument.printparam) {
		var printmode=(params[0]==config.macros.newDocument.printparam);
		params.shift();
		if (!label) var label=config.macros.newDocument.snaplabel;
		if (!prompt) var prompt=config.macros.newDocument.snapprompt;
		var defaultfile=config.macros.newDocument.snapdefault;
		var snapID=config.macros.newDocument.snapID;// default to "contentWrapper"
		if (params[0]) var snapID=params.shift(); // alternate DOM element for snapshot
	}
	if (params[0]==config.macros.newDocument.allparam) {
		if (!label) var label=config.macros.newDocument.saveaslabel;
		if (!prompt) var prompt=config.macros.newDocument.saveasprompt;
		var defaultfile=getLocalPath(document.location.href);
		var slashpos=defaultfile.lastIndexOf("/"); if (slashpos==-1) slashpos=defaultfile.lastIndexOf("\\");
		if (slashpos!=-1) defaultfile=defaultfile.substr(slashpos+1); // get filename only
	}
	if (!prompt) var prompt=config.macros.newDocument.newprompt;
	if (!label) var label=config.macros.newDocument.newlabel;
	if (!defaultfile) var defaultfile=config.macros.newDocument.newdefault;

	var btn=createTiddlyButton(place,label,prompt,onClickNewDocument);
	btn.path=path;
	btn.file=filename;
	btn.defaultfile=defaultfile;
	btn.snapID=snapID; // NULL unless snapshot is being taken
	btn.printmode=printmode;
	btn.filter=params.length?params:[config.macros.newDocument.filter]; 
}

// IE needs explicit global scoping for functions called by browser events
window.onClickNewDocument=function(e)
{
	if (!e) var e = window.event; var btn=resolveTarget(e);

	// assemble document content, write file, report result
	var okmsg=config.macros.newDocument.okmsg;
	var failmsg=config.macros.newDocument.failmsg;
	var count=0;
	var out="";
	if (btn.snapID) { // HTML+CSS snapshot
		var snapID=btn.snapID;
		if (btn.snapID==config.macros.newDocument.askparam)
			snapID=prompt(config.macros.newDocument.snapIDprompt,config.macros.newDocument.snapID);
		if (btn.snapID==config.macros.newDocument.hereparam)
			{ var here=story.findContainingTiddler(btn); if (here) snapID=here.id; }
		if (!document.getElementById(snapID)) { // if specified element does not exist
			if (snapID) // ID=null if prompt was cancelled by user
				displayMessage(config.macros.newDocument.snapIDerrmsg.format([snapID]));
			e.cancelBubble = true; if (e.stopPropagation) e.stopPropagation(); return(false);
		}
		var styles=document.getElementsByTagName("style");
		out+="<html>\n<head>\n<style>\n";
		for(var i=0; i < styles.length; i++)
			out +="/* stylesheet from tiddler:"+styles[i].getAttribute("id")+" */\n"+styles[i].innerHTML+"\n\n";
		out+="</style>\n</head>\n<body>\n\n"+document.getElementById(snapID).innerHTML+"\n\n</body>\n</html>";
		okmsg=config.macros.newDocument.snapmsg;
	} else { // TW starter document
		// get the TiddlyWiki core code source
		var sourcefile=getLocalPath(document.location.href);
		var source=loadFile(sourcefile);
		if(source==null) { alert(config.messages.cantSaveError); return null; }
		// reset existing HTML source markup
		source=updateMarkupBlock(source,"PRE-HEAD");
		source=updateMarkupBlock(source,"POST-HEAD");
		source=updateMarkupBlock(source,"PRE-BODY");
		source=updateMarkupBlock(source,"POST-BODY");
		// find store area
		var posOpeningDiv=source.indexOf(startSaveArea);
		var posClosingDiv=source.lastIndexOf(endSaveArea);
		if((posOpeningDiv==-1)||(posClosingDiv==-1)) { alert(config.messages.invalidFileError.format([sourcefile])); return; }
		// get the matching tiddler divs
		var match=btn.filter;
		if (match[0]==config.macros.newDocument.askparam) { // ask user for tags
			var newfilt=prompt(config.macros.newDocument.filterprompt,config.macros.newDocument.filter);
			if (!newfilt) return;  // cancelled by user
			match=newfilt.readMacroParams();
		}
		var storeAreaDivs=[];
		var tiddlers=store.getTiddlers('title');
		for (var i=0; i<tiddlers.length; i++)
			if (match[0]==config.macros.newDocument.allparam || (tiddlers[i].tags && tiddlers[i].tags.containsAny(match)) )
				storeAreaDivs.push(store.getSaver().externalizeTiddler(store,tiddlers[i]));
		out+=source.substr(0,posOpeningDiv+startSaveArea.length);
		out+=convertUnicodeToUTF8(storeAreaDivs.join("\n"))+"\n\t\t";
		out+=source.substr(posClosingDiv);
		count=storeAreaDivs.length;
	}
	if (btn.printmode) {
		var win=window.open("","_blank","");
		win.document.open();
		win.document.writeln(out);
		win.document.close();
		win.focus(); // bring to front
		win.print(); // trigger print dialog
	} else {
		// get output path/filename
		var filename=btn.file;
		if (filename==config.macros.newDocument.askparam)
			filename=promptForFilename(config.macros.newDocument.fileprompt,btn.path,btn.defaultfile);
		if (!filename) return; // cancelled by user
		// if specified file does not include a path, assemble fully qualified path and filename
		var slashpos=filename.lastIndexOf("/"); if (slashpos==-1) slashpos=filename.lastIndexOf("\\");
		if (slashpos==-1) filename=btn.path+filename;
		var ok=saveFile(filename,out);
		var msg=ok?okmsg.format([count,filename]):failmsg.format([filename]);
		var link=ok?"file:///"+filename.replace(/\\/g,'/'):""; // change local path to link text
		clearMessage(); displayMessage(msg,link);
	}
	e.cancelBubble = true; if (e.stopPropagation) e.stopPropagation(); return(false);
}
//}}}

//{{{
function promptForFilename(msg,path,file)
{
	if(window.Components) { // moz
		try {
			netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
			var nsIFilePicker = window.Components.interfaces.nsIFilePicker;
			var picker = Components.classes['@mozilla.org/filepicker;1'].createInstance(nsIFilePicker);
			picker.init(window, msg, nsIFilePicker.modeSave);
			var thispath = Components.classes['@mozilla.org/file/local;1'].createInstance(Components.interfaces.nsILocalFile);
			thispath.initWithPath(path);
			picker.displayDirectory=thispath;
			picker.defaultExtension='html';
			picker.defaultString=file;
			picker.appendFilters(nsIFilePicker.filterAll|nsIFilePicker.filterText|nsIFilePicker.filterHTML);
			if (picker.show()!=nsIFilePicker.returnCancel) var result=picker.file.persistentDescriptor;
		}
		catch(e) { alert('error during local file access: '+e.toString()) }
	}
	else { // IE
		try { // XP only
			var s = new ActiveXObject('UserAccounts.CommonDialog');
			s.Filter='All files|*.*|Text files|*.txt|HTML files|*.htm;*.html|';
			s.FilterIndex=3; // default to HTML files;
			s.InitialDir=path;
			s.FileName=file;
			if (s.showOpen()) var result=s.FileName;
		}
		catch(e) { var result=prompt(msg,path+file); } // fallback for non-XP IE
	}
	return result;
}
//}}}
/*{{{*/
* html .tiddler {
    height: 1%;
}
body {
font-size: .75em;
font-family: arial, garamond antigua, arial, helvetica;
margin: 0;
padding: 0;
}
[[CustomStyleSheet]]
[[ModifiedStyleSheetColors]]
[[CustomStyleSheetColors]]
[[TagglyTaggingStyles]]
[[MainMenuStyles]]
[[HoverMenuStyles]]
[[PrintStyles]]
[[CommonStyles]]
[[HeaderStyles]]
.admin {
display: none;
}
/*}}}*/
|''Name'' |OnlineTheme |
|''Description'' |Theme for viewing the site online |
|>|Templates, Styles & Palette |
|PageTemplate |PageTemplate |
|ViewTemplate |ViewTemplate |
|EditTemplate |EditTemplate |
|StyleSheet |OnlineStyleSheet |
|StyleSheetReadOnly|OnlineStyleSheet|
|ColorPalette |ColorPalette |
!Style Sheet
/*{{{*/
* html .tiddler {
    height: 1%;
}
body {
font-size: .75em;
font-family: georgia, garamond antigua, arial, helvetica;
margin: 0;
padding: 0;
}
[[CustomStyleSheet]]
[[ModifiedStyleSheetColors]]
[[CustomStyleSheetColors]]
[[TagglyTaggingStyles]]
[[MainMenuStyles]]
[[HoverMenuStyles]]
[[PrintStyles]]
[[CommonStyles]]
[[HeaderStyles]]
.admin {
display: none;
}
/*}}}*/
/***
|Name|''OpenHerePlugin'' |h
|Author |[[Robert Pollard]] |
|Version |1.0 |
|Date|2009.08.26 - Wednesday, 26 August 2009 |
|Description |Creates an internal link that opens the tiddler immediately below the link, building on Eric Shulman's NestedSlidersPlugin  |
|Source |http://www.climatechange3.net/#OpenHerePlugin |
|Requires |[[NestedSlidersPlugin]] - http://www.TiddlyTools.com/#NestedSlidersPlugin |
***/
/***
!!!Example
{{{<<oh "Climate Change 3.0">>}}}
<<oh "Climate Change 3.0">>
!!!Installation
Import (or copy/paste) this tiddler into your document: and tag it with "systemConfig"
!!!Note
This macro generates the following syntax:
<<<
{{{
+++[TiddlerName]
<<tiddler "TiddlerName">>

===
}}}
<<<
!!!Code
***/
//{{{
config.macros.oh = {};
config.macros.oh.handler= function(place,macroName,params) {
   var key=params[0];
   wikify('+++['+key+']\n\n<'+'<tiddler "'+key+'">'+'>\n\n===\n',place)
}
//}}}
<!--{{{-->
<div class='header' macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryMid]]'>
<div class='headerShadow'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>
<br>
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
<div class='headerForeground'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>
<br>
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
</div>
<div id='mainMenu' refresh='content' tiddler='MainMenu'></div>
<div id='displayArea'>
<div id='messageArea'></div>
<div id='tiddlerDisplay'></div>
</div>
<!--}}}-->
/***
|''Name''|PaletteViewMacro|
|''Version''|0.2|
|''Author''|FND|
|''Source''|[[FND's DevPad|http://devpad.tiddlyspot.com/#PaletteViewMacro]]|
|''License''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|''~CoreVersion''|2.1|
|''Type''|macro|
|''Requires''|N/A|
|''Overrides''|N/A|
|''Description''|Displays color palettes.|
!Notes
There is also [[ViewPalettePlugin|http://simon.tiddlyspot.com/#ViewPalettePlugin]], which currently does not work with TiddlyWiki v2.2 though.
!Usage
{{{
<<paletteView [tiddler name]>>
}}}
!!Example
<<paletteView [[ColorPalette]]>>
!Revision History
!!v0.1 (2007-11-18)
* initial release
!!v0.2 (2007-11-20)
* limited processing to slices containing [[actual color values|http://www.w3.org/TR/CSS21/syndata.html#color-units]]
* changed fallback value to the tiddler the macro is called from (instead of using [[ColorPalette]])
!To Do
* selection list for all available palettes (tag-based)
* parameter for custom table class
* customizable column order
* documentation (e.g. using from within [[ViewTemplate]])
!Code
***/
//{{{
config.macros.paletteView = {};

config.macros.paletteView.handler = function(place, macroName, params, wikifier, paramString, tiddler) {
	var title = params[0] || tiddler.title;
	//var palettes = store.getTaggedTiddlers(params[0]); // DEBUG: yet to be implemented
	var colors = store.calcAllSlices(title);
	var labels = [];
	for(var c in colors) {
		if(this.isColor(colors[c])) {
			labels.push(c);
		}
	}
	if(labels.length > 0) {
		var output = "|!Sample|!Value|!Name|h\n";
		for(var i = 0; i < labels.length; i++) {
			output += "|padding:0 4em;background-color:" + colors[labels[i]] + ";&nbsp;|"
				+ "{{{" + colors[labels[i]] + "}}}|"
				+ "[[" + labels[i] + "|" + title + "]]|\n";
		}
		wikify(output, place);
	}
};

config.macros.paletteView.isColor = function(s) {
	var colors = ["Black", "Green", "Silver", "Lime", "Gray", "Olive", "White", "Yellow",
		"Maroon", "Navy", "Red", "Blue", "Purple", "Teal", "Fuchsia", "Aqua", "Orange"];
	var match = s.match(/^#[0-9A-F]{3}$|^#[0-9A-F]{6}$|^RGB\([\d,\s]{5,}\)$/i);
	if(match) return true;
	if(colors.contains(s)) return true;
	return false;
};
//}}}
<<plugins>>
/***
| Name:|QuickOpenTagPlugin|
| Description:|Changes tag links to make it easier to open tags as tiddlers|
| Version:|6.1.1|
| Date:|01-Oct-2006|
| Source:|http://mptw.tiddlyspot.com/#QuickOpenTagPlugin|
| Author:|Simon Baird <simon.baird@gmail.com>|
| CoreVersion:|2.1.x|
***/
//{{{
config.quickOpenTag = {

	dropdownChar: (document.all ? "\u25bc" : "\u25be"), // the little one doesn't work in IE

	createTagButton: function(place,tag,excludeTiddler) {
		// little hack so we can to <<tag PrettyTagName|RealTagName>>
		var splitTag = tag.split("|");
		var pretty = tag;
		if (splitTag.length == 2) {
			tag = splitTag[1];
			pretty = splitTag[0];
		}
		
		var sp = createTiddlyElement(place,"span",null,"quickopentag");
		createTiddlyText(createTiddlyLink(sp,tag,false),pretty);
		
		var theTag = createTiddlyButton(sp,config.quickOpenTag.dropdownChar,
                        config.views.wikified.tag.tooltip.format([tag]),onClickTag);
		theTag.setAttribute("tag",tag);
		if (excludeTiddler)
			theTag.setAttribute("tiddler",excludeTiddler);
    		return(theTag);
	},

	miniTagHandler: function(place,macroName,params,wikifier,paramString,tiddler) {
		var tagged = store.getTaggedTiddlers(tiddler.title);
		if (tagged.length > 0) {
			var theTag = createTiddlyButton(place,config.quickOpenTag.dropdownChar,
                        	config.views.wikified.tag.tooltip.format([tiddler.title]),onClickTag);
			theTag.setAttribute("tag",tiddler.title);
			theTag.className = "miniTag";
		}
	},

	allTagsHandler: function(place,macroName,params) {
		var tags = store.getTags();
		var theDateList = createTiddlyElement(place,"ul");
		if(tags.length == 0)
			createTiddlyElement(theDateList,"li",null,"listTitle",this.noTags);
		for (var t=0; t<tags.length; t++) {
			var theListItem = createTiddlyElement(theDateList,"li");
			var theLink = createTiddlyLink(theListItem,tags[t][0],true);
			var theCount = " (" + tags[t][1] + ")";
			theLink.appendChild(document.createTextNode(theCount));
			var theDropDownBtn = createTiddlyButton(theListItem," " +
			config.quickOpenTag.dropdownChar,this.tooltip.format([tags[t][0]]),onClickTag);
			theDropDownBtn.setAttribute("tag",tags[t][0]);
		}
	},

	// todo fix these up a bit
	styles: 
"/*{{{*/\n"+
"/* created by QuickOpenTagPlugin */\n"+
".tagglyTagged .quickopentag, .tagged .quickopentag \n"+
"	{ margin-right:1.2em; border:1px solid #eee; padding:2px; padding-right:0px; padding-left:1px; }\n"+
".quickopentag .tiddlyLink { padding:2px; padding-left:3px; }\n"+
".quickopentag a.button { padding:1px; padding-left:2px; padding-right:2px;}\n"+
"/* extra specificity to make it work right */\n"+
"#displayArea .viewer .quickopentag a.button, \n"+
"#displayArea .viewer .quickopentag a.tiddyLink, \n"+
"#mainMenu .quickopentag a.tiddyLink, \n"+
"#mainMenu .quickopentag a.tiddyLink \n"+
"	{ border:0px solid black; }\n"+
"#displayArea .viewer .quickopentag a.button, \n"+
"#mainMenu .quickopentag a.button \n"+
"	{ margin-left:0px; padding-left:2px; }\n"+
"#displayArea .viewer .quickopentag a.tiddlyLink, \n"+
"#mainMenu .quickopentag a.tiddlyLink \n"+
"	{ margin-right:0px; padding-right:0px; padding-left:0px; margin-left:0px; }\n"+
"a.miniTag {font-size:150%;} \n"+
"#mainMenu .quickopentag a.button \n"+
"	/* looks better in right justified main menus */\n"+
"	{ margin-left:0px; padding-left:2px; margin-right:0px; padding-right:0px; }\n" + 
"#topMenu .quickopentag { padding:0px; margin:0px; border:0px; }\n" +
"#topMenu .quickopentag .tiddlyLink { padding-right:1px; margin-right:0px; }\n" +
"#topMenu .quickopentag .button { padding-left:1px; margin-left:0px; border:0px; }\n" +
"/*}}}*/\n"+
		"",

	init: function() {
		// we fully replace these builtins. can't hijack them easily
		window.createTagButton = this.createTagButton;
		config.macros.allTags.handler = this.allTagsHandler;
		config.macros.miniTag = { handler: this.miniTagHandler };
		config.shadowTiddlers["QuickOpenTagStyles"] = this.styles;
		if (store)
			store.addNotification("QuickOpenTagStyles",refreshStyles);
		else
			config.notifyTiddlers.push({name:"QuickOpenTagStyles", notify: refreshStyles});
	}

}

config.quickOpenTag.init();

//}}}
The following recently created or updated tiddler uses the syntax {{{<<timeline better:true firstDay:20090201>>}}} to display tiddlers that have been edited since February 1, 2009 - using the [[Better timeline plugin macro]] - may give you a little insight both into some of the recently-added contents of the site, as well as into the "underworld" of shadowed tiddlers, cascading styles, menus, features, plugins, formatting, etc. that lie beneath the surface of TiddlyWiki and that contribute to the genius of TiddlyWiki, the software platform that serves as one of the foundations of this web site and of the companion sites of the [[Climate Change 2.0]] initiative. If you would like to look at a complete listing of tiddlers on this site, visit [[Basic Tiddler Lists]].

<<timeline better:true firstDay:20090201>>
/***
|Name|RecentChangesPlugin|
|Source|http://www.TiddlyTools.com/#RecentChangesPlugin|
|Version|1.0.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <<br>>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|display droplist of recently changed tiddlers with goto, edit, and preview buttons|

!!!!!Usage
<<<
The {{{<<recentChanges>>}}} macro displays a droplist of all tiddlers that have been changed within the last N days (default=10 days).  
<<<
!!!!!Examples
<<<
{{{<<recentChanges>>}}}
<<recentChanges>>
or
{{{<<recentChanges #ofdays previewheight previewclass>>}}}
where:
* #ofdays specifies the time limit for list changed tiddlers.  Use 0 (zero) to list all tiddlers in the document
* previewheight is a CSS height measurement and sets the FIXED height of the tiddler preview area (default is 15em)
* previewclass is any CSS classname, and can be used to apply custom styles to the preview area (default is to use the standard 'viewer' class)
<<recentChanges 14 10em groupbox>>
<<<
!!!!!Installation
<<<
import (or copy/paste) the following tiddlers into your document:
RecentChangesPlugin
<<<
!!!!!Revision History
<<<
''2007.07.26 [2.0.0]'' re-written as plugin
''[1.0.0]'' initial release (as inline script ShowRecentChanges)
<<<
!!!!!Credits
<<<
This feature was developed by Eric Shulman / ELS Design Studios
<<<
!!!!!Code
***/
//{{{
version.extensions.recentChanges= {major: 2, minor: 0, revision: 0, date: new Date(2007,7,26)};

config.macros.recentChanges = {
	layout: '<form><!--\
		--><select size=1 name="list" style="width:69.5%" \
			onchange=" \
				this.form.goto.disabled=this.form.edit.disabled=this.form.preview.disabled=!this.value.length; \
				var target=this.parentNode.parentNode.nextSibling; removeChildren(target); \
				if (!this.value.length) \
					{ target.style.display=\'none\'; this.form.preview.value=\'preview\'; } \
				else if (target.style.display==\'block\') { \
					wikify(\'<\'+\'<tiddler [[\'+this.value+\']]>\'+\'>\',target); \
					target.style.display=\'block\'; \
					this.form.preview.value=\'done\'; \
				} \
			"><!--\
		-->%options%<!--\
		--></select><!--\
		--><input type="button" name="goto" value="goto" disabled title="view selected tiddler" style="width:10%" \
			onclick="var target=this.parentNode.parentNode.nextSibling; removeChildren(target); \
				target.style.display=\'none\'; this.form.preview.value=\'preview\'; \
				story.displayTiddler(story.findContainingTiddler(this),this.form.list.value); \
			"><!--\
		--><input type="button" name="edit" value="edit" disabled title="edit selected tiddler" style="width:10%" \
			onclick="var target=this.parentNode.parentNode.nextSibling; removeChildren(target); \
				target.style.display=\'none\'; this.form.preview.value=\'preview\'; \
				story.displayTiddler(story.findContainingTiddler(this),this.form.list.value,DEFAULT_EDIT_TEMPLATE); \
			"><!--\
		--><input type="button" name="preview" value="preview" disabled title="show/hide tiddler preview" style="width:10%" \
			onclick="var target=this.parentNode.parentNode.nextSibling; \
				if (this.value==\'preview\') { \
					removeChildren(target); \
					wikify(\'<\'+\'<tiddler [[\'+this.form.list.value+\']]>\'+\'>\',target); \
					target.style.display=this.form.list.value.length?\'block\':\'none\'; this.value=\'done\'; \
				} else { \
					removeChildren(target); \
					target.style.display=\'none\'; this.value=\'preview\'; \
				} \
			"><!--\
		--></form>',
	handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		var days=10; if (!isNaN(params[0])) days=parseInt(params[0]); // time limit in days (use 0 for all tiddlers)
		var height='15em'; if (params[1]) height=params[1]; // preview area fixed height
		var previewclass='viewer'; if (params[2]) previewclass=params[2]; // preview area CSS class
		var tiddlers=store.getTiddlers('modified','excludeLists').reverse();
		var count=tiddlers.length;
		if (days) {
			var timelimit=(new Date()).getTime()-86400000*days;
			for (var count=0; count<tiddlers.length && tiddlers[count].modified>timelimit; count++);
		}
		var opts="";
		opts+='<option value="">';
		opts+=count+' tiddlers have changed since ';
		opts+=new Date(timelimit).formatString("DDD, MMM DDth YYYY 0hh:0mm");
		opts+=' ('+days+' days ago)';
		opts+='</option>';
		for (var i=0; i<count; i++) { var t=tiddlers[i];
			opts+='<option value="'+t.title+'">';
			opts+=t.modified.formatString('YYYY.0MM.0DD 0hh:0mm')+' - '+t.title;
			opts+='</option>';
		}
		createTiddlyElement(place,"div").innerHTML=this.layout.replace(/%options%/,opts);
		var preview=createTiddlyElement(place,"span",null,previewclass);
		preview.style.display='none';
		preview.style.whiteSpace='normal';
		preview.style.overflow='auto';
		preview.style.height=height
	}
}
//}}}
/***
***/

//{{{

config.commands.refresh = {
 text: 'refresh',
 tooltip: 'Refresh this tiddler',
 handler: function(e,src,title) {
  clearMessage();
  story.refreshTiddler(title,false,true); // force=true
  return false;
 }
};

//}}}
/***
|Name|RelatedTiddlersPlugin|
|Source|http://www.TiddlyTools.com/#RelatedTiddlersPlugin|
|Version|1.1.6|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <<br>>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|starting from a selected tiddler, display a list and/or tree of linked or transcluded tiddlers|
Given a starting tiddler (default is the current tiddler), this plugin recursively follows the internal links[] data that is associated with each tiddler and constructs a list of all tiddlers that are related to the starting tiddler by being referenced in a TiddlyLink (e.g., {{{[[TiddlerName]]}}}) or used as macro parameter (e.g., {{{<<tiddler TiddlerName>>}}}) within the tiddler content.

Using the terminology of Graph Theory, the plugin's recursive algorithm finds what is called a 'minimal spanning tree' from any specific starting 'root node'.  The results can be displayed as a simple flat list of related tiddler titles, or as an indented tree diagram that shows the specific connections between the related tiddlers, and can be helpful for identifying clusters of interdependent tiddlers or simply generating an on-the-fly site map for quick discovery and navigation through complex or unfamiliar document content. 
!!!!!Usage
<<<
//{{{
<<relatedTiddlers TiddlerName hideform "exclude list">>
//}}}
where:
*TiddlerName (optional)<br>sets the initial "root" to the specified tiddler (and hides the 'select a tiddler' form controls).  You can use keyword 'here' to specify the current tiddler.
*'hideform' (optional) or 'showform' (default)<br>keyword value to suppress display of 'select tiddler' droplist and buttons.
*"exclude list" (optional)<br>space-separated list of tiddlers whose links should not be followed.  use quotes or double-square brackets to ensure list is processed as a single parameter
<<<
!!!!!Configuration
<<<
<<option chkRelatedTiddlersZoom>> enable autosizing of tree display //(aka, "zoom" or "shrink-and-grow")//
don't follow links contained in these tiddlers: <<option txtRelatedTiddlersExclude>>
<<<
!!!!!Examples
<<<
{{smallform{<<relatedTiddlers>>}}}
<<<
!!!!!Installation
<<<
import (or copy/paste) the following tiddlers into your document:
RelatedTiddlersPlugin, InlineJavascriptPlugin, NestedSlidersPlugin, StyleSheetShortcuts
<<<
!!!!!Revision History
<<<
''2007.07.13 [1.1.6]'' performance optimizations, more code cleanup
''2007.07.10 [1.1.5]'' extensive code cleanup
''2007.07.08 [1.1.0]'' converted from inline script
''2007.06.29 [1.0.0]'' started (as inline script)
<<<
!!!!!Credits
<<<
This feature was developed by Eric L. Shulman
<<<
!!!!!Code
***/
//{{{
version.extensions.RelatedTiddlersPlugin={major: 1, minor: 1, revision: 5, date: new Date(2007,7,8)};

// initialize 'autozoom' and 'exclude' tree options (defaults are not to zoom, and to follow all links)
if (config.options.chkRelatedTiddlersZoom===undefined)
	config.options.chkRelatedTiddlersZoom=false;
if (config.options.txtRelatedTiddlersExclude===undefined)
	config.options.txtRelatedTiddlersExclude='GettingStarted DefaultTiddlers SiteNews Download';
if (config.options.chkRelatedTiddlersShowList===undefined)
	config.options.chkRelatedTiddlersShowList=true;
if (config.options.chkRelatedTiddlersShowTree===undefined)
	config.options.chkRelatedTiddlersShowTree=false;

config.macros.relatedTiddlers={
	handler: function(place,macroName,params,wikifier,paramString,tiddler) {

		// create form with unique DOM element ID (using current timestamp)... permits multiple form instances
		var now=new Date().getTime();
		var span=createTiddlyElement(place,"span");
		span.innerHTML=this.form.format(["relatedTiddlers_form"+now]);
		var form=span.getElementsByTagName("form")[0]; // find form that we just created
		var target=createTiddlyElement(span,"div"); // create target block in which generated output will be placed

		// initialize droplist contents (all tiddlers except hidden ones)
		var tids=store.getTiddlers('title','excludeLists');
		for (i=0; i<tids.length; i++) form.list.options[form.list.options.length]=new Option(tids[i].title,tids[i].title,false,false);

		// initialize exclude field (space-separated list)
		if (config.options.txtRelatedTiddlersExclude) form.exclude.value=config.options.txtRelatedTiddlersExclude;

		// set starting tiddler, form display, and/or exclude list from macro params (if present) and then show the results!
		var root="";
		var hide=false;
		var exclude=config.options.txtRelatedTiddlersExclude;
		if (params[0]) root=params[0]; // TiddlerName
		if (params[1]) hide=(params[1].toLowerCase()=="hideform"); // keyword: "hideform" or "showform" (default)
		if (params[2]) exclude=params[2]; // list of tiddlers whose links should not be followed
		if (root=="here") { var tid=story.findContainingTiddler(place); if (tid) root=tid.getAttribute("tiddler"); }
		if (store.tiddlerExists(root)) {
			// NOTE:  don't hide form when running IE, where putting initial focus on hidden form creates an error
			if (!config.browser.isIE) form.style.display=hide?"none":"block"; // show/hide the controls
			form.list.value=root; // set the root
			form.exclude.value=exclude; // set 'exclude' field
			form.get.click(); // DISPLAY INITIAL RESULTS (if tiddler is selected)
		}
	},
	form:
		"<form id='%0' action='javascript:;' style='display:inline;margin:0;padding:0;' onsubmit='return false'><!-- \
		--><span class='fine' style='float:left;vertical-align:bottom;width:39.5%;'><i>find all tiddlers related to:</i></span><!-- \
		--><span class='fine' style='float:left;vertical-align:bottom;'><i>exclude links contained in:</i></span><!-- \
		--><div style='clear:both'><!-- \
		--><select name=list size=1 style='width:39.5%' onchange='this.form.get.click()'><!-- \
		--><option value=''>select a tiddler...</option><!-- \
		--></select><!-- \
		--><input type='text' option='txtRelatedTiddlersExclude' name='exclude' value='' style='width:40%' \
			title='enter the names of tiddlers whose links should NOT be followed' \
			onkeyup='if (event.keyCode==13) { this.blur(); this.form.get.click(); }'  \
			onchange='config.options[this.getAttribute(\"option\")]=this.value;saveOptionCookie(this.getAttribute(\"option\"));'><!-- \
		--><input type=button name=get value='get related' style='width:10%'  \
			onclick='config.macros.relatedTiddlers.show(this.form,this.form.nextSibling);'><!-- \
		--><input type=button name=done value='done' disabled style='width:10%'  \
			onclick='this.form.list.selectedIndex=0; this.form.get.click();'><!-- \
		--></div><!-- \
		--></form>",
	styles:
		".relatedTiddlers blockquote \
			{ border-left:1px dotted #999; margin:0 25px; padding-left:.5em; font-size:%0%; line-height:115%; } \
		.relatedTiddlers .borderleft \
			{ margin:0; padding:0; margin-left:1em; border-left:1px dotted #999; padding-left:.5em; } \
		.relatedTiddlers .fourcolumns \
			{ display:block; -moz-column-count:4; -moz-column-gap:1em; -moz-column-width:25%} \
		.relatedTiddlers a \
			{ font-weight:normal; } \
		.relatedTiddlers .bold, .relatedTiddlers .bold a \
			{ font-weight:bold; } \
		.relatedTiddlers .floatright \
			{ float:right; } \
		.relatedTiddlers .clear \
			{ clear:both; }	",
	toggleform:
		"{{floatright{<html><a href='javascript:;' class='button' title='show/hide tiddler selection droplist and buttons' \
		onclick='var here=story.findContainingTiddler(this); var tid=here?here.getAttribute(\"tiddler\"):\"\"; \
			var f=document.getElementById(\"%0\"); var hide=(f.style.display!=\"none\"); \
			f.style.display=hide?\"none\":\"inline\"; this.innerHTML=hide?\"show form\":\"hide form\"; return false;'>%1</a></html>}}}",
	treecheck:
		"{{floatright{@@display:none;<<option chkRelatedTiddlersShowTree>>@@<html><a href='javascript:;' class='button' onclick='this.parentNode.previousSibling.firstChild.click(); return false;'>tree view</a></html>}}}",
	tree:
		"{{clear{\n----\n}}} \
		{{floatright small{<<option chkRelatedTiddlersZoom>>autosize tree display}}} \
		{{fine{\n''tiddlers linked from or included by'' [[%0]]\n}}}%1",
	listcheck:
		"{{floatright{@@display:none;<<option chkRelatedTiddlersShowList>>@@<html><a href='javascript:;' class='button' onclick='this.parentNode.previousSibling.firstChild.click(); return false;'>list view</a></html>}}}",
	list:
		"{{clear{\n----\n}}} \
		{{fine{\n''tiddlers containing links to'' [[%0]]\n}}} \
		{{small fourcolumns borderleft{\n%1}}} \
		{{fine{\n''tiddlers linked from or included by'' [[%0]]\n}}} \
		{{borderleft{\n \
			{{fine{\n''bold''=//direct links//, plain=//indirect links//, ''...''=//links not followed//}}} \
			{{small fourcolumns{\n%2}}} \
		}}}",
	skipped:
		"<html><span title='links from %0 have NOT been followed'>...</span></html>",
	mouseover: function(ev) {
		this.saveSize=this.style.fontSize;
		this.style.fontSize='100%';
		this.style.borderLeftStyle='solid';
	},
	mouseout: function(ev) {
		this.style.fontSize=this.saveSize;
		this.style.borderLeftStyle='dotted';
	},
	findRelatedTiddlers: function(tid,tids,treeout,level,exclude) { 
		// recursively build list of related tids (links and includes FROM the root tiddler) and generate treeview output
		var t=store.getTiddler(tid);
		if (!t || tids.contains(tid)) return tids; // tiddler already in results (or missing tiddler)... just return current results
		tids.push(t.title); // add tiddler to results
		var skip=exclude && exclude.contains(tid);
		treeout.text+=level+"[["+tid+"]]"+(skip?this.skipped.format([tid]):"")+"\n";
		if (skip) return tids; // branch is pruned... don't follow links
		if (!t.linksUpdated) t.changed();
		for (var i=0; i<t.links.length; i++) tids=this.findRelatedTiddlers(t.links[i],tids,treeout,level+">",exclude);
		return tids;
	},
	show: function(form,target) {
		removeChildren(target); form.done.disabled=true; // clear any existing output and disable 'done' button
		var start=form.list.value; if (!start.length) return; // get selected starting tiddler.  If blank value (heading), do nothing

		// get related tiddlers and generate blockquote-indented tree output
		var rels=[]; var treeview={text:""}; var level="";
		var exclude=config.options.txtRelatedTiddlersExclude.readBracketedList();
		var rels=this.findRelatedTiddlers(start,rels,treeview,level,exclude);
		rels.shift(); // remove self from list
		rels.sort(); // sort titles alphabetically

		// generate list output
		var tid=store.getTiddler(start);
		var relsview=""; for (t=0; t<rels.length; t++) {
			relsview+=tid.links.contains(rels[t])?("{{bold{[["+rels[t]+"]]}}}"):("[["+rels[t]+"]]");
			if (exclude && exclude.contains(rels[t])) relsview+=this.skipped.format([rels[t]]);
			relsview+="\n";
		}
	
		// get references TO the root tiddler, add to related tiddlers and generate refsview output
		var refs=[]; var referers=store.getReferringTiddlers(start);
		for(var r=0; r<referers.length; r++)
			if(referers[r].title!=start && !referers[r].tags.contains("excludeLists")) refs.push(referers[r].title);
		var refcount=refs.length; var relcount=rels.length; // remember individual counts
		for (var r=0; r<refs.length; r++) rels.pushUnique(refs[r]); // combine lists without duplicates
		var total=rels.length; // get combined total
		var refsview="[["+refs.sort().join("]]\n[[")+"]]\n";
	
		// set custom blockquote styles for treeview
		setStylesheet(this.styles.format([config.options.chkRelatedTiddlersZoom?80:100]),'relatedTiddlers_styles');

		// assemble and render output
		var summary=(total?(total+" tiddler"+(total==1?" is":"s are")):"There are no tiddlers")+" related to: [["+start+"]]";
		var list=this.list.format([start,refsview.length?refsview:"//none//",relsview.length?relsview:"//none//"]);
		var tree=this.tree.format([start,treeview.text]);
		var toggle=this.toggleform.format([form.id,(form.style.display=='none'?'show form':'hide form')]);
		var sep="{{floatright{ | }}}";
		var showList=total && config.options.chkRelatedTiddlersShowList;
		var showTree=relcount && config.options.chkRelatedTiddlersShowTree;
		var out="{{relatedTiddlers{"+toggle+(relcount?sep+this.treecheck:"")+(total?sep+this.listcheck:"")+summary+(showList?list:"")+(showTree?tree:"")+"}}}";
		wikify(out,target);
		form.done.disabled=false; // enable 'done' button

		// add mouseover/mouseout handling to blockquotes (for autosizing)
		var blocks=target.getElementsByTagName("blockquote");
		for (var b=0; b<blocks.length; b++)
			{ blocks[b].onmouseover=this.mouseover; blocks[b].onmouseout=this.mouseout; }

		// add side-effect to checkboxes so that display is refreshed when a checkbox state is changed
		var checks=target.getElementsByTagName("input");
		for (var c=0; c<checks.length; c++) {
			if (checks[c].type.toLowerCase()!="checkbox") continue;
			checks[c].coreClick=checks[c].onclick; // save standard click handler
			checks[c].formID=form.id; // link checkbox with correponding form
			checks[c].onclick=function() { this.coreClick.apply(this,arguments); document.getElementById(this.formID).get.click(); }
		}
	}
}
//}}}
//{{{
// location of server-side 'reflector' script. Can be on ANY domain... 
config.options.txtSaveFromWebScriptURL="savefromweb.php";

// use alternative document URL for retrieving TiddlyWiki core source code.
// Using *empty* TW minimizes data transfer for retrieving TW core.
// Can be on ANY domain... If blank, uses current document URL
config.options.txtSaveFromWebSourceFile="http://www.TiddlyTools.com/empty.html";

// use alternative target filename for the downloaded document.
// Can be any valid filename for local filesystem.  If blank, uses current filename
config.options.txtSaveFromWebTargetFilename="";

// Pre-fetch option
// true=get (and cache) TW core code when document is first loaded (i.e., when plugin is initialized)
// false=get  and cache core code the first time the file is being saved
// pre-fetching and caching the core code permits "save changes" to still be performed,
// even if the connection to the net is dropped during the session.
config.options.chkSaveFromWebPreFetch=false;

// Local I/O option (requires browser security permissions, i.e., "trusted site" settings)
config.options.chkSaveFromWebAttemptLocalIO=false;

// enable editing features over http so that 'save changes' is available online by default
config.options.chkHttpReadOnly=readOnly=false;
//}}}
/***
|Name|SaveFromWebPlugin|
|Source|http://www.TiddlyTools.com/#SaveFromWebPlugin|
|Version|1.3.5|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <<br>>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|extend 'save changes' to get remote document contents and save to local filesystem |
|Status| BETA/EXPERIMENTAL - USE WITH CAUTION - VERIFY ALL SAVED CHANGES - RETAIN BACKUPS |

Normally, when you are viewing a TiddlyWiki document over the web (i.e., not via {{{file://}}}) and you select the "save changes" (or "save to disk") command, an error message is displayed: //__"You need to save this TiddlyWiki to a file before you can save changes."__//  This plugin extends the use of {{{<<saveChanges>>}}} so that when you are viewing and/or editing a remote TiddlyWiki document, instead of receiving this somewhat confusing and unhelpful message, you can still click the "save changes" (or "save to disk") command to ''store a copy of the remote document directly onto your local filesystem'', //including any unsaved tiddler changes/additions you have made while working on-line.//
!!!!!Usage
<<<
When you select <<saveChanges>> while viewing a remote document (i.e., a URL starting with http: rather than file:), the plugin first ''retrieves the TiddlyWiki core source code from the original document'' file stored on the remote server.  Then, it ''combines that core source with the tiddlers'' contained in the currently loaded document, ''including any changes you have made.''

While the next step //should// be to simply write the merged core+tiddler data directly to your hard drive, certain JavaScript features, such as reading/writing directly to the local filesystem, require expanded "cross-domain" privileges that are normally restricted for use only with ''signed'' scripts.  Although some browsers will let you grant filesystem permissions to a remotely-loaded script, this usually involves either a series of popup confirmation messages or manually re-configuring (and/or disabling) your browser's built-in security protections, which often include settings and options that most users find difficult to understand and inconvenient to access.

To avoid these security complications, the "save from web" processing requires just a few additional steps to prepare the modified document and deliver it to your browser: rather than writing the document data directly to the local filesystem, the plugin ''sends the merged core+tiddler data to a small companion script installed on the remote server'' (see savefromweb.php, below).  This simple "reflector" script then immediately ''downloads the new document data back to the browser'', which prompts you to either open the downloaded document for viewing or save it to your local hard drive.  Once the document has been stored on your filesystem, you can open that copy in your browser and work offline with full access to all TiddlyWiki features.

+++[Note for users of Internet Explorer's Popup Blocker feature...]>
The default security settings of IE's "Popup Blocker" feature will warn you whenever an attempt is made to download a file in response to a scripted action such as the internal javascript processing performed by SaveFromWebPlugin.  However, if you then click IE's yellow warning message and select the 'download this file...' menu command, this will also cause IE to attempt a 'page transition' away from the currently loaded TiddlyWiki document... but, because there are unsaved changes in the document, you will first receive a confirmation message, allowing you to cancel the page transition.  Regrettably, this also prevents the download from succeeding.  Unfortunately, if you //do// permit the page transition to occur, then your TiddlyWiki document is immediately reloaded and all the unsaved tiddler changes are discarded... and the download still fails to complete.

''__To permit SaveFromWeb to function properly with Internet Explorer, you will need to adjust the "download" security setting...__''
#From the ''Tools > Internet Options > Security'' tab,
#Select the "Internet" security zone (or what ever zone you are using to view the remote document)
#Press the "Custom level..." button
#In the "Settings" listbox, scroll to the "Downloads" section
#''ENABLE "automatic prompting for downloads"''(the first setting in the section)
#Press OK to accept the new settings.
===
<<<
!!!!!Direct filesystem access (configuring browser security permissions)
<<<
Although sending the merged document data from browser to server and back again allows it to be saved to your filesystem without requiring you to extensively re-configure your browser's built-in security protections, it also increases the overall processing time because the document's data is actually being transmitted //three// times: it is first retrieved from the remote server to get the TiddlyWiki core source; then, after merging with the updated tiddler data, it is sent back to the server, which immediately 'reflects' it back to the browser for final handling by the built-in "file download" interface.

However, ''if you are accessing a "trusted site"'' (perhaps on a server within a secure private network), depending upon the specific options provided by your browser, ''you may be able to eliminate the round-trip processing by authorizing the appropriate filesystem security permissions in your browser''.  When filesystem access has been permitted, instead of making the round trip with the merged core+tiddler data, the plugin will immediately prompt you for a destination path/file, using your computer's "native" path/file selection interface, and then write new the TiddlyWiki document data directly to the indicated location on your local file system.

+++[Configuring security in FireFox...]>
''FireFox needs security permissions to be set to allow a remote URL to save a new file to your local filesystem.''  FireFox can be configured to allow or disallow expanded "cross-domain" privileges based on the digital signature of the originator (or ''principal'') of a signed script.  However, ''unsigned'' scripts, such as TiddlyWiki, do not contain a digital signature and are not normally allowed access to filesystem functions.  Fortunately, an //''unsigned''// script can still be granted expanded filesystem privileges through use of a ''codebase principal'', which relies upon the originating URL of the script (it's "codebase") to identify the "trusted source", rather than verifying a digital signature of a certificate.
>''In FireFox (and most other browsers) use of codebase principals is disabled by default'';
>To use codebase principals, go to "about:config" in your browser, and set:
>&nbsp;&nbsp;''{{{signed.applets.codebase_principal_support}}}'' to ''{{{true}}}''
>//note: you can also set this value by editing FireFox's {{{prefs.js}}} and adding://
>&nbsp;&nbsp;{{{user_pref("signed.applets.codebase_principal_support", true);}}}
After you have enabled codebase principals, you will begin receiving security notices whenever TiddlyWiki requests permission to invoke various privileged functions.  You can press the "allow" button to permit the processing to continue, or press "deny" to prevent the privileged functions from being used by that remote site.

When you invoke {{{<<saveChanges>>}}}, there may be several of these notices in a row before the file saving process is done.  These messages are normal, and you should ALLOW each of them, so that the file saving procedure can continue to completion.  Once you are confident that the remote site is trustworthy, you can mark the "remember this decision" checkbox to eliminate additional notices for that remote site, so that the process can proceed without further interruptions.  This setting will only be applied to the specific web domain in question, so you will still receive security notices when using privileged functions from any other web sites.

//Note: If codebase principals are enabled, security notices are also reported when accessing TiddlyWiki documents locally (i.e., via {{{file://}}}).  This is a result of TiddlyWiki's normal file I/O processing and should always be considered safe to allow, inasmuch as you control the contents of your own local filesystem, and thus, should be able to consider the {{{file://}}} codebase location as a trusted source.//
===
<<<
!!!!!Configuration
<<<
Target (destination) filename: <<option txtSaveFromWebTargetFilename>>
{{fine borderleft{
specifies the desired destination filename for the saved file.  This will appear as the default value when you are prompted to save the file.  If blank, default is the filename from the URL of the current document (or the current domain name if there is no filename in the URL)}}}
TW core source location: <<option txtSaveFromWebSourceFile>>
{{fine borderleft{
specifies the URL from which to retrieve the TW core source.  If blank, defaults to the current document URL.}}}
Server-side reflector script location: <<option txtSaveFromWebScriptURL>>
{{fine borderleft{
note: the reflector script can be located at any URL, even one on a different domain from the document you are saving}}}
<<option chkSaveFromWebAttemptLocalIO>> attempt to use direct filesystem I/O (requires browser security permissions)
{{fine borderleft{
the plugin will try to obtain security permission for direct filesystem I/O.  If you grant filesystem access to the script, then it writes the document directly to your filesystem, and doesn't use the server-side reflector script at all.  This allows you to save a remote file to your local filesystem, even if your net connection drops after you open the document.  Note: if filesystem permissions are not granted, the plugin will automatically attempt to use the server-side reflector script as a fallback... even if no longer connected to the net.}}}
<<option chkSaveFromWebPreFetch>> pre-fetch TW core source (in background) during document startup
{{fine borderleft{
this option causes the plugin to retrieve the TiddlyWiki core source as soon as you load the document, instead of waiting for the first time you save.  This ensures that the TiddlyWiki core source can still be saved to the local filesystem even if your network connection is dropped before you save your changes.  Note that, even without pre-fetching, the core source is always cached after it is retrieved, so that subsequent saves don't do extra work to get it again.}}}
Important note: while you can configure the plugin using the fields shown above, these settings will be stored as cookies, which are associated with the local browser installation, rather than the document itself.  To "hard-code" these settings so they are always applied to the document when viewed from //any// browser, please see [[SaveFromWebConfig]].
<<<
!!!!!Installation
<<<
import (or copy/paste) the following tiddlers into your document:
[[SaveFromWebPlugin]], [[SaveFromWebConfig]]

On your web server, in the same directory as your published document, create a file called ''{{{savefromweb.php}}}'', containing the following PHP server-side script.  //(note: you can actually give this script any name you like, and place it at //any// URL, even one that is on a different domain from the document you are saving.  However, to do so you must specify the server-side script location using the plugin's configuration settings (see above).//
//{{{
<?php
// savefromweb.php
// Author: Eric L. Shulman / ELS Design Studios
// Source: http://www.TiddlyTools.com/savefromweb.php
// License: http://www.TiddlyTools.com/#LegalStatements
// Usage: install the php script on the server in the same directory as your TiddlyWiki document(s)

// This script acts as a 'reflector', so that any contents sent to it (via form POST) will
// be sent back to the browser as a binary file.  The browser then prompts you to
// save the content to a local file.  Because this process uses the browser's built-in
// download-and-save/open handler, it does not require security permissions to access
// the local filesystem.

$args=$_POST;
header('Pragma: private');
header('Cache-control: private, must-revalidate');
header('Content-type: application/binary; charset="UTF-8"');
header('Content-disposition: attachment; filename="'.$args['filename'].'"');
$c=$args['contents'];
$c=str_replace("\\'","'",$c); // decode single-quotes
$c=str_replace("\\\"","\"",$c); // decode double-quotes
$c=str_replace("\\\\","\\",$c); // decode backslashes
$c=str_replace("\r\n","\n",$c); // change CRLF to LF
print $c;
?>
//}}}
<<<
!!!!!Revision History
<<<
''2007.08.08 [1.3.0]'' added caching of the downloaded TW core source code so it only has to be retrieved once.  Also, added an option to 'pre-fetch' the TW core when plugin is initialized, so that the download-and-cache will be performed, in background, each time the document is loaded/re-loaded.  Also, added option to allow attempt to use direct filesystem access (bypassing the round-trip through the server-side reflector script) so you can save a remote file to your local filesystem, even if the connection to the network is dropped after the document was loaded into the browser.  If local filesystem permissions are not granted, the plugin will still attempt to use the server-side reflector script as a fallback.
''2007.08.07 [1.2.0]'' removed 'download only' optimization: when a document is unchanged, instead of performing a simple download from server, the plugin now performs a full 'round-trip' process (i.e., download the TW source from a server, merge with current tiddlers, and then upload merged document and reflect back as a binary file).  Although the round-trip takes longer, it does permit the reflector script to be located ANYWHERE on the net, at ANY valid URL, rather than having to be placed on the same server and in the same directory as the remote document.  This should permit online services such as TiddlySpot to support SaveFromWebPlugin using a single hosted copy of the reflector script that can be shared by all users.
''2007.07.27 [1.1.1]'' new documentation and code cleanup
''2007.07.26 [1.1.0]'' re-wrote to support savefromweb.php remote "reflector" script.  Allows use of browser's native download dialog to receive file as a fallback alternative to using local filesystem I/O (which would require additional security permissions)
''2007.06.27 [1.0.1]'' in saveFromWeb(), pass content from server through convertUnicodeToUTF8() before writing to file.
''2007.06.26 [1.0.0]'' initial release
<<<
!!!!!Credits
<<<
This feature was developed by Eric L Shulman / ELS Design Studios
<<<
!!!!!Code
***/
//{{{
version.extensions.SaveFromWeb= {major: 1, minor: 3, revision: 0, date: new Date(2007,8,8)};
//}}}

//{{{
// DEFAULT SETTINGS
if (config.options.txtSaveFromWebScriptURL==undefined)
	config.options.txtSaveFromWebScriptURL="savefromweb.php";
if (config.options.txtSaveFromWebTargetFilename==undefined)
	config.options.txtSaveFromWebTargetFilename=""; // use current filename when blank
if (config.options.txtSaveFromWebSourceFile==undefined)
	config.options.txtSaveFromWebSourceFile=""; // use current URL when blank
if (config.options.chkSaveFromWebAttemptLocalIO==undefined)
	config.options.chkSaveFromWebAttemptLocalIO=true; // true=try to use local filesystem I/O (requires security permissions)
if (config.options.chkSaveFromWebPreFetch==undefined)
	config.options.chkSaveFromWebPreFetch=false; // true=retrieve TW core when document is first loaded
//}}}

//{{{
// OPTIONAL: get TW core source code when plugin is loaded (i.e., once per document session)
if (document.location.protocol!="file:" && config.options.chkSaveFromWebPreFetch) {
	// retrieve TW source from server...
	var src=document.location.href;
	if (config.options.txtSaveFromWebSourceFile && config.options.txtSaveFromWebSourceFile.length)
		src=config.options.txtSaveFromWebSourceFile;
	var target=config.options.txtSaveFromWebTargetFilename;
	if (!target.length) { // use current filename
		var loc=document.location.pathname;
		var slashpos=loc.lastIndexOf("/");
		target=(slashpos==-1)?loc:loc.substr(slashpos+1);
		if (!target.length) target=document.location.host+".html";
	}
	var xhr=loadRemoteFile(src,function(success,target,txt,src,xhr){if(success)config.saveFromWebSourceCache=txt;},target);
}
//}}}

//{{{
window.saveFromWeb_saveChanges = window.saveChanges;
window.saveChanges = function(onlyIfDirty,tiddlers) {
	// if on file:, just use standard core save handling
	if(document.location.protocol == "file:") { window.saveFromWeb_saveChanges.apply(this,arguments); return; }
	// get target filename
	var target=config.options.txtSaveFromWebTargetFilename;
	if (!target.length) { // use current filename
		var loc=document.location.pathname;
		var slashpos=loc.lastIndexOf("/");
		target=(slashpos==-1)?loc:loc.substr(slashpos+1);
		if (!target.length) target=document.location.host+".html";
	}
	// get TW core source location
	var src=document.location.href;
	if (config.options.txtSaveFromWebSourceFile && config.options.txtSaveFromWebSourceFile.length)
		src=config.options.txtSaveFromWebSourceFile;
	// if core source has already been cached, go straight to saving the file...
	if (config.saveFromWebSourceCache)
		{ window.saveFromWeb(true,target,config.saveFromWebSourceCache,src,null); return; }
	// otherwise, retrieve TW source from server...
	displayMessage("Retrieving TiddlyWiki core from "+src);
	var xhr=loadRemoteFile(src,window.saveFromWeb,target);
	if (!xhr) { // couldn't load remote, report core error message
		displayMessage("Could not retrieve TiddlyWiki core... download unsuccessful.");
		alert(config.messages.notFileUrlError);
		if(store.tiddlerExists(config.messages.saveInstructions))
			story.displayTiddler(null,config.messages.saveInstructions);
	}
	return;
}
//}}}

//{{{
window.saveFromWeb = function(success,target,txt,url,xhr) {
	if(!success) {
		displayMessage("Could not retrieve TiddlyWiki core... download unsuccessful.");
		alert(config.messages.cantSaveError);
		if(store.tiddlerExists(config.messages.saveInstructions))
			story.displayTiddler(null,config.messages.saveInstructions);
		return;
	}
	// Locate the storeArea div's in the original source
	var posDiv = locateStoreArea(txt);
	if(!posDiv) {
		alert(config.messages.invalidFileError.format([url]));
		return;
	}

	// cache the document source so subsequent saves don't have to retrieve the source each time
	if (!config.saveFromWebSourceCache) config.saveFromWebSourceCache=txt;

	// if we can get local filesystem access, then ask for a filename and merge/write the file
	if (config.options.chkSaveFromWebAttemptLocalIO) {
		try {
			// get destination path+filename
			var target=promptForFilename( "Save file as:","C:\\",target,"html"); // this be blocked by browser security
			if (!target || !target.length) return;
			saveBackup(target,txt);
			saveRss(target);
			saveEmpty(target,txt,posDiv);
			saveMain(target,txt,posDiv);
			return;
		}
		catch(e) { 
			displayMessage("Direct file access has been blocked by browser security settings.");
			if (config.options.txtSaveFromWebScriptURL.length)
				displayMessage("Attempting to download document using server-side 'reflector' script...");
		}
	}
	// otherwise, fallback to using online 'reflector' script (if any)
	if (config.options.txtSaveFromWebScriptURL.length) {
		displayMessage("Merging tiddlers with core and preparing for download...");
		// create form in a hidden frame and submit it to server
		var html='<input type="hidden" name="filename" value=""><input type="hidden" name="contents" value="">';
		var form=window.createHiddenForm(config.options.txtSaveFromWebScriptURL,html);
		form.filename.value=target;
		form.contents.value=updateOriginal(txt,posDiv); // merge tiddlers with source and set into form field
		form.submit();
	}
}
//}}}

//{{{
window.createHiddenForm=function(action,body) {
	var f=document.getElementById("saveFromWebFrame");
	if (f) document.body.removeChild(f);
	var f=createTiddlyElement(document.body,"iframe","saveFromWebFrame");
	f.style.width="0px"; f.style.height="0px"; f.style.border="0px";
	var d=f.document;
	if (f.contentDocument) d=f.contentDocument; // For NS6
	else if (f.contentWindow) d=f.contentWindow.document; // For IE5.5 and IE6
	d.open();
	d.writeln('<form target="_self" action="'+action+'" method="post" enctype="multipart/form-data">'+body+'</form>');
	d.close();
	return d.getElementsByTagName("form")[0];
}
//}}}

//{{{
// note: if blocked by browser security, this function will throw an error...
// the CALLING function should use "try{...} catch(e){...}" to handle the security errors
window.promptForFilename=function(msg,path,file,defext) {
	var result="";
	if(window.Components) { // moz
		netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
		var nsIFilePicker = window.Components.interfaces.nsIFilePicker;
		var picker = Components.classes['@mozilla.org/filepicker;1'].createInstance(nsIFilePicker);
		picker.init(window, msg, nsIFilePicker.modeSave);
		picker.displayDirectory=null;
		picker.defaultExtension=defext;
		picker.defaultString=file;
		picker.appendFilters(nsIFilePicker.filterAll|nsIFilePicker.filterText|nsIFilePicker.filterHTML);
		if (picker.show()!=nsIFilePicker.returnCancel) var result=picker.file.persistentDescriptor;
	}
	else { // IE (XP only)
		var s = new ActiveXObject('UserAccounts.CommonDialog');
		s.Filter='All files|*.*|Text files|*.txt|HTML files|*.htm;*.html|';
		s.FilterIndex=1; // default to ALL files;
		s.InitialDir=path;
		s.FileName=file;
		if (s.showOpen()) var result=s.FileName;
	}
	return result;
}
//}}}
|>|>|>|>|<<search>> |
| in:|titles |text |tags |hold |
||<<option chkSearchTitles>> |<<option chkSearchText>> |<<option chkSearchTags>> |<<option chkHoldSearches>> |
TiddlyWiki offers a number of powerful features for searching within a TiddlyWiki site. The built-in search features in TiddlyPerfect are enhance with the installation of [[SearchOptions plugin]] and [[YourSearchPlugin macro]]. The options you select will be saved in a cookie, and will remain in effect when you re-visit this site.
!!!Search Options
<<option chkSearchTitles>> Search in tiddler titles
<<option chkSearchText>> Search in tiddler text
<<option chkSearchTags>> Search in tiddler tags
<<option chkSearchTitlesFirst>> Search results show title matches first
<<option chkSearchList>> Search results show list of matching tiddlers
<<option chkSearchIncremental>> Incremental searching
<<option chkSearchAsYouType>> 'Search As You Type' Mode (No RETURN required to start search)
Default Search Filter: <<option chkSearchInTitle>>Titles ('!') <<option chkSearchInText>>Texts ('%') <<option chkSearchInTags>>Tags ('#') <html><br><font size="-2">The parts of a tiddlers that are searched when you don't explicitly specify a filter in the search text (using a '!', '%' or '#' prefix).</font></html>
Number of items on search result page: <<option txtItemsPerPage>>
Number of items on search result page with preview text: <<option txtItemsPerPageWithPreview>>
/***
|Name|''SearchOptions''|h
|Author|[[Eric Shulman]]|
|Version|2.2.1 (2006.02.03)|
|Description|Allows modification of search criteria.|
|Source|http://www.TiddlyTools.com/#SearchOptionsPlugin|
|Licence|[[Creative Commons Attribution ShareAlike 2.5 Licence]]|
***/
/***
The TiddlyWiki search function normally looks in both tiddler titles and tiddler body content ('text'). However, narrowing the search so that it examines only titles or only text, or expanding the search to include text contained in tiddler tags can be very helpful, especially when searching on common words or phrases.  In addition, it is often useful for the search results to show tiddlers with matching titles before tiddlers that contain matching text or tags.

!!!!!Usage
<<<
This plugin adds checkboxes (see below and in AdvancedOptions) to let you selectively configure the TiddlyWiki search function to just examine any combination of tiddler titles, text, or tags.  It also provides an option to switch the search results order between 'titles mixed in' (default) and 'titles shown first', as well as an option display the search results as a list of links (in an auto-generated "SearchResults" tiddler), rather than actually displaying all matching tiddlers.  You can also enable/disable the "incremental search" (key-by-key searching), so that a search is only initiated when you press the ENTER key or click on the "search:" prompt text.
<<<
!!!!!Configuration
<<<
In additional to the checkboxes in AdvancedOptions, a self-contained control panel is included here for your convenience:
<<option chkSearchTitles>> Search tiddler titles
<<option chkSearchText>> Search tiddler text
<<option chkSearchTags>> Search in tiddler tags
<<option chkSearchTitlesFirst>> Show title matches first
<<option chkSearchList>> Show list of matching tiddlers
<<option chkSearchIncremental>> Incremental searching
<<<
!!!!!Installation
<<<
import (or copy/paste) the following tiddlers into your document:
''SearchOptionsPlugin'' (tagged with <<tag systemConfig>>)
^^documentation and javascript for SearchOptionsPlugin handling^^

When installed, this plugin automatically adds checkboxes in the AdvancedOptions shadow tiddler so you can enable/disable the extended search behavior.  However, if you have customized your AdvancedOptions, you will need to manually add {{{<<option chkSearchTitles>>}}},  {{{<<option chkSearchText>>}}} and {{{<<option chkSearchTitlesFirst>>}}}  (with suitable prompt text) to your customized tiddler.
<<<
!!!!!Revision History
<<<
''2006.02.03 [2.2.1]''
rewrite timeout clearing code and blank search text handling to match 2.0.4 core release changes.  note that core no longer permits "blank=all" searches, so neither does this plugin.  To search for all, use "." with text patterns enabled.
''2006.02.02 [2.2.0]''
in search.handler(), KeyHandler() function clears 'left over' timeout when search input is < 3 chars.  Prevents searching on shorter text when shortened by rapid backspaces (<500msec)
''2006.02.01 [2.1.9]''
in Story.prototype.search(), correct inverted logic for using/not using regular expressions when searching
also, blank search text now presents "No search text.  Continue anyway?" confirm() message box, so search on blank can still be processed if desired by user.
''2006.02.01 [2.1.8]''
in doSearch(), added alert/return if search text is blank
''2006.01.20 [2.1.7]''
fixed setting of config.macros.search.reportTitle so that Tweaks can override it.
''2006.01.19 [2.1.6]''
improved SearchResults formatting, added a "search again" form to the report (based on a suggestion from MorrisGray)
define results report title using config.macros.search.reportTitle instead of hard-coding the tiddler title
''2006.01.18 [2.1.5]''
Created separate functions for reportSearchResults(text,matches) and discardSearchResults(), so that other developers can create alternative report generators.
''2006.01.17 [2.1.4]''
Use regExp.search() instead of regExp.test() to scan for matches.  Correctd the problem where only half the matching tiddlers (the odd-numbered ones) were being reported.
''2006.01.15 [2.1.3]''
Added information (date/time, username, search options used) to SearchResults output
''2006.01.10 [2.1.2]''
use displayTiddlers() to render matched tiddlers.  This lets you display multiple matching tiddlers, even if SinglePageModePlugin is enabled.
''2006.01.08 [2.1.1]''
corrected invalid variable reference, "txt.value" to "text" in story.search()
''2006.01.08 [2.1.0]''
re-write to match new store.search(), store.search.handler() and story.search() functions.
''2005.12.30 [2.0.0]''
Upgraded to TW2.0
when rendering SearchResults tiddler, closeTiddler() first to ensure display is refreshed.
''2005.12.26 [1.4.0]''
added option to search for matching text in tiddler tags
''2005.12.21 [1.3.7]''
use \\ to 'escape' single quotes in tiddler titles when generating "Open all matching tiddlers" link.  Also, added access key: "O", to trigger "open all" link.
Based on a suggestion by UdoBorkowski.
''2005.12.18 [1.3.6]''
call displayMessage() AFTER showing matching tiddlers so message is not cleared too soon
''2005.12.17 [1.3.5]''
if no matches found, just display message and delete any existing SearchResults tiddler.
''2005.12.17 [1.3.4]''
use """{{{"""  and """}}}""" to 'escape' display text in SearchResults tiddler to ensure that formatting contained in search string is not rendered 
Based on a suggestion by UdoBorkowski.
''2005.12.14 [1.3.3]''
tag SearchResults tiddler with 'excludeSearch' so it won't list itself in subsequent searches
Based on a suggestion by UdoBorkowski.
''2005.12.14 [1.3.2]''
added "open all matching tiddlers..." link to search results output.
Based on a suggestion by UdoBorkowski.
''2005.12.10 [1.3.1]''
added "discard search results" link to end of search list tiddler output for quick self-removal of 'SearchResults' tiddler.
''2005.12.01 [1.3.0]''
added chkSearchIncremental to enable/disable 'incremental' searching (i.e., search after each keystroke) (default is ENABLED).
added handling for Enter key so it can be used to start a search.
Based on a suggestion by LyallPearce
''2005.11.25 [1.2.1]''
renamed from SearchTitleOrTextPlugin to SearchOptionsPlugin
''2005.11.25 [1.2.0]''
added chkSearchList option
Based on a suggestion by RodneyGomes
''2005.10.19 [1.1.0]''
added chkSearchTitlesFirst option.
Based on a suggestion by ChristianHauck
''2005.10.18 [1.0.0]''
Initial Release
<<<
!!!!!Credits
<<<
This feature was developed by [[Eric Shulman]] from [[ELS Design Studios|http:/www.elsdesign.com]].
Based on a suggestion by Lyall Pearce.
<<<
!!!!!Code
***/
//{{{
version.extensions.SearchTitleOrText = {major: 2, minor: 2, revision: 1, date: new Date(2006,2,3)};
//}}}

//{{{
if (config.options.chkSearchTitles==undefined) config.options.chkSearchTitles=true;
if (config.options.chkSearchText==undefined) config.options.chkSearchText=true;
if (config.options.chkSearchTags==undefined) config.options.chkSearchTags=true;
if (config.options.chkSearchTitlesFirst==undefined) config.options.chkSearchTitlesFirst=false;
if (config.options.chkSearchList==undefined) config.options.chkSearchList=false;
if (config.options.chkSearchIncremental==undefined) config.options.chkSearchIncremental=true;

config.shadowTiddlers.AdvancedOptions += "\n<<option chkSearchTitles>> Search in tiddler titles";
config.shadowTiddlers.AdvancedOptions += "\n<<option chkSearchText>> Search in tiddler text";
config.shadowTiddlers.AdvancedOptions += "\n<<option chkSearchTags>> Search in tiddler tags";
config.shadowTiddlers.AdvancedOptions += "\n<<option chkSearchTitlesFirst>> Search results show title matches first";
config.shadowTiddlers.AdvancedOptions += "\n<<option chkSearchList>> Search results show list of matching tiddlers";
config.shadowTiddlers.AdvancedOptions += "\n<<option chkSearchIncremental>> Incremental searching";
//}}}

//{{{
if (config.macros.search.reportTitle==undefined)
config.macros.search.reportTitle="SearchResults";
//}}}

//{{{
config.macros.search.handler = function(place,macroName,params)
{
var lastSearchText = "";
var searchTimeout = null;
var doSearch = function(txt)
{
if (txt.value.length>0)
{
story.search(txt.value,config.options.chkCaseSensitiveSearch,config.options.chkRegExpSearch);
lastSearchText = txt.value;
}
};
var clickHandler = function(e)
{
doSearch(this.nextSibling);
return false;
};
var keyHandler = function(e)
{
if (!e) var e = window.event;
switch(e.keyCode)
{
case 13: // ELS: handle enter key
doSearch(this);
break;
case 27:
this.value = "";
clearMessage();
break;
}
if (config.options.chkSearchIncremental)
{
if(this.value.length > 2)
{
if(this.value != lastSearchText)
{
if(searchTimeout) clearTimeout(searchTimeout);
var txt = this;
searchTimeout = setTimeout(function() {doSearch(txt);},500);
}
}
else
if(searchTimeout) clearTimeout(searchTimeout);
}
};
var focusHandler = function(e)
{
this.select();
};
var btn = createTiddlyButton(place,this.label,this.prompt,clickHandler);
var txt = createTiddlyElement(place,"input",null,null,null);
if(params[0])
txt.value = params[0];
txt.onkeyup = keyHandler;
txt.onfocus = focusHandler;
txt.setAttribute("size",this.sizeTextbox);
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");
}
//}}}

//{{{
Story.prototype.search = function(text,useCaseSensitive,useRegExp)
{
highlightHack = new RegExp(useRegExp ? text : text.escapeRegExp(),useCaseSensitive ? "mg" : "img");
var matches = store.search(highlightHack,"title","excludeSearch");
var q = useRegExp ? "/" : "'";
clearMessage();
if (!matches.length) {
if (config.options.chkSearchList) discardSearchResults();
displayMessage(config.macros.search.failureMsg.format([q+text+q]));
} else {
if (config.options.chkSearchList) 
reportSearchResults(text,matches);
else {
var titles = []; for(var t=0; t<matches.length; t++) titles.push(matches[t].title);
this.closeAllTiddlers(); story.displayTiddlers(null,titles);
displayMessage(config.macros.search.successMsg.format([matches.length, q+text+q]));
}
}
highlightHack = null;
}
//}}}

//{{{
TiddlyWiki.prototype.search = function(searchRegExp,sortField,excludeTag)
{
var candidates = this.reverseLookup("tags",excludeTag,false,sortField);

// scan for matching titles
var title_results = [];
if (config.options.chkSearchTitles)
for(var t=0; t<candidates.length; t++)
if(candidates[t].title.search(searchRegExp)!=-1)
title_results.push(candidates[t]);

// scan for matching text
var text_results = [];
if (config.options.chkSearchText)
for(var t=0; t<candidates.length; t++)
if(candidates[t].text.search(searchRegExp)!=-1)
text_results.push(candidates[t]);

// scan for matching tags
var tag_results = [];
if (config.options.chkSearchTags)
for(var t=0; t<candidates.length; t++)
if(candidates[t].tags.join(" ").search(searchRegExp)!=-1)
tag_results.push(candidates[t]);

// merge the results, eliminating redundant matches
var results = [];
for(var t=0; t<title_results.length; t++) results.pushUnique(title_results[t]);
for(var t=0; t<text_results.length; t++) results.pushUnique(text_results[t]);
for(var t=0; t<tag_results.length; t++) results.pushUnique(tag_results[t]);

// if not 'titles first',  re-sort results to so titles, text and tag matches are mixed together
if(!sortField) sortField = "title";
var bySortField=function (a,b) {if(a[sortField] == b[sortField]) return(0); else return (a[sortField] < b[sortField]) ? -1 : +1; }
if (!config.options.chkSearchTitlesFirst) results.sort(bySortField);
return results;
}
//}}}

// // ''REPORT GENERATOR''
//{{{
if (!window.reportSearchResults) window.reportSearchResults=function(text,matches)
{
var title=config.macros.search.reportTitle
var q = config.options.chkRegExpSearch ? "/" : "'";
var body="";

// summary: nn tiddlers found matching '...', options used
body+="''"+config.macros.search.successMsg.format([matches.length,q+"{{{"+text+"}}}"+q])+"''\n";
body+="^^//searched in:// ";
body+=(config.options.chkSearchTitles?"''titles'' ":"");
body+=(config.options.chkSearchText?"''text'' ":"");
body+=(config.options.chkSearchTags?"''tags'' ":"");
if (config.options.chkCaseSensitiveSearch||config.options.chkRegExpSearch) {
body+=" //with options:// ";
body+=(config.options.chkCaseSensitiveSearch?"''case sensitive'' ":"");
body+=(config.options.chkRegExpSearch?"''text patterns'' ":"");
}
body+="^^";

// numbered list of links to matching tiddlers
body+="\n<<<";
for(var t=0;t<matches.length;t++) body+="\n# [["+matches[t].title+"]]";
body+="\n<<<\n";

// open all matches button
body+="<html><input type=\"button\" href=\"javascript:;\" ";
body+="onclick=\"story.displayTiddlers(null,["
for(var t=0;t<matches.length;t++)
body+="'"+matches[t].title.replace(/\'/mg,"\\'")+"'"+((t<matches.length-1)?", ":"");
body+="],1);\" ";
body+="accesskey=\"O\" ";
body+="value=\"open all matching tiddlers\"></html> ";

// discard search results button
body+="<html><input type=\"button\" href=\"javascript:;\" ";
body+="onclick=\"story.closeTiddler('"+title+"'); store.deleteTiddler('"+title+"');\" ";
body+="value=\"discard "+title+"\"></html>";

// search again
body+="\n\n----\n";
body+="<<search \""+text+"\">> ";
body+="<<option chkSearchTitles>>titles ";
body+="<<option chkSearchText>>text ";
body+="<<option chkSearchTags>>tags";
body+="<<option chkCaseSensitiveSearch>>case-sensitive ";
body+="<<option chkRegExpSearch>>text patterns";

// create/update the tiddler
var tiddler=store.getTiddler(title); if (!tiddler) tiddler=new Tiddler();
tiddler.set(title,body,config.options.txtUserName,(new Date()),"excludeLists excludeSearch");
store.addTiddler(tiddler); story.closeTiddler(title);

// use alternate "search again" label in <<search>> macro
var oldprompt=config.macros.search.label;
config.macros.search.label="search again";

// render tiddler
story.displayTiddler(null,title,1); // force refresh

// restore standard search label
config.macros.search.label=oldprompt;

}

if (!window.discardSearchResults) window.discardSearchResults=function()
{
// remove the tiddler
story.closeTiddler(config.macros.search.reportTitle);
store.deleteTiddler(config.macros.search.reportTitle);
}
//}}}


This set of shadowed tiddlers contain, and display key items for visitors, browsers and search engines. For convenience of reference, the current contents of some of these tiddlers is also displayed using the built in {{{<<tiddler>>}}} macro. Once you have [[downloaded this web site|Download this web site]], the ''Setup Menu'' serves as a control panel from which you can re-organize and customize and discover how it can work for you and members of your community - who can in turn download your organization's TiddlyWiki site ... 
* [[SiteTitle]] - the short title for the site; displayed by the browser and at the head of the page and included in the page's "title tag"
>> ''<<tiddler SiteTitle>>''
* [[SiteSubtitle]] - a subtitle for the site, also displayed by the browser and at the head of the page and included in the page's "title tag"
>> ''<<tiddler SiteSubtitle>>''
* [[SiteUrl]] - the Url where the page is hosted; be sure to define this correctly if you will be generating an XML page
>> <<tiddler SiteUrl>>
* [[DefaultTiddlers[[ - list of tiddlers displayed when the page is opened
>> <<tiddler DefaultTiddlers>>
* MainMenu - the Main Menu, displayed here in the left sidebar, and a key to effective navigation - makes extensive use of sub-menus using the NestedSlidersPlugin
>> <<tiddler MainMenu>>
** [[Administrative Menu]] - a component of the Main Menu, it includes common site tools & a nested set of [[Tiddler Administration]] menus for modifying and reconfiguring the appearance and organization of the page 
>> <<tiddler "Administrative Menu">>
* MarkupPreHead - "meta tags" for browsers & search engines & to define the opening [[Splash Screen]], displayed below:
<<tiddler "Splash Screen">>
* [[Templates & Stylesheets]] - These tiddlers allow you to change the appearance, colors, font types and sizes of your own Climate Change Summer - or of any other TiddlyWiki pages you and your friends may develop and build
>> <<tiddler "Templates & Stylesheets">>
* [[More Menus|Menus]]
When your browser reads a [[TiddlyWiki Page]] a set of built-in ''Shadowed Tiddlers'' is automatically generated, with shadow default values if the [[Shadowed Tiddler]]. Note that a "Shadowed Tiddlers'' is not the same as a "[[Missing Tiddlers]]; the latter is an as-yet undefined Tiddler that has been referred to in another Tiddler.  For those who are familiar with WikiPedia, a Shadow Tiddler is the equivalent of red link.

There are several different [[Shadowed Tiddler Groups]], that you can  to address different aspects of your TiddlyWiki experiences,

!!Page Layour
* ColorPalette
* StyleSheetLayout

<<tiddler SideBarTabs>>
/*{{{*/
#sidebar {
position: absolute;
right: 3px;
width: 16em;
font-size: .9em;
}

#sidebarOptions {
padding-top: 0.3em;
}

#sidebarOptions a {
margin: 0em 0.2em;
padding: 0.2em 0.3em;
display: block;
}

#sidebarOptions input {
margin: 0.4em 0.5em;
}

#sidebarOptions .sliderPanel {
margin-left: 1em;
padding: 0.5em;
font-size: .85em;
}

#sidebarOptions .sliderPanel a {
font-weight: bold;
display: inline;
padding: 0;
}

#sidebarOptions .sliderPanel input {
margin: 0 0 .3em 0;
}

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

#sidebarTabs .tabContents {
width: 15em;
overflow: hidden;
}
/*}}}*/
Testing different TW Themes for file: & http:
/***
|''Name:''|SparklinePlugin|
|''Description:''|Sparklines macro|
***/
//{{{
if(!version.extensions.SparklinePlugin) {
version.extensions.SparklinePlugin = {installed:true};

//--
//-- Sparklines
//--

config.macros.sparkline = {};
config.macros.sparkline.handler = function(place,macroName,params)
{
	var data = [];
	var min = 0;
	var max = 0;
	var v;
	for(var t=0; t<params.length; t++) {
		v = parseInt(params[t]);
		if(v < min)
			min = v;
		if(v > max)
			max = v;
		data.push(v);
	}
	if(data.length < 1)
		return;
	var box = createTiddlyElement(place,"span",null,"sparkline",String.fromCharCode(160));
	box.title = data.join(",");
	var w = box.offsetWidth;
	var h = box.offsetHeight;
	box.style.paddingRight = (data.length * 2 - w) + "px";
	box.style.position = "relative";
	for(var d=0; d<data.length; d++) {
		var tick = document.createElement("img");
		tick.border = 0;
		tick.className = "sparktick";
		tick.style.position = "absolute";
		tick.src = "data:image/gif,GIF89a%01%00%01%00%91%FF%00%FF%FF%FF%00%00%00%C0%C0%C0%00%00%00!%F9%04%01%00%00%02%00%2C%00%00%00%00%01%00%01%00%40%02%02T%01%00%3B";
		tick.style.left = d*2 + "px";
		tick.style.width = "2px";
		v = Math.floor(((data[d] - min)/(max-min)) * h);
		tick.style.top = (h-v) + "px";
		tick.style.height = v + "px";
		box.appendChild(tick);
	}
};


}
//}}}
/***

''Inspired by [[TiddlyPom|http://www.warwick.ac.uk/~tuspam/tiddlypom.html]]''

|Name|SplashScreenPlugin|
|Created by|SaqImtiaz|
|Location|http://tw.lewcid.org/#SplashScreenPlugin|
|Version|0.21 |
|Requires|~TW2.08+|
!Description:
Provides a simple splash screen that is visible while the TW is loading.

!Installation
Copy the source text of this tiddler to your TW in a new tiddler, tag it with systemConfig and save and reload. The SplashScreen will now be installed and will be visible the next time you reload your TW.

!Customizing
Once the SplashScreen has been installed and you have reloaded your TW, the splash screen html will be present in the MarkupPreHead tiddler. You can edit it and customize to your needs.

!History
* 20-07-06 : version 0.21, modified to hide contentWrapper while SplashScreen is displayed.
* 26-06-06 : version 0.2, first release

!Code
***/
//{{{
var old_lewcid_splash_restart=restart;

restart = function()
{   if (document.getElementById("SplashScreen"))
        document.getElementById("SplashScreen").style.display = "none";
      if (document.getElementById("contentWrapper"))
        document.getElementById("contentWrapper").style.display = "block";
    
    old_lewcid_splash_restart();
   
    if (splashScreenInstall)
       {if(config.options.chkAutoSave)
			{saveChanges();}
        displayMessage("TW SplashScreen has been installed, please save and refresh your TW.");
        }
}


var oldText = store.getTiddlerText("MarkupPreHead");
if (oldText.indexOf("SplashScreen")==-1)
   {var siteTitle = store.getTiddlerText("SiteTitle");
   var splasher='\n\n<style type="text/css">#contentWrapper {display:none;}</style><div id="SplashScreen" style="border: 3px solid #ccc; display: block; text-align: center; width: 320px; margin: 100px auto; padding: 50px; color:#000; font-size: 28px; font-family:Tahoma; background-color:#eee;"><b>'+siteTitle +'</b> is loading<blink> ...</blink><br><br><span style="font-size: 14px; color:red;">Requires Javascript.</span></div>';
   if (! store.tiddlerExists("MarkupPreHead"))
       {var myTiddler = store.createTiddler("MarkupPreHead");}
   else
      {var myTiddler = store.getTiddler("MarkupPreHead");}
      myTiddler.set(myTiddler.title,oldText+splasher,config.options.txtUserName,null,null);
      store.setDirty(true);
      var splashScreenInstall = true;
}
//}}}
/*{{{*/
* html .tiddler {
    height: 1%;
}
body {
font-size: .75em;
font-family: georgia, garamond antigua, arial, helvetica;
margin: 0;
padding: 0;
}
[[CustomStyleSheet]]
[[ModifiedStyleSheetColors]]
[[CustomStyleSheetColors]]
[[TagglyTaggingStyles]]
[[MainMenuStyles]]
[[HoverMenuStyles]]
[[PrintStyles]]
[[CommonStyles]]
[[HeaderStyles]]
.onlineMode  .admin {
display:none;
}
/*}}}*/
/*{{{*/
body {
	background: [[ColorPalette::Background]];
	color: [[ColorPalette::Foreground]];
}

a.externalLink {
 color: #007700;
}
a {
	color: [[ColorPalette::PrimaryMid]];
}

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

.cleartable table {
border: 1px solid #fff;
}
h1,h2,h3,h4,h5 {
	color: [[ColorPalette::PrimaryDark]];
}


.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::SecondaryLight]];
	border-top: 1px solid [[ColorPalette::SecondaryMid]];
	border-left: 1px solid [[ColorPalette::SecondaryMid]];
}

.wizard h1 {
	color: [[ColorPalette::SecondaryDark]];
}

.wizard h2 {
	color: [[ColorPalette::Foreground]];
}

.wizardStep {
	background: [[ColorPalette::Background]];
	border-top: 1px solid [[ColorPalette::SecondaryMid]];
	border-bottom: 1px solid [[ColorPalette::SecondaryMid]];
	border-left: 1px solid [[ColorPalette::SecondaryMid]];
}

.wizard .button {
	color: [[ColorPalette::Background]];
	background: [[ColorPalette::PrimaryMid]];
	border-top: 1px solid [[ColorPalette::PrimaryLight]];
	border-right: 1px solid [[ColorPalette::PrimaryDark]];
	border-bottom: 1px solid [[ColorPalette::PrimaryDark]];
	border-left: 1px solid [[ColorPalette::PrimaryLight]];
}

.wizard .button:hover {
	color: [[ColorPalette::PrimaryLight]];
	background: [[ColorPalette::PrimaryDark]];
	border-color: [[ColorPalette::PrimaryLight]];
}

.wizard .button:active {
	color: [[ColorPalette::Background]];
	background: [[ColorPalette::PrimaryMid]];
	border-top: 1px solid [[ColorPalette::PrimaryLight]];
	border-right: 1px solid [[ColorPalette::PrimaryDark]];
	border-bottom: 1px solid [[ColorPalette::PrimaryDark]];
	border-left: 1px solid [[ColorPalette::PrimaryLight]];
}

#messageArea {
	border: 1px solid [[ColorPalette::SecondaryDark]];
	background: [[ColorPalette::SecondaryMid]];
	color: [[ColorPalette::PrimaryDark]];
}

#messageArea .button {
	padding: 0.2em 0.2em 0.2em 0.2em;
	color: [[ColorPalette::PrimaryDark]];
	background: [[ColorPalette::Background]];
}

.popup {
	background: [[ColorPalette::PrimaryLight]];
	border: 1px solid [[ColorPalette::PrimaryMid]];
}

.popup hr {
	color: [[ColorPalette::PrimaryDark]];
	background: [[ColorPalette::PrimaryDark]];
	border-bottom: 1px;
}

.listBreak div{
	border-bottom: 1px solid [[ColorPalette::PrimaryDark]];
}

.popup li.disabled {
	color: [[ColorPalette::PrimaryMid]];
}

.popup li a, .popup li a:visited {
	color: [[ColorPalette::TertiaryPale]];
	border: none;
}

.popup li a:hover {
	background: [[ColorPalette::PrimaryDark]];
	color: [[ColorPalette::Background]];
	border: none;
}

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

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

.title {
	color: [[ColorPalette::PrimaryDark]];
}

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

.toolbar {
	color: [[ColorPalette::PrimaryMid]];
}

.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]];
}

.cascade {
	background: [[ColorPalette::TertiaryPale]];
	color: [[ColorPalette::TertiaryMid]];
	border: 1px solid [[ColorPalette::TertiaryMid]];
}

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

.viewer .listTitle {list-style-type: none; margin-left: -2em;}

.viewer .button {
	border: 1px solid [[ColorPalette::SecondaryMid]];
}

.viewer blockquote {
	[[ColorPalette::Foeground]];
}

.viewer table {
	border: 2px solid [[ColorPalette::TertiaryDark]];
}

.viewer th, thead td {
	background: [[ColorPalette::PrimaryPale]];
	color: [[ColorPalette::PrimaryDark]];
}

.viewer td, .viewer 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: solid2px [[ColorPalette::TertiaryDark]];
	color: [[ColorPalette::TertiaryDark]];
}

.box {
	background: #ccecff;
	border; 1px;
}

#mainMenu .highlight, #mainMenu .marked {
	background: [[ColorPalette::PrimaryPale]];
}

.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]];
}

/*}}}*/
/*{{{*/
* html .tiddler {
    height: 1%;
}

[[TagglyTaggingStyles]]
[[Main Menu Styles]]
[[Custom Styles]]

body {
font-size: .75em;
font-family: bookman old style, garamond antigua, arial, helvetica;
margin: 0;
padding: 0;
}

#displayArea {
margin-left: 16em;
margin-right: 3em;
}

h1, h2, h3, h4, h5 {
font-weight: bold;
text-decoration: none;
}

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: none;
font-weight: bold;
}

.indent {
margin-left: 0.5em;
padding-left: 1.5em;
}

.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 a bold */
a.tiddlyLinkNonExisting.shadow {
font-weight: bold;
}

.header {
position: relative;
}

.header a:hover {
	background: transparent;
}

.headerShadow {
	position: relative;
	padding: 1.5em 0em 1em 1em;
	left: -1px;
	top: -1px;
}

.headerForeground {
position: absolute;
padding: 1.5em 0em 1em 1em;
left: 0px;
top: 0px;
}

.siteTitle {
font-size: 3em;
}

.siteSubtitle {
font-size: 1.2em;
}

.wizard {
padding: 0.1em 0em 0em 2em;
}

.wizard h1 {
font-size: 2em;
font-weight: bold;
background: none;
padding: 0em 0em 0em 0em;
margin: 0.4em 0em 0.2em 0em;
}

.wizard h2 {
font-size: 1.2em;
font-weight: bold;
background: none;
padding: 0em 0em 0em 0em;
margin: 0.2em 0em 0.2em 0em;
}

.wizardStep {
padding: 1em 1em 1em 1em;
}

.wizard .button {
margin: 0.5em 0em 0em 0em;
font-size: 1.2em;
}

#messageArea {
position:absolute; top:0; right:0; margin: 0.5em; padding: 0.5em;
}

*[id='messageArea'] {
position:fixed !important; z-index:99;}

.messageToolbar {
display: block;
text-align: right;
}

#messageArea a{
text-decoration: underline;
}

.popup {
font-size: .9em;
padding: 0.2em;
list-style: none;
margin: 0;
}

.popup hr {
display: block;
height: 1px;
width: auto;
padding: 0;
margin: 0.2em 0em;
}

.listBreak {
font-size: 1px;
line-height: 1px;
}

.listBreak div {
margin: 2px 0;
}

.popup li.disabled {
padding: 0.2em;
}

.popup li a{
display: block;
padding: 0.2em;
}

.tabset {
padding: 1em 0em 0em 0.5em;
}

.tab {
margin: 0em 0em 0em 0.25em;
padding: 2px;
}

.tabContents {
padding: 0.5em;
}

.tabContents ul, .tabContents ol {
margin: 0;
padding: 0;
}

.txtMainTab .tabContents li {
list-style: none;
}

.tabContents li.listLink {
 margin-left: .75em;
}

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

.selected .toolbar {
visibility: visible;
}

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

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

.title {
font-size: 1.6em;
font-weight: bold;
padding-left: 1px;
}

.missing .subtitle {
display: none;
}

.subtitle {
font-size: 1.1em;
padding-left: 2px;
}

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

.tagging {
margin: 0.5em 0.5em 0.5em 0;
float: right;
display: none;
}

.isTag .tagging {
display: block;
}

.tagged {
margin: 0.5em;
}

.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;
}

* html .viewer pre {
width: 99%;
padding: 0 0 1em 0;
}

.viewer {
line-height: 1.4em;
padding-left: 1em;
}

.viewer .button {
margin: 0em 0.25em;
padding: 0em 0.25em;
}

.viewer blockquote {
margin-left: 0.5em;
padding-left: 1.5em;
}

.viewer ul, .viewer ol{
margin-left: 0.5em;
padding-left: 1.5em;
}

.viewer li {
margin-top: 0.8em;
}

.viewer table {
border-collapse: collapse;
margin: 0.5em 0.5em;
}

.viewer th, .viewer td, .viewer tr,.viewer caption{
vertical-align: top;
padding: 1px;
}

.viewer table.listView {
font-size: 0.85em;
margin: 0.8em 1.0em;
}

.viewer table.listView th, .viewer table.listView td, .viewer table.listView tr {
padding: 0px 2px 0px 2px;
}

.viewer pre {
padding: 0.2em;
font-size: 0.9em;
line-height: 110%;
overflow: auto;
}

.viewer code {
font-size: 90%;
}

.editor {
font-size: 1.1em;
}

.editor input, .editor textarea {
display: block;
width: 100%;
font: inherit;
}

.editorFooter {
padding: 0.25em 0em;
font-size: .9em;
}

.editorFooter .button {
padding-top: 0px; padding-bottom: 0px;}

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

.sparkline {
line-height: 1em;
}

.sparktick {
outline: 0;
}

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

.cascade {
font-size: 1.1em;
position: absolute;
overflow: hidden;
}
/*}}}*/
|>|bgcolor(#8af):@@color(#000080):''5 tiddlers found matching /{{{search}}}/''@@|bgcolor(#8af):  @@color(#A00000): SearchHelp@@ |
|>|>|bgcolor(#E3FFE3):<<search>> <<option chkSearchTitles>> Titles <<option chkSearchText>> Text <<option chkSearchTags>>Tags <<option chkHoldSearches>> Hold |

|&nbsp;|bgcolor(#8af): @@color(#000080):sort by: ''Titles''@@ |bgcolor(#8af): @@color(#000080): ''Size'' (bytes)@@ |bgcolor(#8af): @@color(#000080): ''Tags''@@ |h
| 1|[[Search Box]]| 232||
| 2|[[Search Options]]| 1265|options,search|
| 3|[[SearchOptions plugin]]| 14282|3rd party plugin,excludeLists,plugin macro,systemConfig,els design,search|
| 4|[[TWHelpSearchDoc]]| 2595||
| 5|[[TwHelpSearchPlugin]]| 5826|quickedit,systemConfig|
!!!<<gradient horiz #fc3 #fff>>&nbsp;TWHelpSearchDoc^^<<tiddler CloseThisOpen with: ThirdPartyPlugins  '« back'>>|<<toolbar editTiddler>>» ^^>>
''Now you can have the same search as used on TW Help.''

* Get this plugin here TwHelpSearchPlugin or here:
* http://twhelp.tiddlyspot.com/#TwHelpSearchPlugin

Optionally you can put this+++[search box]<<tiddler SearchBox>>===in SideBarOptions as seen on TW Help.+++[see the code]
{{{
|>|>|>|<<search>> |
|>|>| look for in |>|>|
| <<option chkSearchTitles>> | <<option chkSearchText>> | <<option chkSearchTags>> | <<option chkHoldSearches>> |
| titles |  text  | tags | hold |
}}}
===


----
''A Plugin Tweak for:'' SearchOptionsPlugin
!!!<<gradient horiz #abf #fff>>&nbsp;Description>>
<<<
The TwHelpSearchPlugin defines an alternative format for the ~SearchResults tiddler that is generated by the SearchOptionsPlugin . It presents the search results in tabular form numbering the rows and showing the tiddler title, the size in bytes, and the tags.  It is ready to be used with the [[SortableGridPlugin|http://solo.dc3.com/tw/#SortableGridPlugin]] (check versions) so any column can be sorted; such as size in ascending or descending order.
<<<
!!!<<gradient horiz #abf #fff>>Installation>>
If you have already installed SearchOptionsPlugin then your AdvancedOptions will have already been modified by that plugin to include the following: +++[see the code for this]
{{{
<<option chkSearchTitles>> Search tiddler titles
<<option chkSearchText>> Search tiddler text
<<option chkSearchTags>> Search in tiddler tags
<<option chkSearchTitlesFirst>> Show title matches first
<<option chkSearchList>> Show list of matching tiddlers 
}}}
===

<<<
<<option chkSearchTitles>> Search tiddler titles
<<option chkSearchText>> Search tiddler text
<<option chkSearchTags>> Search in tiddler tags
<<option chkSearchTitlesFirst>> Show title matches first
<<option chkSearchList>> Show list of matching tiddlers^^[1]^^
<<<
 ^^[1]^^@@color:#C06;(This option is critical in preventing normal ~TiddlyWiki search method.)@@

TwHelpSearchPlugin requires an additional insertion into AdvancedOptions for the option of holding the search results and appending any number of additional searches.  +++[see the code for this]
{{{
<<option chkHoldSearches>> Hold search results
}}}
===

<<<
<<option chkHoldSearches>> Hold search results
<<<
TwHelpSearchPlugin will attempt to add this to AdvancedOptions upon installation.

|bgcolor:#FCF;''NOTE:''  If either plugin fails to install their options; add them manually by pasting the code for them into AdvancedOptions.|
!!!End
/***
| Name:|TagglyTaggingPlugin|
| Description:|tagglyTagging macro is a replacement for the builtin tagging macro in your ViewTemplate|
| Version:|6.1.5|
| Date:|05-Oct-2006|
| Source:|http://mptw.tiddlyspot.com/#TagglyTaggingPlugin|
| Author:|Simon Baird <simon.baird@gmail.com>|
| CoreVersion:|2.1.x|
!!See also:
* [[1. What is TagglyTagging?]] 
* [[2. What's different about TagglyTagging?]] 
* [[3. Why use TagglyTagging?]] 
* [[4. How do I install it?]]
* [[5. Where did it come from?]] 
!!Notes
See http://mptw.tiddlyspot.com/#TagglyTagging
***/
//{{{
config.taggly = {

	// for translations
	lingo: {
		labels: {
			asc:      "\u2191", // down arrow
			desc:     "\u2193", // up arrow
			title:    "title",
			modified: "modified",
			created:  "created",
			show:     "+",
			hide:     "-",
			normal:   "normal",
			group:    "group",
			commas:   "commas",
			sitemap:  "sitemap",
			numCols:  "cols\u00b1", // plus minus sign
			label:    "Tagged as '%0':"
		},

		tooltips: {
			title:    "Click to sort by title",
			modified: "Click to sort by modified date",
			created:  "Click to sort by created date",
			show:     "Click to show tagging list",
			hide:     "Click to hide tagging list",
			normal:   "Click to show a normal ungrouped list",
			group:    "Click to show list grouped by tag",
			sitemap:  "Click to show a sitemap style list",
			commas:   "Click to show a comma separated list",
			numCols:  "Click to change number of columns"
		}
	},

	config: {
		showTaggingCounts: true,
		listOpts: {
			// the first one will be the default
			sortBy:     ["title","modified","created"],
			sortOrder:  ["asc","desc"],
			hideState:  ["show","hide"],
			listMode:   ["normal","group","sitemap","commas"],
			numCols:    ["1","2","3","4","5","6"]
		},
		valuePrefix: "taggly."
	},

	getTagglyOpt: function(title,opt) {
		var val = store.getValue(title,this.config.valuePrefix+opt);
		return val ? val : this.config.listOpts[opt][0];
	},

	setTagglyOpt: function(title,opt,value) {
		if (!store.tiddlerExists(title))
			// create it silently
			store.saveTiddler(title,title,config.views.editor.defaultText.format([title]),config.options.txtUserName,new Date(),null);
		// if value is default then remove it to save space
		return store.setValue(title,
			this.config.valuePrefix+opt,
			value == this.config.listOpts[opt][0] ? null : value);
	},

	getNextValue: function(title,opt) {
		var current = this.getTagglyOpt(title,opt);
		var pos = this.config.listOpts[opt].indexOf(current);
		// a little usability enhancement. actually it doesn't work right for grouped or sitemap
		var limit = (opt == "numCols" ? store.getTaggedTiddlers(title).length : this.config.listOpts[opt].length);
		var newPos = (pos + 1) % limit;
		return this.config.listOpts[opt][newPos];
	},

	toggleTagglyOpt: function(title,opt) {
		var newVal = this.getNextValue(title,opt);
		this.setTagglyOpt(title,opt,newVal);
	}, 

	createListControl: function(place,title,type) {
		var lingo = config.taggly.lingo;
		var label;
		var tooltip;
		var onclick;

		if ((type == "title" || type == "modified" || type == "created")) {
			// "special" controls. a little tricky. derived from sortOrder and sortBy
			label = lingo.labels[type];
			tooltip = lingo.tooltips[type];

			if (this.getTagglyOpt(title,"sortBy") == type) {
				label += lingo.labels[this.getTagglyOpt(title,"sortOrder")];
				onclick = function() {
					config.taggly.toggleTagglyOpt(title,"sortOrder");
					return false;
				}
			}
			else {
				onclick = function() {
					config.taggly.setTagglyOpt(title,"sortBy",type);
					config.taggly.setTagglyOpt(title,"sortOrder",config.taggly.config.listOpts.sortOrder[0]);
					return false;
				}
			}
		}
		else {
			// "regular" controls, nice and simple
			label = lingo.labels[type == "numCols" ? type : this.getNextValue(title,type)];
			tooltip = lingo.tooltips[type == "numCols" ? type : this.getNextValue(title,type)];
			onclick = function() {
				config.taggly.toggleTagglyOpt(title,type);
				return false;
			}
		}

		// hide button because commas don't have columns
		if (!(this.getTagglyOpt(title,"listMode") == "commas" && type == "numCols"))
			createTiddlyButton(place,label,tooltip,onclick,type == "hideState" ? "hidebutton" : "button");
	},

	makeColumns: function(orig,numCols) {
		var listSize = orig.length;
		var colSize = listSize/numCols;
		var remainder = listSize % numCols;

		var upperColsize = colSize;
		var lowerColsize = colSize;

		if (colSize != Math.floor(colSize)) {
			// it's not an exact fit so..
			upperColsize = Math.floor(colSize) + 1;
			lowerColsize = Math.floor(colSize);
		}

		var output = [];
		var c = 0;
		for (var j=0;j<numCols;j++) {
			var singleCol = [];
			var thisSize = j < remainder ? upperColsize : lowerColsize;
			for (var i=0;i<thisSize;i++) 
				singleCol.push(orig[c++]);
			output.push(singleCol);
		}

		return output;
	},

	drawTable: function(place,columns,theClass) {
		var newTable = createTiddlyElement(place,"table",null,theClass);
		var newTbody = createTiddlyElement(newTable,"tbody");
		var newTr = createTiddlyElement(newTbody,"tr");
		for (var j=0;j<columns.length;j++) {
			var colOutput = "";
			for (var i=0;i<columns[j].length;i++) 
				colOutput += columns[j][i];
			var newTd = createTiddlyElement(newTr,"td",null,"tagglyTagging"); // todo should not need this class
			wikify(colOutput,newTd);
		}
		return newTable;
	},

	createTagglyList: function(place,title) {
		switch(this.getTagglyOpt(title,"listMode")) {
			case "group":  return this.createTagglyListGrouped(place,title); break;
			case "normal": return this.createTagglyListNormal(place,title,false); break;
			case "commas": return this.createTagglyListNormal(place,title,true); break;
			case "sitemap":return this.createTagglyListSiteMap(place,title); break;
		}
	},

	getTaggingCount: function(title) {
		// thanks to Doug Edmunds
		if (this.config.showTaggingCounts) {
			var tagCount = store.getTaggedTiddlers(title).length;
			if (tagCount > 0)
				return " ("+tagCount+")";
		}
		return "";
	},

	// this is for normal and commas mode
	createTagglyListNormal: function(place,title,useCommas) {

		var list = store.getTaggedTiddlers(title,this.getTagglyOpt(title,"sortBy"));

		if (this.getTagglyOpt(title,"sortOrder") == "desc")
			list = list.reverse();

		var output = [];
		for (var i=0;i<list.length;i++) {
			var countString = this.getTaggingCount(list[i].title);
			if (useCommas)
				output.push((i > 0 ? ", " : "") + "[[" + list[i].title + "]]" + countString);
			else
				output.push("*[[" + list[i].title + "]]" + countString + "\n");
		}

		return this.drawTable(place,
			this.makeColumns(output,useCommas ? 1 : parseInt(this.getTagglyOpt(title,"numCols"))),
			useCommas ? "commas" : "normal");
	},

	// this is for the "grouped" mode
	createTagglyListGrouped: function(place,title) {
		var sortBy = this.getTagglyOpt(title,"sortBy");
		var sortOrder = this.getTagglyOpt(title,"sortOrder");

		var list = store.getTaggedTiddlers(title,sortBy);

		if (sortOrder == "desc")
			list = list.reverse();

		var leftOvers = []
		for (var i=0;i<list.length;i++)
			leftOvers.push(list[i].title);

		var allTagsHolder = {};
		for (var i=0;i<list.length;i++) {
			for (var j=0;j<list[i].tags.length;j++) {

				if (list[i].tags[j] != title) { // not this tiddler

					if (!allTagsHolder[list[i].tags[j]])
						allTagsHolder[list[i].tags[j]] = "";

					allTagsHolder[list[i].tags[j]] += "**[["+list[i].title+"]]"
									+ this.getTaggingCount(list[i].title) + "\n";
					leftOvers.setItem(list[i].title,-1); // remove from leftovers. at the end it will contain the leftovers
				}
			}
		}

		var allTags = [];
		for (var t in allTagsHolder)
			allTags.push(t);

		var sortHelper = function(a,b) {
			if (a == b) return 0;
			if (a < b) return -1;
			return 1;
		};

		allTags.sort(function(a,b) {
			var tidA = store.getTiddler(a);
			var tidB = store.getTiddler(b);
			if (sortBy == "title") return sortHelper(a,b);
			else if (!tidA && !tidB) return 0;
			else if (!tidA) return -1;
			else if (!tidB) return +1;
			else return sortHelper(tidA[sortBy],tidB[sortBy]);
		});

		var leftOverOutput = "";
		for (var i=0;i<leftOvers.length;i++)
			leftOverOutput += "*[["+leftOvers[i]+"]]" + this.getTaggingCount(leftOvers[i]) + "\n";

		var output = [];

		if (sortOrder == "desc")
			allTags.reverse();
		else if (leftOverOutput != "")
			// leftovers first...
			output.push(leftOverOutput);

		for (var i=0;i<allTags.length;i++)
			output.push("*[["+allTags[i]+"]]" + this.getTaggingCount(leftOvers[i]) + "\n" + allTagsHolder[allTags[i]]);

		if (sortOrder == "desc" && leftOverOutput != "")
			// leftovers last...
			output.push(leftOverOutput);

		return this.drawTable(place,
				this.makeColumns(output,parseInt(this.getTagglyOpt(title,"numCols"))),
				"grouped");

	},

	// used to build site map
	treeTraverse: function(title,depth,sortBy,sortOrder) {

		var list = store.getTaggedTiddlers(title,sortBy);
		if (sortOrder == "desc")
			list.reverse();

		var indent = "";
		for (var j=0;j<depth;j++)
			indent += "*"

		var childOutput = "";
		for (var i=0;i<list.length;i++)
			if (list[i].title != title)
				childOutput += this.treeTraverse(list[i].title,depth+1,sortBy,sortOrder);

		if (depth == 0)
			return childOutput;
		else
			return indent + "[["+title+"]]" + this.getTaggingCount(title) + "\n"+childOutput;
	},

	// this if for the site map mode
	createTagglyListSiteMap: function(place,title) {
		var output = this.treeTraverse(title,0,this.getTagglyOpt(title,"sortBy"),this.getTagglyOpt(title,"sortOrder"));
		return this.drawTable(place,
				this.makeColumns(output.split(/(?=^\*\[)/m),parseInt(this.getTagglyOpt(title,"numCols"))), // regexp magic
				"sitemap"
				);
	},

	macros: {
		tagglyTagging: {
			handler: function (place,macroName,params,wikifier,paramString,tiddler) {
				var refreshContainer = createTiddlyElement(place,"div");
				// do some refresh magic to make it keep the list fresh - thanks Saq
				refreshContainer.setAttribute("refresh","macro");
				refreshContainer.setAttribute("macroName",macroName);
        			refreshContainer.setAttribute("title",tiddler.title);
				this.refresh(refreshContainer);
			},

			refresh: function(place) {
				var title = place.getAttribute("title");
				removeChildren(place);
				if (store.getTaggedTiddlers(title).length > 0) {
					var lingo = config.taggly.lingo;
					config.taggly.createListControl(place,title,"hideState");
					if (config.taggly.getTagglyOpt(title,"hideState") == "show") {
						createTiddlyElement(place,"span",null,"tagglyLabel",lingo.labels.label.format([title]));
						config.taggly.createListControl(place,title,"title");
						config.taggly.createListControl(place,title,"modified");
						config.taggly.createListControl(place,title,"created");
						config.taggly.createListControl(place,title,"listMode");
						config.taggly.createListControl(place,title,"numCols");
						config.taggly.createTagglyList(place,title);
					}
				}
			}
		}
	},

	// todo fix these up a bit
	styles: 
"/*{{{*/\n"+
"/* created by TagglyTaggingPlugin */\n"+
".tagglyTagging { padding-top:0.5em; }\n"+
".tagglyTagging li.listTitle { display:none; }\n"+
".tagglyTagging ul {\n"+
"	margin-top:0px; padding-top:0.5em; padding-left:2em;\n"+
"	margin-bottom:0px; padding-bottom:0px;\n"+
"}\n"+
".tagglyTagging { vertical-align: top; margin:0px; padding:0px; }\n"+
".tagglyTagging table { margin:0px; padding:0px; }\n"+
".tagglyTagging .button { display:none; margin-left:3px; margin-right:3px; }\n"+
".tagglyTagging .button, .tagglyTagging .hidebutton {\n"+
"	color:[[ColorPalette::TertiaryLight]]; font-size:90%;\n"+
"	border:0px; padding-left:0.3em;padding-right:0.3em;\n"+
"}\n"+
".tagglyTagging .button:hover, .hidebutton:hover {\n"+
"	background:[[ColorPalette::TertiaryPale]]; color:[[ColorPalette::TertiaryDark]];\n"+
"}\n"+
".selected .tagglyTagging .button {\n"+
"	display:inline;\n"+
"}\n"+
".tagglyTagging .hidebutton { color:[[ColorPalette::Background]]; }\n"+
".selected .tagglyTagging .hidebutton { color:[[ColorPalette::TertiaryLight]] }\n"+
".tagglyLabel { color:[[ColorPalette::TertiaryMid]]; font-size:90%; }\n"+
".tagglyTagging ul {padding-top:0px; padding-bottom:0.5em; margin-left:1em; }\n"+
".tagglyTagging ul ul {list-style-type:disc; margin-left:-1em;}\n"+
".tagglyTagging ul ul li {margin-left:0.5em; }\n"+
".editLabel { font-size:90%; padding-top:0.5em; }\n"+
".tagglyTagging .commas { padding-left:1.8em; }\n"+
"/*}}}*/\n"+
		"",

	init: function() {
		merge(config.macros,this.macros);
		config.shadowTiddlers["TagglyTaggingStyles"] = this.styles;
		if (store)
			store.addNotification("TagglyTaggingStyles",refreshStyles);
		else
			config.notifyTiddlers.push({name:"TagglyTaggingStyles", notify: refreshStyles});
	}
};

config.taggly.init();

//}}}

/*{{{*/
/* created by TagglyTaggingPlugin */
.tagglyTagging { padding-top:0.5em; }
.tagglyTagging li.listTitle { display:none; }
.tagglyTagging ul {
	margin-top:0px; padding-top:0.5em; padding-left:2em;
	margin-bottom:0px; padding-bottom:0px;
}
.tagglyTagging { vertical-align: top; margin:0px; padding:0px; }
.tagglyTagging table { margin:0px; padding:0px; }
.tagglyTagging .button { display:none; margin-left:3px; margin-right:3px; }
.tagglyTagging .button, .tagglyTagging .hidebutton {
	color:[[ColorPalette::TertiaryLight]]; font-size:90%;
	border:0px; padding-left:0.3em;padding-right:0.3em;
}
.tagglyTagging .button:hover, .hidebutton:hover {
	background:[[ColorPalette::TertiaryPale]]; color:[[ColorPalette::TertiaryDark]];
}
.selected .tagglyTagging .button {
	display:inline;
}
.tagglyTagging .hidebutton { color:[[ColorPalette::Background]]; }
.selected .tagglyTagging .hidebutton { color:[[ColorPalette::TertiaryLight]] }
.tagglyLabel { color:[[ColorPalette::TertiaryMid]]; font-size:90%; }
.tagglyTagging ul {padding-top:0px; padding-bottom:0.5em; margin-left:1em; }
.tagglyTagging ul ul {list-style-type:disc; margin-left:-1em;}
.tagglyTagging ul ul li {margin-left:0.5em; }
.editLabel { font-size:90%; padding-top:0.5em; }
.tagglyTagging .commas { padding-left:1.8em; }
/* displays the list of a tiddler's tags horizontally. used in ViewTemplate */
.tagglyTagged {
text-align: right 
}
.tagglyTagged li.listTitle {
	display:none
}
.tagglyTagged li {
	display: inline; font-size:90%;
}
.tagglyTagged ul {
	margin:0px; padding:0px;
}
/*}}}*/
This tiddler provides some resources for use when creating and or editing tiddlers: One way of using it is to copy the contents to a separate window with a simple text editor, such as [[Notepad]], to which you can more quickly switch to select and copy relevant snippets of code for tiddlers, than by re-opening this tiddler..

[[Iframe template]]
{{{
@@font-size:90%;''Note'': This is a "framed" page from the '' '' web site.
You can view this page in a separate browser tab or window at @@
<html><iframe
	src = ""
	title = ""
	style="
		background-color:#ffffff; 
		border-color:#ffffff;
		border:none;"
	width = "100%"
	height = "1000"
	frameborder = "0"
	scrolling = "yes">
</iframe></html>
}}}

''Iframe template for [[UN Documents Cooperation Circles|UN Documents Cooperation Circles: Gathering a Body of Global Agreements]] 
{{{
@@font-size:90%;''Note'': This is a "framed" page from the [[UN Documents Cooperation Circles|UN Documents Cooperation Circles: Gathering a Body of Global Agreements]] web site.
You can view this page in a separate browser tab or window at http://www.un-documents.net/@@
<html><iframe
	title = ""
	src = "http://www.un-documents.net/"
	style="
		background-color:#ffffff; 
		border-color:#ffffff;
		border:none;"
	width = "100%"
	height = "1000"
	frameborder = "0"
	scrolling = "yes">
</iframe></html>
}}}

[[Tag templates]]

{{{
The '' '' tag is for tiddlers and tags relating to

|<<siteMap >> |<<siteMap >> |


The '' '' tag is for tiddlers and tags relating to

|<<siteMap >> |<<siteMap >> |<<siteMap >> |


The '' '' tag is for tiddlers and tags relating to

|<<siteMap >> |<<siteMap >> |<<siteMap >> |<<siteMap >> |


}}}

This tiddler provides links to some of the tiddlers that control the layout, format, fonts, colours, etc. for a TiddlyWiki web page.
!!Templates
* [[PageTemplate]] - defines the overall organization and layout of the page
* [[ViewTemplate]] - defines the organization and layout of the display of tiddlers
* [[EditTemplate]] - defines the organization and layout of the tiddlers when they are being edited
!!Stylesheets
* [[StyleSheetLayout]] - defines the fonts, font sizes, margins, borders for the various "styles" used
** [[TagglyTaggingStyles]] - a set of imported styles that control the format by which the tiddler "tags" are presented
** [[Main Menu Styles]] - Styles for the Main Menu
** [[Custom Styles]]
* [[StyleSheetColors]] - defines the colour of fonts, background, borders, etc. for the various styles
!!Palette
* [[Colour Palette]] - displays a palette of colours - 
* [[ColorPalette]] - shadowed tiddler that defined the colours used in the StyleSheetColors tiddler
(function($){
	
	if(window.location.protocol == "file:") {
		config.options.txtTheme = "LocalTheme";
	}
	
})(jQuery);
[[LocalTheme]]
[[OnlineTheme]]
These tiddlers are included for their usefulness in administering, managing and editing this TiddlyWiki web page, and may be of interest to visitors who want to explore some of the unique design features of TiddlyWiki web pages, and perhaps to being developing your own TiddyWiki pages.  A central key to the genius of the design of TiddlyWiki is the way that virtually all aspects of a TiddlyWiki web page - organization and classification of the content, layout, format, colours, fonts, functions and features can be managed through tiddlers that define templates, styles or macros and features written in Javascript.
* [[Tiddler Lists]] 
** [[Alphabetical Tiddlers]] 
** [[Tiddler Timeline]]
** [[Shadow Tiddlers]] 
** [[Missing Tiddlers]] 
** [[Imported Tiddlers]] 
** [[Tiddler Tags]] 
** [[Included TiddlyWikis]] 
* [[Main Menu|MainMenu]] 
** [[Default Tiddlers|DefaultTiddlers]] 
* [[Import Tiddlers]] 
* [[Plugin Macros]] 
* [[Templates & Stylesheets]] 
** PageTemplate 
** ViewTemplate 
** EditTemplate 
** StyleSheetLayout 
** StyleSheetColors 
** [[Colour Palette]] 
* [[Formatting Tiddlers]] 
** [[Formatting Text]] 
** [[Headers & Outlines]] 
** [[Tiddly Links]] 
** [[Tables]] 
** [[Images]] 
TiddlyWiki offers many ways by which you can create list of tiddlers
* [[Alphabetical Tiddlers]] - a list of tiddlers in alphabetical order
* [[Tiddler Timeline]] - a list of tiddlers by date they were created or edited
* [[Shadow Tiddlers]] - tiddlers for which a default value is generated - either by TiddlyWiki itself, or by a plugin macro
* [[Missing Tiddlers]] - tiddlers that have not been defined, but that have been referenced in one or more other tiddlers
* [[Site Maps]] - 
<<tiddler TabTimeline>>
/***
| Name:|ToggleTagMacro|
| Description:|Makes a checkbox which toggles a tag in a tiddler|
| Version:|6.1.2|
| Date:|20-Oct-2006|
| Source:|http://tiddlyspot.com/mptw/#ToggleTagMacro|
| Author:|SimonBaird|
| License:|[[BSD open source license]]|
| CoreVersion:|2.1|
!Usage
{{{<<toggleTag }}}//{{{TagName TiddlerName LabelText}}}//{{{>>}}}
* TagName - the tag to be toggled, default value "checked"
* TiddlerName - the tiddler to toggle the tag in, default value the current tiddler
* LabelText - the text (gets wikified) to put next to the check box, default value is '{{{[[TagName]]}}}' or '{{{[[TagName]] [[TiddlerName]]}}}'
(If a parameter is '.' then the default will be used)

Examples:

|Code|Description|Example|h
|{{{<<toggleTag>>}}}|Toggles the default tag (checked) in this tiddler|<<toggleTag>>|
|{{{<<toggleTag TagName>>}}}|Toggles the TagName tag in this tiddler|<<toggleTag TagName>>|
|{{{<<toggleTag TagName TiddlerName>>}}}|Toggles the TagName tag in the TiddlerName tiddler|<<toggleTag TagName TiddlerName>>|
|{{{<<toggleTag TagName TiddlerName 'click me'>>}}}|Same but with custom label|<<toggleTag TagName TiddlerName 'click me'>>|
|{{{<<toggleTag . . 'click me'>>}}}|dot means use default value|<<toggleTag . . 'click me'>>|
(Note if TiddlerName doesn't exist it will be silently created)

!Known issues
* Doesn't smoothly handle the case where you toggle a tag in a tiddler that is current open for editing. Should it stick the tag in the edit box?

***/
//{{{

merge(config.macros,{

	toggleTag: {

		doRefreshAll: true,
		createIfRequired: true,
		shortLabel: "[[%0]]",
		longLabel: "[[%0]] [[%1]]",

		handler: function(place,macroName,params,wikifier,paramString,tiddler) {
			var tag = (params[0] && params[0] != '.') ? params[0] : "checked";
			var title = (params[1] && params[1] != '.') ? params[1] : tiddler.title;
			var defaultLabel = (title == tiddler.title ? this.shortLabel : this.longLabel);
			var label = (params[2] && params[2] != '.') ? params[2] : defaultLabel;
			var theTiddler =  title == tiddler.title ? tiddler : store.getTiddler(title);
			var cb = createTiddlyCheckbox(place, label.format([tag,title]), theTiddler && theTiddler.isTagged(tag), function(e) {
				if (!store.tiddlerExists(title)) {
					if (config.macros.toggleTag.createIfRequired) {
						var content = store.getTiddlerText(title); // just in case it's a shadow
						store.saveTiddler(title,title,content?content:"",config.options.txtUserName,new Date(),null);
					}
					else 
						return false;
				}
				//store.suspendNotifications(); 
				store.setTiddlerTag(title,this.checked,tag);
				//refreshDisplay(); 
				//store.resumeNotifications();
				return true;
			});
		}
	}
});

//}}}

/***
''TwHelpSearch'' for TiddlyWiki 2.0.x to 2.2.x
^^author: Morris S. Gray
source: http://twhelp.tiddlyspot.com/#TwHelpSearchPlugin
license: [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]^^

|>|>|>|<<search>> |
|>|>| look for in |>|>|
| <<option chkSearchTitles>> | <<option chkSearchText>> | <<option chkSearchTags>> | <<option chkHoldSearches>> |
| titles |  text  | tags | hold |

''A Plugin Tweak for:'' SearchOptionsPlugin
!!!!!Description
<<<
This plugin defines an alternative format for the SearchResults tiddler that is generated by the SearchOptionsPlugin . It presents the search results in tabular form numbering the rows; and showing the tiddler title, the size in bytes, and the tags.  It is ready to be used with the [[SortableGridPlugin|http://solo.dc3.com/tw/#SortableGridPlugin]] (check versions) so any column can be sorted; such as size in ascending or descending order.
<<<
!!!!!Installation
<<<
Import (or copy/paste) the following tiddlers into your ~TiddlyWiki:
* http://twhelp.tiddlyspot.com/#TwHelpSearchPlugin
*SearchOptionsPlugin from http://www.tiddlytools.com/#SearchOptionsPlugin
* Get more documentation here TwHelpSearchDoc or here:
* http://twhelp.tiddlyspot.com/#TwHelpSearchDoc
<<<
!!!!!Revision History
<<<

''2007.09.12  [1.0.6]''
Added overflow scroll to TWHelp-SearchResults for long titles or tags.
''2006.02.03  [1.0.5]''
Added facility for holding the results of multiple searches with tick box on dashboard.
''2006.02.02  [1.0.4]''
Added several options, cleaned up design.Planning one version basic and one with added options this is the added options version.
''2006.01.27  [1.0.3''
Added a column for the size of the text in each tiddler, this does not include the size of the title or tags.  Added overall TW statistics button requires TiddlerStatsPlugin.
''2006.01.23 [1.0.2 ]''
''a)''Changed function reportSearchResults(text,matches) to  window.reportSearchResults=function(text,matches)
''b)''Added a line so that Incremental Search is automatically disabled config.options.chkSearchIncremental=false; turn off key-by-key searching
''c)''Removed space inside parens. bgcolor(#fe8 )" to "bgcolor(#fe8)".  This
is what was causing IE to 'crap out' halfway through drawing the table
headings.
''d)''Added {{{config.options.chkSearchList=true;}}}
''2006.01.20 [1.0.1]''
ELS: reportSearchResults() definition moved to this Plugin Tweak tiddler and removed extranous code
''2006.01.19 [1.0.0]''
This is an adaptation of Eric Shulman's SearchOptionsPlugin. Adapted by MorrisGray to provide search results in table form. All the necessary controls for refining the search is provided within the table including slide-down access to AdvancedOptions.
<<<
!!!!!Code
***/

//{{{
if (config.options.chkSinglePageMode==undefined) config.options.chkSinglePageMode=false;
if (config.options.chkRegExpSearch==undefined) config.options.chkRegExpSearch=true;
if (config.options.chkSearchTitles==undefined) config.options.chkSearchTitles=false;
if (config.options.chkSearchText==undefined) config.options.chkSearchText=true;
if (config.options.chkSearchTags==undefined) config.options.chkSearchTags=false;
if (config.options.chkSearchTitlesFirst==undefined) config.options.chkSearchTitlesFirst=true;
if (config.options.chkSearchList==undefined) config.options.chkSearchList=true;
if (config.options.chkSearchIncremental==undefined) config.options.chkSearchIncremental=false;
if (config.options.chkToggleLinks==true) config.options.chkToggleLinks=false;
if (config.options.chkHoldSearches==undefined) config.options.chkHoldSearches=false;
if (config.options.chkSortTags==undefined) config.options.chkSortTags=false;

config.options.chkToggleLinks=false;
config.options.chkSinglePageMode=false;
config.options.chkHoldSearches=false;
config.options.chkSearchIncremental=false;
config.options.chkHttpReadOnly = false;
config.options.chkRegExpSearch=true;
config.options.chkSearchList=true;
config.options.chkToggleLinks=false;

config.shadowTiddlers.AdvancedOptions += "\n<<option chkHoldSearches>> Hold search results";


//}}}

//{{{

// Give the report a custom name
config.macros.search.reportTitle="TWHelp-SearchResults";

// Override default SearchOptionsPlugin formatting for SearchResults tiddler
window.reportSearchResults=function(text,matches)

{
  
        var title=config.macros.search.reportTitle
	config.macros.search.reportTitle;
	var q = config.options.chkRegExpSearch ? "/" : "'";
        if (!config.options.chkHoldSearches)  body="";

body+="\n|>|bgcolor(#8af):@@color(#000080):''"+config.macros.search.successMsg.format([matches.length,q+"{{{"+text+"}}}"+q])+"''@@|bgcolor(#8af):  @@color(#A00000): SearchHelp@@ "+"|"+"\n";
        body+="|>|>|bgcolor(#E3FFE3):<<search>> <<option chkSearchTitles>> Titles <<option chkSearchText>> Text <<option chkSearchTags>>Tags <<option chkHoldSearches>> Hold |"+"\n";
        body+="\n|&nbsp;|bgcolor(#8af): @@color(#000080):sort by: ''Titles''@@ |bgcolor(#8af): @@color(#000080): ''Size'' (bytes)@@ |bgcolor(#8af): @@color(#000080): ''Tags''@@ |h";
	for(var t=0;t<matches.length;t++) 
        body+="\n"+"| "+(t+1)+"|[["+matches[t].title+"]]| "+matches[t].text.length+"|"+matches[t].tags+"|";
        body+="\n";
       


	// create/update the tiddler
	var tiddler=store.getTiddler(title); if (!tiddler) tiddler=new Tiddler();
	tiddler.set(title,body,config.options.txtUserName,(new Date()),"excludeLists excludeSearch killbookmark");
	store.addTiddler(tiddler); story.closeTiddler(title);


	// render tiddler
	var oldprompt=config.macros.search.label;
	config.macros.search.label="search again"; // use alternate "search again" label
        story.displayTiddler(null,title,1); // force refresh
	config.macros.search.label=oldprompt;	// restore standard search label
}

//}}}
!!Basic Options
TiddlyWiki offers a number of "Interface Options" - using the {{{<<option>>}}} built-in macro - that allow you to customise some of the ways this web site behaves. The options you select are saved in your browser, and will remain in effect when you visit this site again.  Note that if you [[download this web site|Download this web site]], there are many more ways you can customize the site.
!!Display Options
<<<
''Font size'': You can increase the size of the font - of the tiddlers only, not the header of menu - by clicking on the ''+'', ''='' or ''-'' <<fontSize "font-size:">> displayed in the [[Hover Menu]] - on the right of the screen - or under ''User Options'' in the menu on the left.
''Full screen display'': You can switch back and forth between full screen display of tiddlers - i.e. without the menu being displayed - by clicking on the <<fullscreen>> in the [[Hover Menu]], or when you "mouse over" the space above the tags that are displayed here at the top right of each tiddler.
<<<
!!Search Options
This site incorporates a number of ''Search option'' - using the built-in search features of TiddlyWiki, supplemented with two plugin macros - [[SearchOptions plugin]] and [[TwHelpSearchPlugin]]
<<<
<<option chkSearchTitles>> Search in tiddler titles
<<option chkSearchText>> Search in tiddler text
<<option chkSearchTags>> Search in tiddler tags
<<option chkSearchTitlesFirst>> Search results show title matches first
<<option chkSearchList>> Search results show list of matching tiddlers
<<option chkSearchIncremental>> Incremental searching
<<option chkRegExpSearch>> RegExpSearch
<<option chkCaseSensitiveSearch>> Case Sensitive Search
<<<
!!Navigation Options
<<<
<<option chkAnimate>> Enable Animations
<<option chkToggleLinks>> Clicking on links to tiddlers that are already open causes them to close
^^(override with Control or other modifier key)^^
<<option chkOpenInNewWindow>> Open Links In New Window
<<<
!Editing Options
The ''Editing Options'' will only apply if you have [[downloaded this web site|Download this web site]], and open it from a local drive
!!Username
> Enter your username, that is recorded in any tiddlers you edit or create: <<option txtUserName>>
> Conventionally, TiddlyWiki developers suggest this be written as a WikiWord (eg JoeBloggs), however TiddlyWikiPerfect recommends a user name with separate elements, eg Firstname Lastname, a Nickname or an organizational name. 
<<<
<<option chkHttpReadOnly>> HideEditingFeatures when viewed over HTTP
<<option chkForceMinorUpdate>> Treat edits as MinorChanges by preserving date and time
^^(override with Shift key when clicking 'done' or by pressing Ctrl-Shift-Enter^^
<<option chkConfirmDelete>> Confirm Before Deleting a tiddler
Maximum number of lines in a tiddler edit box: <<option txtMaxEditRows>>
<<option chkInsertTabs>> Use tab key to insert tab characters instead of jumping to next field
<<<
!!Save Options
<<<
<<option chkSaveBackups>> Save Backups
<<option chkAutoSave>> Auto Save
<<option chkGenerateAnRssFeed>> Generate an Rss Feed
<<option chkSaveEmptyTemplate>> Save Empty Template - i.e. just TiddlyWiki, without any of the tiddlers
Folder name for backup files: <<option txtBackupFolder>>
<<option chkAutoSave>> Auto Save: When selected, the page will be saved each time you save a tiddler; note that it will slow down your editing, while it protects you from losing your work if your browser crashes. 
<<<
!!Private Settings: 
<<<
<<option chkUsePrivateSettings>> Use private settings. 
<<option chkMakeSettingPrivateWhenChanged>> Make setting private when changed.&#160;&#160;&#160;[[Show Settings]].
^^(Private settings are stored in this ~TiddlyWiki, shared settings are stored as cookies. For more information see the [[Settings documentation|SettingsPlugin Documentation]].)^^
<<<
!!Plugins
<<<
See [[Plugin Macros]] for information on the 3rd party plugin macros used in the web site.
<<<

The ''View ~ColorPalette'' tiddler uses the combination of a "template" - [[TemplateShowColor]] with the built-in [[TiddlerSlice]] feature that allows it to extract information  and display the [[RGB]] values and the display colour of the various elements of the ColorPalette. This tiddler uses the expression:
{{{<<tiddler [[TemplateShowColor]] with:{{store.getTiddlerSlice('ColorPalette','Background')}} Background>>}}}
for each of the colors that are defined and editable in the [[ColorPalette]]

The ''~TemplateShowColor'' tiddler consists of the following expression:
{{{@@font-family:courier new, monospace; ''$1'' @@@@padding-bottom: 5em;width: 25em;background-color: $1;&nbsp;@@ [[$2|ColorPalette]]}}}
however, it is displayed as follows, using the syntax {{{> <<tiddler TemplateShowColor>>}}}: Note the preceding {{{>}}} indents the line that follows.  For more information on why it displays that way, and to find out more about how to format the content of tiddlers, visit [[Formatting Tiddlers]].

> <<tiddler TemplateShowColor>>
<<<
<<tiddler [[TemplateShowColor]] with:{{store.getTiddlerSlice('ColorPalette','Background')}} Background>> 
<<tiddler [[TemplateShowColor]] with:{{store.getTiddlerSlice('ColorPalette','Foreground')}} Foreground>>
<<tiddler [[TemplateShowColor]] with:{{store.getTiddlerSlice('ColorPalette','PrimaryPale')}} PrimaryPale>>
<<tiddler [[TemplateShowColor]] with:{{store.getTiddlerSlice('ColorPalette','PrimaryLight')}} PrimaryLight>>
<<tiddler [[TemplateShowColor]] with:{{store.getTiddlerSlice('ColorPalette','PrimaryMid')}} PrimaryMid>>
<<tiddler [[TemplateShowColor]] with:{{store.getTiddlerSlice('ColorPalette','PrimaryDark')}} PrimaryDark>>
<<tiddler [[TemplateShowColor]] with:{{store.getTiddlerSlice('ColorPalette','SecondaryPale')}} SecondaryPale>>
<<tiddler [[TemplateShowColor]] with:{{store.getTiddlerSlice('ColorPalette','SecondaryLight')}} SecondaryLight>>
<<tiddler [[TemplateShowColor]] with:{{store.getTiddlerSlice('ColorPalette','SecondaryMid')}} SecondaryMid>>
<<tiddler [[TemplateShowColor]] with:{{store.getTiddlerSlice('ColorPalette','SecondaryDark')}} SecondaryDark>>
<<tiddler [[TemplateShowColor]] with:{{store.getTiddlerSlice('ColorPalette','TertiaryPale')}} TertiaryPale>>
<<tiddler [[TemplateShowColor]] with:{{store.getTiddlerSlice('ColorPalette','TertiaryLight')}} TertiaryLight>>
<<tiddler [[TemplateShowColor]] with:{{store.getTiddlerSlice('ColorPalette','TertiaryMid')}} TertiaryMid>>
<<tiddler [[TemplateShowColor]] with:{{store.getTiddlerSlice('ColorPalette','TertiaryDark')}} TertiaryDark>>
<<tiddler [[TemplateShowColor]] with:{{store.getTiddlerSlice('ColorPalette','Error')}} Error>>
<<<
<!--{{{-->

<div class='toolbar'>
	<span macro="showWhenTagged systemConfig">
		<span macro="toggleTag systemConfigDisable . '[[disable|systemConfigDisable]]'"></span>
	</span>
	<span style="padding:1em;"></span>
	<span macro='toolbar closeTiddler closeOthers'></span> <span class='toolbar' macro='newDocument  "label:print" "prompt:print an HTML snapshot of this tiddler"  nofilename  print  here'></span> <span macro='toolbar deleteTiddler refresh permalink fullscreen references newTiddler newJournal jump +editTiddler '></span>
</div>

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

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

<!-- <div class='subtitle'> 	<span macro='view modifier link'></span>, created <span macro='view created date [[YYYY.0MM.0DD]]'></span>, modified <span macro='view modified date [[YYYY.0MM.0DD]]'></span></div> -->

<div macro="showWhenExists ViewPanelTemplate">[[ViewPanelTemplate]]</div>

<div macro="hideWhen tiddler.tags.containsAny(['html','pre','systemConfig']) && !tiddler.text.match('{{'+'{')">
	<div class='viewer' macro='view text wikified'></div>
</div>
<div macro="showWhen tiddler.tags.containsAny(['html','pre','systemConfig']) && !tiddler.text.match('{{'+'{')">
	<div class='viewer'><pre macro='view text'></pre></div>
</div>

<div macro="showWhenExists ViewDashboardTemplate">[[ViewDashboardTemplate]]</div>

<div class="tagglyTagging" macro="tagglyTagging"></div>

<!--}}}-->
The following tiddlers provide an example of  how the appearance of a TiddlyWiki page can be made different depending on whether the page is viewed as a local file or over the Internet.  In this case, the Internet version does not display administrative / developer / editor items on the [[Main Menu|MainMenu]] & [[Hover Menu|HoverMenu]] when the page is viewed online. To view these items, download the page, and open it from a local drive. Thanks to Colm Britton, Jon Ronson  & Tobias Beer for help with this. Relevant tiddlers:
!! [[Add Class]]
: <<tiddler "Add Class">>
!![[StyleSheet]]
:  <<tiddler StyleSheet>>
/***
|Name|WikifyPlugin|
|Source|http://www.TiddlyTools.com/#WikifyPlugin|
|Version|1.0.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <<br>>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|substitute fields, slices, or computed values into wiki-syntax source and render results dynamically|
|Status| ALPHA - SUBJECT TO CHANGE - USE AT YOUR OWN RISK |

The "wikify" macro allows you to easily retrieve values from custom tiddler fields, tiddler slices, computed values (using javascript) or just plain old literals, and assemble them into small bits of generated wiki-syntax content that can be rendered directly into a tiddler, or used in the ViewTemplate or EditTemplate to add dynamically-generated content to each tiddler.
!!!!!Usage
<<<
The syntax for use in tiddlers:
{{{
<<wikify source value value value value ...>>
}}}
The syntax for use in templates:
{{{
<span macro='wikify source value value value value ...'></span>
}}}
where ''source'' specifies the wiki-syntax source,
followed by zero or more space-separated ''value'' parameters, specified using any of:
* ''"tiddlername::slicename"'' - a tiddler slice reference
* ''"fieldname@tiddlername"'' - a tiddler custom field reference
* ''"""{{config.options.txtUserName}}"""'' - evaluated javascript
* ''"none of the above"'' - literal text
When the initial ''source'' parameter contains //substitution markers// (using "%0" through "%9" character sequences), each value parameter is retrieved and embedded into the source content, replacing its corresponding marker.  If the ''source'' parameter does //not// contain any substitution markers, then all parameters are simply joined together for output.  Once the source and values have been assembled, the resulting content is then passed to the core wikify() parser to render and display it.

Notes:
* If a parameter is not recognized as fitting any of the above syntax, or if the slice/field referred to cannot be located, the reference will be inserted as literal text into the output
* When working with custom tiddler fields or tiddler slices, you can enter a special psuedo-tiddler name, ''@here'' (e.g., "fieldname@here") or ''here::'' (e.g., "here::slicename") to access custom fields and slices associated with the //current// tiddler.  This //relative// reference syntax can be particularly helpful when placed directly into a ViewTemplate and/or EditTemplate definition, where it can be applied automatically to each tiddler that is displayed.   Note: if you omit the ''@here'' portion of a field reference (e.g., just using "fieldname"), it is assumed to be a reference to a field in the current tiddler (i.e., it is treated as if you specified ''fieldname@here'').
<<<
!!!!!Examples
<<<
{{{
<<wikify [[This tiddler is: %0 using %1 bytes (last author: %2)]] title {{tiddler.text.length}} modifier>>
<<wikify [[The source of this plugin is: %0]] 'here::Source'>>
<<wikify [[The tiddler has been changed %0 times]] changecount@here>>
<<wikify [[The Primary Mid color is: @@background:%0;%0@@]] 'ColorPalette::PrimaryMid'>>
<<wikify [[This current user is: %0]] {{config.options.txtUserName}}>>
}}}
<<wikify [[This tiddler is: %0 using %1 bytes (last author: %2)]] title {{tiddler.text.length}} modifier>>
<<wikify [[The source of this plugin is: %0]] 'here::Source'>>
<<wikify [[The tiddler has been changed %0 times]] changecount@here>>
<<wikify [[The Primary Mid color is: @@background:%0;%0@@]] 'ColorPalette::PrimaryMid'>>
<<wikify [[This current user is: %0]] {{config.options.txtUserName}}>>
<<<
!!!!!Installation
<<<
import (or copy/paste) the following tiddlers into your document:
[[WikifyPlugin]]
<<<
!!!!!Revision History
<<<
''2007.06.22 [1.0.0]'' initial release
<<<
!!!!!Credits
<<<
This feature was developed by Eric L Shulman / ELS Design Studios
<<<
!!!!!Code
***/
//{{{
version.extensions.wikify= {major: 1, minor: 0, revision: 0, date: new Date(2007,6,22)};

config.macros.wikify={
	handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		var source=params.shift();
		var values=[];
		var out="";
		if (!source.match(/\%[0-9]/g)) // source param has no substitution markers, just join all params
			out=source+" "+params.join("");
		else { // source param has markers, get values and perform substitution
			while (p=params.shift()) values.push(this.getFieldReference(place,p));
			out=source.format(values);
		}
		wikify(out,place);
	},
	getFieldReference: function(place,p) { // where p is "slicename::tiddlername" or "fieldname@tiddlername" or "fieldname"
		if (typeof p != "string") return p; // literal non-string value... just return it...
		var parts=p.split(config.textPrimitives.sliceSeparator);
		if (parts.length==2) {// maybe a slice reference?
			var tid=parts[0]; var slice=parts[1];
			if (!tid || !tid.length || tid=="here") { // no target specified (or "here" placeholder), use containing tiddler
				tid=story.findContainingTiddler(place);
				if (tid) tid=tid.getAttribute("tiddler")
				else tid="SiteSlices"; // fallback for references from 'non-tiddler' areas (e.g, header, sidebar, etc.)
			}
			var val=store.getTiddlerSlice(tid,slice);  // get tiddler slice value
		}
		if (val==undefined) {// not a slice reference, or slice not found, maybe a field reference?
			var parts=p.split("@");
			var field=parts[0];
			if (!field || !field.length) field="checked"; // fallback for missing fieldname (e.g., "@tiddlername")
			var tid=parts[1];
			if (!tid || !tid.length || tid=="here") { // no target specified (or "here" placeholder), use containing tiddler
				tid=story.findContainingTiddler(place);
				if (tid) tid=tid.getAttribute("tiddler")
				else tid="SiteFields"; // fallback for references from 'non-tiddler' areas (e.g, header, sidebar, etc.)
			}
			var val=store.getValue(tid,field);
		}
		// not a slice, not a field, or slice/field not found... use original param value
		return val===undefined?p:val;
	}
}
//}}}
/***
|Name|''allTagsExcept''|h
|Author|[[Clint Checketts]]|
|Version|1.0 (2005.09.08)|
|Description|Lists all tags except for those specified.|
|Source|http://tiddlystyles.com/#AllTagsExceptMacro|
***/
/***
|Usage:|{{{<< allTagsExcept systemConfig excludeLists systemTiddlers >>}}} This will show all tags but those listed (e.g. systemConfig and systemTiddlers|

<<allTagsExcept systemConfig excludeLists systemTiddlers >>
***/
//{{{
version.extensions.allTagsExcept = {major: 0, minor: 1, revision: 0, date: new Date(2005,8,15)};
config.macros.allTagsExcept = {tooltip: "Show tiddlers tagged with '%0'",noTags: "There are no tags to display"};

config.macros.allTagsExcept.handler = function(place,macroName,params)
{
 var tags = store.getTags();
 var theTagList = createTiddlyElement(place,"ul",null,null,null);
 if(tags.length == 0)
 createTiddlyElement(theTagList,"li",null,"listTitle",this.noTags);
 for (var t=0; t<tags.length; t++) {
 var includeTag = true;
 for (var p=0;p<params.length; p++) if (tags[t][0] == params[p]) includeTag = false;
 if (includeTag){
 var theListItem =createTiddlyElement(theTagList,"li",null,null,null);
 var theTag = createTiddlyButton(theListItem,tags[t][0] + " (" + tags[t][1] + ")",this.tooltip.format([tags[t][0]]),onClickTag);
 theTag.setAttribute("tag",tags[t][0]);
 }
 }
}
//}}}
/***
|Name|''fontSize''|h
|Author|[[Saq Imtiaz]]|
|Version|1.0|
|Description|Resize tiddler text on the fly. The text size is remembered between sessions by use of a cookie.|
|Source|http://lewcid.googlepages.com/lewcid.html#FontSizePlugin|
|TW Version|2.x|
***/
/***
You can customize the maximum and minimum allowed sizes. (only affects tiddler content text, not any other text)|

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

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

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

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

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

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

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

!Code
***/

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

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

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

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

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

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

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

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

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

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

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

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

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

config.paramifiers.font =
{
               onstart: function(v)
                  {
                   config.options.txtFontSize = v;
                   config.macros.fontSize.setFont();
                  }
};
//}}}
/***
|Name|''fullscreen''|h
|Author|[[Saq Imtiaz]]|
|Version|1.1|
|Description|Toggle between viewing tiddlers fullscreen and normally. Very handy for when you need more viewing space.|
|Source|http://lewcid.googlepages.com/lewcid.html#FullScreenPlugin|
|TW Version|2.x|
***/
/***
!Demo:
Click the ↕ button in the toolbar for this tiddler. Click it again to turn off fullscreen.

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

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

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

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

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

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

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


Slider.prototype.lewcidStop = Slider.prototype.stop;
Slider.prototype.stop = function()
{
           this.lewcidStop();
           if (story.isEmpty() && lewcidFullScreen == true)
              config.commands.fullscreen.handler();
}
//}}}
{{iframe{''Note'': This is a "framed" page from the '' '' web site. You can click on <<fullscreen>> to toggle full-screen mode, or you can view this page in a separate browser tab or window at }}}
<html><iframe
	src = ""
	title = ""
	style="
		background-color:#ffffff; 
		border-color:#ffffff;
		border:none;"
	width = "100%"
	height = "1000"
	frameborder = "0"
	scrolling = "yes">
</iframe></html>
|<html> </html>| <br><br> photos. |
/***
|Name|''siteMap''|h
|Author|[[Simon Baird]]|
|Version|1.0.3 (2006.03.15)|
|Description|Displays a Site Map|
|Syntax|{{{<<siteMap tiddlertitle>>}}}|
|Source|http://mptw2.tiddlyspot.com/#SiteMapMacro|
***/
/***
!!Examples
See SiteMap and SliderSiteMap for example usage.

!!Parameters
* Name of tiddler to start at
* Max depth (a number) 
* Format (eg, nested, see formats below)
* Don't show root flag (anything other than null turns it on)
* Tags - a string containing a bracketed list of tags that we are interested in

!!History
* 1.0.3 (15-Mar-06)
** added tag filtering
* 1.0.2 (15-Mar-06)
** Added json format and dontshowroot option
* 1.0.1 (9-Mar-06)
** Added selectable formats and fixed nested slider format
* 1.0.0 (8-Mar-06)
** first release

***/
//{{{

version.extensions.SiteMapMacro = {
major: 1,
minor: 0,
revision: 3,
date: new Date(2006,3,15),
source: "http://simonbaird.com/mptw/#SiteMapMacro"
};

config.macros.siteMap = {

formats: {
bullets: {
formatString: "%0[[%1]]\n%2",
indentString: "*"
},

// put this in your StyleSheet to make it look good.
// .sliderPanel { margin-left: 2em; }

sliders: {
formatString: "[[%1]]+++\n%2===\n\n",
formatStringLeaf: "[[%1]]\n"
},

openSliders: {
formatString: "[[%1]]++++\n%2===\n\n",
formatStringLeaf: "[[%1]]\n"
},

popups: {
formatString: "[[%1]]+++^\n%2===\n\n",
formatStringLeaf: "[[%1]]\n"
},

// these don't work too well
openPopups: {
formatString: "[[%1]]++++^\n%2===\n\n",
formatStringLeaf: "[[%1]]\n"
},

// this is a little nuts but it works
json: {
formatString: '\n%0{"%1":[%2\n%0]}',
formatStringLeaf: '\n%0"%1"',
indentString: "  ",
separatorString: ","
}


},

defaultFormat: "bullets",

treeTraverse: function(title,depth,maxdepth,format,dontshowroot,tags,excludetags) {

var tiddler = store.getTiddler(title);
var tagging = store.getTaggedTiddlers(title);

if (dontshowroot)
depth = 0;

var indent = "";
if (this.formats[format].indentString)
for (var j=0;j<depth;j++)
indent += this.formats[format].indentString;

var childOutput = "";
if (!maxdepth || depth < parseInt(maxdepth)) 
for (var i=0;i<tagging.length;i++)
if (tagging[i].title != title) {
if (this.formats[format].separatorString && i != 0)
childOutput += this.formats[format].separatorString;
childOutput += this.treeTraverse(tagging[i].title,depth+1,maxdepth,format,null,tags,excludetags);
}

if (childOutput == "" && (
(tags && tags != "" && !tiddler.tags.containsAll(tags.readBracketedList())) ||
(excludetags && excludetags != "" && tiddler.tags.containsAny(excludetags.readBracketedList()))
)
) {
// so prune it cos it doesn't have the right tags and neither do any of it's children
return "";
}

if (dontshowroot)
return childOutput;

if (this.formats[format].formatStringLeaf && childOutput == "") {
// required for nestedSliders
return this.formats[format].formatStringLeaf.format([indent,title,childOutput]);
}

return this.formats[format].formatString.format([indent,title,childOutput]);
},

handler: function (place,macroName,params,wikifier,paramString,tiddler) {
wikify(this.treeTraverse(
params[0] && params[0] != '.' ? params[0] : tiddler.title, 1, 
params[1] && params[1] != '.' ? params[1] : null, // maxdepth
params[2] && params[2] != '.' ? params[2] : this.defaultFormat, // format
params[3] && params[3] != '.' ? params[3] : null, // dontshowroot
params[4] && params[4] != '.' ? params[4] : null, // tags
params[5] && params[5] != '.' ? params[5] : null // excludetags
),place);
}

}

//}}}
The ''systemConfig'' tag is used for [[Plugin Macros]] and instructs TiddlyWiki to include the plugin in its Javascript engine when the web page is loaded.

|<<siteMap >> |<<siteMap tiddlywiki>> |<<siteMap javascript>> |