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
<!--{{{-->
<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>>
<<importTiddlers>>
<!--{{{-->
<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml' />
<!--}}}-->
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]]
<!--{{{-->
<div class='header' role='banner' 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' role='navigation' refresh='content' tiddler='MainMenu'></div>
<div id='sidebar'>
<div id='sidebarOptions' role='navigation' refresh='content' tiddler='SideBarOptions'></div>
<div id='sidebarTabs' role='complementary' refresh='content' force='true' tiddler='SideBarTabs'></div>
</div>
<div id='displayArea' role='main'>
<div id='messageArea'></div>
<div id='tiddlerDisplay'></div>
</div>
<!--}}}-->
/*{{{*/
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]];}

.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:0; top:0;}

.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:0 3px 0 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:0; padding-bottom:0;}

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

.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='toolbar' role='navigation' 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>
<!--}}}-->
/***
|''Name''|ImageMacroPlugin|
|''Version''|0.9.4|
|''Description''|Allows the rendering of svg images in a TiddlyWiki|
|''Author''|Osmosoft|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''Notes''|Currently only works in modern browsers (not IE)|
|''Requires''|BinaryTiddlersPlugin|
!Usage
{{{<<image SVG>>}}} will render the text of the tiddler with title SVG as an SVG image (but not in ie where it will fail silently)
!!Parameters
width/height: specify width/height parameters
link: make the image link to a given location
tiddlyLink: link to a tiddler

!Notes
Binary tiddlers in TiddlyWeb when passed through the wikifier will be shown as images.
eg. {{{<<view text wikified>>}}} on a binary tiddler will show the image.
{{{<<view fieldname image>>}}}
will render the value of the tiddler field 'fieldname' as an image. This field can contain a tid
{{{<<image SiteIcon>>}}}
will create an image tag where the tiddler has content type beginning image and not ending +xml
will attempt to create svg object in other scenarios
{{{<<image /photos/x.jpg>>}}}
will create an image tag with src /photos/x.jpg as long as there is not a tiddler called /photos/x.jpg in 
which case it will render that tiddler as an image. Note for the case of svg files it will attempt to render as an svg if possible via the image
tag. It doesn't embed the svg in the dom for security reasons as svg code can contain javascript.
!Code
***/
//{{{
(function($) {

var macro = config.macros.image = {
	shim: "/bags/common/tiddlers/shim",
	ieVersion: config.browser.isIE ? parseInt(config.browser.ieVersion[1], 10) : false,
	svgns: "http://www.w3.org/2000/svg",
	xlinkns: "http://www.w3.org/1999/xlink", 
	svgAvailable: document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"),
	_fixPrefix: 1,
	_external_cache: {},
	_image_tag_cache: {},
	_image_dimensions: {},
	locale: {
		badImage: "This image cannot be displayed."
	},
	handler: function(place, macroName, params, wikifier, paramString, tiddler){
		var imageSource = params[0];
		// collect named arguments
		var args = macro.getArguments(paramString, params);
		this.renderImage(place, imageSource, args);
	},
	init: function() {
		var startupImages = store.getTaggedTiddlers("systemImage");
		var place = $("<div />").attr("id", "systemImageArea").appendTo("body").hide()[0];
		for(var i = 0; i < startupImages.length; i++) {
			var image = startupImages[i];
			macro.renderImage(place, image.title, { idPrefix: "" });
		}
		var data = new Image();
		data.onload = function() {
			// note ie 8 only supports data uris up to 32k so cannot be relied on
			macro.supportsDataUris = this.width != 1 || this.height != 1 ? false : true;
			macro.supportsDataUris = macro.ieVersion && macro.ieVersion < 9 ? false : macro.supportsDataUris;
		};
		data.onerror = data.onload;
		data.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
	},
	refreshImage: function(src) {
		var elements = macro._image_tag_cache[src] ? macro._image_tag_cache[src] : [];
		if(macro._image_dimensions[src]) {
			macro._image_dimensions[src] = false;
		}
		for(var i = 0; i < elements.length; i++) {
			var el = $(elements[i]);
			var newSrc = "%0?nocache=%1".format(src, Math.random());
			el.attr("src", newSrc); // force reload
		}
	},
	isBinaryImageType: function(contentType) {
		return (contentType && contentType.indexOf("image") === 0 &&
			contentType.indexOf("+xml") != contentType.length - 4) ? true : false;
	},
	isImageTiddler: function(tiddler) {
		return macro.isSVGTiddler(tiddler) || macro.isBinaryImageTiddler(tiddler);
	},
	isSVGTiddler: function(tiddler) {
		var type = tiddler ? tiddler.fields['server.content-type'] : false;
		return type == "image/svg+xml";
	},
	isBinaryImageTiddler: function(tiddler) {
		return macro.isBinaryImageType(tiddler.fields['server.content-type']);
	},
	renderImage: function(place, imageSource, options) {
		var imageTiddler = store.getTiddler(imageSource);
		var container;
		var classes = ["image"];
		if(options.link) {
			classes = classes.concat(["imageLink", "externalLink"]);
			container = $("<a />").attr("href", options.link).appendTo(place)[0];
		} else if(options.tiddlyLink) {
			classes.push("imageLink");
			container = createTiddlyLink(place, options.tiddlyLink, false);
		} else {
			container = $("<span />").appendTo(place)[0];
		}
		$(container).addClass(classes.join(" "));

		options = options ? options : {};
		if(imageTiddler && macro.isBinaryImageTiddler(imageTiddler)) { // handle the case where we have an image url
			return macro._renderBinaryImageTiddler(container, imageTiddler, options);
		} else if(imageTiddler){ // handle the case where we have a tiddler
			return macro._renderSVGTiddler(container, imageTiddler, options);
		} else { // we have a string representing a url
			return macro._renderBinaryImageUrl(container, imageSource, options);
		}
	},
	_renderAlternateText: function(container, options) {
		var img;
		var src = options.src || "";
		if(options.width && options.height) {
			img = $("<img />").attr("src", src).addClass("svgImageText").attr("width", options.width).
				attr("height", options.height).appendTo(container);
		}
		var alt = options.alt;
		if(img && alt) {
			img.attr("alt", alt).attr("title", alt);
		} else if(alt) {
			$(container).addClass("svgImageText").text(alt);
		}
		macro._image_tag_cache[src] = img;
	},
	_renderSVGTiddler: function(place, tiddler, options) {
		if(!options) {
			options = {};
		}
		merge(options, { tiddler: tiddler, fix: true});

		if(macro.svgAvailable) {
			this._importSVG(place, options); // display the svg
		} else if(options.altImage) {
			var image = options.altImage;
			delete options.altImage;
			this._renderBinaryImageUrl(place, image, options);
		} else {
			this._renderAlternateText(place, options); // instead of showing the image show the alternate text.
		}
	},
	_renderBinaryImageTiddler: function(place, tiddler, options) {
		var resourceURI;
		var fields = tiddler.fields;
		if(fields["server.type"] == "tiddlyweb") { // construct an accurate url for the resource
			resourceURI = "%0/%1/tiddlers/%2".format(config.defaultCustomFields["server.host"],
				fields["server.workspace"], encodeURI(fields["server.title"]));
		} else { // guess the url for the resource
			resourceURI = tiddler.title;
		}
		var ctype = fields["server.content-type"] || tiddler.type;
		var text = tiddler.text;
		if(macro.supportsDataUris && ctype && text.indexOf("<html") == -1) {
			var uri = "data:%0;base64,%1".format(ctype, text);
			options.src = resourceURI;
			return macro._renderBinaryImageUrl(place, uri, options);
		} else if(options.src) {
			return macro._renderBinaryImageUrl(place, options.src, options);
		} else {
			return macro._renderBinaryImageUrl(place, resourceURI, options);
		}
	},
	_renderImageTag: function(container, src, width, height, options) {
		var img;
		img = $("<img />").appendTo(container);
		if(height) {
			img.attr("height", height);
		}
		if(width) {
			img.attr("width", width);
		}
		if(macro.ieVersion && macro.ieVersion < 7 && macro.shim && options.ie6png) {
			$(img).css({width: userW, height: userH,
					filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='%0', sizingMethod='scale')".format(src)
				}).attr("src", macro.shim);
		} else {
			img.attr("src", src);
		}
		if(!macro._image_tag_cache[options.srcUrl]) {
			macro._image_tag_cache[options.srcUrl] = [];
		}
		img = $(img).addClass(options.imageClass)[0];
		macro._image_tag_cache[options.srcUrl].push(img);
		return img;
	},
	_getDimensions: function(realDimensions, reqDimensions, preserve) {
		var w = realDimensions.width;
		var h = realDimensions.height;
		var reqh = reqDimensions.height;
		var reqw = reqDimensions.width;
		var finalw = w, finalh = h;
		var ratiow = reqw / w, ratioh = reqh / h;
		var scaledw = ratioh * w;
		var scaledh = ratiow * h;
		if(!reqw && reqh) {
			finalw = scaledw;
			finalh = reqh;
		} else if(reqw && !reqh) {
			finalw = reqw;
			finalh = scaledh;
		} else if(reqh && reqw) {
			var preserveWidth = w > h ? true : false;
			if(preserve) {
				if(preserveWidth && scaledh < reqh) {
					finalh = scaledh;
					finalw = reqw;
				} else {
					finalh = reqh;
					finalw = scaledw;
				}
			} else {
				finalw = reqw;
				finalh = reqh;
			}
		}
		return { width: parseInt(finalw, 10), height: parseInt(finalh, 10) };
	},
	_renderBinaryImageUrl: function(container, src, options) {
		var srcUrl = options.src ? options.src : src;
		srcUrl = srcUrl.indexOf("/") === -1 ? "/%0".format(srcUrl) : srcUrl; // for IE. 
		var image_dimensions = macro._image_dimensions[srcUrl];
		var image = new Image(); // due to weird scaling issues where you use just a width or just a height
		var createImageTag = function(dimensions, error) {
			if(error) {
				var altImage = options.altImage;
				if(altImage) {
					delete options.altImage;
					macro._renderBinaryImageUrl(container, altImage, options);
				} else {
					options.src = src;
					macro._renderAlternateText(container, options);
				}
			} else {
				var dim = macro._getDimensions(dimensions, { 
					width: options.width, height: options.height }, options.preserveAspectRatio);
				options.srcUrl = srcUrl;
				macro._renderImageTag(container, src, dim.width, dim.height, options);
			}
		};

		if(!image_dimensions) {
			image.onload = function() {
				var dimensions = { width: image.width, height: image.height};
				macro._image_dimensions[srcUrl] = dimensions;
				createImageTag(dimensions);
			};
			image.onerror = function() {
				createImageTag(null, true);
			};
			image.src = src;
		} else {
			createImageTag(image_dimensions);
		}
	},
	_generateIdPrefix: function(){
		return "twsvgfix_" + (this._fixPrefix++).toString() + "_";
	},
	_fixSVG: function(childNodes, idPrefix) {
		var urlPattern = /url\(\#([^\)]*)\)*/ig;
		var fixes = [
		{ attr: "id", pattern: /^(.*)$/ig },
		{ attr: "href", namespace: macro.xlinkns, pattern: /^#(.*)$/ig }
		];
		var url_fixes = ["filter", "fill", "mask", "stroke", "style"];
		for(var i = 0; i < url_fixes.length; i++) {
			fixes.push({ attr: url_fixes[i], pattern: urlPattern });
		}
		for(var t = 0; t < childNodes.length; t++) {
			var node = childNodes[t];
			for(var a = 0; a < fixes.length; a++) {
				var fix = fixes[a];
				var attr = fix.attr;
				var ns = fix.namespace || "";
				if(node.hasAttributeNS && node.hasAttributeNS(ns, attr)) {
					var v = node.getAttributeNS(ns, attr);
					fix.pattern.lastIndex = 0;
					var match = fix.pattern.exec(v);
					if(match) {
						// Make sure replacement string doesn't contain any single dollar signs
						var toReplace = match[1];
						if(toReplace.indexOf(idPrefix) !== 0 && toReplace.indexOf("twglobal_") !== 0) {
							var replacement = (idPrefix + toReplace).replace("$", "$$$$"); 
							v = v.replace(match[1], replacement);
						}
						node.setAttributeNS(ns, attr,v);
					}
				}
			}
			var children = node.childNodes;
			if(children.length > 0) {
				this._fixSVG(children, idPrefix);
			}
		}
	},
	_importSVG: function(place, options){
		options = options ? options : {};
		var svgDoc, tiddlerText = options.tiddler.text;
		if (window.DOMParser) {
			svgDoc = new DOMParser().parseFromString(tiddlerText, "application/xml").documentElement;
			var idPrefix = options.idPrefix || this._generateIdPrefix();
			this._fixSVG([svgDoc], idPrefix);
			var el = document.importNode(svgDoc, true);
			var svgHolder = document.createElementNS(macro.svgns,"svg");
			var width = options.width;
			var height = options.height;
			if(width || height) {
				if(width && height) { // set view box of containing svg element based on the svg viewbox and width and height.
					var viewBox = el.getAttribute("viewBox");
					var topLeft = "0 0";
					if(viewBox) {
						topLeft = viewBox.replace(/([0-9]*) +([0-9]*) +([0-9]*) +([0-9]*) */gi,"$1 $2");
					}
					svgHolder.setAttributeNS(macro.svgns, "viewBox", "0 0 %0 %1".format(width, height));
				} else {
					if(!width) {
						width = el.getAttribute("width");
					}
					if(!height) {
						height = el.getAttribute("height");
					}
				}
				svgHolder.setAttribute("width", width);
				svgHolder.setAttribute("height", height);

				el.setAttribute("width", "100%");
				el.setAttribute("height", "100%");
				svgHolder.setAttribute("class", "svgImage svgIcon %0".format(options.imageClass || ""));
				svgHolder.appendChild(el);
				place.appendChild(svgHolder);
			}
			else {
				var existing = el.className ? el.className.baseVal : "";
				el.setAttribute("class","svgImage %0".format(existing));
				place.appendChild(el);
			}
			// if a tiddler attribute is set this is read as a link
			$("[tiddler], [tiddlyLink]", place).attr("refresh", "link").click(function(ev) {
				var tiddler = $(ev.target).attr("tiddlyLink");
				if(tiddler) {
					story.displayTiddler(ev.target, tiddler);
				}
			});
		}
	},
	getArguments: function(paramString, params) {
		var args = paramString.parseParams("name", null, true, false, true)[0];
		var options = {};
		for(var id in args) {
			if(true) {
				var p = args[id];
				if(id == "def") {
					options[id] = p;
				} else {
					options[id] = p[0];
				}
			}
		}
		var width = isNaN(params[1]) ? false : parseInt(params[1], 10);
		var height = isNaN(params[2]) ? false : parseInt(params[2], 10);

		options.width = macro.lookupArgument(options, "width", width);
		options.height = macro.lookupArgument(options, "height", height);
		options.preserveAspectRatio = args.preserveAspectRatio && 
			args.preserveAspectRatio[0] == "yes" ? true : false;
		options.tiddlyLink = macro.lookupArgument(options, "tiddlyLink", false);
		options.link = macro.lookupArgument(options, "link", false);
		return options;
	},
	lookupArgument: function(args, id, ifEmpty) {
		return args[id] ? args[id] : ifEmpty;
	}
};

// update views
var _oldwikifiedview = config.macros.view.views.wikified;
// update wikifier to check tiddler type before rendering
merge(config.macros.view.views, {
	wikified: function(value, place, params, wikifier, paramString, tiddler) {
		if(macro.isImageTiddler(tiddler) && params[0] == "text") {
			var newplace = $("<div />").addClass("wikifiedImage").appendTo(place)[0];
			macro.renderImage(newplace, tiddler.title, { alt: macro.locale.badImage });
		} else {
			_oldwikifiedview.apply(this, arguments);
		}
	},
	image: function(value, place, params, wikifier, paramString, tiddler) {
		// a field can point to another tiddler whereas text is the current tiddler.
		var title = params[0] == "text" ? tiddler.title : value;
		var args = macro.getArguments(paramString, params);
		macro.renderImage(place, title, args);
	}
});
config.shadowTiddlers.StyleSheetImageMacro = [".wikifiedImage svg, .wikifiedImage .image { width: 80%; }",
	".svgImageText { background-color:[[ColorPalette::Error]]; color:#ddd; display: inline-block; }",
	"span.svgImageText { display: inline-block; overflow: hidden; }"
].join("");
store.addNotification("StyleSheetImageMacro", refreshStyles);

})(jQuery);
//}}}
tscount
|Date|Users|Spaces|Created|Modified|Tiddlertime|Searchtime|
|20130301|6770|10166|4685|4887|321.6|2840.56|
|20130302|6772|10169|116|200|327.2|2923.21|
|20130303|6779|10176|270|379|320.9|2866.33|
|20130304|6783|10183|410|680|328.8|2849.28|
|20130305|6798|10201|868|1152|332.6|3065.84|
|20130306|6805|10214|927|1100|320.7|3001.36|
|20130307|6817|10227|819|975|582.7|266.4|
|20130308|6820|10238|1100|1376|325|2970.13|
|20130309|6824|10244|251|544|316.3|3038.67|
|20130310|6828|10251|180|382|319|3161.15|
|20130311|6834|10256|344|441|5425.8|524.79|
|20130312|6838|10264|1058|1202|359.4|338.12|
|20130313|6840|10268|422|543|377|3402.79|
|20130314|6846|10277|677|778|317.8|5468.57|
|20130315|6852|10284|295|379|325.9|2911.51|
|20130316|6857|10290|234|395|322|316.98|
|20130317|6860|10294|99|184|347.6|361.73|
|20130318|6863|10298|119|202|631.3|3083.78|
|20130319|6870|10306|355|507|321.3|2926.3|
|20130320|6877|10327|716|835|5428.7|3058.46|
|20130321|6878|10331|99|164|559.5|3183.13|
|20130322|6888|10341|335|439|322.6|2989.93|
|20130323|6896|10348|161|260|351.2|2974.04|
|20130324|6902|10354|322|394|328|2894.42|
|20130325|6908|10361|237|371|341.3|3131.6|
|20130326|6914|10369|163|279|356.9|3070.22|
|20130327|6921|10378|876|1029|340|238.53|
|20130328|6935|10398|435|559|336.4|2956.8|
|20130329|6945|10413|673|805|325.6|7021.03|
|20130330|6948|10416|108|311|353.1|2848.48|
|20130331|6949|10419|445|525|322.8|2832.47|
/*{{{*/
Background: #f6e6de
Foreground: #201008
PrimaryPale: #e8bca7
PrimaryLight: #d68762
PrimaryMid: #b2582e
PrimaryDark: #28140a
SecondaryPale: #a7cae8
SecondaryLight: #62a0d6
SecondaryMid: #2e75b2
SecondaryDark: #0a1a28
TertiaryPale: #a7dde8
TertiaryLight: #62c2d6
TertiaryMid: #2e9cb2
TertiaryDark: #0a2328
Error: #f88
ColorPaletteParameters: HSL([19|9], [0.585999132366851],[0.1|0.7846414344385266])
/*}}}*/
Date|Users|Spaces|Created|Modified|Tiddlertime|Searchtime|
|20121101|6083|9237|324|419|310.7|2577.91|
|20121102|6088|9243|193|279|316.2|227.96|
|20121103|6098|9254|142|250|309.7|2564.16|
|20121104|6101|9260|154|227|313|7445.13|
|20121105|6106|9265|936|1235|480.5|2817.05|
|20121106|6114|9274|473|604|308.6|2551.81|
|20121107|6119|9280|411|703|313.6|207.73|
|20121108|6129|9295|282|418|312|2595.59|
|20121109|6136|9305|675|790|314.7|6724.4|
|20121110|6138|9307|89|184|317.5|212.74|
|20121111|6142|9311|165|260|1229.5|5473.94|
|20121112|6147|9318|1524|1657|311.9|2630.28|
|20121113|6154|9328|305|425|316.1|2664.34|
|20121114|6160|9335|223|305|312.5|2607.71|
|20121115|6165|9340|308|443|344.2|2734.58|
|20121116|6172|9350|190|2748|306|430.12|
|20121117|6176|9356|106|253|311.5|2750.48|
|20121118|6180|9360|128|322|316.4|2633.54|
|20121119|6183|9364|128|242|478.4|3296.74|
|20121120|6189|9372|1402|1560|307.8|17521.5|
|20121121|6198|9381|151|230|314.2|14275.1|
|20121122|6209|9394|353|495|310.7|7389.99|
|20121123|6213|9402|255|437|306.4|7646.3|
|20121124|6217|9408|1211|1803|314.2|6771.54|
|20121125|6222|9413|919|1807|330.9|2488.6|
|20121126|6227|9420|351|485|315.9|2639.09|
|20121127|6233|9442|623|729|327.1|2426.29|
|20121128|6247|9459|474|721|312.5|2587.84|
|20121129|6270|9483|472|686|318.4|270.85|
|20121130|6274|9488|825|929|318.4|2570.87|
This space provides some information on the number of users and spaces in TiddlySpace by integrating several facets:
* A series of shell scripts gathers data from the database on the server and then uses {{{curl}}} to PUT it to this space in SomeInfo. See SomeInfo2010 for historical data.
* The space includes @jquery-gchart to present a graph of the info via macro ChartTablePlugin
* Created and Modified are the number of tiddlers created or modified that day.

!Month by Month, past year
<<charttable SomeInfoWindow>>
!Month by Month
Since start of data
<<charttable SomeInfoMonthly>>
!2013
!!May
<<charttable>>
!!April
<<charttable SomeInfo201304>>
!!March
<<charttable SomeInfo201303>>
!!Feburary
<<charttable SomeInfo201302>>
!!January
<<charttable SomeInfo201301>>
!2012
!!December
<<charttable SomeInfo201212>>
!!November
<<charttable SomeInfo201211>>
!!October
<<charttable SomeInfo201210>>
!!September
<<charttable SomeInfo201209>>
!!August
<<charttable SomeInfo201208>>
!!July
<<charttable SomeInfo201207>>
!!June
<<charttable SomeInfo201206>>
!!May
<<charttable SomeInfo201205>>
!!April
<<charttable SomeInfo201204>>
!!March
<<charttable SomeInfo201203>>

@jquery-chart does not result in the slow script warnings that @charts does.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->

<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:xlink="http://www.w3.org/1999/xlink"
   version="1.1"
   width="14pt"
   height="14pt"
   viewBox="918 510 14 14"
   id="svg3070">
  <metadata
     id="metadata3089">
    <rdf:RDF>
      <cc:Work
         rdf:about="">
        <dc:format>image/svg+xml</dc:format>
        <dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
        <dc:title></dc:title>
      </cc:Work>
    </rdf:RDF>
  </metadata>
  <defs
     id="defs3072">
    <radialGradient
       cx="0"
       cy="0"
       r="1"
       id="Gradient"
       gradientUnits="userSpaceOnUse">
      <stop
         id="stop3075"
         style="stop-color:#ffffff;stop-opacity:1"
         offset="0" />
      <stop
         id="stop3077"
         style="stop-color:#2b2b2b;stop-opacity:1"
         offset="1" />
    </radialGradient>
    <radialGradient
       id="Obj_Gradient"
       xlink:href="#Gradient"
       gradientTransform="matrix(11.473944,0,0,11.473944,922.3752,513.7837)" />
  </defs>
  <g
     id="g3080"
     style="fill:none;stroke:none">
    <g
       id="g3082">
      <path
         d="m 929.6952,512.9018 c -2.5384,-2.53843 -6.654,-2.53843 -9.1924,0 -2.5384,2.5384 -2.5384,6.654 0,9.19238 2.5384,2.53839 6.654,2.53839 9.1924,0 2.5384,-2.53838 2.5384,-6.65398 0,-9.19238 m -4.5962,2.8407 2.07733,-2.07734 1.75547,1.75549 -2.0773,2.07735 2.0773,2.07732 -1.75547,1.75548 -2.07733,-2.07732 -2.07733,2.07732 -1.75547,-1.75548 2.0773,-2.07732 -2.0773,-2.07735 1.75547,-1.75549 z"
         id="path3084"
         style="fill:url(#Obj_Gradient)" />
      <path
         d="m 927.61447,515.38354 a 4.51205,4.2590378 0 1 1 -9.0241,0 4.51205,4.2590378 0 1 1 9.0241,0 z"
         transform="matrix(1.0218069,0,0,1.0462046,-18.063694,-21.648443)"
         id="path2394"
         style="fill:#000000;fill-opacity:0;fill-rule:evenodd;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
    </g>
  </g>
</svg>
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
<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="100%" width="100%" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" viewBox="0 0 40 40"><metadata><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/><dc:title/></cc:Work></rdf:RDF></metadata><defs><linearGradient id="lG3826" x1="7.0996" gradientUnits="userSpaceOnUse" y1="18.829" gradientTransform="matrix(1.5858347,0,0,1.8078238,1098.1851,351.13716)" x2="1.5461" y2="-0.95166"><stop stop-color="#000" offset="0"/><stop stop-color="#9c9b99" offset="1"/></linearGradient><linearGradient id="lG3828" y2="372.44" gradientUnits="userSpaceOnUse" y1="375.7" x2="1111.7" x1="1097.7"><stop style="stop-color:#ac9393;" offset="0"/><stop style="stop-color:#c8b7b7;" offset="1"/></linearGradient></defs><g transform="translate(-1080.9375,-357.3329)"><path style="stroke-width:0;stroke-miterlimit:4;fill:url(#lG3826);" d="m1080.9,357.32,39.996-0.0426-0.01,40.008c-15.507-25.519-15.36-25.95-39.988-39.965z"/><path style="stroke-dashoffset:0;stroke:#7aa3be;stroke-linecap:round;stroke-miterlimit:4;stroke-width:1.49999988;fill:#c1e6fd;" d="m1091.9,363.55c6.5716-6.4925,16.576-7.3925,23.147-0.90003,6.5717,6.4925,6.5717,17.019,0,23.511-4.4424-8.6113-12.288-15.713-23.147-22.611z"/><path style="stroke-dashoffset:0;stroke:#ce81b0;stroke-linecap:round;stroke-miterlimit:4;stroke-width:1.5;fill:#f4c4e2;" d="m1110.2,367.62c3.217,3.2168,3.217,8.4323,0,11.649-3.8194-4.2357-8.3307-8.1824-11.649-11.649,3.217-3.2168,8.4325-3.2168,11.649-0.00002z"/><path style="stroke-linejoin:bevel;stroke:#000000;stroke-linecap:round;stroke-dasharray:none;stroke-miterlimit:4;stroke-width:0.80000001;fill:url(#lG3828);" d="m1081,357.34c18.79,6.4752,32.53,16.56,39.894,39.892-11.19-17.028-14.878-19.19-27.352-14.96,6.2984-12.098,3.9371-13.19-12.542-24.932z"/></g></svg>
|Date|Users|Spaces|
|20110201|960|2247|
|20110202|962|2251|
|20110203|963|2255|
|20110204|964|2256|
|20110205|965|2259|
|20110206|965|2260|
|20110207|966|2263|
|20110208|967|2267|
|20110209|968|2270|
|20110210|977|2284|
|20110211|982|2293|
|20110212|986|2301|
|20110213|991|2309|
|20110214|994|2319|
|20110215|996|2322|
|20110216|1002|2331|
|20110217|1007|2343|
|20110218|1013|2348|
|20110219|1018|2357|
|20110220|1024|2364|
|20110221|1030|2373|
|20110222|1035|2383|
|20110223|1039|2389|
|20110224|1042|2394|
|20110225|1047|2402|
|20110226|1048|2404|
|20110227|1050|2407|
|20110228|1051|2409|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<title>jQuery Google Chart</title>
<style type="text/css">
#basicGChart { width: 450px; height: 300px }
</style>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
<script type="text/javascript" src="/jquery.gchart"></script>
<script type="text/javascript">
$(function () {
	$('#basicGChart').gchart({type: 'line', maxValue: 40,
		title: 'Weather for|Brisbane, Australia', titleColor: 'green',
		backgroundColor: $.gchart.gradient('horizontal', 'ccffff', 'ccffff00'),
		series: [$.gchart.series('Max', [29.1, 28.9, 28.1, 26.3,
		23.5, 21.2, 20.6, 21.7, 23.8, 25.6, 27.3, 28.6], 'red', 'ffcccc'),
		$.gchart.series('Min', [20.9, 20.8, 19.5, 16.9,
		13.8, 10.9, 9.5, 10.0, 12.5, 15.6, 18.0, 19.8], 'green'),
		$.gchart.series('Rainfall', [157.7, 174.6, 138.5, 90.4,
		98.8, 71.2, 62.6, 42.7, 34.9, 94.4, 96.5, 126.2], 'blue', 0, 200)],
		axes: [$.gchart.axis('bottom', ['Jan', 'Feb', 'Mar', 'Apr',
		'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], 'black'),
		$.gchart.axis('left', 0, 40, 'red', 'right'),
		$.gchart.axis('left', ['C'], [50], 'red', 'right'),
		$.gchart.axis('right', 0, 200, 50, 'blue', 'left'),
		$.gchart.axis('right', ['mm'], [50], 'blue', 'left')],
		legend: 'right'});
});
</script>
</head>
<body>
<h1>jQuery Google Chart Basics</h1>
<p>This page demonstrates the very basics of the
	<a href="http://keith-wood.name/gChart.html">jQuery Google Chart plugin</a>.
	It contains the minimum requirements for using the plugin and
	can be used as the basis for your own experimentation.</p>
<p>For more detail see the <a href="http://keith-wood.name/gChartRef.html">documentation reference</a> page.</p>
<div id="basicGChart"></div>
</body>
</html>
|Date|Users|Spaces|
|20110901|2849|5038|
|20110902|2855|5046|
|20110903|2871|5066|
|20110904|2878|5075|
|20110905|2886|5084|
|20110906|2895|5093|
|20110907|2912|5111|
|20110908|2919|5119|
|20110909|2937|5140|
|20110910|2959|5165|
|20110911|2968|5174|
|20110912|2983|5193|
|20110913|2990|5202|
|20110914|3003|5219|
|20110915|3015|5236|
|20110916|3020|5243|
|20110917|3028|5253|
|20110918|3035|5261|
|20110919|3044|5275|
|20110920|3054|5290|
|20110921|3063|5303|
|20110922|3079|5326|
|20110923|3095|5345|
|20110924|3169|5419|
|20110925|3186|5436|
|20110926|3197|5450|
|20110927|3212|5465|
|20110928|3235|5489|
|20110929|3245|5500|
|20110930|3255|5513|
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
|Date|Users|Spaces|
|20110301|1060|2422|
|20110302|1064|2428|
|20110303|1072|2444|
|20110304|1076|2449|
|20110305|1085|2460|
|20110306|1088|2468|
|20110307|1091|2471|
|20110308|1101|2488|
|20110309|1110|2503|
|20110310|1114|2509|
|20110311|1126|2529|
|20110312|1133|2539|
|20110313|1138|2546|
|20110314|1138|2549|
|20110315|1149|2563|
|20110316|1161|2581|
|20110317|1171|2594|
|20110318|1180|2611|
|20110319|1183|2617|
|20110320|1188|2625|
|20110321|1193|2635|
|20110322|1201|2644|
|20110323|1211|2663|
|20110324|1212|2675|
|20110325|1217|2686|
|20110326|1226|2700|
|20110327|1232|2708|
|20110328|1237|2715|
|20110329|1247|2732|
|20110330|1260|2754|
|20110331|1279|2776|
/***
|''Name''|TiddlySpaceSearcher|
|''Version''|0.2.5|
|''Requires''|TiddlySpaceConfig TiddlySpaceFollowingPlugin|
***/
//{{{
(function($) {
var tiddlyspace = config.extensions.tiddlyspace;
var tsScan = config.macros.tsScan;

config.shadowTiddlers.SearchTemplate = "<<view server.bag SiteIcon label:no width:24 height:24 preserveAspectRatio:yes>> <<view server.bag spaceLink title external:no>> in space <<view server.bag spaceLink>>";
config.shadowTiddlers.StyleSheetSearch = [".resultsArea .siteIcon { display: inline; }",
	".searchForm {text-align: left;}"].join("\n");
store.addNotification("StyleSheetSearch", refreshStyles);

var search = config.macros.tsSearch = {
	locale: {
		advanced: "Advanced Options",
		header: "Search",
		resultsHeader: "Results (%0)",
		find: "find",
		noResults: "No tiddlers matched your search query",
		query: "QUERY: ",
		error: "please provide a search query or a tag, modifier or title!",
		titleAdvanced: "where the title is",
		modifierAdvanced: "where the last modifier is",
		spaceAdvanced: "only in the space: ",
		notspaceAdvanced: "but not in the spaces: ",
		tagsAdvanced: "with the tags: "
	},
	andConstructor: function(container, label, fieldname, negationMode) {
		var tags = $("<div />").appendTo(container);
		$('<span />').text(label).appendTo(tags);
		var id = "area" + Math.random();
		container = $("<span />").attr("id", id).appendTo(tags)[0];
		function add(container) {
			var el = $('<input type="text" />').attr("field", fieldname).appendTo(container);
			if(negationMode) {
				el.attr("negation", "true");
			}
		}
		add(container);
		var el = $("<button />").text("AND").click(function(ev) {
			add($(ev.target).data("container"));
			ev.preventDefault();
		}).appendTo(tags);
		$(el).data("container", container);
	},
	fieldConstructor: function(container, label, field) {
		container = $("<div />").appendTo(container)[0];
		$("<span />").text(label).appendTo(container);
		$("<input />").attr("text", "input").attr("field", field).appendTo(container);
	},
	advancedOptions: function(form) {
		var locale = search.locale;
		var container = $("<div />").addClass("tsAdvancedOptions").appendTo(form)[0];
		$("<h2/ >").text(search.locale.advanced).appendTo(container);
		$("<div />").addClass("separator").appendTo(container);
		search.fieldConstructor(container, locale.titleAdvanced, "title");
		search.fieldConstructor(container, locale.modifierAdvanced, "modifier");
		search.fieldConstructor(container, locale.spaceAdvanced, "space");
		search.andConstructor(container, locale.notspaceAdvanced, "space", true);
		search.andConstructor(container, locale.tagsAdvanced, "tag");
	},
	constructSearchQuery: function(form) {
		var data = [], select = [];
		var query = $("[name=q]", form).val();
		if(query) {
			data.push("q=%0".format(query));
		}

		// add tags, fields etc..
		$("[field]", form).each(function(i, el) {
			var val = $(el).val();
			var name = $(el).attr("field");
			var negate = $(el).attr("negation") == "true";
			if(val && name) {
				val = encodeURIComponent(val);
				val = negate ? "!" + val : val;
				if(name == "space") {
					val += "_public";
					name = "bag";
				}
				if(negate) {
					select.push("select=%0:%1".format(name,val));
				} else {
					var prefix = data.length === 0 ? "q=" : "";
					data.push('%0%1:"%2"'.format(prefix, name, val));
				}
			}
		});
		var dataString = data.join(" ");
		if(dataString.length === 0 && !query) {
			return false;
		}
		var selectStatement = select.join("&");
		if(dataString.length > 0 && selectStatement.length > 0) {
			dataString += "&";
		}
		dataString += selectStatement;
		return "/search?%0".format(dataString);
	},
	constructForm: function(place) {
		var locale = search.locale;
		$("<h1 />").text(locale.header).appendTo(place);
		var form = $("<form />").appendTo(place)[0];
		$('<input type="text" name="q" />').appendTo(form);
		$('<input type="submit" />').val(locale.find).appendTo(form);
		search.advancedOptions(form);
		var query = $('<h2 class="query"/>').appendTo(place)[0];
		var results = $("<div />").appendTo(place).addClass("resultsArea")[0];
		var lookup = function(url) {
			if(!url) {
				results.empty().addClass("error").text(locale.error);
				return;
			}
			config.extensions.tiddlyweb.getStatus(function(status) {
				$(query).text(locale.query);
				var href = status.server_host.url + url;
				$("<a />").attr("href", href).text(href).appendTo(query);
				tsScan.scan(results, { url: url, emptyMessage: search.locale.noResults, cache: true,
					template: "SearchTemplate", sort: "title", callback: function(tiddlers) {
						$("<h2 />").text(locale.resultsHeader.format(tiddlers.length)).prependTo(results);
					}
				});
			});
		};
		$(form).submit(function(ev) {
			ev.preventDefault();
			var url = search.constructSearchQuery(form);
			config.macros.tsSearch.lastSearch = url;
			lookup(url);
		});
		if(search.lastSearch) {
			lookup(search.lastSearch);
		}
		return form;
	},
	handler: function(place) {
		var container = $("<div />").addClass("searchForm").appendTo(place)[0];
		search.constructForm(container);
	}
};

})(jQuery);
//}}}
|Date|Users|Spaces|
|20101112|627|1501|
|20101113|629|1506|
|20101114|642|1521|
|20101115|646|1531|
|20101116|652|1542|
|20101117|658|1562|
|20101118|661|1573|
|20101119|662|1578|
|20101120|667|1588|
|20101121|670|1600|
|20101122|672|1608|
|20101123|681|1623|
|20101124|682|1625|
|20101125|689|1641|
|20101126|692|1664|
|20101127|694|1671|
|20101128|697|1675|
|20101129|702|1687|
|20101130|702|1692|
|20101201|705|1697|
|20101202|708|1707|
|20101203|709|1737|
|20101204|715|1749|
|20101205|717|1752|
|20101206|721|1763|
|20101207|730|1776|
|20101208|736|1787|
|20101209|742|1797|
|20101210|745|1815|
|20101211|750|1829|
|20101212|752|1832|
|20101213|757|1845|
|20101214|764|1855|
|20101215|766|1861|
|20101216|769|1866|
|20101217|771|1873|
|20101218|777|1888|
|20101219|778|1891|
|20101220|783|1901|
|20101221|787|1908|
|20101222|797|1920|
|20101223|802|1931|
|20101224|804|1934|
|20101225|808|1941|
|20101226|811|1945|
|20101227|817|1952|
|20101228|823|1964|
|20101229|826|1974|
|20101230|832|1988|
|20101231|835|1992|
/***
|''Name''|TiddlyFileImporter|
|''Version''|0.3.8|
|''Author''|Ben Gillies|
|''Type''|plugin|
|''Description''|Upload a TiddlyWiki file to TiddlyWeb, and import the tiddlers.|
!Usage
Upload a TiddlyWiki file to TiddlyWeb, and import the tiddlers.
!Requires
tiddlyweb
tiddlywebplugins.reflector
!Code
***/
//{{{
(function($){
if(!version.extensions.TiddlyFileImporter)
{ //# ensure that the plugin is only installed once
	version.extensions.TiddlyFileImporter = { installed: true };
}

config.macros.fileImport = {
	reflectorURI: '/reflector?csrf_token=%0',
	incorrectTypeError: 'Incorrect File Type. You must upload a TiddlyWiki',
	uploadLabel: 'Upload',
	uploadLabelPrompt: 'Import tiddlers from this TiddlyWiki',
	step1FileText: 'File:',
	step1PostText: 'In the next screen you will select the tiddlers to import.',
	step1Title: 'Step 1: Pick a TiddlyWiki to import',
	step1TypeChooser: 'Import From:',
	step3Html: ['<input type="hidden" name="markList" />',
		'<input type="hidden" checked="true" name="chkSync" />',
		'<input type="hidden" name="chkSave" />',
		'<input type="hidden" name="txtSaveTiddler" />'].join(),

	handler: function(place, macroName, params, wikifier, paramString) {
		var wizard = new Wizard();
		wizard.createWizard(place, 'Import a TiddlyWiki');
		this.restart(wizard);
	},

	restart: function(wizard) {
		var me = config.macros.fileImport;
		wizard.addStep(me.step1Title, ['<input type="hidden" ',
			'name="markList" />'].join(""));
		var markList = wizard.getElement('markList');
		var uploadWrapper = document.createElement('div');
		markList.parentNode.insertBefore(uploadWrapper, markList);
		uploadWrapper.setAttribute('refresh', 'macro');
		uploadWrapper.getAttribute('macroName', 'fileImport');
		var iframeName = 'reflectorImporter' + Math.random().toString();
		me.createForm(uploadWrapper, wizard, iframeName);
		$(uploadWrapper).append('<p>' + me.step1PostText + '</p>');
		wizard.setValue('serverType', 'tiddlyweb');
		wizard.setValue('adaptor', new config.adaptors.file());
		wizard.setValue('host', config.defaultCustomFields['server.host']);
		wizard.setValue('context', {});
		var iframe = $(['<iframe name="' + iframeName + '" ',
			'style="display: none" />'].join("")).appendTo(uploadWrapper);
		var onSubmit = function(ev) {
			var uploadType = $('select[name=uploadtype]', wizard.formElem).val();
			if (uploadType == "file") {
				// set an onload ready to hijack the form
				me.setOnLoad(uploadWrapper, wizard, iframe[0]);
				wizard.importType = 'file';
				wizard.formElem.submit();
			} else {
				var csrf_token = config.extensions.tiddlyspace.getCSRFToken();
				$.ajax({
					url: "%0/reflector?csrf_token=%1".format(
						config.defaultCustomFields["server.host"], csrf_token),
					type: "POST",
					dataType: "text",
					data: {
						uri: $("input", ".importFrom", wizard.formElem).val()
					},
					success: function(data, txtStatus, xhr) {
						wizard.POSTResponse = data;
						me.importTiddlers(uploadWrapper, wizard);
					},
					error: function(xhr, txtStatus, error) {
						displayMessage(["There was an error fetching the ",
							'url: ', txtStatus].join(""));
						me.restart(wizard);
					}
				});
				return false;
			}
		};
		wizard.setButtons([{
			caption: me.uploadLabel,
			tooltip: me.uploadLabelPrompt,
			onClick: onSubmit
		}]);
		$(wizard.formElem).submit(function(ev) {
			onSubmit(ev);
			ev.preventDefault();
		});
	},

	createForm: function(place, wizard, iframeName) {
		var form = wizard.formElem;
		var me = config.macros.fileImport;
		form.action = me.reflectorURI.format(
			config.extensions.tiddlyspace.getCSRFToken());
		form.enctype = 'multipart/form-data';
		form.encoding = 'multipart/form-data';
		form.method = 'POST';
		form.target = iframeName;
		onSelectChange = function(e) {
			var changeTo = $(this).val();
			if (changeTo == "file") {
				$(".importFrom").html('%0 <input type="file" name="file" />'.
					format(me.step1FileText));
			} else {
				$(".importFrom").html('URL: <input type="text" name="uri" />'
					+ ' Do you want <a target="_blank" href="http://faq.tiddlyspace.com/How%20do%20I%20include%2Fexclude%20spaces%3F">inclusion</a> instead?');
			}
		};
		$(place).append('<span>%0</span>'.format(me.step1TypeChooser)).
			append($(['<select name="uploadtype"><option value="file" selected="selected">file',
				'<option value="uri">url</select>'].join("")).change(onSelectChange)).
			append('<div class="importFrom">%0<input type="file" name="file" /></div>'.
					format(me.step1FileText));
	},

	setOnLoad: function(place, wizard, iframe) {
		var me = config.macros.fileImport;
		var loadHandler = function() {
			me.importTiddlers.apply(this, [place, wizard, iframe]);
		};
		iframe.onload = loadHandler;
		completeReadyStateChanges = 0;
		iframe.onreadystatechange = function() {
			if (++(completeReadyStateChanges) == 5) {
				loadHandler();
			}
		};
	},

	importTiddlers: function(place, wizard, iframe) {
		var tmpStore = new TiddlyWiki();
		var POSTedWiki = "";
		if (wizard.importType == "file") {
			try {
				POSTedWiki= iframe.contentWindow
					.document.documentElement.innerHTML;
			} catch(e) {
				displayMessage(config.macros.fileImport.incorrectTypeError);
				config.macros.fileImport.restart(wizard);
				return;
			}
			// now we are done, so remove the iframe
			$(iframe).remove();
		} else {
			POSTedWiki = wizard.POSTResponse;
		}

		tmpStore.importTiddlyWiki(POSTedWiki);
		var newTiddlers = tmpStore.getTiddlers();
		var workspace = config.defaultCustomFields['server.workspace'];
		var context = {
			status: true,
			statusText: 'OK',
			httpStatus: 200,
			adaptor: wizard.getValue('adaptor'),
			tiddlers: newTiddlers
		};
		context.adaptor.store = tmpStore;
		wizard.setValue('context', context);
		wizard.setValue('workspace', workspace);
		wizard.setValue('inFileImport', true);
		config.macros.importTiddlers.onGetTiddlerList(context, wizard);
	}
};

var _onGetTiddler = config.macros.importTiddlers.onGetTiddler;
config.macros.importTiddlers.onGetTiddler = function(context, wizard) {
	if (wizard.getValue('inFileImport')) {
		var me = config.macros.importTiddlers;
		if(!context.status)
			displayMessage("Error in importTiddlers.onGetTiddler: " + context.statusText);
		var tiddler = context.tiddler;
		var fields = tiddler.fields;
		merge(fields, config.defaultCustomFields);
		fields["server.workspace"] = wizard.getValue('workspace');
		delete fields['server.permissions'];
		delete fields['server.bag'];
		fields['server.page.revision'] = 'false';
		delete fields['server.recipe'];
		fields.changecount = 1;
		store.suspendNotifications();
		store.saveTiddler(tiddler.title, tiddler.title, tiddler.text,
			tiddler.modifier, tiddler.modified, tiddler.tags, tiddler.fields,
			false, tiddler.created);
		store.resumeNotifications();
		var remainingImports = wizard.getValue("remainingImports")-1;
		wizard.setValue("remainingImports",remainingImports);
		if(remainingImports === 0) {
			if(context.isSynchronous) {
				store.notifyAll();
				refreshDisplay();
			}
			wizard.setButtons([
					{caption: me.doneLabel, tooltip: me.donePrompt, onClick: me.onClose}
				],me.statusDoneImport);
			autoSaveChanges();
		}
	} else {
		_onGetTiddler.apply(this, arguments);
	}
};

var _onCancel = config.macros.importTiddlers.onCancel;
config.macros.importTiddlers.onCancel = function(e)
{
	var wizard = new Wizard(this);
	if (!wizard.getValue('inFileImport')) {
		return _onCancel.apply(this, arguments);
	}
	var place = wizard.clear();
	config.macros.fileImport.restart(wizard);
	return false;
};

var _step3Html = config.macros.importTiddlers.step3Html;
var _onGetTiddlerList = config.macros.importTiddlers.onGetTiddlerList;
config.macros.importTiddlers.onGetTiddlerList = function(context, wizard) {
	var fileImport = config.macros.fileImport;
	var importTiddlers = config.macros.importTiddlers;
	if (wizard.getValue('inFileImport')) {
		importTiddlers.step3Html = fileImport.step3Html;
	} else {
		importTiddlers.step3Html = _step3Html;
	}
	_onGetTiddlerList.apply(this, arguments);
};
})(jQuery);
//}}}
|Date|Users|Spaces|
|20110101|837|1998|
|20110102|837|2001|
|20110103|844|2013|
|20110104|852|2024|
|20110105|862|2040|
|20110106|866|2049|
|20110107|867|2055|
|20110108|874|2067|
|20110109|878|2074|
|20110110|880|2079|
|20110111|884|2083|
|20110112|889|2092|
|20110113|894|2097|
|20110114|895|2105|
|20110115|898|2122|
|20110116|901|2132|
|20110117|906|2139|
|20110118|907|2146|
|20110119|917|2162|
|20110120|920|2167|
|20110121|922|2172|
|20110122|924|2178|
|20110123|927|2184|
|20110125|932|2197|
|20110126|936|2207|
|20110127|940|2215|
|20110128|943|2221|
|20110129|946|2229|
|20110130|948|2231|
|20110131|957|2241|
|Date|Users|Spaces|
|20110601|1784|3525|
|20110602|1801|3546|
|20110603|1824|3585|
|20110604|1842|3612|
|20110605|1843|3613|
|20110606|1851|3625|
|20110607|1865|3641|
|20110608|1879|3666|
|20110609|1886|3680|
|20110610|1898|3698|
|20110611|1922|3728|
|20110612|1928|3735|
|20110613|1937|3744|
|20110614|1955|3778|
|20110615|1965|3796|
|20110616|1977|3814|
|20110617|1987|3830|
|20110618|1996|3846|
|20110619|2007|3864|
|20110620|2015|3875|
|20110621|2025|3901|
|20110622|2037|3916|
|20110623|2045|3927|
|20110624|2055|3938|
|20110625|2065|3963|
|20110626|2070|3973|
|20110627|2075|3982|
|20110628|2085|4002|
|20110629|2092|4030|
|20110630|2104|4046|
/***
https://github.com/tiddlyweb/chrjs/raw/master/main.js
***/
//{{{
// TiddlyWeb adaptor
// v0.14.3

/*jslint vars: true, unparam: true, nomen: true, white: true */
/*global jQuery */

var tiddlyweb = (function($) {

"use strict";

var tw = {
	routes: {
		// host is the TiddlyWeb instance's URI (including server_prefix)
		// placeholders "_type" & "name" refer to the respective bag/recipe
		root     : "{host}/",
		bags     : "{host}/bags",
		bag      : "{host}/bags/{name}",
		recipes  : "{host}/recipes",
		recipe   : "{host}/recipes/{name}",
		tiddlers : "{host}/{_type}s/{name}/tiddlers",
		tiddler  : "{host}/{_type}s/{name}/tiddlers/{title}",
		revisions: "{host}/{_type}s/{name}/tiddlers/{title}/revisions",
		revision : "{host}/{_type}s/{name}/tiddlers/{title}/revisions/{revision}",
		search   : "{host}/search?q={query}"
	}
};

var convertTimestamp, supplant;

// host (optional) is the URI of the originating TiddlyWeb instance
tw.Resource = function(type, host) {
	if(arguments.length) { // initialization
		this._type = type;
		if(host !== false) {
			this.host = host !== undefined ? host.replace(/\/$/, "") : null;
		}
	}
};
$.extend(tw.Resource.prototype, {
	// retrieves resource from server
	// callback is passed resource, status, XHR (cf. jQuery.ajax success)
	// errback is passed XHR, error, exception, resource (cf. jQuery.ajax error)
	// filters is an optional filter string (e.g. "select=tag:foo;limit=5")
	get: function(callback, errback, filters) {
		var uri = this.route();
		if(filters) {
			var separator = uri.indexOf("?") === -1 ? "?" : ";";
			uri += separator + filters;
		}
		var self = this;
		return $.ajax({
			url: uri,
			type: "GET",
			dataType: "json",
			success: function(data, status, xhr) {
				var resource = self.parse(data);
				resource.etag = xhr.getResponseHeader("Etag");
				callback(resource, status, xhr);
			},
			error: function(xhr, error, exc) {
				errback(xhr, error, exc, self);
			}
		});
	},
	// sends resource to server
	// callback is passed data, status, XHR (cf. jQuery.ajax success)
	// errback is passed XHR, error, exception, resource (cf. jQuery.ajax error)
	put: function(callback, errback) {
		var self = this;
		var options = {
			url: this.route(),
			type: "PUT",
			contentType: "application/json",
			data: JSON.stringify(this.baseData()),
			success: function(data, status, xhr) {
				callback(self, status, xhr);
			},
			error: function(xhr, error, exc) {
				errback(xhr, error, exc, self);
			}
		};
		if(this.ajaxSetup) {
			this.ajaxSetup(options);
		}
		return $.ajax(options);
	},
	// deletes resource on server
	// callback is passed data, status, XHR (cf. jQuery.ajax success)
	// errback is passed XHR, error, exception, resource (cf. jQuery.ajax error)
	"delete": function(callback, errback) {
		var self = this;
		var options = {
			url: this.route(),
			type: "DELETE",
			success: function(data, status, xhr) {
				callback(self, status, xhr);
			},
			error: function(xhr, error, exc) {
				errback(xhr, error, exc, self);
			}
		};
		if(this.ajaxSetup) {
			this.ajaxSetup(options);
		}
		return $.ajax(options);
	},
	// returns an object carrying only the essential information of the resource
	baseData: function() {
		var data = {},
			self = this;
		$.each(this.data, function(i, item) {
			var value = self[item];
			if(value !== undefined) {
				data[item] = value;
			}
		});
		return data;
	},
	// returns corresponding instance from a raw object (if applicable)
	parse: function(data) {
		return data;
	},
	// list of accepted keys in serialization
	data: [],
	// returns resource's URI
	route: function() {
		return supplant(tw.routes[this._type], this);
	}
});

var Container = function(type, name, host) {
	if(arguments.length) { // initialization
		tw.Resource.apply(this, [type, host]);
		this.name = name;
		this.desc = "";
		this.policy = new tw.Policy({});
	}
};
Container.prototype = new tw.Resource();
$.extend(Container.prototype, {
	tiddlers: function() {
		return new tw.TiddlerCollection(this);
	},
	parse: function(data) {
		var type = tw._capitalize(this._type),
			container = new tw[type](this.name, this.host);
		data.policy = new tw.Policy(data.policy);
		return $.extend(container, data);
	},
	data: ["desc", "policy"]
});

// attribs is an object whose members are merged into the instance (e.g. query)
tw.Collection = function(type, host, attribs) {
	if(arguments.length) { // initialization
		tw.Resource.apply(this, [type, host]);
		$.extend(this, attribs);
	}
};
tw.Collection.prototype = new tw.Resource();

tw.TiddlerCollection = function(container, tiddler) {
	if(arguments.length) { // initialization
		tw.Collection.apply(this, [tiddler ? "revisions" : "tiddlers"]);
		this.container = container || null;
		this.tiddler = tiddler || null;
	}
};
tw.TiddlerCollection.prototype = new tw.Collection();
$.extend(tw.TiddlerCollection.prototype, {
	parse: function(data) {
		var container = this.container;
		return $.map(data, function(item, i) {
			var tiddler = new tw.Tiddler(item.title, container),
				bag = item.bag;
			tiddler = tw.Tiddler.prototype.parse.apply(tiddler, [item]);
			if(!tiddler.bag && bag) { // XXX: bag always present!?
				tiddler.bag = new tw.Bag(bag, container.host);
			}
			if(!tiddler.recipe && item.recipe) {
				tiddler.recipe = new tw.Recipe(item.recipe, container.host);
			}
			delete item.recipe;
			return $.extend(tiddler, item);
		});
	},
	route: function() {
		var params = this.container;
		if(this.tiddler) {
			var container = this.tiddler.bag || this.tiddler.recipe;
			params = {
				_type: container._type,
				host: container.host,
				name: container.name,
				title: this.tiddler.title
			};
		}
		return supplant(tw.routes[this._type], params);
	}
});

tw.Search = function(query, host) {
	tw.Collection.apply(this, ["search", host]);
	this.query = query;
};
tw.Search.prototype = new tw.Collection();
$.extend(tw.Search.prototype, {
	parse: function(data) {
		this.container = { // XXX: hacky
			_type: "bag",
			host: this.host
		};
		var tiddlers = tw.TiddlerCollection.prototype.parse.apply(this, arguments);
		delete this.container;
		return tiddlers;
	}
});

// title is the name of the tiddler
// container (optional) is an instance of either Bag or Recipe
// optionally accepts a single object representing tiddler attributes
tw.Tiddler = function(title, container) {
	tw.Resource.apply(this, ["tiddler", false]);
	this.title = title;
	this.bag = container && container._type === "bag" ? container : null;
	this.recipe = container && container._type === "recipe" ? container : null;
	var self = this;
	$.each(this.data, function(i, item) {
		self[item] = undefined; // exposes list of standard attributes for inspectability
	});
	if(title && title.title) { // title is an object of tiddler attributes
		$.extend(this, title);
	}
};
tw.Tiddler.prototype = new tw.Resource();
$.extend(tw.Tiddler.prototype, {
	revisions: function() {
		return new tw.TiddlerCollection(this.bag || this.recipe, this);
	},
	route: function() {
		var container = this.bag || this.recipe;
		var params = $.extend({}, this, {
			host: container ? container.host : null,
			_type: this.bag ? "bag" : (this.recipe ? "recipe" : null),
			name: container ? container.name : null
		});
		return supplant(tw.routes[this._type], params);
	},
	parse: function(data) {
		var tiddler = new tw.Tiddler(this.title),
			container = this.bag || this.recipe;
		if(data.bag) {
			tiddler.bag = new tw.Bag(data.bag, container.host);
			delete data.bag;
		}
		delete data.recipe;
		tiddler.created = data.created ? convertTimestamp(data.created) : new Date();
		delete data.created;
		tiddler.modified = data.modified ? convertTimestamp(data.modified) : new Date();
		delete data.modified;
		if(this.recipe) {
			tiddler.recipe = this.recipe;
		}
		return $.extend(tiddler, data);
	},
	data: ["created", "creator", "modifier", "modified", "tags", "type", "text",
			"fields"],
	ajaxSetup: function(options) {
		var self = this;
		if(this.etag && (options.type === "PUT" || options.type === "DELETE")) {
			options.beforeSend = function(xhr) {
				xhr.setRequestHeader("If-Match", self.etag);
			};
		}
		if(options.type === "PUT") {
			var callback = options.success;
			options.success = function(data, status, xhr) {
				var loc = xhr.getResponseHeader("Location"),
					etag = xhr.getResponseHeader("Etag");
				if(loc && etag) {
					self.etag = etag;
					if(!self.bag) {
						var bag = loc.split("/bags/").pop().split("/")[0];
						self.bag = new tw.Bag(bag, self.recipe.host);
					}
					callback(self, status, xhr);
				} else { // IE
					self.get(callback, options.error);
				}
			};
		}
	}
});

tw.Revision = function(id, tiddler) {
	var container = tiddler.bag || tiddler.recipe;
	tw.Tiddler.apply(this, [tiddler.title, container]);
	this._type = "revision";
	this.revision = id;
};
tw.Revision.prototype = new tw.Tiddler();
$.extend(tw.Revision.prototype, {
	revisions: false,
	data: false,
	put: false,
	"delete": false
});

tw.Bag = function(name, host) {
	Container.apply(this, ["bag", name, host]);
};
tw.Bag.prototype = new Container();

tw.Recipe = function(name, host) {
	Container.apply(this, ["recipe", name, host]);
	this.recipe = [];
};
tw.Recipe.prototype = new Container();
$.extend(tw.Recipe.prototype, {
	data: ["recipe"].concat(Container.prototype.data)
});

tw.Policy = function(constraints) { // TODO: validation?
	var self = this;
	$.each(this.constraints, function(i, item) {
		self[item] = constraints[item];
	});
};
tw.Policy.prototype.constraints = ["read", "write", "create", "delete",
	"manage", "accept", "owner"];

/*
 * utilities
 */

tw._capitalize = function(str) {
	return str.charAt(0).toUpperCase() + str.slice(1);
};

// convert YYYYMMDDhhmmss timestamp to Date instance
convertTimestamp = function(t) {
	if (t.match(/^\d{12,17}$/)) {
		return new Date(Date.UTC(
			parseInt(t.substr(0, 4), 10),
			parseInt(t.substr(4, 2), 10) - 1,
			parseInt(t.substr(6, 2), 10),
			parseInt(t.substr(8, 2), 10),
			parseInt(t.substr(10, 2), 10),
			parseInt(t.substr(12, 2) || "0", 10),
			parseInt(t.substr(14, 3) || "0", 10)
		));
	} else {
		return new Date(Date.parse(t));
	}
};

// adapted from Crockford (http://javascript.crockford.com/remedial.html)
supplant = function(str, obj) {
	return str.replace(/{([^{}]*)}/g, function (a, b) {
		var r = obj[b];
		r = typeof r === "string" || typeof r === "number" ? r : a;
		return $.inArray(b, ["host", "query"]) !== -1 ? r : encodeURIComponent(r); // XXX: special-casing
	});
};

return tw;

}(jQuery));
//}}}
|Date|Users|Spaces|
|20110401|1285|2786|
|20110402|1293|2809|
|20110403|1299|2820|
|20110404|1310|2833|
|20110405|1321|2854|
|20110406|1328|2864|
|20110407|1342|2883|
|20110408|1352|2895|
|20110409|1357|2906|
|20110410|1363|2913|
|20110411|1365|2916|
|20110412|1381|2937|
|20110413|1396|2960|
|20110414|1403|2972|
|20110415|1409|2986|
|20110416|1415|2992|
|20110417|1422|3002|
|20110418|1426|3007|
|20110419|1432|3017|
|20110420|1445|3032|
|20110421|1451|3043|
|20110422|1456|3049|
|20110423|1463|3058|
|20110424|1468|3066|
|20110425|1474|3078|
|20110426|1481|3086|
|20110427|1491|3104|
|20110428|1501|3118|
|20110429|1507|3128|
|20110430|1514|3139|
|Date|Users|Spaces|
|20110501|1520|3151|
|20110502|1525|3158|
|20110503|1528|3169|
|20110504|1532|3175|
|20110505|1542|3190|
|20110506|1550|3202|
|20110507|1560|3217|
|20110508|1563|3221|
|20110509|1564|3223|
|20110510|1572|3235|
|20110511|1584|3255|
|20110512|1594|3269|
|20110513|1600|3278|
|20110514|1606|3292|
|20110515|1616|3307|
|20110516|1617|3309|
|20110517|1625|3320|
|20110518|1630|3325|
|20110519|1640|3341|
|20110520|1652|3359|
|20110521|1660|3372|
|20110522|1669|3381|
|20110523|1680|3395|
|20110524|1685|3402|
|20110525|1699|3418|
|20110526|1716|3437|
|20110527|1735|3464|
|20110528|1743|3472|
|20110529|1754|3487|
|20110530|1761|3497|
|20110531|1771|3509|
|Date|Users|Spaces|Created|Modified|Tiddlertime|Searchtime|
|20121201|6281|9496|668|755|311.1|8321.71|
|20121202|6287|9502|171|299|318.9|2532.8|
|20121203|6293|9510|169|261|313|15078.2|
|20121204|6306|9525|500|592|304.9|2464.89|
|20121205|6309|9530|130|239|314.6|230.37|
|20121206|6318|9540|486|557|309.2|2676.49|
|20121207|6324|9548|3191|3290|316.3|225.64|
|20121208|6328|9555|128|220|310.8|6987.59|
|20121209|6330|9557|84|211|320.3|7256.83|
|20121210|6337|9565|216|1352|308.9|2532.47|
|20121211|6345|9574|195|313|324.5|2515.01|
|20121212|6348|9577|199|564|310.8|2613.25|
|20121213|6353|9584|619|680|316.9|3445.34|
|20121214|6361|9593|199|266|316.8|2522.74|
|20121215|6366|9599|1125|1219|325.7|403.18|
|20121216|6369|9602|272|353|319.3|7430.16|
|20121217|6373|9607|180|251|319.7|2619.2|
|20121218|6376|9610|81|186|319.1|2712.72|
|20121219|6381|9616|90|194|316.5|2717.98|
|20121220|6384|9619|194|352|319.8|7489.38|
|20121221|6387|9622|149|281|318.1|2620.24|
|20121222|6389|9625|368|519|2966.4|233.49|
|20121223|6392|9628|216|320|498.9|2604.14|
|20121224|6395|9632|197|255|318.5|2592.12|
|20121225|6397|9634|116|1629|312.2|7324.65|
|20121226|6402|9641|180|324|322.3|2652.92|
|20121227|6410|9648|176|502|318.6|2713.99|
|20121228|6419|9657|152|401|325|2547.97|
|20121229|6422|9660|278|353|324.2|8524.68|
|20121230|6424|9662|69|153|318|2677.97|
|20121231|6427|9667|328|601|850.4|2664.26|
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AP8zZgAAAGYA//8zAADMMwD/mTMAAGYzAP8zMwAAADMAzP8AAADMAADMmQAAAGYAAMwzAAAAAADuzAAA3QAAALvMAACqAAAAiMwAAHcAAABVmQAARAAAACKZAAARAADuAJkA3QAAALsAmQCqAAAAiACZAHcAAABVAJkARAAAACIAZgARAADuAABm3QAAALsAAGaqAAAAiAAAZncAAABVAABmRAAAACIAAGYRAAAA7u7uM93d3QC7u7szqqqqAIiIiDN3d3cAVVVVM0RERAAiIiIzERERAAAAADMBAQEBAQEBAQEBpXl5eXl5eXl5eXmlAQEBAQEBAQEBAQEBAQEBAQEBgHl5eXl5eXl5eXl5eXl5gAEBAQEBAQEBAQEBAQEB/Xp5eXlVT04qKioqTk9VeXl5ev0BAQEBAQEBAQEBAaV5eXlPKioqKioqKioqKioqT3l5eaUBAQEBAQEBAQGAeXlVTioqKioqKioqKioqKioqTlV5eYABAQEBAQEBgHl5VSoqKioqKioqKioqKioqKioqKlV5eYABAQEBAaV5eVUqKioqKioqKioqKioqKioqKioqKlV5eaUBAQEBeXlVKioqKioqKioqKioqKioqKioqKioqKlV5eQEBAXl5eU4qKioqKioqKjExMTExMSoqKioqKioqTnl5eQEBeXlPKioqKioqKjEyMjIyMjIyMjEqKioqKioqT3l5AXp5eSoqKioqKioxMjIxBwcHBzEyMjEqKioqKioqeXl6eXlVKioqKioqMTIxBwcHBwcHBwcxMjEqKioqKipVeXl5eU8qKioqKioyMgcHBwcHBwcHBwcyMioqKioqKk95eXl5TioqKioqMTIxBwcHBwcHBwcHBzEyMSoqKioqTnl5eXkqKioqKioxMgcHBwcHBwcHBwcHBzIxKioqKioqeXl5eSoqKioqKjEyBwcHBwcHBwcHBwcHMjEqKioqKip5eXl5KioqKioqMTIHBwcHBwcHBwcHBwcyMSoqKioqKnl5eXkqKioqKioxMgcHBwcHBwcHBwcHBzIxKioqKioqeXl5eU4qKioqKjEyMQcHBwcHBwcHBwcxMjEqKioqKk55eXl5TyoqKioqKjIyBwcHBwcHBwcHBzIyKioqKioqT3l5eXlVKioqKioqMTIxBwcHBwcHBwcxMjEqKioqKipVeXl6eXkqKioqKioqMTIyMQcHBwcxMjIxKioqKioqKnl5egF5eU8qKioqKioqMTIyMjIyMjIyMSoqKioqKipPeXkBAXl5eU4qKioqKioqKjExMTExMSoqKioqKioqTnl5eQEBAXl5VSoqKioqKioqKioqKioqKioqKioqKipVeXkBAQEB+nl5VSoqKioqKioqKioqKioqKioqKioqVXl5+gEBAQEBenl5VSoqKioqKioqKioqKioqKioqKlV5eXoBAQEBAQEBeXl5VU4qKioqKioqKioqKioqKk5VeXl5AQEBAQEBAQEBenl5eU8qKioqKioqKioqKipPeXl5egEBAQEBAQEBAQEB+nl5eXlVT04qKioqTk9VeXl5efoBAQEBAQEBAQEBAQEBAXl5eXl5eXl5eXl5eXl5eXkBAQEBAQEBAQEBAQEBAQEBAQF6eXl5eXl5eXl5eXoBAQEBAQEBAQEB/+AH//+AAf/+AAB//AAAP/gAAB/wAAAP4AAAB8AAAAPAAAADgAAAAYAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAYAAAAHAAAADwAAAA+AAAAfwAAAP+AAAH/wAAD/+AAB//4AB///gB/8oAAAAIAAAAEAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAACAAAAAwAAAAMAAAADAAAABG1bSA61m3JXuqB4mbuhd8m9o3jqvaF4+b2hePm9o3jqu6F3ybqgeJm1m3JXbVtIDgAAAAQAAAADAAAAAwAAAAMAAAACAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAAwAAAAUAAAAGAAAACI98Wye0nXWavKF4876kev++pHr/vqR6/76kev++pHr/vqR6/76kev++pHr/vqR6/76kev+8oXjztJ11mo98WycAAAAIAAAABgAAAAUAAAADAAAAAgAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAgAAAAQAAAAHAAAAChwcHBKulnGJvaN5+L6kev++pHr/y7GJ/9/Fnv/s1K7/9t25//rivv/64r7/9t25/+zUrv/fxZ7/y7GJ/76kev++pHr/vaN5+K6WcYkcHBwSAAAACgAAAAcAAAAEAAAAAgAAAAEAAAAAAAAAAAAAAAEAAAADAAAABwAAAAtuYkUst552z76kev++pHr+1LuS//Latf/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD/8tq1/9S7kv++pHr+vqR6/7eeds9uYkUsAAAACwAAAAcAAAADAAAAAQAAAAAAAAABAAAAAgAAAAQAAAAIi3hbNbqgd+a+pHr/xayD/+3Vr//85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA/+3Vr//FrIP/vqR6/7qgd+aJdVg0AAAACAAAAAQAAAACAAAAAQAAAAEAAAACAAAABIl8WSW8oXjlvqR6/8yyiv/54Lz//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//ngvP/Msor/vqR6/7yheOWJfFklAAAABAAAAAIAAAABAAAAAAAAAAFfXz8Iu6F4zL6kev/Msor/+uK+//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//rivv/Msor/vqR6/7uheMxfXz8IAAAAAQAAAAAAAAAAAAAAAbqid4K+pHr/xayD//ngvP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//fgvP/FrIP/vqR6/7qid4IAAAABAAAAAAAAAAC3l28gvaN5+L6kev7t1a///OXA//zlwP/85cD//OXA//zlwP/85cD//OXA/+/Twv/Qq8f/u5HK/7OGzP+zhsz/u5HK/9Crx//v08L//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA/+3Vr/++pHr+vaN5+LeXbyAAAAAAAAAAALuheJa+pHr/1LuS//zlwP/85cD//OXA//zlwP/85cD//OXA//riwP/Pq8f/r4HM/6+Bzf+vgc3/r4HN/6+Bzf+vgc3/r4HN/6+BzP/Pq8f/+uLA//zlwP/85cD//OXA//zlwP/85cD//OXA/9S5kv++pHr/u6F4lgAAAACii3MLvKF4876kev/y2rX//OXA//zlwP/85cD//OXA//zlwP/64sD/w5vJ/6+Bzf+vg83/w5vc/9W06v/dwPD/3cDw/9W06v/Dm9z/r4PN/6+Bzf/Dm8n/+uLA//zlwP/85cD//OXA//zlwP/85cD/8tq1/76kev+8oXjzootzC72feFW+pHr/y7GJ//zlwP/85cD//OXA//zlwP/85cD//OXA/8+rx/+vgc3/tIfQ/9a16//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//Wtev/tIfQ/6+Bzf/Pq8f//OXA//zlwP/85cD//OXA//zlwP/85cD/y7GJ/76kev+9n3hVvaF4mL6kev/fxZ7//OXA//zlwP/85cD//OXA//zlwP/v08L/r4HM/6+Dzf/Wtev/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//Wtev/r4PN/6+BzP/v08L//OXA//zlwP/85cD//OXA//zlwP/fxZ7/vqR6/72heJi8oXfIvqR6/+zUrv/85cD//OXA//zlwP/85cD//OXA/9Crx/+vgc3/w5vc/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//Dm9z/r4HN/9Crx//85cD//OXA//zlwP/85cD//OXA/+zUrv++pHr/vKF3yL2jeOq+pHr/9t25//zlwP/85cD//OXA//zlwP/85cD/u5HK/6+Bzf/VtOr/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/9W06v+vgc3/u5HK//zlwP/85cD//OXA//zlwP/85cD/9t25/76kev+9o3jqvaF4+b6kev/64r7//OXA//zlwP/85cD//OXA//zlwP+zhsz/r4HN/93A8P/hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/3cDw/6+Bzf+zhsz//OXA//zlwP/85cD//OXA//zlwP/64r7/vqR6/72hePm9oXj5vqR6//rivv/85cD//OXA//zlwP/85cD//OXA/7OGzP+vgc3/3cDw/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//dwPD/r4HN/7OGzP/85cD//OXA//zlwP/85cD//OXA//rivv++pHr/vaF4+b2jeOq+pHr/9t25//zlwP/85cD//OXA//zlwP/85cD/u5HK/6+Bzf/VtOr/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/9W06v+vgc3/u5HK//zlwP/85cD//OXA//zlwP/85cD/9t25/76kev+9o3jqvKF3yL6kev/s1K7//OXA//zlwP/85cD//OXA//zlwP/Qq8f/r4HN/8Ob3P/hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/w5vc/6+Bzf/Qq8f//OXA//zlwP/85cD//OXA//zlwP/s1K7/vqR6/7yhd8i9oXiYvqR6/9/Fnv/85cD//OXA//zlwP/85cD//OXA/+/Twv+vgcz/r4PN/9a16//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/9a16/+vg83/r4HM/+/Twv/85cD//OXA//zlwP/85cD//OXA/9/Fnv++pHr/vaF4mL2feFW+pHr/y7GJ//zlwP/85cD//OXA//zlwP/85cD//OXA/8+rx/+vgc3/tIfQ/9a16//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//Wtev/tIfQ/6+Bzf/Pq8f//OXA//zlwP/85cD//OXA//zlwP/85cD/y7GJ/76kev+9n3hVootzC7yhePO+pHr/8tq1//zlwP/85cD//OXA//zlwP/85cD/+uLA/8Obyf+vgc3/r4PN/8Ob3P/VtOr/3cDw/93A8P/VtOr/w5vc/6+Dzf+vgc3/w5vJ//riwP/85cD//OXA//zlwP/85cD//OXA//Latf++pHr/vKF486KLcwsAAAAAu6N3l76kev/Uu5L//OXA//zlwP/85cD//OXA//zlwP/85cD/+uLA/8+rx/+vgcz/r4HN/6+Bzf+vgc3/r4HN/6+Bzf+vgc3/r4HM/8+rx//64sD//OXA//zlwP/85cD//OXA//zlwP/85cD/1LmS/76kev+7oXiWAAAAAAAAAAC3l28gvaN5+L6kev7t1a///OXA//zlwP/85cD//OXA//zlwP/85cD//OXA/+/Twv/Qq8f/u5HK/7OGzP+zhsz/u5HK/9Crx//v08L//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA/+3Vr/++pHr+vaN5+LeXbyAAAAAAAAAAAAAAAAC6oneCvqR6/8Wsg//54Lz//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/34Lz/xayD/76kev+6oneCAAAAAAAAAAAAAAAAAAAAAH9/VQa8oHjLvqR6/8yyiv/64r7//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD/+uK+/8yyiv++pHr/vKB4y39/VQYAAAAAAAAAAAAAAAAAAAAAAAAAALKhbh67o3nkvqR6/8yyiv/54Lz//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//ngvP/Msor/vqR6/7ujeeSyoW4eAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALqbdim7o3nkvqR6/8Wsg//t1a///OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/t1a//xayD/76kev+7o3nkupt2KQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALKhbh68oHjLvqR6/76kev7Uu5L/8tq1//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/y2rX/1LmS/76kev6+pHr/vKB4y7Khbh4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH9/VQa6oneCvaN5+L6kev++pHr/y7GJ/9/Fnv/s1K7/9t25//rivv/64r7/9t25/+zUrv/fxZ7/y7GJ/76kev++pHr/vaN5+Lqid4J/f1UGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC3l28gu6F4lryhePO+pHr/vqR6/76kev++pHr/vqR6/76kev++pHr/vqR6/76kev++pHr/vKF487uheJa3l28gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAootzC72feFW9oXiYvKF3yL2jeOq9oXj5vaF4+b2jeOq8oXfIvaF4mL2feFWii3MLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/gB///gAH//gAAf/wAAD/4AAAf8AAAD+AAAAfAAAADwAAAA4AAAAGAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAGAAAABwAAAA8AAAAPgAAAH8AAAD/gAAB/8AAA//gAAf/+AAf//4Af/
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
	<title>Reply</title>
	<link rel="stylesheet" href="http://tiddlyspace.com/bags/benspa_public/tiddlers/bootvelcro.css">
	<style>
		html,
		body {
			overflow: hidden;
			background-color: transparent;
		}

		#container {
			/* prevent a fouc if no images present */
			display: none;
		}

		.modal-header {
			border-bottom: none;
			padding: 5px 0 0;
			position: absolute;
			width: 100%;
			background-color: #e0e0e0;
			-webkit-border-radius: 6px 6px 0 0;
			-moz-border-radius: 6px 6px 0 0;
			border-radius: 6px 6px 0 0;
			cursor: move;
		}

		.form-actions {
			position: absolute;
			bottom: 0;
			box-sizing: border-box;
			-moz-box-sizing: border-box;
			width: 100%;
			margin: 0;
			border-radius: 0 0 6px 6px;
			background-color: #e0e0e0;
			border-top: 1px solid gray;
		}

		.form-actions input.btn {
			width: auto;
			float: right;
			margin: 0 0.2em;
		}

		.closeBtn {
			background-color: #DCE7F1 !important;
		}

		.primary {
			background-color: #09F !important;
		}

		h1 {
			margin-bottom: 9px;
			margin-top: 9px;
		}

		body {
			width: 100%;
			height: 100%;
			position: absolute;
		}

		.modal {
			margin: 10px;
			top: 0;
			left: 0;
			bottom: 0;
			width: 510px;
			position: absolute;
			box-shadow: #444 0px 0px 10px 2px;
			border-radius: 6px;
			background-color: white;
			border: 1px solid gray;
			background-color: #F0F4F8;
		}

		label em {
			cursor: pointer;
		}

		.modal-body {
			overflow: auto;
			position: absolute;
			top: 0;
			bottom: 0;
			left: 0;
			right: 0;
			margin: 65px 20px 67px;
			background-color: transparent;
		}

		.nav-tabs {
			padding-left: 1%;;
			margin: 0;
			width: 99%;
			border-color: gray;
		}

		.nav-tabs > li {
			cursor: pointer;
		}

		.nav-tabs > li > a {
			line-height: 2.4em;
			font-weight: bold;
			font-size: 100%;
		}

		.nav-tabs > li.active > a{
			background-color: #F0F4F8;
			border-color: gray;
			border-bottom-color: #F0F4F8;
		}

		.active {
			display: block;
		}

		input,
		textarea,
		select,
		.uneditable-input {
			color: #606060;
		}

		.imagePicker {
			-moz-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1);
			-webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1);
			box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1);
			border: 1px solid #CCC;
			height: 110px;
			overflow: auto;
			-webkit-border-radius: 3px;
			-moz-border-radius: 3px;
			border-radius: 3px;
			margin-left: 0;
		}

		.imagePicker img {
			margin: 5px;
			border: 2px solid transparent;
		}

		.imagePicker .current {
			border: 2px dotted #555;
		}

		label {
			font-weight: bold;
		}

		.form-actions label {
			float: left;
			margin-top: 0.75em;
		}

		fieldset input,
		fieldset textarea {
			width: 90%;
			border-color: gray;
		}

		@media all and (max-width: 550px) {
			.modal {
				width: 95%;
			}
		}

		#help {
			position: absolute;
			border: 0;
			right: 4px;
			top: 5px;
			text-indent: -9999px;
			color: transparent;
			height: 16px;
			width: 16px;
			background: none;
			background-image: url(http://tiddlyspace.com/bags/common/tiddlers/help.png);
			background-repeat: no-repeat;
			background-color: white;
			z-index: 2;
			border-radius: 10px;
		}

		#help-info {
			padding: 0;
			border: 1px solid gray;
			width: 60%;
			height: 50px;
			color: #404040;
			background-color: white;
			position: absolute;
			top: 5px;
			right: 5px;
			z-index: 1;
			cursor: auto;
			border-radius: 5px;

		}

		#help-info p {
			padding: 10px 25px;
			margin-bottom: 0;
		}
	</style>
</head>
<body>
	<div id="container">
		<form action="#" class="modal">
			<div class="modal-header">
				<button id="help">help</button>
				<div id="help-info" style="display:none;"><p>
				Found something interesting? Write about it in your own space. <a href="http://docs.tiddlyspace.com/Reply to this Tiddler" target="_blank">Find out more</a>
				</p></div>
				<ul class="nav nav-tabs" data-tabs="tabs">
					<li class="active" data-tab-name="post"><a href="#postForm">Reply</a></li>
				</ul>
			</div>


			<fieldset id="postForm" class="modal-body">
				<label>Title
					<input type="text" name="title">
				</label>
				<input type="hidden" name="url">
				<label>Post
					<textarea name="text" rows="8"></textarea>
				</label>
				<label>Tags
					<input type="text" name="tags" value="">
				</label>
			</fieldset>


			<div class="form-actions">
				<label class="checkbox">
					<input type="checkbox" name="private" val="private">
					keep private
				</label>
				<input type="submit" class="btn primary btn-large" value="Done">
				<input type="button" class="btn btn-large closeBtn" value="Cancel">
			</div>
		</form>
	</div>

	<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
	<script type="text/javascript" src="http://tiddlyspace.com/bags/tiddlyspace/tiddlers/chrjs"></script>
	<script type="text/javascript" src="/bags/common/tiddlers/_reply.js"></script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
	<title>Account</title>
	<link href="/bags/common/tiddlers/profile.css" type='text/css' rel='stylesheet' >
	<link href="/bags/common/tiddlers/admin.css" type='text/css' rel='stylesheet' >
	<link href="/bags/common/tiddlers/jquery-ui.custom.css" type='text/css' rel='stylesheet' >
</head>
<body>

<div id="container">
	<div class="main section">
		<a class="app" href="/">home</a>
		<div class="left">
		<div id="siteiconArea">
		<h2>User Icon</h2>
		<div>
			<img id="siteicon" class="siteicon">
			<form id="upload" method="POST" enctype="multipart/form-data">
				<input type="hidden" name="title" value="SiteIcon" />
				<input type="hidden" name="tags" value="excludeLists">
				<input type="hidden" name="csrf_token" class="csrf" />
				<input type="file" name="file" accept="image/*" />
				<input type="submit" value="upload" />
			</form>
			<div id="dropzone">Drop file here
				<img class="notloading" src="/bags/common/tiddlers/ajax-loader.gif" alt="submitting SiteIcon" />
			</div>
		</div>
		</div>
		<h2>Find Space</h2>
		<form class="spaceSearch">
			<input class="inputBox" type="text" placeholder="find space" />
			<a href="http://docs.tiddlyspace.com/What%20is%20a%20Space%3F" class="help"
				title="What is a space?">What is a space?</a>
			<button>view all</button>
		</form>
		<div class='list-container'>
			You are a member of the following spaces:
			<ul class='ts-space-search'>
			</ul>
		</div>
		<h2>Create New Space</h2>
		<form class="ts-spaces">
			<input class="inputBox" type="text" name="spacename" placeholder="space name"><span class="hostSuffix">.tiddlyspace.com</span>
			<input type="submit" value="Create Space" />
		</form>
		</div>
		<div class="right">
		<h2>Change Password</h2>
		<form class="ts-password">
			<input class="inputBox" placeholder="existing password" type="password" name="password">
			<input class="inputBox" placeholder="new password" type="password" name="new_password">
			<input class="inputBox" placeholder="new password"	type="password" name="new_password_confirm">
			<input type="submit" value="Change password">
		</form>
		<h2>OpenID</h2>
		<h3>Why OpenID?</h3>
		<a href="http://openid.net/"><img src="/bags/common/tiddlers/openid.png" alt="openid" ></a><br />
		Use just one username and password across hundreds of OpenID-enabled sites.<br />
		It's an open standard.<br />
		<a href="http://openid.net/what/">learn more</a>
		<ul class="ts-identities"></ul>
		<form class="ts-openid" target="_top">
			<div>
				Add an openid:
			</div>
			<input class="inputBox" type="text" name="openid" placeholder="your openid" />
			<input type="submit" value="Register" />
			<a href="http://openid.net/get-an-openid/" class="help"
			title="What is an open id?">What is an open id?</a>
		</form>
		</div>
		<div class="clear"></div>
	</div>
</div>
<script src="/bags/common/tiddlers/backstage.js"></script>
<script src='/bags/common/tiddlers/jquery.js'></script>
<script src='/bags/tiddlyspace/tiddlers/chrjs'></script>
<script src='/bags/common/tiddlers/chrjs.space'></script>
<script src='/bags/common/tiddlers/chrjs.users'></script>
<script src='/bags/common/tiddlers/chrjs.identities'></script>
<script src="/bags/common/tiddlers/jquery-ui.custom.js"></script>
<script src='/bags/common/tiddlers/jquery-form.js'></script>
<script src="/bags/common/tiddlers/siteiconupload.js"></script>
<script src='/bags/common/tiddlers/ts.js'></script>
<script src="/status.js"></script>
<script type="text/javascript">
/*
 * jQuery UI Autocomplete HTML Extension
 *
 * Copyright 2010, Scott González (http://scottgonzalez.com)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 *
 * http://github.com/scottgonzalez/jquery-ui-extensions
 */
(function( $ ) {

var proto = $.ui.autocomplete.prototype,
	initSource = proto._initSource;

function filter( array, term ) {
	var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
	return $.grep( array, function(value) {
		return matcher.test( $( "<div>" ).html( value.label || value.value || value ).text() );
	});
}

$.extend( proto, {
	_initSource: function() {
		if ( this.options.html && $.isArray(this.options.source) ) {
			this.source = function( request, response ) {
				response( filter( this.options.source, request.term ) );
			};
		} else {
			initSource.call( this );
		}
	},

	_renderItem: function( ul, item) {
		return $( "<li></li>" )
			.data( "item.autocomplete", item )
			.append( $( "<a></a>" )[ this.options.html ? "html" : "text" ]( item.label ) )
			.appendTo( ul );
	}
});

})( jQuery );

/***
_accounts application specific javascript
***/
var link;
ts.init(function(ts) {
	if(ts.user.anon) { // redirect to homepage when user not logged in
		window.location = ts.getHost();
	} else if(ts.user.name === ts.currentSpace){
		initSiteIconUpload(ts.user.name);
	} else {
		link = $("<a />").attr("href", ts.getHost(ts.user.name) + "/_account").text("Change User Icon");
		$("#siteiconArea div").empty().append(link);
	}
	$(".hostSuffix").text("." + ts.getHost("").split("//")[1]);
	ts.getSpaces(function(spaces) {
		$("<div class='info' />").text("You have " + spaces.length + " spaces.").insertBefore($(".spaceSearch")[0]);
		$("form.spaceSearch input").autocomplete({
			html: true,
			source: function(req, response) {
				ts.getSpaces(function(spaces) {
					var selected = [];
					for(var i = 0; i < spaces.length; i++) {
						var space = spaces[i];
						if(space.name.indexOf(req.term) > -1) {
							var host = ts.getHost(space.name) ;
							var img = host + "/SiteIcon";
							selected.push({
								value: space.name,
								label: '<a href="' + host + '" target="_parent" class="autocompleteLink"><img src="' + img + '" style="height:24px;width:auto;max-height:24px;max-width:24px;"/>' + space.name + '</a>'
							});
						}
					}
					response(selected);
				});
			},
			select: function(event, ui) {
				window.top.location = ts.getHost(ui.item.value);
			}
		});

		var $ul = $('.ts-space-search');
		$.each(spaces, function(i, space) {
			$ul.append($('<li/>').html($('<a/>').attr('href', space.uri)
				.text(space.name)));
		});

		$('form.spaceSearch button').click(function(ev) {
			$('.list-container').slideToggle('fast');
			ev.preventDefault();
			return false;
		});
	});
});

if(window != window.top) {
	$("html").addClass("iframeMode");
	$("a").live("click",function(ev) {
		$(ev.target).attr("target", "_parent");
	});
}
</script>
<!--[if lt IE 8]>
<script type="text/javascript" src="/bags/common/tiddlers/json2.js"></script>
<![endif]-->
</body>
</html>
|Date|Users|Spaces|Created|Modified|Tiddlertime|Searchtime|
|20130101|6427|9668|46|123|321.3|265.43|
|20130102|6435|9679|415|556|326.3|2870.93|
|20130103|6437|9681|192|989|324.4|2587.87|
|20130104|6439|9685|259|404|397.4|2828.7|
|20130105|6442|9689|425|744|315.4|254.83|
|20130106|6444|9692|1015|1092|324.3|2516.1|
|20130107|6451|9705|216|323|664.2|6388.47|
|20130108|6458|9713|240|365|311.7|2692.42|
|20130109|6462|9717|928|1106|317|7895.48|
|20130110|6469|9732|261|347|312.9|2539.79|
|20130111|6473|9738|314|394|317.9|2493.77|
|20130112|6479|9746|197|276|311.9|7040.26|
|20130113|6482|9749|176|293|318|2620.36|
|20130114|6492|9762|179|327|316.5|2555.05|
|20130115|6502|9774|383|533|318|2702.77|
|20130116|6515|9788|459|570|313.3|2616.4|
|20130117|6525|9802|453|631|321|12858.8|
|20130118|6527|9809|666|794|314.8|2705.77|
|20130119|6527|9811|65|150|320.1|2714.4|
|20130120|6529|9815|102|157|316.8|2627.85|
|20130121|6537|9824|603|715|318.8|7349.58|
|20130122|6562|9870|680|870|323.2|10353.4|
|20130123|6571|9881|300|445|320.5|2607.19|
|20130124|6579|9896|655|756|324|7862.56|
|20130125|6584|9904|199|307|322.2|3160.22|
|20130126|6585|9908|253|347|310.1|2839.41|
|20130127|6592|9915|178|264|321.6|2677.86|
|20130128|6599|9922|2605|2744|334|2661.46|
|20130129|6605|9930|379|543|336.4|2856.58|
|20130130|6612|9938|447|575|315.3|2610.55|
|20130131|6618|9947|352|525|328.7|190.8|
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="utf-8"/>
	<title>TiddlySpace Apps</title>
	<link rel="stylesheet" href="/bags/common/tiddlers/reset.css" />
	<link rel="stylesheet" href="/bags/common/tiddlers/appspage.css" />
	<!--[if lt IE 7 ]>
	<link rel="stylesheet" href="/bags/common/tiddlers/appspageie6.css" />
	<![endif]-->
</head>
<body>
	
	<div id="wrapper">
		<div id="TSbar"></div>
		<div id="main-content">
			<div id="space-details">
				<a href="/_space"><img class="siteicon"></a>
				<div id="title-subtitle">
					<h1 class="spaceaddress">
						<span class="spaceName"></span><span class="hostName"></span>
					</h1>
					<p class="tagline"><span class="subTitle"></span><a class="managespaces" href="/_space">manage space</a></p>
				</div>
			</div>
			<div id="holder">
				<div id="appswitcher-wrapper">
					<div id="appswitcher">
						<h2>Your Apps</h2>
						<ul id="app-list">
							<li class="htmlserialisation">
								<a href="/tiddlers.html?select=tag:!excludeLists;sort=-modified">
									<img src="/bags/common/tiddlers/browse_read_blue.png" alt="Icon for the HTML Serialisation" class="app-img" />
									BROWSE
								</a>
							</li>
							<li class="tiddlywiki">
								<a href="/tiddlers.wiki">
									<img src="/bags/common/tiddlers/tiddlywiki2_blue.png" alt="Icon for TiddlyWiki" class="app-img" />
									TIDDLYWIKI
								</a>
							</li>
						</ul>
						<div id="addapp">
							<button class="inactive">Add More!</button>
						</div>
					</div>
					<div id="app-desc">
						<ul>
							<li class="htmlserialisationdesc"><p>an easy to understand HTML representation of your content.</p></li>
							<li class="tiddlywikidesc"><p>use TiddlyWiki to create, edit and organise your content.</p></li>
						</ul>
					</div>
					<div style="clear: both;"></div>
				</div>
			</div>
		</div>
		<div id="footer"><!-- ie doesn't support footer tag -->
			<div id="footer-content">
				<div class="links">
					<a href="http://blog.tiddlyspace.com">blog</a>
					<a href="http://featured.tiddlyspace.com">featured</a>
					<a href="http://docs.tiddlyspace.com">documentation</a>
					<a href="https://github.com/TiddlySpace/tiddlyspace">source</a>
				</div>
				<p>TiddlySpace 2011, created by <a href="http://osmosoft.com">Osmosoft</a></p>
			</div>
		</div>
	</div>
	
	<script type="text/javascript" src="/bags/common/tiddlers/backstage.js"></script>
	<script type="text/javascript" src="/bags/common/tiddlers/jquery.js"></script>
	<script type="text/javascript" src="/bags/tiddlyspace/tiddlers/chrjs"></script>
	<script type="text/javascript" src="/bags/common/tiddlers/chrjs-store.js"></script>
	<script type="text/javascript" src="/bags/common/tiddlers/jquery-json.js"></script>
	<script type="text/javascript" src="/bags/common/tiddlers/appspage.js"></script>
</body>
</html>
/***
|''Name''|TiddlyWebConfig|
|''Description''|configuration settings for TiddlyWebWiki|
|''Author''|FND|
|''Version''|1.3.2|
|''Status''|stable|
|''Source''|http://svn.tiddlywiki.org/Trunk/association/plugins/TiddlyWebConfig.js|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''Requires''|TiddlyWebAdaptor ServerSideSavingPlugin|
|''Keywords''|serverSide TiddlyWeb|
!Code
***/
//{{{
(function($) {

if(!config.extensions.ServerSideSavingPlugin) {
	throw "Missing dependency: ServerSideSavingPlugin";
}
if(!config.adaptors.tiddlyweb) {
	throw "Missing dependency: TiddlyWebAdaptor";
}

if(window.location.protocol != "file:") {
	config.options.chkAutoSave = true;
}

var adaptor = tiddler.getAdaptor();
var recipe = tiddler.fields["server.recipe"];
var workspace = recipe ? "recipes/" + recipe : "bags/common";

var plugin = config.extensions.tiddlyweb = {
	host: tiddler.fields["server.host"].replace(/\/$/, ""),
	username: null,
	status: {},

	getStatus: null, // assigned later
	getUserInfo: function(callback) {
		this.getStatus(function(status) {
			callback({
				name: plugin.username,
				anon: plugin.username ? plugin.username == "GUEST" : true
			});
		});
	},
	hasPermission: function(type, tiddler) {
		var perms = tiddler.fields["server.permissions"];
		if(perms) {
			return perms.split(", ").contains(type);
		} else {
			return true;
		}
	}
};

config.defaultCustomFields = {
	"server.type": tiddler.getServerType(),
	"server.host": plugin.host,
	"server.workspace": workspace
};

// modify toolbar commands

config.shadowTiddlers.ToolbarCommands = config.shadowTiddlers.ToolbarCommands.
	replace("syncing ", "revisions syncing ");

config.commands.saveTiddler.isEnabled = function(tiddler) {
	return plugin.hasPermission("write", tiddler) && !tiddler.isReadOnly();
};

config.commands.deleteTiddler.isEnabled = function(tiddler) {
	return !readOnly && plugin.hasPermission("delete", tiddler);
};

// hijack option macro to disable username editing
var _optionMacro = config.macros.option.handler;
config.macros.option.handler = function(place, macroName, params, wikifier,
		paramString) {
	if(params[0] == "txtUserName") {
		params[0] = "options." + params[0];
		var self = this;
		var args = arguments;
		args[0] = $("<span />").appendTo(place)[0];
		plugin.getUserInfo(function(user) {
			config.macros.message.handler.apply(self, args);
		});
	} else {
		_optionMacro.apply(this, arguments);
	}
};

// hijack isReadOnly to take into account permissions and content type
var _isReadOnly = Tiddler.prototype.isReadOnly;
Tiddler.prototype.isReadOnly = function() {
	return _isReadOnly.apply(this, arguments) ||
		!plugin.hasPermission("write", this);
};

var getStatus = function(callback) {
	if(plugin.status.version) {
		callback(plugin.status);
	} else {
		var self = getStatus;
		if(self.pending) {
			if(callback) {
				self.queue.push(callback);
			}
		} else {
			self.pending = true;
			self.queue = callback ? [callback] : [];
			var _callback = function(context, userParams) {
				var status = context.serverStatus || {};
				for(var key in status) {
					if(key == "username") {
						plugin.username = status[key];
						config.macros.option.propagateOption("txtUserName",
							"value", plugin.username, "input");
					} else {
						plugin.status[key] = status[key];
					}
				}
				for(var i = 0; i < self.queue.length; i++) {
					self.queue[i](plugin.status);
				}
				delete self.queue;
				delete self.pending;
			};
			adaptor.getStatus({ host: plugin.host }, null, _callback);
		}
	}
};
(plugin.getStatus = getStatus)(); // XXX: hacky (arcane combo of assignment plus execution)

})(jQuery);
//}}}
/***
|''Name''|TiddlySpaceConfig|
|''Version''|0.7.7|
|''Description''|TiddlySpace configuration|
|''Status''|stable|
|''Source''|http://github.com/TiddlySpace/tiddlyspace/raw/master/src/plugins/TiddlySpaceConfig.js|
|''CoreVersion''|2.6.1|
|''Requires''|TiddlyWebConfig ServerSideSavingPlugin TiddlyFileImporter|
!Code
***/
//{{{
(function($) {

var tweb = config.extensions.tiddlyweb;

var recipe = config.defaultCustomFields["server.workspace"].split("recipes/")[1];
var currentSpace; // assigned later

var disabledTabs = [];

var coreBags = ["system", "tiddlyspace"];
var systemSpaces = ["plugins", "info", "images", "theme"];
systemSpaces = $.map(systemSpaces, function(item, i) {
	return "system-%0_public".format(item);
});

// hijack search macro to add custom attributes for mobile devices
var _search = config.macros.search.handler;
config.macros.search.handler = function(place, macroName, params) {
	_search.apply(this, arguments);
	$(".searchField:input", place).
		attr({ autocapitalize: "off", autocorrect: "off" });
};

// arg is either a container name or a tiddler object
// if fuzzy is truthy, space may be inferred from workspace (for new tiddlers)
// returns space object or false
var determineSpace = function(arg, fuzzy) {
	if(typeof arg == "string") { // container name
		var space = split(arg, "_", "r");
		return ["public", "private"].contains(space.type) ? space : false;
	} else if(arg) { // tiddler
		var container = determineContainer(arg, fuzzy);
		return container ? determineSpace(container.name, fuzzy) : false;
	} else {
		return false;
	}
};

// if fuzzy is truthy, container may be inferred from workspace for new tiddlers
// returns container object or false
var determineContainer = function(tiddler, fuzzy) { // TODO: expose?
	var bag = tiddler.fields["server.bag"];
	var recipe = tiddler.fields["server.recipe"]; // XXX: unused/irrelevant/redundant!?
	if(bag) {
		return { type: "bag", name: bag };
	} else if(recipe) {
		return { type: "recipe", name: recipe };
	} else if(fuzzy) { // new tiddler
		var workspace = tiddler.fields["server.workspace"];
		if(workspace) {
			var container = split(workspace, "/", "l");
			return ["bags", "recipes"].contains(container.type) ? container : false;
		} else {
			return false;
		}
	} else {
		return false;
	}
};

// hijack removeTiddlerCallback to restore tiddler from recipe cascade -- TODO: move into TiddlyWebWiki?
var sssp = config.extensions.ServerSideSavingPlugin;
var _removeTiddlerCallback = sssp.removeTiddlerCallback;
sssp.removeTiddlerCallback = function(context, userParams) {
	var title = context.tiddler.title;
	var recipe = context.tiddler.fields["server.recipe"];
	_removeTiddlerCallback.apply(this, arguments);
	if(recipe) {
		context.workspace = "recipes/" + recipe;
		var callback = function(context, userParams) {
			if(context.status) {
				var dirty = store.isDirty();
				store.saveTiddler(context.tiddler).clearChangeCount();
				store.setDirty(dirty);
			} else {
				store.notify(title, true);
			}
		};
		context.adaptor.getTiddler(title, context, null, callback);
	}
};

// splits a string once using delimiter
// mode "l" splits at the first, "r" at the last occurrence
// returns an object with members type and name
var split = function(str, sep, mode) {
	mode = mode == "r" ? "pop" : "shift"; // TODO: use +/-1 instead of "l"/"r"?
	var arr = str.split(sep);
	var type = arr.length > 1 ? arr[mode]() : null;
	return { type: type, name: arr.join(sep) };
};

var plugin = config.extensions.tiddlyspace = {
	currentSpace: determineSpace(recipe),
	coreBags: coreBags.concat(systemSpaces),

	determineSpace: determineSpace,
	isValidSpaceName: function(name) {
		return name.match(/^[a-z][0-9a-z\-]*[0-9a-z]$/) ? true : false;
	},
	getCurrentBag: function(type) {
		return "%0_%1".format(currentSpace, type);
	},
	getCurrentWorkspace: function(type) {
		return "bags/" + this.getCurrentBag(type);
	},
	// returns the URL for a space's avatar (SiteIcon) based on a server_host
	// object and an optional space name
	// optional nocors argument prevents cross-domain URLs from being generated
	getAvatar: function(host, space, nocors) {
		if(space && typeof space != "string") { // backwards compatibility -- XXX: deprecated
			space = space.name;
		}
		var subdomain = nocors ? currentSpace : space;
		host = host ? this.getHost(host, subdomain) : "";
		var bag = space ? "%0_public".format(space) : "tiddlyspace";
		return "%0/bags/%1/tiddlers/SiteIcon".format(host, bag);
	},
	// returns the URL based on a server_host object (scheme, host, port) and an
	// optional subdomain
	getHost: function(host, subdomain) {
		if(host === undefined) { // offline
			tweb.status.server_host = {}; // prevents exceptions further down the stack -- XXX: hacky workaround, breaks encapsulation
			return null;
		}
		subdomain = subdomain ? subdomain + "." : "";
		var url = "%0://%1%2".format(host.scheme, subdomain, host.host);
		var port = host.port;
		if(port && !["80", "443"].contains(port)) {
			url += ":" + port;
		}
		return url;
	},
	disableTab: function(tabTiddler) {
		if(typeof(tabTiddler) == "string") {
			disabledTabs.push(tabTiddler);
		} else {
			for(var i = 0; i < tabTiddler.length; i++) {
				plugin.disableTab(tabTiddler[i]);
			}
		}
	},
    checkSyncStatus: function(tiddler) {
		if(tiddler) {
			var title = typeof(tiddler) === "string" ? tiddler : tiddler.title;
			var el = story.getTiddler(title) || false;
			if(el) {
				refreshElements(el);
			}
		}
	},
	isDisabledTab: function(tabTitle) {
		var match = new RegExp("(?:\\[\\[([^\\]]+)\\]\\])", "mg").exec(tabTitle);
		var tabIdentifier = match ? match[1] : tabTitle;
		return disabledTabs.contains(tabIdentifier);
	},
	getCSRFToken: window.getCSRFToken || null // this may not have been processed yet
};

currentSpace = plugin.currentSpace.name;

tweb.serverPrefix = tweb.host.split("/")[3] || ""; // XXX: assumes root handler
tweb.getStatus(function(status) {
	var url = plugin.getHost(status.server_host);
	tweb.status.server_host.url = url;
	config.messages.tsVersion = status.version;
});

if(window.location.protocol == "file:") {
	// enable AutoSave by default
	config.options.chkAutoSave = config.options.chkAutoSave === undefined ?
		true : config.options.chkAutoSave;
} else {
	// set global read-only mode based on membership heuristics
	var indicator = store.getTiddler("SiteTitle") || tiddler;
	readOnly = !(recipe.split("_").pop() == "private" ||
		tweb.hasPermission("write", indicator));
	// replace TiddlyWiki's ImportTiddlers due to cross-domain restrictions
	if(config.macros.fileImport) {
		$.extend(config.macros.importTiddlers, config.macros.fileImport);
	}
}

// hijack saveChanges to ensure SystemSettings is private by default
var _saveChanges = saveChanges;
saveChanges = function(onlyIfDirty, tiddlers) {
	if(tiddlers && tiddlers.length == 1 &&
			tiddlers[0] && tiddlers[0].title == "SystemSettings") {
		var fields = tiddlers[0].fields;
		delete fields["server.recipe"];
		fields["server.bag"] = plugin.getCurrentBag("private");
		fields["server.workspace"] = plugin.getCurrentWorkspace("private");
	}
	return _saveChanges.apply(this, arguments);
};

// ensure backstage is always initialized
// required to circumvent TiddlyWiki's read-only based handling
config.macros.backstageInit = {
	init: function() {
		showBackstage = true;
	}
};

// disable evaluated macro parameters for security reasons
config.evaluateMacroParameters = "none";
var _parseParams = String.prototype.parseParams;
String.prototype.parseParams = function(defaultName, defaultValue, allowEval,
		noNames, cascadeDefaults) {
	if(config.evaluateMacroParameters == "none") {
		arguments[2] = false;
	}
	return _parseParams.apply(this, arguments);
};

var _tabsMacro = config.macros.tabs.handler;
config.macros.tabs.handler = function(place, macroName, params) {
	var newParams = [params[0]]; // keep cookie name
	for(var i = 1; i < params.length; i += 3) {
		var tabTitle = params[i + 2];
		if(!plugin.isDisabledTab(tabTitle)){
			newParams = newParams.concat(params[i], params[i + 1], tabTitle);
		}
	}
	_tabsMacro.apply(this, [place, macroName, newParams]);
};

// disable ControlView for XHRs by default
$.ajaxSetup({
	beforeSend: function(xhr) {
		xhr.setRequestHeader("X-ControlView", "false");
	}
});
// TiddlyWeb adaptor currently still uses httpReq, which needs extra magic -- XXX: obsolete this!
var _httpReq = httpReq;
httpReq = function(type, url, callback, params, headers, data, contentType,
		username, password, allowCache) {
	headers = headers || {};
	headers["X-ControlView"] = "false";
	_httpReq.apply(this, arguments);
};

// register style sheet for backstage separately (important)
store.addNotification("StyleSheetBackstage", refreshStyles);

// option for default privacy setting
config.optionsDesc.chkPrivateMode = "Set your default privacy mode to private";
config.optionsSource.chkPrivateMode = "setting";
config.options.chkPrivateMode = config.options.chkPrivateMode || false;
saveSystemSetting("chkPrivateMode", true);
config.defaultCustomFields["server.workspace"] = plugin.
	getCurrentWorkspace(config.options.chkPrivateMode ? "private" : "public");

config.paramifiers.follow = {
	onstart: function(v) {
		if(!readOnly) {
			var bag = "%0_public".format(currentSpace);
			story.displayTiddler(null, v, DEFAULT_EDIT_TEMPLATE, null, null,
				"server.bag:%0 server.workspace:bags/%0".format(bag));
			story.setTiddlerTag(v, "follow", 1);
			story.focusTiddler(v, "text");
		}
	}
};

var fImport = config.macros.fileImport;
if(fImport) {
	fImport.uploadTo = "Upload to: ";
	var _createForm = config.macros.fileImport.createForm;
	config.macros.fileImport.createForm = function(place, wizard, iframeName) {
		var container = $("<div />").text(fImport.uploadTo).appendTo(place);
		var select = $('<select name="mode" />').appendTo(container)[0];
		$('<option value="private" selected>private</a>').appendTo(select);
		$('<option value="public">public</a>').appendTo(select);
		wizard.setValue("importmode", select);
		_createForm.apply(this, [place, wizard, iframeName]);
	};

	var _onGet = config.macros.importTiddlers.onGetTiddler;
	config.macros.importTiddlers.onGetTiddler = function(context, wizard) {
		var type = $(wizard.getValue("importmode")).val();
		var ws =  plugin.getCurrentWorkspace(type);
		wizard.setValue("workspace", ws);
		_onGet.apply(this, [context, wizard]);
	};
}

config.extensions.ServerSideSavingPlugin.reportSuccess = function(msg, tiddler) {
	plugin.checkSyncStatus(tiddler);
	msg = config.extensions.ServerSideSavingPlugin.locale[msg];
	var link = "/" + encodeURIComponent(tiddler.title);
	displayMessage(msg.format([tiddler.title]), link);
};


})(jQuery);
//}}}
!SpaceUnplugged
{{unpluggedSpaceTab{
{{wizard{
<<image unsyncedIcon width:48>> Sync is currently unavailable in ~TiddlyWiki due to security constraints in modern browsers. Research is being done to build a suitable alternative. In the meantime if you have changed content in an offline ~TiddlyWiki, you can get your content back into ~TiddlySpace by using the ''import'' functionality from the backstage of the online wiki.
}}}
}}}

!Menu
<<message messages.memberStatus>> <<homeLink>>
{{unsyncedList{<<message messages.syncListHeading>> <<list filter [is[unsynced]]>>}}}

running TiddlySpace@glossary version <<message extensions.tiddlyweb.status.tiddlyspace_version>>
{{autotable{
<<tiddler Backstage##Resources>>
}}}

!Resources
[[blog|@@blog]] [[documentation|@@docs]] [[featured spaces|@@featured]] 

!ImportExport
<<fileImport>>
You can download this TiddlySpace as an offline TiddlyWiki:

{{chunkyButton{<<exportSpace>>}}}

!BackstageTiddlers
|upload a <<message messages.privacySetting>> file: <<binaryUpload>>|<<closeAll>><<permaview>><<newTiddler>><<newJournal "DD MMM YYYY" "journal">><<saveChanges>>|
|>|<<search>>|
|>|<<tiddler Backstage##Tiddlers>>|

!Tiddlers
<<tabs
	txtMainTab
	"Recent" "Recently edited tiddlers" TabTimeline
	"All" "All tiddlers" TabAll
	"Public" "All public tiddlers" [[TiddlySpaceTabs##Public]]
	"Private" "All private tiddlers" [[TiddlySpaceTabs##Private]]
	"Tags" "All tags" TabTags
	"Spaces" "Tiddlers grouped by space" [[TiddlySpaceTabs##Spaces]]
	"Missing" "Missing tiddlers" TabMoreMissing
	"Orphans" "Orphaned tiddlers" TabMoreOrphans
	"Shadows" "Shadowed tiddlers" TabMoreShadowed
>>

!BatchOps
<<tabs
	txtPublisherTab
	"Private" "Move tiddlers from private to public" Backstage##BatchPrivate
	"Public" "Move tiddlers from public to private" Backstage##BatchPublic
>>

!BatchPrivate
<<TiddlySpacePublisher type:private>>

!BatchPublic
<<TiddlySpacePublisher type:public>>

!Plugins
''Note:'' Many of these plugins are core TiddlySpace plugins and cannot be changed unless first cloned.

<<tiddler PluginManager>>

!Tweaks
These options change behavior in TiddlyWiki //only// and may be ineffective in TiddlySpace.

<<tiddler AdvancedOptions>>
/***
|''Name''|TiddlyWebAdaptor|
|''Description''|adaptor for interacting with TiddlyWeb|
|''Author:''|FND|
|''Contributors''|Chris Dent, Martin Budden|
|''Version''|1.4.10|
|''Status''|stable|
|''Source''|http://svn.tiddlywiki.org/Trunk/association/adaptors/TiddlyWebAdaptor.js|
|''CodeRepository''|http://svn.tiddlywiki.org/Trunk/association/|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''CoreVersion''|2.5|
|''Keywords''|serverSide TiddlyWeb|
!Notes
This plugin includes [[jQuery JSON|http://code.google.com/p/jquery-json/]].
!To Do
* createWorkspace
* document custom/optional context attributes (e.g. filters, query, revision) and tiddler fields (e.g. server.title, origin)
!Code
***/
//{{{
(function($) {

var adaptor = config.adaptors.tiddlyweb = function() {};

adaptor.prototype = new AdaptorBase();
adaptor.serverType = "tiddlyweb";
adaptor.serverLabel = "TiddlyWeb";
adaptor.mimeType = "application/json";

adaptor.parsingErrorMessage = "Error parsing result from server";
adaptor.noBagErrorMessage = "no bag specified for tiddler";
adaptor.locationIDErrorMessage = "no bag or recipe specified for tiddler"; // TODO: rename

// retrieve current status (requires TiddlyWeb status plugin)
adaptor.prototype.getStatus = function(context, userParams, callback) {
	context = this.setContext(context, userParams, callback);
	var uriTemplate = "%0/status";
	var uri = uriTemplate.format([context.host]);
	var req = httpReq("GET", uri, adaptor.getStatusCallback, context,
		null, null, null, null, null, true);
	return typeof req == "string" ? req : true;
};

adaptor.getStatusCallback = function(status, context, responseText, uri, xhr) {
	context.status = responseText ? status : false;
	try {
		context.statusText = xhr.statusText;
	} catch(exc) { // offline (Firefox)
		context.status = false;
		context.statusText = null;
	}
	context.httpStatus = xhr.status;
	if(context.status) {
		context.serverStatus = $.evalJSON(responseText); // XXX: error handling!?
	}
	if(context.callback) {
		context.callback(context, context.userParams);
	}
};

// retrieve a list of workspaces
adaptor.prototype.getWorkspaceList = function(context, userParams, callback) {
	context = this.setContext(context, userParams, callback);
	context.workspaces = [];
	var uriTemplate = "%0/recipes"; // XXX: bags?
	var uri = uriTemplate.format([context.host]);
	var req = httpReq("GET", uri, adaptor.getWorkspaceListCallback,
		context, { accept: adaptor.mimeType }, null, null, null, null, true);
	return typeof req == "string" ? req : true;
};

adaptor.getWorkspaceListCallback = function(status, context, responseText, uri, xhr) {
	context.status = status;
	context.statusText = xhr.statusText;
	context.httpStatus = xhr.status;
	if(status) {
		try {
			var workspaces = $.evalJSON(responseText);
		} catch(ex) {
			context.status = false; // XXX: correct?
			context.statusText = exceptionText(ex, adaptor.parsingErrorMessage);
			if(context.callback) {
				context.callback(context, context.userParams);
			}
			return;
		}
		context.workspaces = workspaces.map(function(itm) { return { title: itm }; });
	}
	if(context.callback) {
		context.callback(context, context.userParams);
	}
};

// retrieve a list of tiddlers
adaptor.prototype.getTiddlerList = function(context, userParams, callback) {
	context = this.setContext(context, userParams, callback);
	var uriTemplate = "%0/%1/%2/tiddlers%3";
	var params = context.filters ? "?" + context.filters : "";
	if(context.format) {
		params = context.format + params;
	}
	var workspace = adaptor.resolveWorkspace(context.workspace);
	var uri = uriTemplate.format([context.host, workspace.type + "s",
		adaptor.normalizeTitle(workspace.name), params]);
	var req = httpReq("GET", uri, adaptor.getTiddlerListCallback,
		context, merge({ accept: adaptor.mimeType }, context.headers), null, null, null, null, true);
	return typeof req == "string" ? req : true;
};

adaptor.getTiddlerListCallback = function(status, context, responseText, uri, xhr) {
	context.status = status;
	context.statusText = xhr.statusText;
	context.httpStatus = xhr.status;
	if(status) {
		context.tiddlers = [];
		try {
			var tiddlers = $.evalJSON(responseText); //# NB: not actual tiddler instances
		} catch(ex) {
			context.status = false; // XXX: correct?
			context.statusText = exceptionText(ex, adaptor.parsingErrorMessage);
			if(context.callback) {
				context.callback(context, context.userParams);
			}
			return;
		}
		for(var i = 0; i < tiddlers.length; i++) {
			var tiddler = adaptor.toTiddler(tiddlers[i], context.host);
			context.tiddlers.push(tiddler);
		}
	}
	if(context.callback) {
		context.callback(context, context.userParams);
	}
};

// perform global search
adaptor.prototype.getSearchResults = function(context, userParams, callback) {
	context = this.setContext(context, userParams, callback);
	var uriTemplate = "%0/search?q=%1%2";
	var filterString = context.filters ? ";" + context.filters : "";
	var uri = uriTemplate.format([context.host, context.query, filterString]); // XXX: parameters need escaping?
	var req = httpReq("GET", uri, adaptor.getSearchResultsCallback,
		context, { accept: adaptor.mimeType }, null, null, null, null, true);
	return typeof req == "string" ? req : true;
};

adaptor.getSearchResultsCallback = function(status, context, responseText, uri, xhr) {
	adaptor.getTiddlerListCallback(status, context, responseText, uri, xhr); // XXX: use apply?
};

// retrieve a particular tiddler's revisions
adaptor.prototype.getTiddlerRevisionList = function(title, limit, context, userParams, callback) {
	context = this.setContext(context, userParams, callback);
	var uriTemplate = "%0/%1/%2/tiddlers/%3/revisions";
	var workspace = adaptor.resolveWorkspace(context.workspace);
	var uri = uriTemplate.format([context.host, workspace.type + "s",
		adaptor.normalizeTitle(workspace.name), adaptor.normalizeTitle(title)]);
	var req = httpReq("GET", uri, adaptor.getTiddlerRevisionListCallback,
		context, merge({ accept: adaptor.mimeType }, context.headers), null, null, null, null, true);
	return typeof req == "string" ? req : true;
};

adaptor.getTiddlerRevisionListCallback = function(status, context, responseText, uri, xhr) {
	context.status = status;
	context.statusText = xhr.statusText;
	context.httpStatus = xhr.status;
	if(status) {
		context.revisions = [];
		try {
			var tiddlers = $.evalJSON(responseText); //# NB: not actual tiddler instances
		} catch(ex) {
			context.status = false; // XXX: correct?
			context.statusText = exceptionText(ex, adaptor.parsingErrorMessage);
			if(context.callback) {
				context.callback(context, context.userParams);
			}
			return;
		}
		for(var i = 0; i < tiddlers.length; i++) {
			var tiddler = adaptor.toTiddler(tiddlers[i], context.host);
			context.revisions.push(tiddler);
		}
		var sortField = "server.page.revision";
		context.revisions.sort(function(a, b) {
			return a.fields[sortField] < b.fields[sortField] ? 1 :
				(a.fields[sortField] == b.fields[sortField] ? 0 : -1);
		});
	}
	if(context.callback) {
		context.callback(context, context.userParams);
	}
};

// retrieve an individual tiddler revision -- XXX: breaks with standard arguments list -- XXX: convenience function; simply use getTiddler?
adaptor.prototype.getTiddlerRevision = function(title, revision, context, userParams, callback) {
	context = this.setContext(context, userParams, callback);
	context.revision = revision;
	return this.getTiddler(title, context, userParams, callback);
};

// retrieve an individual tiddler
//# context is an object with members host and workspace
//# callback is passed the new context and userParams
adaptor.prototype.getTiddler = function(title, context, userParams, callback) {
	context = this.setContext(context, userParams, callback);
	context.title = title;
	if(context.revision) {
		var uriTemplate = "%0/%1/%2/tiddlers/%3/revisions/%4";
	} else {
		uriTemplate = "%0/%1/%2/tiddlers/%3";
	}
	if(!context.tiddler) {
		context.tiddler = new Tiddler(title);
	}
	context.tiddler.fields["server.type"] = adaptor.serverType;
	context.tiddler.fields["server.host"] = AdaptorBase.minHostName(context.host);
	context.tiddler.fields["server.workspace"] = context.workspace;
	var workspace = adaptor.resolveWorkspace(context.workspace);
	var uri = uriTemplate.format([context.host, workspace.type + "s",
		adaptor.normalizeTitle(workspace.name), adaptor.normalizeTitle(title),
		context.revision]);
	var req = httpReq("GET", uri, adaptor.getTiddlerCallback, context,
		merge({ accept: adaptor.mimeType }, context.headers), null, null, null, null, true);
	return typeof req == "string" ? req : true;
};

adaptor.getTiddlerCallback = function(status, context, responseText, uri, xhr) {
	context.status = status;
	context.statusText = xhr.statusText;
	context.httpStatus = xhr.status;
	if(status) {
		try {
			var tid = $.evalJSON(responseText);
		} catch(ex) {
			context.status = false;
			context.statusText = exceptionText(ex, adaptor.parsingErrorMessage);
			if(context.callback) {
				context.callback(context, context.userParams);
			}
			return;
		}
		var tiddler = adaptor.toTiddler(tid, context.host);
		tiddler.title = context.tiddler.title;
		tiddler.fields["server.etag"] = xhr.getResponseHeader("Etag");
		// normally we'd assign context.tiddler = tiddler here - but we can't do
		// that because of IE, which triggers getTiddler in putTiddlerCallback,
		// and since ServerSideSavingPlugin foolishly relies on persistent
		// object references, we need to merge the data into the existing object
		$.extend(context.tiddler, tiddler);
	}
	if(context.callback) {
		context.callback(context, context.userParams);
	}
};

// retrieve tiddler chronicle (all revisions)
adaptor.prototype.getTiddlerChronicle = function(title, context, userParams, callback) {
	context = this.setContext(context, userParams, callback);
	context.title = title;
	var uriTemplate = "%0/%1/%2/tiddlers/%3/revisions?fat=1";
	var workspace = adaptor.resolveWorkspace(context.workspace);
	var uri = uriTemplate.format([context.host, workspace.type + "s",
		adaptor.normalizeTitle(workspace.name), adaptor.normalizeTitle(title)]);
	var req = httpReq("GET", uri, adaptor.getTiddlerChronicleCallback,
		context, { accept: adaptor.mimeType }, null, null, null, null, true);
	return typeof req == "string" ? req : true;
};

adaptor.getTiddlerChronicleCallback = function(status, context, responseText, uri, xhr) {
	context.status = status;
	context.statusText = xhr.statusText;
	context.httpStatus = xhr.status;
	if(status) {
		context.responseText = responseText;
	}
	if(context.callback) {
		context.callback(context, context.userParams);
	}
};

// store an individual tiddler
adaptor.prototype.putTiddler = function(tiddler, context, userParams, callback) {
	context = this.setContext(context, userParams, callback);
	context.title = tiddler.title;
	context.tiddler = tiddler;
	context.host = context.host || this.fullHostName(tiddler.fields["server.host"]);
	var uriTemplate = "%0/%1/%2/tiddlers/%3";
	try {
		context.workspace = context.workspace || tiddler.fields["server.workspace"];
		var workspace = adaptor.resolveWorkspace(context.workspace);
	} catch(ex) {
		return adaptor.locationIDErrorMessage;
	}
	var uri = uriTemplate.format([context.host, workspace.type + "s",
		adaptor.normalizeTitle(workspace.name),
		adaptor.normalizeTitle(tiddler.title)]);
	var etag = adaptor.generateETag(workspace, tiddler);
	var headers = etag ? { "If-Match": etag } : null;
	var payload = {
		type: tiddler.fields["server.content-type"] || null,
		text: tiddler.text,
		tags: tiddler.tags,
		fields: $.extend({}, tiddler.fields)
	};
	delete payload.fields.changecount;
	$.each(payload.fields, function(key, value) {
		if(key.indexOf("server.") == 0) {
			delete payload.fields[key];
		}
	});
	payload = $.toJSON(payload);
	var req = httpReq("PUT", uri, adaptor.putTiddlerCallback,
		context, headers, payload, adaptor.mimeType, null, null, true);
	return typeof req == "string" ? req : true;
};

adaptor.putTiddlerCallback = function(status, context, responseText, uri, xhr) {
	context.status = [204, 1223].contains(xhr.status);
	context.statusText = xhr.statusText;
	context.httpStatus = xhr.status;
	if(context.status) {
		var loc = xhr.getResponseHeader("Location");
		var etag = xhr.getResponseHeader("Etag");
		if(loc && etag) {
			var bag = loc.split("/bags/").pop().split("/")[0];
			context.tiddler.fields["server.bag"] = bag;
			context.tiddler.fields["server.workspace"] = "bags/" + bag;
			var rev = etag.split("/").pop().split(/;|:/)[0];
			context.tiddler.fields["server.page.revision"] = rev;
			context.tiddler.fields["server.etag"] = etag;
			if(context.callback) {
				context.callback(context, context.userParams);
			}
		} else { // IE
			context.adaptor.getTiddler(context.tiddler.title, context,
				context.userParams, context.callback);
		}
	} else if(context.callback) {
		context.callback(context, context.userParams);
	}
};

// store a tiddler chronicle
adaptor.prototype.putTiddlerChronicle = function(revisions, context, userParams, callback) {
	context = this.setContext(context, userParams, callback);
	context.title = revisions[0].title;
	var headers = null;
	var uriTemplate = "%0/%1/%2/tiddlers/%3/revisions";
	var host = context.host || this.fullHostName(tiddler.fields["server.host"]);
	var workspace = adaptor.resolveWorkspace(context.workspace);
	var uri = uriTemplate.format([host, workspace.type + "s",
		adaptor.normalizeTitle(workspace.name),
		adaptor.normalizeTitle(context.title)]);
	if(workspace.type == "bag") { // generate ETag
		var etag = [adaptor.normalizeTitle(workspace.name),
			adaptor.normalizeTitle(context.title), 0].join("/"); //# zero-revision prevents overwriting existing contents
		headers = { "If-Match": '"' + etag + '"' };
	}
	var payload = $.toJSON(revisions);
	var req = httpReq("POST", uri, adaptor.putTiddlerChronicleCallback,
		context, headers, payload, adaptor.mimeType, null, null, true);
	return typeof req == "string" ? req : true;
};

adaptor.putTiddlerChronicleCallback = function(status, context, responseText, uri, xhr) {
	context.status = [204, 1223].contains(xhr.status);
	context.statusText = xhr.statusText;
	context.httpStatus = xhr.status;
	if(context.callback) {
		context.callback(context, context.userParams);
	}
};

// store a collection of tiddlers (import TiddlyWiki HTML store)
adaptor.prototype.putTiddlerStore = function(store, context, userParams, callback) {
	context = this.setContext(context, userParams, callback);
	var uriTemplate = "%0/%1/%2/tiddlers";
	var host = context.host;
	var workspace = adaptor.resolveWorkspace(context.workspace);
	var uri = uriTemplate.format([host, workspace.type + "s",
		adaptor.normalizeTitle(workspace.name)]);
	var req = httpReq("POST", uri, adaptor.putTiddlerStoreCallback,
		context, null, store, "text/x-tiddlywiki", null, null, true);
	return typeof req == "string" ? req : true;
};

adaptor.putTiddlerStoreCallback = function(status, context, responseText, uri, xhr) {
	context.status = [204, 1223].contains(xhr.status);
	context.statusText = xhr.statusText;
	context.httpStatus = xhr.status;
	if(context.callback) {
		context.callback(context, context.userParams);
	}
};

// rename an individual tiddler or move it to a different workspace -- TODO: make {from|to}.title optional
//# from and to are objects with members title and workspace (bag; optional),
//# representing source and target tiddler, respectively
adaptor.prototype.moveTiddler = function(from, to, context, userParams, callback) { // XXX: rename parameters (old/new)?
	var self = this;
	var newTiddler = store.getTiddler(from.title) || store.getTiddler(to.title); //# local rename might already have occurred
	var oldTiddler = $.extend(true, {}, newTiddler); //# required for eventual deletion
	oldTiddler.title = from.title; //# required for original tiddler's ETag
	var _getTiddlerChronicle = function(title, context, userParams, callback) {
		return self.getTiddlerChronicle(title, context, userParams, callback);
	};
	var _putTiddlerChronicle = function(context, userParams) {
		if(!context.status) {
			return callback(context, userParams);
		}
		var revisions = $.evalJSON(context.responseText); // XXX: error handling?
		// change current title while retaining previous location
		for(var i = 0; i < revisions.length; i++) {
			delete revisions[i].revision;
			if(!revisions[i].fields.origin) { // NB: origin = "<workspace>/<title>"
				revisions[i].fields.origin = ["bags", revisions[i].bag, revisions[i].title].join("/");
			}
			revisions[i].title = to.title;
		}
		// add new revision
		var rev = $.extend({}, revisions[0]);
		$.each(newTiddler, function(i, item) {
			if(!$.isFunction(item)) {
				rev[i] = item;
			}
		});
		rev.title = to.title;
		rev.created = rev.created.convertToYYYYMMDDHHMM();
		rev.modified = new Date().convertToYYYYMMDDHHMM();
		delete rev.fields.changecount;
		revisions.unshift(rev);
		if(to.workspace) {
			context.workspace = to.workspace;
		} else if(context.workspace.substring(0, 4) != "bags") { // NB: target workspace must be a bag
			context.workspace = "bags/" + rev.bag;
		}
		var subCallback = function(context, userParams) {
			if(!context.status) {
				return callback(context, userParams);
			}
			context.adaptor.getTiddler(newTiddler.title, context, userParams, _deleteTiddler);
		};
		return self.putTiddlerChronicle(revisions, context, context.userParams, subCallback);
	};
	var _deleteTiddler = function(context, userParams) {
		if(!context.status) {
			return callback(context, userParams);
		}
		$.extend(true, newTiddler, context.tiddler);
		context.callback = null;
		return self.deleteTiddler(oldTiddler, context, context.userParams, callback);
	};
	callback = callback || function() {};
	context = this.setContext(context, userParams);
	context.host = context.host || oldTiddler.fields["server.host"];
	context.workspace = from.workspace || oldTiddler.fields["server.workspace"];
	return _getTiddlerChronicle(from.title, context, userParams, _putTiddlerChronicle);
};

// delete an individual tiddler
adaptor.prototype.deleteTiddler = function(tiddler, context, userParams, callback) {
	context = this.setContext(context, userParams, callback);
	context.title = tiddler.title; // XXX: not required!?
	var uriTemplate = "%0/bags/%1/tiddlers/%2";
	var host = context.host || this.fullHostName(tiddler.fields["server.host"]);
	var bag = tiddler.fields["server.bag"];
	if(!bag) {
		return adaptor.noBagErrorMessage;
	}
	var uri = uriTemplate.format([host, adaptor.normalizeTitle(bag),
		adaptor.normalizeTitle(tiddler.title)]);
	var etag = adaptor.generateETag({ type: "bag", name: bag }, tiddler);
	var headers = etag ? { "If-Match": etag } : null;
	var req = httpReq("DELETE", uri, adaptor.deleteTiddlerCallback, context, headers,
		null, null, null, null, true);
	return typeof req == "string" ? req : true;
};

adaptor.deleteTiddlerCallback = function(status, context, responseText, uri, xhr) {
	context.status = [204, 1223].contains(xhr.status);
	context.statusText = xhr.statusText;
	context.httpStatus = xhr.status;
	if(context.callback) {
		context.callback(context, context.userParams);
	}
};

// compare two revisions of a tiddler (requires TiddlyWeb differ plugin)
//# if context.rev1 is not specified, the latest revision will be used for comparison
//# if context.rev2 is not specified, the local revision will be sent for comparison
//# context.format is a string as determined by the TiddlyWeb differ plugin
adaptor.prototype.getTiddlerDiff = function(title, context, userParams, callback) {
	context = this.setContext(context, userParams, callback);
	context.title = title;

	var tiddler = store.getTiddler(title);
	try {
		var workspace = adaptor.resolveWorkspace(tiddler.fields["server.workspace"]);
	} catch(ex) {
		return adaptor.locationIDErrorMessage;
	}
	var tiddlerRef = [workspace.type + "s", workspace.name, tiddler.title].join("/");

	var rev1 = context.rev1 ? [tiddlerRef, context.rev1].join("/") : tiddlerRef;
	var rev2 = context.rev2 ? [tiddlerRef, context.rev2].join("/") : null;

	var uriTemplate = "%0/diff?rev1=%1";
	if(rev2) {
		uriTemplate += "&rev2=%2";
	}
	if(context.format) {
		uriTemplate += "&format=%3";
	}
	var host = context.host || this.fullHostName(tiddler.fields["server.host"]);
	var uri = uriTemplate.format([host, adaptor.normalizeTitle(rev1),
		adaptor.normalizeTitle(rev2), context.format]);

	if(rev2) {
		var req = httpReq("GET", uri, adaptor.getTiddlerDiffCallback, context, null,
			null, null, null, null, true);
	} else {
		var payload = {
			title: tiddler.title,
			text: tiddler.text,
			modifier: tiddler.modifier,
			tags: tiddler.tags,
			fields: $.extend({}, tiddler.fields)
		}; // XXX: missing attributes!?
		payload = $.toJSON(payload);
		req = httpReq("POST", uri, adaptor.getTiddlerDiffCallback, context,
			null, payload, adaptor.mimeType, null, null, true);
	}
	return typeof req == "string" ? req : true;
};

adaptor.getTiddlerDiffCallback = function(status, context, responseText, uri, xhr) {
	context.status = status;
	context.statusText = xhr.statusText;
	context.httpStatus = xhr.status;
	context.uri = uri;
	if(status) {
		context.diff = responseText;
	}
	if(context.callback) {
		context.callback(context, context.userParams);
	}
};

// generate tiddler information
adaptor.prototype.generateTiddlerInfo = function(tiddler) {
	var info = {};
	var uriTemplate = "%0/%1/%2/tiddlers/%3";
	var host = this.host || tiddler.fields["server.host"]; // XXX: this.host obsolete?
	host = this.fullHostName(host);
	var workspace = adaptor.resolveWorkspace(tiddler.fields["server.workspace"]);
	info.uri = uriTemplate.format([host, workspace.type + "s",
		adaptor.normalizeTitle(workspace.name),
		adaptor.normalizeTitle(tiddler.title)]);
	return info;
};

// create Tiddler instance from TiddlyWeb tiddler JSON
adaptor.toTiddler = function(json, host) {
	var created = Date.convertFromYYYYMMDDHHMM(json.created);
	var modified = Date.convertFromYYYYMMDDHHMM(json.modified);
	var fields = json.fields;
	fields["server.type"] = adaptor.serverType;
	fields["server.host"] = AdaptorBase.minHostName(host);
	fields["server.bag"] = json.bag;
	fields["server.title"] = json.title;
	if(json.recipe) {
		fields["server.recipe"] = json.recipe;
	}
	if(json.type && json.type != "None") {
		fields["server.content-type"] = json.type;
	}
	fields["server.permissions"] = json.permissions.join(", ");
	fields["server.page.revision"] = json.revision;
	fields["server.workspace"] = "bags/" + json.bag;
	var tiddler = new Tiddler(json.title);
	tiddler.assign(tiddler.title, json.text, json.modifier, modified, json.tags,
		created, json.fields, json.creator);
	return tiddler;
};

adaptor.resolveWorkspace = function(workspace) {
	var components = workspace.split("/");
	return {
		type: components[0] == "bags" ? "bag" : "recipe",
		name: components[1] || components[0]
	};
};

adaptor.generateETag = function(workspace, tiddler) {
	var revision = tiddler.fields["server.page.revision"];
	var etag = revision == "false" ? null : tiddler.fields["server.etag"];
	if(!etag && workspace.type == "bag") {
		if(typeof revision == "undefined") {
			revision = "0";
		} else if(revision == "false") {
			return null;
		}
		etag = [adaptor.normalizeTitle(workspace.name),
			adaptor.normalizeTitle(tiddler.title), revision].join("/");
		etag = '"' + etag + '"';
	}
	return etag;
};

adaptor.normalizeTitle = function(title) {
	return encodeURIComponent(title);
};

})(jQuery);


/*
 * jQuery JSON Plugin
 * version: 1.3
 * source: http://code.google.com/p/jquery-json/
 * license: MIT (http://www.opensource.org/licenses/mit-license.php)
 */
(function($){function toIntegersAtLease(n)
{return n<10?'0'+n:n;}
Date.prototype.toJSON=function(date)
{return this.getUTCFullYear()+'-'+
toIntegersAtLease(this.getUTCMonth())+'-'+
toIntegersAtLease(this.getUTCDate());};var escapeable=/["\\\x00-\x1f\x7f-\x9f]/g;var meta={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'};$.quoteString=function(string)
{if(escapeable.test(string))
{return'"'+string.replace(escapeable,function(a)
{var c=meta[a];if(typeof c==='string'){return c;}
c=a.charCodeAt();return'\\u00'+Math.floor(c/16).toString(16)+(c%16).toString(16);})+'"';}
return'"'+string+'"';};$.toJSON=function(o,compact)
{var type=typeof(o);if(type=="undefined")
return"undefined";else if(type=="number"||type=="boolean")
return o+"";else if(o===null)
return"null";if(type=="string")
{return $.quoteString(o);}
if(type=="object"&&typeof o.toJSON=="function")
return o.toJSON(compact);if(type!="function"&&typeof(o.length)=="number")
{var ret=[];for(var i=0;i<o.length;i++){ret.push($.toJSON(o[i],compact));}
if(compact)
return"["+ret.join(",")+"]";else
return"["+ret.join(", ")+"]";}
if(type=="function"){throw new TypeError("Unable to convert object of type 'function' to json.");}
var ret=[];for(var k in o){var name;type=typeof(k);if(type=="number")
name='"'+k+'"';else if(type=="string")
name=$.quoteString(k);else
continue;var val=$.toJSON(o[k],compact);if(typeof(val)!="string"){continue;}
if(compact)
ret.push(name+":"+val);else
ret.push(name+": "+val);}
return"{"+ret.join(", ")+"}";};$.compactJSON=function(o)
{return $.toJSON(o,true);};$.evalJSON=function(src)
{return eval("("+src+")");};$.secureEvalJSON=function(src)
{var filtered=src;filtered=filtered.replace(/\\["\\\/bfnrtu]/g,'@');filtered=filtered.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']');filtered=filtered.replace(/(?:^|:|,)(?:\s*\[)+/g,'');if(/^[\],:{}\s]*$/.test(filtered))
return eval("("+src+")");else
throw new SyntaxError("Error parsing JSON, source is not valid.");};})(jQuery);
//}}}
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
//{{{
/* http://keith-wood.name/gChart.html
   Google Chart interface for jQuery v1.3.2.
   See API details at http://code.google.com/apis/chart/.
   Written by Keith Wood (kbwood{at}iinet.com.au) September 2008.
   Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and 
   MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses. 
   Please attribute the author if you use it. */

/* Request a chart from Google charts.
   $('div selector').gchart({type: 'pie', series: [$.gchart.series([101, 84])]});
*/

(function($) { // Hide scope, no $ conflict

/* Google Charting manager. */
function GChart() {
	this._defaults = {
		width: 0, // Width of the chart
		height: 0, // Height of the chart
		format: 'png', // Returned format: png, gif
		usePost: false, // True to POST instead of GET - for larger charts with more data
		margins: null, // The minimum margins (pixels) around the chart:
			// all or [left/right, top/bottom] or [left, right, top, bottom]
		title: '', // The title of the chart
		titleColor: '', // The colour of the title
		titleSize: 0, // The font size of the title
		opacity: 0, // Make the entire chart semi-transparent (0.0-1.0 or 0-100)
		backgroundColor: null, // The background colour for the entire image
		chartColor: null, // The background colour for the chart area
		legend: '', // The location of the legend: top, topVertical,
			// bottom, bottomVertical, left, right, or '' for none
		legendOrder: 'normal', // The order of items within a legend: normal, reverse, automatic
		legendSize: null, // The minimum size (pixels) of the legend: [width, height]
		type: 'pie3D', // Type of chart requested: line, lineXY, sparkline,
			// barHoriz, barVert, barHorizGrouped, barVertGrouped, pie, pie3D (default),
			// pieConcentric, venn, scatter, radar, radarCurved, map, meter, qrCode, formula
		encoding: '', // Type of data encoding: text (default), scaled, simple, extended
		series: [this.series('Hello World', [60, 40])], // Details about the values to be plotted
		visibleSeries: 0, // The number of series that are directly displayed, 0 for all
		dataLabels: [], // Labels for the values across all the series
		axes: [], // Definitions for the various axes, each entry is either
			// a string of the axis name or a GChartAxis object
		ranges: [], // Definitions of ranges for the chart, each entry is an object with
			// vertical (boolean), color (string), start (number, 0-1),
			// and end (number, 0-1) attributes
		markers: [], // Definitions of markers for the chart, each entry is an object with
			// shape (arrow, circle, cross, diamond, down, flag, horizontal,
			// number, plus, sparkfill, sparkline, square, text, vertical),
			// color (string), series (number), item (number), size (number),
			// priority (number), text (string), positioned (boolean),
			// placement (string or string[]), offsets (number[2])
		icons: [], // Definitions of dynamic icons for the chart, each entry is an object with
			// name (string), data (string), series (number), item (number), zIndex (number),
			// position (number[2]), offsets (number[2])
		minValue: 0, // The minimum value of the data, $.gchart.calculate to calculate from data
		maxValue: 100, // The maximum value of the data, $.gchart.calculate to calculate from data
		gridSize: [], // The x and y spacings between grid lines
		gridLine: [], // The line and gap lengths for the grid lines
		gridOffsets: [], // The x and y offsets for the grid lines
		extension: {}, // Any custom extensions to the Google chart parameters
		// Bar charts -------------
		barWidth: null, // The width of each bar (pixels) or 'a' for automatic or 'r' for relative
		barSpacing: null, // The space (pixels) between bars in a group
		barGroupSpacing: null, // The space (pixels) between groups of bars
		barZeroPoint: null, // The position (0.0 to 1.0) of the zero-line
		// Pie charts -------------
		pieOrientation: 0, // The angle (degrees) of orientation from the positive x-axis
		// Maps -------------------
		mapArea: 'world', // The general area to show: world,
			// africa, asia, europe, middle_east, south_america, usa
		mapRegions: [], // List of country/state codes to plot
		mapDefaultColor: 'bebebe', // The colour for non-plotted countries/states
		mapColors: ['blue', 'red'], // The colour range for plotted countries/states
		// QR Code ----------------
		qrECLevel: null, // Error correction level: low, medium, quarter, high
		qrMargin: null, // Margin (squares) around QR code, default is 4
		// Callback
		onLoad: null, // Function to call when loaded
		provideJSON: false // True to return JSON description of chart with the onLoad callback
	};
};

/* The name of the data property that holds the instance settings. */
var PROP_NAME = 'gChart';
/* Translations of text colour names into chart values. */
var COLOURS = {aqua: '008080', black: '000000', blue: '0000ff', fuchsia: 'ff00ff', gray: '808080',
	green: '008000', grey: '808080', lime: '00ff00', maroon: '800000', navy: '000080',
	olive: '808000', orange: 'ffa500', purple: '800080', red: 'ff0000', silver: 'c0c0c0',
	teal: '008080', transparent: '00000000', white: 'ffffff', yellow: 'ffff00'};
/* Mapping from plugin chart types to Google chart types. */
var CHART_TYPES = {line: 'lc', lineXY: 'lxy', sparkline: 'ls',
	barHoriz: 'bhs', barVert: 'bvs', barHorizGrouped: 'bhg', barVertGrouped: 'bvg', graphviz: 'gv',
	pie: 'p', pie3D: 'p3', pieConcentric: 'pc', venn: 'v', scatter: 's',
	radar: 'r', radarCurved: 'rs', map: 't', meter: 'gom', qrCode: 'qr', formula: 'tx',
	lc: 'lc', lxy: 'lxy', ls: 'ls', bhs: 'bhs', bvs: 'bvs', bhg: 'bhg', bvg: 'bvg', gv: 'gv',
	p: 'p', p3: 'p3', pc: 'pc', v: 'v', s: 's',
	r: 'r', rs: 'rs', t: 't', gom: 'gom', qr: 'qr', tx: 'tx'};
/* Mapping from plugin shape types to Google chart shapes. */
var SHAPES = {annotation: 'A', arrow: 'a', candlestick: 'F', circle: 'o', cross: 'x',
	diamond: 'd', down: 'v', errorbar: 'E', flag: 'f', financial: 'F', horizbar: 'H',
	horizontal: 'h', number: 'N', plus: 'c', rectangle: 'C', sparkfill: 'B',
	sparkline: 'D', sparkslice: 'b', square: 's', text: 't', vertical: 'V'};
/* Mapping from plugin priority names to chart priority codes. */
var PRIORITIES = {behind: -1, below: -1, normal: 0, above: +1, inFront: +1, '-': -1, '+': +1};
/* Mapping from plugin gradient names to angles. */
var GRADIENTS = {diagonalDown: -45, diagonalUp: 45, horizontal: 0, vertical: 90,
	dd: -45, du: 45, h: 0, v: 90};
/* Mapping from plugin alignment names to chart alignment codes. */
var ALIGNMENTS = {left: -1, center: 0, centre: 0, right: +1, l: -1, c: 0, r: +1};
/* Mapping from plugin drawing control names to chart drawing control codes. */
var DRAWING = {line: 'l', ticks: 't', both: 'lt'};
/* Mapping from legend order names to chart drawing control codes. */
var ORDERS = {normal: 'l', reverse: 'r', automatic: 'a', '': '', l: 'l', r: 'r', a: 'a'};
/* Mapping from marker placement names to chart drawing placement codes. */
var PLACEMENTS = {barbase: 's', barcenter: 'c', barcentre: 'c', bartop: 'e', bottom: 'b',
	center: 'h', centre: 'h', left: 'l', middle: 'v', right: 'r', top: 't',
	b: 'b', c: 'c', e: 'e', h: 'h', l: 'l', r: 'r', s: 's', t: 't', v: 'v'};

/* Characters to use for encoding schemes. */
var SIMPLE_ENCODING = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var EXTENDED_ENCODING = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-.';

$.extend(GChart.prototype, {
	/* Class name added to elements to indicate already configured with Google charting. */
	markerClassName: 'hasGChart',
	
	/* Marker value to indicate min/max calculation from data. */
	calculate: -0.123,
	
	/* Possible values for bar width. */
	barWidthAuto: 'a', // Automatic resize to fill
	barWidthRelative: 'r', // Spacings are relative to bars (0.0 - 1.0)
	
	/* Possible values for number format. */
	formatFloat: 'f',
	formatPercent: 'p',
	formatScientific: 'e',
	formatCurrency: 'c',

	/* Override the default settings for all Google chart instances.
	   @param  options  (object) the new settings to use as defaults */
	setDefaults: function(options) {
		extendRemove(this._defaults, options || {});
	},

	/* Create a new data series.
	   @param  label       (string, optional) the label for this series
	   @param  data        (number[]) the data values for this series
	   @param  colour      (string or string[]) the colour(s) for this series
	   @param  fillColour  (string, optional) the fill colour for this series or
	                       (object, optional) fill slice with attributes color and range ('start:end') or
						   (object[], optional) array of above
	   @param  minValue    (number, optional with maxValue) the minimum value for this series
	   @param  maxValue    (number, optional with minValue) the maximum value for this series
	   @param  thickness   (number) the thickness (pixels) of the line for this series
	   @param  segments    (number[2]) the line and gap lengths (pixels) for this series
	   @return  (object) the new series object */
	series: function(label, data, colour, fillColour, minValue, maxValue, thickness, segments) {
		if ($.isArray(label)) { // Optional label
			segments = thickness;
			thickness = maxValue;
			maxValue = minValue;
			minValue = fillColour;
			fillColour = colour;
			colour = data;
			data = label;
			label = '';
		}
		if (typeof colour == 'number') { // Optional colour/fillColour
			segments = maxValue;
			thickness = minValue;
			maxValue = fillColour;
			minValue = colour;
			fillColour = null;
			colour = null;
		}
		if (typeof fillColour == 'number') { // Optional fillColour
			segments = thickness;
			thickness = maxValue;
			maxValue = minValue;
			minValue = fillColour;
			fillColour = null;
		}
		if ($.isArray(maxValue)) { // Optional min/max values
			segments = maxValue;
			thickness = minValue;
			maxValue = null;
			minValue = null;
		}
		return {label: label, data: data || [], color: colour || '',
			fillColor: fillColour, minValue: minValue, maxValue: maxValue,
			lineThickness: thickness, lineSegments: segments};
	},

	/* Load series data from CSV.
	   Include a header row if fields other than data required.
	   Use these names - label, color, fillColor, minValue, maxValue,
	   lineThickness, lineSegmentLine, lineSegmentGap - for series attributes.
	   Data columns should be labelled ynn, where nn is a sequential number.
	   For X-Y line charts, include xnn columns before corresponding ynn.
	   @param  csv  (string or string[]) the series data in CSV format
	   @return  (object[]) the series definitions */
	seriesFromCsv: function(csv) {
		var seriesData = [];
		if (!$.isArray(csv)) {
			csv = csv.split('\n');
		}
		if (!csv.length) {
			return seriesData;
		}
		var xyData = false;
		var sColumns = [];
		var xColumns = [];
		var fields = ['label', 'color', 'fillColor', 'minValue', 'maxValue',
			'lineThickness', 'lineSegmentLine', 'lineSegmentGap'];
		$.each(csv, function(i, line) {
			var cols = line.split(',');
			if (i == 0 && isNaN(parseFloat(cols[0]))) { // Header row
				$.each(cols, function(i, val) {
					if ($.inArray(val, fields) > -1) { // Note the positions of the columns
						sColumns[i] = val;
					}
					else if (val.match(/^x\d+$/)) { // Column with x-coordinate
						xColumns[i] = val;
					}
				});
			}
			else {
				var series = {};
				var data = [];
				var saveX = null;
				$.each(cols, function(i, val) {
					if (sColumns[i]) { // Non-data value
						var pos = $.inArray(sColumns[i], fields);
						series[sColumns[i]] = (pos > 2 ? $.gchart._numeric(val, 0) : val);
					}
					else if (xColumns[i]) { // X-coordinate
						saveX = (val ? $.gchart._numeric(val, -1) : null);
						xyData = true;
					}
					else {
						var y = $.gchart._numeric(val, -1);
						data.push(saveX != null ? [saveX, y] : y);
						saveX = null;
					}
				});
				if (series.lineSegmentLine != null && series.lineSegmentGap != null) {
					series.lineSegments = [series.lineSegmentLine, series.lineSegmentGap];
					series.lineSegmentLine = series.lineSegmentGap = null;
				}
				seriesData.push($.extend(series, {data: data}));
			}
		});
		return (xyData ? this.seriesForXYLines(seriesData) : seriesData);
	},

	/* Load series data from XML. All attributes are optional except point/@y.
	   <data>
	     <series label="" color="" fillColor="" minValue="" maxValue="" lineThickness="" lineSegments="">
	       <point x="" y=""/>
	       ...
	     </series>
	     ...
	   </data>
	   @param  xml  (string or Document) the XML containing the series data
	   @return  (object[]) the series definitions */
	seriesFromXml: function(xml) {
		if ($.browser.msie && typeof xml == 'string') {
			var doc = new ActiveXObject('Microsoft.XMLDOM');
			doc.validateOnParse = false;
			doc.resolveExternals = false;
			doc.loadXML(xml);
			xml = doc;
		}
		xml = $(xml);
		var seriesData = [];
		var xyData = false;
		try {
			xml.find('series').each(function() {
				var series = $(this);
				var data = [];
				series.find('point').each(function() {
					var point = $(this);
					var x = point.attr('x');
					if (x != null) {
						xyData = true;
						x = $.gchart._numeric(x, -1);
					}
					y = $.gchart._numeric(point.attr('y'), -1);
					data.push(x ? [x, y] : y);
				});
				var segments = series.attr('lineSegments');
				if (segments) {
					segments = segments.split(',');
					for (var i = 0; i < segments.length; i++) {
						segments[i] = $.gchart._numeric(segments[i], 1);
					}
				}
				seriesData.push({label: series.attr('label'), data: data,
					color: series.attr('color'), fillColor: series.attr('fillColor'),
					minValue: $.gchart._numeric(series.attr('minValue'), null),
					maxValue: $.gchart._numeric(series.attr('maxValue'), null),
					lineThickness: $.gchart._numeric(series.attr('lineThickness'), null),
					lineSegments: segments});
			});
		}
		catch (e) {
			// Ignore
		}
		return (xyData ? this.seriesForXYLines(seriesData) : seriesData);
	},

	/* Force a value to be numeric.
	   @param  val      (string) the value to convert
	   @param  whenNaN  (number) value to use if not numeric
	   @return  (number) the numeric equivalent or whenNaN if not numeric */
	_numeric: function(val, whenNaN) {
		val = parseFloat(val);
		return (isNaN(val) ? whenNaN : val);
	},

	/* Prepare series for a line XY chart.
	   @param  series  (object[]) the details of the points to plot,
	                   each data value may be an array of two points
	   @return  (object[]) the transformed series
	   @deprecated  in favour of seriesForXYLines */
	lineXYSeries: function(series) {
		return this.seriesForXYLines(series);
	},

	/* Prepare series for a line XY chart.
	   @param  series  (object[]) the details of the points to plot,
	                   each data value may be an array of two points
	   @return  (object[]) the transformed series */
	seriesForXYLines: function(series) {
		var xySeries = [];
		for (var i = 0; i < series.length; i++) {
			var xNull = !$.isArray(series[i].data[0]);
			var xData = (xNull ? [null] : []);
			var yData = [];
			for (var j = 0; j < series[i].data.length; j++) {
				if (xNull) {
					yData.push(series[i].data[j]);
				}
				else {
					xData.push(series[i].data[j][0]);
					yData.push(series[i].data[j][1]);
				}
			}
			xySeries.push($.gchart.series(series[i].label, xData, series[i].color,
				series[i].fillColor, series[i].minValue, series[i].maxValue,
				series[i].lineThickness, series[i].lineSegments));
			xySeries.push($.gchart.series('', yData, '',
				series[i].fillColor, series[i].minValue, series[i].maxValue,
				series[i].lineThickness, series[i].lineSegments));
		}
		return xySeries;
	},

	/* Prepare options for a scatter chart.
	   @param  values   (number[][]) the coordinates of the points:
	                    [0] is the x-coord, [1] is the y-coord, [2] is the percentage size
	   @param  labels   (string[]) the labels for the groups (optional)
	   @param  colours  (string[]) the colours for the labels (optional)
	   @param  options  (object) additional settings (optional)
	   @return  (object) the configured options object */
	scatter: function(values, labels, colours, options) {
		if (!$.isArray(labels)) {
			options = labels;
			colours = null;
			labels = null;
		}
		var series = [[], [], []];
		for (var i = 0; i < values.length; i++) {
			series[0][i] = values[i][0];
			series[1][i] = values[i][1];
			series[2][i] = values[i][2] || 100;
		}
		options = options || {};
		if (labels) {
			options.extension = {chdl: labels.join('|')};
		}
		if (colours) {
			colours = $.map(colours, function(v, i) {
				return $.gchart.color(v);
			});
			$.extend(options.extension, {chco: colours.join('|')});
		}
		return $.extend({}, options,
			{type: 'scatter', series: [$.gchart.series(series[0]),
				$.gchart.series(series[1]), $.gchart.series(series[2])]});
	},

	/* Prepare options for a Venn diagram.
	   @param  size1       (number) the relative size of the first circle
	   @param  size2       (number) the relative size of the second circle
	   @param  size3       (number) the relative size of the third circle
	   @param  overlap12   (number) the overlap between circles 1 and 2
	   @param  overlap13   (number) the overlap between circles 1 and 3
	   @param  overlap23   (number) the overlap between circles 2 and 3
	   @param  overlap123  (number) the overlap between all circles
	   @param  options     (object) additional settings (optional)
	   @return  (object) the configured options object */
	venn: function(size1, size2, size3, overlap12, overlap13, overlap23, overlap123, options) {
		return $.extend({}, options || {}, {type: 'venn', series:
			[$.gchart.series([size1, size2, size3, overlap12, overlap13, overlap23, overlap123])]});
	},

	/* Prepare options for a Google meter.
	   @param  text      (string or string[]) the text to show on the arrow (optional)
	   @param  values    (number or number[] or [] of these) the position(s) of the arrow(s)
	   @param  maxValue  (number) the maximum value for the meter (optional, default 100)
	   @param  colours   (string[]) the colours to use for the band (optional)
	   @param  labels    (string[]) labels appearing beneath the meter (optional)
	   @param  styles    (number[][4]) the styles of each series' arrows:
	                     width, dash, space, arrow size (optional)
	   @param  options   (object) additional settings (optional)
	   @return  (object) the configured options object */
	meter: function(text, values, maxValue, colours, labels, styles, options) {
		if (typeof text != 'string' && !$.isArray(text)) {
			options = styles;
			styles = labels;
			labels = colours;
			colours = maxValue;
			maxValue = values;
			values = text;
			text = '';
		}
		if (typeof maxValue != 'number') {
			options = styles;
			styles = labels;
			labels = colours;
			colours = maxValue;
			maxValue = null;
		}
		if (!$.isArray(colours)) {
			options = styles;
			styles = labels;
			labels = colours;
			colours = null;
		}
		if (!$.isArray(labels)) {
			options = styles;
			styles = labels;
			labels = null;
		}
		if (!$.isArray(styles)) {
			options = styles;
			styles = null;
		}
		values = ($.isArray(values) ? values : [values]);
		var multi = false;
		for (var i = 0; i < values.length; i++) {
			multi = multi || $.isArray(values[i]);
		}
		var ss = (multi ? [] : [$.gchart.series(values)]);
		if (multi) {
			for (var i = 0; i < values.length; i++) {
				ss.push($.gchart.series($.isArray(values[i]) ? values[i] : [values[i]]));
			}
		}
		values = ss;
		if (colours) {
			var cs = '';
			$.each(colours, function(i, v) {
				cs += ',' + $.gchart.color(v);
			});
			colours = cs.substr(1);
		}
		if (styles) {
			var ls = ['', ''];
			$.each(styles, function(i, v) {
				v = ($.isArray(v) ? v : [v]);
				ls[0] += '|' + $.gchart.color(v.slice(0, 3).join(','));
				ls[1] += '|' + (v[3] || 15);
			});
			styles = ls[0].substr(1) + ls[1];
		}
		var axis = (labels && labels.length ?  $.gchart.axis('y', labels) : null);
		return $.extend({}, options || {}, {type: 'meter',
			maxValue: maxValue || 100, series: values,
			dataLabels: ($.isArray(text) ? text : [text || ''])},
			(colours ? {extension: {chco: colours}} : {}),
			(axis ? {axes: [axis]} : {}),
			(styles ? {extension: {chls: styles}} : {}));
	},

	/* Prepare options for a map chart.
	   @param  mapArea        (string) the region of the world to show (optional)
	   @param  values         (object) the countries/states to plot -
	                          attributes are country/state codes and values
	   @param  defaultColour  (string) the colour for regions without values (optional)
	   @param  colour         (string or string[]) the starting colour or
	                          gradient colours for rendering values (optional)
	   @param  endColour      (string) the ending colour for rendering values (optional)
	   @param  options        (object) additional settings (optional)
	   @return  (object) the configured options object */
	map: function(mapArea, values, defaultColour, colour, endColour, options) {
		if (typeof mapArea == 'object') { // Optional mapArea
			options = endColour;
			endColour = colour;
			colour = defaultColour;
			defaultColour = values;
			values = mapArea;
			mapArea = 'world';
		}
		if (typeof defaultColour == 'object') {
			options = defaultColour;
			endColour = null;
			colour = null;
			defaultColour = null;
		}
		else if (typeof colour == 'object' && !$.isArray(colour)) {
			options = colour;
			endColour = null;
			colour = null;
		}
		else if (typeof endColour == 'object') {
			options = endColour;
			endColour = null;
		}
		var mapRegions = [];
		var data = [];
		var i = 0;
		for (var name in values) {
			mapRegions[i] = name;
			data[i] = values[name];
			i++;
		}
		return $.extend({}, options || {}, {type: 'map',
			mapArea: mapArea, mapRegions: mapRegions,
			mapDefaultColor: defaultColour || $.gchart._defaults.mapDefaultColor,
			mapColors: ($.isArray(colour) ? colour : [colour || $.gchart._defaults.mapColors[0],
			endColour || $.gchart._defaults.mapColors[1]]),
			series: [$.gchart.series('', data)]});
	},

	/* Prepare options for generating a QR Code.
	   @param  text      (object) the QR code settings or
	                     (string) the text to encode
	   @param  encoding  (string) the encoding scheme (optional)
	   @param  ecLevel   (string) the error correction level: l, m, q, h (optional)
	   @param  margin    (number) the margin around the code (optional)
	   @return  (object) the configured options object */
	qrCode: function(text, encoding, ecLevel, margin) {
		var options = {};
		if (typeof text == 'object') {
			options = text;
		}
		else { // Individual fields
			options = {dataLabels: [text], encoding: encoding,
				qrECLevel: ecLevel, qrMargin: margin};
		}
		options.type = 'qrCode';
		if (options.text) {
			options.dataLabels = [options.text];
			options.text = null;
		}
		return options;
	},

	/* Prepare options for a GraphViz chart.
	   @param  engine    (string, optional) the graphing engine to use:
	                     dot (default), neato, twopi, circo, fdp
	   @param  options   (object, optional) other options for the chart
	   @param  graph     (string) the DOT representation of the nodes to graph
	   @return  (object) the configured options object */
	graphviz: function(engine, options, graph) {
		if (arguments.length == 1) {
			graph = engine;
			engine = 'dot';
		}
		if (options && typeof options != 'object') {
			graph = options;
			options = {};
		}
		options = options || {};
		options.type = 'gv' + (engine != 'dot' ? ':' + engine : '');
		options.dataLabels = [graph];
		return options;
	},

	/* Generate a Google chart color.
	   @param  r  (string) colour name or '#hhhhhh' or
	              (number) red value (0-255)
	   @param  g  (number) green value (0-255) or
	              (number) alpha value (0-255, optional) if r is name
	   @param  b  (number) blue value (0-255)
	   @param  a  (number) alpha value (0-255, optional)
	   @return  (string) the translated colour */
	color: function(r, g, b, a) {
		var checkRange = function(value) {
			if (typeof value == 'number' && (value < 0 || value > 255)) {
				throw 'Value out of range (0-255) ' + value;
			}
		};
		var twoDigits = function(value) {
			return (value.length == 1 ? '0' : '') + value;
		};
		if (typeof r == 'string') {
			checkRange(g);
			return (r.match(/^#([A-Fa-f0-9]{2}){3,4}$/) ? r.substring(1) :
				(COLOURS[r] || r) + (g ? twoDigits(g.toString(16)) : ''));
		}
		checkRange(r);
		checkRange(g);
		checkRange(b);
		checkRange(a);
		return twoDigits(r.toString(16)) + twoDigits(g.toString(16)) +
			twoDigits(b.toString(16)) + (a ? twoDigits(a.toString(16)) : '');
	},

	/* Create a simple linear gradient definition for a background.
	   @param  angle    (string or number) the angle of the gradient from positive x-axis
	   @param  colour1  (string[]) an array of colours or
	                    (string) the starting colour
	   @param  colour2  (string, optional) the ending colour
	   @return  (object) the gradient definition */
	gradient: function(angle, colour1, colour2) {
		var colourPoints = [];
		if ($.isArray(colour1)) {
			var step = 1 / (colour1.length - 1);
			for (var i = 0; i < colour1.length; i++) {
				colourPoints.push([colour1[i], Math.round(i * step * 100) / 100]);
			}
		}
		else {
			colourPoints = [[colour1, 0], [colour2, 1]];
		}
		return {angle: angle, colorPoints: colourPoints};
	},

	/* Create a colour striping definition for a background.
	   @param  angle    (string or number) the angle of the stripes from positive x-axis
	   @param  colours  (string[]) the colours to stripe
	   @return  (object) the stripe definition */
	stripe: function(angle, colours) {
		var colourPoints = [];
		var width = Math.round(100 / colours.length) / 100;
		for (var i = 0; i < colours.length; i++) {
			colourPoints.push([colours[i], width]);
		}
		return {angle: angle, striped: true, colorPoints: colourPoints};
	},

	/* Create a range definition.
	   @param  vertical  (boolean, optional) true if vertical, false if horizontal
	   @param  colour    (string) the marker's colour
	   @param  start     (number) the starting point for the range (0.0 to 1.0)
	   @param  end       (number, optional) the ending point for the range (0.0 to 1.0)
	   @return  (object) the range definition */
	range: function(vertical, colour, start, end) {
		if (typeof vertical == 'string') { // Optional vertical
			end = start;
			start = colour;
			colour = vertical;
			vertical = false;
		}
		return {vertical: vertical, color: colour, start: start, end: end};
	},

	/* Create a marker definition.
	   @param  shape       (string) the marker shape
	   @param  colour      (string) the marker's colour
	   @param  series      (number) the series to which the marker applies
	   @param  item        (number or string or number[2 or 3], optional)
	                       the item in the series to which it applies or 'all' or
	                       'everyn' or 'everyn[s:e]' or [start, end, every]
	   @param  size        (number, optional) the size (pixels) of the marker or
	                       (string) 'thickness:length' for horizline or vertical
	   @param  priority    (string or number, optional) the rendering priority
	   @param  text        (string, optional) the display text for a text type marker
	   @param  positioned  (boolean, optional) true to absolutely position the marker
	   @param  placement   (string or string[], optional) placement locations
	   @param  offsets     (number[2], optional) pixel offsets, horizontal and vertical
	   @return  (object) the marker definition */
	marker: function(shape, colour, series, item, size, priority, text,
			positioned, placement, offsets) {
		if (typeof size == 'boolean') {
			offsets = text;
			placement = priority;
			positioned = size;
			text = null;
			priority = null;
			size = null;
		}
		if ($.isArray(size)) {
			if (typeof size[0] == 'string') {
				offsets = priority;
				placement = size;
			}
			else {
				offsets = size;
				placement = null;
			}
			positioned = null;
			text = null;
			priority = null;
			size = null;
		}
		if (typeof priority == 'boolean') {
			offsets = positioned;
			placement = text;
			positioned = priority;
			text = null;
			priority = null;
		}
		if ($.isArray(priority)) {
			if (typeof priority[0] == 'string') {
				offsets = text;
				placement = priority;
			}
			else {
				offsets = priority;
				placement = null;
			}
			positioned = null;
			text = null;
			priority = null;
		}
		if (typeof text == 'boolean') {
			offsets = placement;
			placement = positioned;
			positioned = text;
			text = null;
		}
		if ($.isArray(text)) {
			if (typeof text[0] == 'string') {
				offsets = positioned;
				placement = text;
			}
			else {
				offsets = text;
				placement = null;
			}
			positioned = null;
			text = null;
		}
		if ($.isArray(positioned)) {
			if (typeof positioned[0] == 'string') {
				offsets = placement;
				placement = positioned;
			}
			else {
				offsets = positioned;
				placement = null;
			}
			positioned = null;
		}
		if ($.isArray(placement) && typeof placement[0] != 'string') {
			offsets = placement;
			placement = null;
		}
		return {shape: shape, color: colour, series: series,
			item: (item || item == 0 ? item : -1), size: size || 10,
			priority: (priority != null ? priority : 0), text: text,
			positioned: positioned, placement: placement, offsets: offsets};
	},

	/* Create a dynamic icon definition.
	   @param  name      (string) the name of the icon to use
	   @param  data      (string) the icon's encoded parameters
	   @param  series    (number, optional) the series to which the icon applies
	   @param  item      (number or string or number[2 or 3], optional)
	                     the item in the series to which it applies or 'all' (default)
	                     or 'everyn' or [start, end, every]
	   @param  zIndex    (number, optional) the z-index (-1.0 to 1.0)
	   @param  position  (number[2], optional) an absolute chart position (0.0 to 1.0)
	   @param  offsets   (number[2], optional) pixel offsets
	   @return  (object) the icon definition */
	icon: function(name, data, series, item, zIndex, position, offsets) {
		if ($.isArray(series)) {
			offsets = item;
			position = series;
			zIndex = null;
			item = null;
			series = null;
		}
		if ($.isArray(zIndex)) {
			offsets = position;
			position = zIndex;
			zIndex = null;
		}
		return {name: name, data: data, series: series || 0, item: (item || item == 0 ? item : 'all'),
			zIndex: zIndex, position: position, offsets: offsets};
	},

	/* Create a number format for a marker.
	   @param  type        (object) containing all these settings or
	                       (string) 'f' for floating point, 'p' for percentage,
	                       'e' for scientific notation, 'c<CUR>' for currency (as specified by CUR)
	   @param  prefix      (string, optional) text appearing before the number
	   @param  suffix      (string, optional - can only be present if prefix is present)
	                       text appearing after the number
	   @param  precision   (number, optional) the number of decimal places
	   @param  showX       (boolean, optional) true to show the x-value, false for the y-value
	   @param  zeroes      (boolean, optional - can only be present if showX is present)
	                       true to display trailing zeroes
	   @param  separators  (boolean, optional - can only be present if showX and zeroes are present)
	                       true to display group separators
	   @return  (string) the format definition */
	numberFormat: function(type, prefix, suffix, precision, showX, zeroes, separators) {
		var format = initNumberFormat(type, prefix, suffix, precision, showX, zeroes, separators);
		return format.prefix + '*' + format.type + format.precision + (format.zeroes ? 'z' : '') +
			(format.separators ? 's' : '') + (format.showX ? 'x' : '') + '*' + format.suffix;
	},

	/* Create an axis definition.
	   @param  axis           (string) the axis position: top, bottom, left, right
	   @param  labels         (string[]) the labels for this axis
	   @param  positions      (number[], optional) the positions of the labels
	   @param  rangeStart     (number, optional with next two) start of range
	   @param  rangeEnd       (number, optional with above) end of range
	   @param  rangeInterval  (number, optional with above) interval between values in the range
	   @param  colour         (string, optional) the axis colour
	   @param  alignment      (string, optional) the labels' alignment
	   @param  size           (number, optional) the labels' size
	   @param  format         (object, optional) the labels' number format options
	   @return  (object) the axis definition */
	axis: function(axis, labels, positions, rangeStart,
			rangeEnd, rangeInterval, colour, alignment, size, format) {
		return new GChartAxis(axis, labels, positions, rangeStart,
			rangeEnd, rangeInterval, colour, alignment, size, format);
	},
	
	/* Determine the region within a chart.
	   @param  event     (MouseEvent) the mouse event contining the cursor position
	   @param  jsonData  (object) the JSON description of the chart
	   @return  (object) the current region details (type, series, and point) or null if none */
	findRegion: function(event, jsonData) {
		if (!jsonData || !jsonData.chartshape) {
			return null;
		}
		var decodeName = function(name) {
			var matches = name.match(/([^\d]+)(\d+)(?:_(\d)+)?/);
			return {type: matches[1], series: parseInt(matches[2]), point: parseInt(matches[3] || -1)};
		};
		var offset = $(event.target).offset();
		var x = event.pageX - offset.left;
		var y = event.pageY - offset.top;
		for (var i = 0; i < jsonData.chartshape.length; i++) {
			var shape = jsonData.chartshape[i];
			switch (shape.type) {
				case 'RECT':
					if (shape.coords[0] <= x && x <= shape.coords[2] &&
							shape.coords[1] <= y && y <= shape.coords[3]) {
						return decodeName(shape.name);
					}
					break;
				case 'CIRCLE':
					if (Math.abs(x - shape.coords[0]) <= shape.coords[2] &&
							Math.abs(y - shape.coords[1]) <= shape.coords[2] &&
							Math.sqrt(Math.pow(x - shape.coords[0], 2) +
							Math.pow(y - shape.coords[1], 2)) <= shape.coords[2]) {
						return decodeName(shape.name);
					}
					break;
				case 'POLY':
					if ($.gchart._insidePolygon(shape.coords, x, y)) {
						return decodeName(shape.name);
					}
					break;
			}
		}
		return null;
	},

	/* Determine whether a point is within a polygon.
	   Ray casting algorithm adapted from http://ozviz.wasp.uwa.edu.au/~pbourke/geometry/insidepoly/.
	   @param  coords  (number[]) the polygon coords as [x1, y1, x2, y2, ...]
	   @param  x       (number) the point's x-coord
	   @param  y       (number) the point's y-coord
	   @return  (boolean) true if the point is inside, false if not */
	_insidePolygon: function(coords, x, y) {
		var counter = 0;
		var p1 = [coords[0], coords[1]];
		for (var i = 2; i <= coords.length; i += 2) {
			var p2 = [coords[i % coords.length], coords[i % coords.length + 1]];
			if (y > Math.min(p1[1], p2[1]) && y <= Math.max(p1[1], p2[1])) {
				if (x <= Math.max(p1[0], p2[0]) && p1[1] != p2[1]) {
					var xinters = (y - p1[1]) * (p2[0] - p1[0]) / (p2[1] - p1[1]) + p1[0];
					if (p1[0] == p2[0] || x <= xinters) {
						counter++;
					}
				}
			}
			p1 = p2;
		}
		return (counter % 2 != 0);
	},

	/* Attach the Google chart functionality to a div.
	   @param  target   (element) the containing division
	   @param  options  (object) the settings for this Google chart instance (optional) */
	_attachGChart: function(target, options) {
		target = $(target);
		if (target.is('.' + this.markerClassName)) {
			return;
		}
		target.addClass(this.markerClassName);
		options = options || {};
		var width = options.width || parseInt(target.css('width'), 10);
		var height = options.height || parseInt(target.css('height'), 10);
		var allOptions = $.extend({}, this._defaults, options,
			{width: width, height: height});
		$.data(target[0], PROP_NAME, allOptions);
		this._updateChart(target[0], allOptions);
	},

	/* Reconfigure the settings for a Google charting div.
	   @param  target   (element) the containing division
	   @param  name     (object) the new settings for this Google chart instance or
	                    (string) the name of a single option
	   @param  value    (any, optional) the option's value */
	_changeGChart: function(target, name, value) {
		var options = name || {};
		if (typeof name == 'string') {
			options = {};
			options[name] = value;
		}
		var curOptions = $.data(target, PROP_NAME);
		extendRemove(curOptions || {}, options);
		$.data(target, PROP_NAME, curOptions);
		this._updateChart(target, curOptions);
	},

	/* Remove the Google charting functionality from a div.
	   @param  target  (element) the containing division */
	_destroyGChart: function(target) {
		target = $(target);
		if (!target.is('.' + this.markerClassName)) {
			return;
		}
		target.removeClass(this.markerClassName).empty();
		$.removeData(target[0], PROP_NAME);
	},

	/* Generate the Google charting request with the new settings.
	   @param  options  (object) the new settings for this Google chart instance
	   @return  (string) the Google chart URL */
	_generateChart: function(options) {
		var type = (options.type && options.type.match(/.+:.+/) ?
			options.type : CHART_TYPES[options.type] || 'p3');
		var encoding = this['_' + options.encoding + 'Encoding'] ||
			this['_textEncoding'];
		var labels = '';
		for (var i = 0; i < options.dataLabels.length; i++) {
			labels += '|' + encodeURIComponent(options.dataLabels[i] || '');
		}
		labels = (labels.length == options.dataLabels.length ? '' : labels);
		var legends = '';
		var colours = '';
		var hasColour = false;
		var lines = '';
		for (var i = 0; i < options.series.length; i++) {
			var clrs = '';
			if (type != 'lxy' || i % 2 == 0) {
				legends += '|' + encodeURIComponent(options.series[i].label || '');
				var sep = ',';
				$.each(($.isArray(options.series[i].color) ? options.series[i].color :
						[options.series[i].color]), function(i, v) {
					var colour = $.gchart.color(v || '');
					if (colour) {
						hasColour = true;
					}
					clrs += sep + (colour || '000000');
					sep = '|';
				});
			}
			colours += (hasColour ? clrs : '');
			if (type.substr(0, 1) == 'l' && options.series[i].lineThickness &&
					$.isArray(options.series[i].lineSegments)) {
				lines += '|' + options.series[i].lineThickness + ',' +
					options.series[i].lineSegments.join(',');
			}
		}
		var include = function(name, value) {
			return (value ? name + value : '');
		};
		var addSize = function() {
			options.width = Math.max(10, Math.min(options.width, 1000));
			options.height = Math.max(10, Math.min(options.height, 1000));
			if (type != 't' && options.width * options.height > 300000) {
				options.height = Math.floor(300000 / options.width);
			}
			return (type != 't' ? '&chs=' + options.width + 'x' + options.height :
				'&chs=' + Math.min(440, options.width) + 'x' + Math.min(220, options.height));
		};
		var addMargins = function() {
			var margins = options.margins;
			margins = (margins == null ? null :
				(typeof margins == 'number' ? [margins, margins, margins, margins] :
				(!$.isArray(margins) ? null :
				(margins.length == 4 ? margins :
				(margins.length == 2 ? [margins[0], margins[0], margins[1], margins[1]] : null)))));
			return (!margins ? '' : '&chma=' + margins.join(',') +
				(!options.legendSize || options.legendSize.length != 2 ? '' :
				'|' + options.legendSize.join(',')));
		};
		var qrOptions = function() {
			return include('&choe=', options.encoding) +
				(options.qrECLevel || options.qrMargin ?
				'&chld=' + (options.qrECLevel ? options.qrECLevel.charAt(0) : 'l') +
				(options.qrMargin != null ? '|' + options.qrMargin : '') : '') +
				(labels ? '&chl=' + labels.substr(1) : '');
		};
		var noDataOptions = function() {
			return '&chl=' + labels.substr(1);
		};
		var mapOptions = function() {
			var colours = '';
			for (var i = 0; i < options.mapColors.length; i++) {
				colours += ',' + $.gchart.color(options.mapColors[i]);
			}
			return '&chtm=' + (options.mapArea || 'world') +
				'&chd=' + encoding.apply($.gchart, [options]) +
				(options.mapRegions && options.mapRegions.length ?
				'&chld=' + options.mapRegions.join('') : '') +
				'&chco=' + $.gchart.color(options.mapDefaultColor) + colours;
		};
		var pieOptions = function() {
			return (options.pieOrientation ?
				'&chp=' + (options.pieOrientation / 180 * Math.PI) : '') +
				standardOptions();
		};
		var standardOptions = function() {
			return '&chd=' + encoding.apply($.gchart, [options]) +
				(labels ? '&chl=' + labels.substr(1) : '');
		};
		var addBarSizings = function() {
			return (type.substr(0, 1) != 'b' ? '' : (options.barWidth == null ? '' :
				'&chbh=' + options.barWidth +
				(options.barSpacing == null ? '' : ',' + (options.barWidth == $.gchart.barWidthRelative ?
				Math.min(Math.max(options.barSpacing, 0.0), 1.0) : options.barSpacing) +
				(options.barGroupSpacing == null ? '' : ',' + (options.barWidth == $.gchart.barWidthRelative ?
				Math.min(Math.max(options.barGroupSpacing, 0.0), 1.0) : options.barGroupSpacing)))) +
				(options.barZeroPoint == null ? '' : '&chp=' + options.barZeroPoint));
		};
		var addLineStyles = function() {
			return (type.charAt(0) == 'l' && lines ? '&chls=' + lines.substr(1) : '');
		};
		var addColours = function() {
			return (colours.length > options.series.length ? '&chco=' + colours.substr(1) : '');
		};
		var addTitle = function() {
			return include('&chtt=', encodeURIComponent(options.title)) +
			(options.titleColor || options.titleSize ?
			'&chts=' + ($.gchart.color(options.titleColor) || '000000') + ',' +
			(options.titleSize || 20) : '');
		};
		var addBackground = function(area, background) {
			if (background == null) {
				return '';
			}
			if (typeof background == 'string') {
				return area + ',s,' + $.gchart.color(background);
			}
			var bg = area + ',l' + (background.striped ? 's' : 'g') + ',' +
				(GRADIENTS[background.angle] != null ?
				GRADIENTS[background.angle] : background.angle);
			for (var i = 0; i < background.colorPoints.length; i++) {
				bg += ',' + $.gchart.color(background.colorPoints[i][0]) +
					',' + background.colorPoints[i][1];
			}
			return bg;
		};
		var addBackgrounds = function() {
			var opacity = (!options.opacity ? null : '000000' +
				Math.floor(options.opacity / (options.opacity > 1 ? 100 : 1) * 255).toString(16));
			if (opacity && opacity.length < 8) {
				opacity = '0' + opacity;
			}
			var backgrounds = addBackground('|a', opacity) +
				addBackground('|bg', options.backgroundColor) +
				addBackground('|c', options.chartColor);
			return (backgrounds ? '&chf=' + backgrounds.substr(1) : '');
		};
		var addGrids = function() {
			return (options.gridSize.length == 0 ? '' :
				'&chg=' + options.gridSize[0] + ',' + options.gridSize[1] +
				(options.gridLine.length == 0 ? '' :
				',' + options.gridLine[0] + ',' + options.gridLine[1] +
				(options.gridOffsets.length == 0 ? '' :
				',' + options.gridOffsets[0] + ',' + options.gridOffsets[1])));
		};
		var addLegends = function() {
			var order = (options.legendOrder && options.legendOrder.match(/^\d+(,\d+)*$/) ?
				options.legendOrder : ORDERS[options.legendOrder]) || '';
			return (!options.legend ||
				(type != 'lxy' && legends.length <= options.series.length) ||
				(type == 'lxy' && legends.length <= (options.series.length / 2)) ? '' :
				'&chdl=' + legends.substr(1) + include('&chdlp=',
				options.legend.charAt(0) + (options.legend.indexOf('V') > -1 ? 'v' : '') +
				include('|', order)));
		};
		var addExtensions = function() {
			var params = '';
			for (var name in options.extension) {
				params += '&' + name + '=' + options.extension[name];
			}
			return params;
		};
		var format = options.format || 'png';
		return 'http://chart.apis.google.com/chart?' +
			(format != 'png' ? 'chof=' + format + '&' : '') +
			'cht=' + type + addSize() + addMargins() +
			(type == 'qr' ? qrOptions() : (type.match(/tx|gv(:\w+)?/) ? noDataOptions() :
			(type == 't' ? mapOptions() : (type.charAt(0) == 'p' ? pieOptions() : standardOptions())))) +
			addBarSizings() + addLineStyles() + addColours() + addTitle() +
			this._addAxes(options) + addBackgrounds() + addGrids() +
			this._addMarkers(options) + this._addIcons(options) + addLegends() + addExtensions();
	},

	/* Generate axes parameters.
	   @param  options  (object) the current instance settings
	   @return  (string) the axes parameters */
	_addAxes: function(options) {
		var axes = '';
		var axesLabels = '';
		var axesPositions = '';
		var axesRanges = '';
		var axesStyles = '';
		var axesTicks = '';
		for (var i = 0; i < options.axes.length; i++) {
			var axisDef = (typeof options.axes[i] == 'string' ?
				new GChartAxis(options.axes[i]) : options.axes[i]);
			var axis = axisDef.axis().charAt(0);
			axes += ',' + (axis == 'b' ? 'x' : (axis == 'l' ? 'y' : axis));
			if (axisDef.labels()) {
				var labels = '';
				for (var j = 0; j < axisDef.labels().length; j++) {
					labels += '|' + encodeURIComponent(axisDef.labels()[j] || '');
				}
				axesLabels += (labels ? '|' + i + ':' + labels : '');
			}
			if (axisDef.positions()) {
				var positions = '';
				for (var j = 0; j < axisDef.positions().length; j++) {
					positions += ',' + axisDef.positions()[j];
				}
				axesPositions += (positions ? '|' + i + positions : '');
			}
			if (axisDef.range()) {
				var range = axisDef.range();
				axesRanges += '|' + i + ',' + range[0] + ',' + range[1] +
					(range[2] ? ',' + range[2] : '');
			}
			if (axisDef.style() || axisDef.drawing() || axisDef.ticks() || axisDef.format()) {
				var style = axisDef.style() || {};
				var ticks = axisDef.ticks() || {};
				axesStyles += '|' + i +
					(axisDef.format() ? 'N' + this.numberFormat(axisDef.format()) : '') + ',' +
					$.gchart.color(style.color || 'gray') + ',' +
					(style.size || 10) + ',' + 
					(ALIGNMENTS[style.alignment] || style.alignment || 0) +
					(!axisDef.drawing() && !ticks.color ? '' : ',' +
					(DRAWING[axisDef.drawing()] || axisDef.drawing() || 'lt') +
					(ticks.color ? ',' + $.gchart.color(ticks.color) : ''));
			}
			if (axisDef.ticks() && axisDef.ticks().length) {
				axesTicks += '|' + i + ',' + axisDef.ticks().length;
			}
		}
		return (!axes ? '' : '&chxt=' + axes.substr(1) +
			(!axesLabels ? '' : '&chxl=' + axesLabels.substr(1)) +
			(!axesPositions ? '' : '&chxp=' + axesPositions.substr(1)) +
			(!axesRanges ? '' : '&chxr=' + axesRanges.substr(1)) +
			(!axesStyles ? '' : '&chxs=' + axesStyles.substr(1)) +
			(!axesTicks ? '' : '&chxtc=' + axesTicks.substr(1)));
	},

	/* Generate markers parameters.
	   @param  options  (object) the current instance settings
	   @return  (string) the markers parameters */
	_addMarkers: function(options) {
		var markers = '';
		var decodeItem = function(item, positioned) {
			if (item == 'all') {
				return -1;
			}
			if (typeof item == 'string') {
				var matches = /^every(\d+)(?:\[(\d+):(\d+)\])?$/.exec(item);
				if (matches) {
					var every = parseInt(matches[1], 10);
					return (matches[2] && matches[3] ?
						(positioned ? Math.max(0.0, Math.min(1.0, matches[2])) : matches[2]) + ':' +
						(positioned ? Math.max(0.0, Math.min(1.0, matches[3])) : matches[3]) + ':' +
						every : -every);
				}
			}
			if ($.isArray(item)) {
				item = $.map(item, function(v, i) {
					return (positioned ? Math.max(0.0, Math.min(1.0, v)) : v);
				});
				return item.join(':') + (item.length < 2 ? ':' : '');
			}
			return item;
		};
		var escapeText = function(value) {
			return value.replace(/,/g, '\\,');
		};
		for (var i = 0; i < options.markers.length; i++) {
			var marker = options.markers[i];
			var shape = SHAPES[marker.shape] || marker.shape;
			var placement = '';
			if (marker.placement) {
				var placements = $.makeArray(marker.placement);
				for (var j = 0; j < placements.length; j++) {
					placement += PLACEMENTS[placements[j]] || '';
				}
			}
			markers += '|' + (marker.positioned ? '@' : '') + shape +
				('AfNt'.indexOf(shape) > -1 ? escapeText(marker.text || '') : '') + ',' +
				$.gchart.color(marker.color) + ',' +
				marker.series + ',' + decodeItem(marker.item, marker.positioned) +
				',' + marker.size + ',' + (PRIORITIES[marker.priority] != null ?
				PRIORITIES[marker.priority] : marker.priority) +
				(placement || marker.offsets ? ',' + placement +
				':' + (marker.offsets && marker.offsets[0] ? marker.offsets[0] : '') +
				':' + (marker.offsets && marker.offsets[1] ? marker.offsets[1] : '') : '');
		}
		for (var i = 0; i < options.ranges.length; i++) {
			markers += '|' + (options.ranges[i].vertical ? 'R' : 'r') + ',' +
				$.gchart.color(options.ranges[i].color) + ',0,' +
				options.ranges[i].start + ',' +
				(options.ranges[i].end || options.ranges[i].start + 0.005);
		}
		for (var i = 0; i < options.series.length; i++) {
			if (options.series[i].fillColor) {
				var fills = ($.isArray(options.series[i].fillColor) ?
					options.series[i].fillColor : [options.series[i].fillColor]);
				for (var j = 0; j < fills.length; j++) {
					if (typeof fills[j] == 'string') {
						markers += '|b,' + $.gchart.color(options.series[i].fillColor) +
							',' + i + ',' + (i + 1) + ',0';
					}
					else {
						var props = ($.isArray(fills[j]) ? fills[j] : [fills[j].color, fills[j].range]);
						markers += '|B,' + $.gchart.color(props[0]) +
							',' + i + ',' + props[1] + ',0';
					}
				}
			}
		}
		return (markers ? '&chm=' + markers.substr(1) : '');
	},

	/* Generate dynamic icon parameters.
	   @param  options  (object) the current instance settings
	   @return  (string) the icons parameters */
	_addIcons: function(options) {
		var icons = '';
		var decodeItem = function(item) {
			if (item == 'all') {
				return item;
			}
			if (typeof item == 'string') {
				if (/^every(\d+)$/.exec(item)) {
					return item.replace(/every/, 'every,');
				}
			}
			if ($.isArray(item)) {
				return 'range,' + item.join(',');
			}
			return item;
		};
		for (var i = 0; i < options.icons.length; i++) {
			var icon = options.icons[i];
			icons += '|y;s=' + icon.name + ';d=' + icon.data +
				(icon.position ? '' : ';ds=' + icon.series + ';dp=' + decodeItem(icon.item)) +
				(icon.zIndex ? ';py=' + icon.zIndex : '') + 
				(icon.position ? ';po=' + icon.position.join(',') : '') + 
				(icon.offsets ? ';of=' + icon.offsets.join(',') : '');
		}
		return (icons ? '&chem=' + icons.substr(1) : '');
	},

	/* Update the Google charting div with the new settings.
	   @param  target   (element) the containing division
	   @param  options  (object) the new settings for this Google chart instance */
	_updateChart: function(target, options) {
		options._src = this._generateChart(options);
		if (options.usePost) {
			var form = '<form action="http://chart.apis.google.com/chart?' +
				Math.floor(Math.random() * 1e8) + '" method="POST">';
			var pattern = /(\w+)=([^&]*)/g;
			var match = pattern.exec(options._src);
			while (match) {
				form += '<input type="hidden" name="' + match[1] + '" value="' +
					($.inArray(match[1], ['chdl', 'chl', 'chtt', 'chxl']) > -1 ?
					decodeURIComponent(match[2]) : match[2]) + '">';
				match = pattern.exec(options._src);
			}
			form += '</form>';
			target = $(target);
			target.empty();
			var ifr = $('<iframe></iframe>').appendTo(target).css({width: '100%', height: '100%'});
			var doc = ifr.contents()[0]; // Write iframe directly
			doc.open();
			doc.write(form);
			doc.close();
			ifr.show().contents().find('form').submit();	
		}
		else {
			var img = $(new Image()); // Prepare to load chart image in background
			img.load(function() { // Once loaded...
				$(target).find('img').remove().end().append(this); // Replace
				if (options.onLoad) {
					if (options.provideJSON) { // Retrieve JSON details
						$.getJSON(options._src + '&chof=json&callback=?', 
							function(data) {
								options.onLoad.apply(target, [$.gchart._normaliseRects(data)]);
							});
					}
					else {
						options.onLoad.apply(target, []);
					}
				}
			});
			$(img).attr('src', options._src);
		}
	},

	/* Ensure that rectangle coords go from min to max.
	   @param  jsonData  (object) the JSON description of the chart
	   @return  (object) the normalised JSON description */
	_normaliseRects: function(jsonData) {
		if (jsonData && jsonData.chartshape) {
			for (var i = 0; i < jsonData.chartshape.length; i++) {
				var shape = jsonData.chartshape[i];
				if (shape.type == 'RECT') {
					if (shape.coords[0] > shape.coords[2]) {
						var temp = shape.coords[0];
						shape.coords[0] = shape.coords[2];
						shape.coords[2] = temp;
					}
					if (shape.coords[1] > shape.coords[3]) {
						var temp = shape.coords[1];
						shape.coords[1] = shape.coords[3];
						shape.coords[3] = temp;
					}
				}
			}
		}
		return jsonData;
	},

	/* Encode all series with text encoding.
	   @param  options  (object) the settings for this Google chart instance
	   @return  (string) the encoded series data */
	_textEncoding: function(options) {
		var minValue = (options.minValue == $.gchart.calculate ?
			this._calculateMinValue(options.series) : options.minValue);
		var maxValue = (options.maxValue == $.gchart.calculate ?
			this._calculateMaxValue(options.series) : options.maxValue);
		var data = '';
		for (var i = 0; i < options.series.length; i++) {
			data += '|' + this._textEncode(options.series[i], minValue, maxValue);
		}
		return 't' + (options.visibleSeries || '') + ':' + data.substr(1);
	},

	/* Encode values in text format: numeric 0.0 to 100.0, comma separated, -1 for null
	   @param  series    (object) details about the data values to encode
	   @param  minValue  (number) the minimum possible data value
	   @param  maxValue  (number) the maximum possible data value
	   @return  (string) the encoded data values */
	_textEncode: function(series, minValue, maxValue) {
		minValue = (series.minValue != null ? series.minValue : minValue);
		maxValue = (series.maxValue != null ? series.maxValue : maxValue);
		var factor = 100 / (maxValue - minValue);
		var data = '';
		for (var i = 0; i < series.data.length; i++) {
			data += ',' + (series.data[i] == null || isNaN(series.data[i]) ? '-1' :
				Math.round(factor * (series.data[i] - minValue) * 100) / 100);
		}
		return data.substr(1);
	},

	/* Encode all series with scaled text encoding.
	   @param  options  (object) the settings for this Google chart instance
	   @return  (string) the encoded series data */
	_scaledEncoding: function(options) {
		var minValue = (options.minValue == $.gchart.calculate ?
			this._calculateMinValue(options.series) : options.minValue);
		var maxValue = (options.maxValue == $.gchart.calculate ?
			this._calculateMaxValue(options.series) : options.maxValue);
		var data = '';
		var minMax = '';
		for (var i = 0; i < options.series.length; i++) {
			data += '|' + this._scaledEncode(options.series[i], minValue);
			minMax += ',' + (options.series[i].minValue != null ?
				options.series[i].minValue : minValue) +
				',' + (options.series[i].maxValue != null ?
				options.series[i].maxValue : maxValue);
		}
		return 't' + (options.visibleSeries || '') + ':' + data.substr(1) +
			'&chds=' + minMax.substr(1);
	},

	/* Encode values in text format: numeric min to max, comma separated, min - 1 for null
	   @param  series    (object) details about the data values to encode
	   @param  minValue  (number) the minimum possible data value
	   @return  (string) the encoded data values */
	_scaledEncode: function(series, minValue) {
		minValue = (series.minValue != null ? series.minValue : minValue);
		var data = '';
		for (var i = 0; i < series.data.length; i++) {
			data += ',' + (series.data[i] == null || isNaN(series.data[i]) ?
				(minValue - 1) : series.data[i]);
		}
		return data.substr(1);
	},

	/* Encode all series with simple encoding.
	   @param  options  (object) the settings for this Google chart instance
	   @return  (string) the encoded series data */
	_simpleEncoding: function(options) {
		var minValue = (options.minValue == $.gchart.calculate ?
			this._calculateMinValue(options.series) : options.minValue);
		var maxValue = (options.maxValue == $.gchart.calculate ?
			this._calculateMaxValue(options.series) : options.maxValue);
		var data = '';
		for (var i = 0; i < options.series.length; i++) {
			data += ',' + this._simpleEncode(options.series[i], minValue, maxValue);
		}
		return 's' + (options.visibleSeries || '') + ':' + data.substr(1);
	},

	/* Encode values in simple format: single character,
	   banded-62 as A-Za-z0-9, _ for null.
	   @param  series    (object) details about the data values to encode
	   @param  minValue  (number) the minimum possible data value
	   @param  maxValue  (number) the maximum possible data value
	   @return  (string) the encoded data values */
	_simpleEncode: function(series, minValue, maxValue) {
		minValue = (series.minValue != null ? series.minValue : minValue);
		maxValue = (series.maxValue != null ? series.maxValue : maxValue);
		var factor = 61 / (maxValue - minValue);
		var data = '';
		for (var i = 0; i < series.data.length; i++) {
			data += (series.data[i] == null || isNaN(series.data[i]) ? '_' :
				SIMPLE_ENCODING.charAt(Math.round(factor * (series.data[i] - minValue))));
		}
		return data;
	},

	/* Encode all series with extended encoding.
	   @param  options  (object) the settings for this Google chart instance
	   @return  (string) the encoded series data */
	_extendedEncoding: function(options) {
		var minValue = (options.minValue == $.gchart.calculate ?
			this._calculateMinValue(options.series) : options.minValue);
		var maxValue = (options.maxValue == $.gchart.calculate ?
			this._calculateMaxValue(options.series) : options.maxValue);
		var data = '';
		for (var i = 0; i < options.series.length; i++) {
			data += ',' + this._extendedEncode(options.series[i], minValue, maxValue);
		}
		return 'e' + (options.visibleSeries || '') + ':' + data.substr(1);
	},

	/* Encode values in extended format: double character,
	   banded-4096 as A-Za-z0-9-., __ for null.
	   @param  series    (object) details about the data values to encode
	   @param  minValue  (number) the minimum possible data value
	   @param  maxValue  (number) the maximum possible data value
	   @return  (string) the encoded data values */
	_extendedEncode: function(series, minValue, maxValue) {
		minValue = (series.minValue != null ? series.minValue : minValue);
		maxValue = (series.maxValue != null ? series.maxValue : maxValue);
		var factor = 4095 / (maxValue - minValue);
		var encode = function(value) {
			return EXTENDED_ENCODING.charAt(value / 64) +
				EXTENDED_ENCODING.charAt(value % 64);
		};
		var data = '';
		for (var i = 0; i < series.data.length; i++) {
			data += (series.data[i] == null || isNaN(series.data[i]) ? '__' :
				encode(Math.round(factor * (series.data[i] - minValue))));
		}
		return data;
	},

	/* Determine the minimum value amongst the data values.
	   @param  series  (object[]) the series to examine
	   @return  (number) the minimum value therein */
	_calculateMinValue: function(series) {
		var minValue = 99999999;
		for (var i = 0; i < series.length; i++) {
			var data = series[i].data;
			for (var j = 0; j < data.length; j++) {
				minValue = Math.min(minValue, (data[j] == null ? 99999999 : data[j]));
			}
		}
		return minValue;
	},

	/* Determine the maximum value amongst the data values.
	   @param  series  (object[]) the series to examine
	   @return  (number) the maximum value therein */
	_calculateMaxValue: function(series) {
		var maxValue = -99999999;
		for (var i = 0; i < series.length; i++) {
			var data = series[i].data;
			for (var j = 0; j < data.length; j++) {
				maxValue = Math.max(maxValue, (data[j] == null ? -99999999 : data[j]));
			}
		}
		return maxValue;
	}
});

/* The definition of a chart axis.
   @param  axis           (string) the axis position: top, bottom, left, right
   @param  labels         (string[]) the labels for this axis
   @param  positions      (number[], optional) the positions of the labels
   @param  rangeStart     (number, optional with next two) start of range
   @param  rangeEnd       (number, optional with above) end of range
   @param  rangeInterval  (number, optional with above) interval between values in the range
   @param  colour         (string, optional) the axis colour
   @param  alignment      (string, optional) the labels' alignment
   @param  size           (number, optional) the labels' size
   @param  format         (object, optional) the labels' number format options */
function GChartAxis(axis, labels, positions, rangeStart, rangeEnd, rangeInterval,
		colour, alignment, size, format) {
	if (typeof labels == 'number') { // Range instead of labels/positions
		format = alignment;
		size = colour;
		alignment = rangeInterval;
		colour = rangeEnd;
		rangeInterval = rangeStart;
		rangeEnd = positions;
		rangeStart = labels;
		positions = null;
		labels = null;
	}
	else if (!$.isArray(positions)) { // Optional positions
		format = size;
		size = alignment;
		alignment = colour;
		colour = rangeInterval;
		rangeInterval = rangeEnd;
		rangeEnd = rangeStart;
		rangeStart = positions;
		positions = null;
	}
	if (typeof rangeStart == 'string') { // Optional rangeStart/rangeEnd/rangeInterval
		format = colour;
		size = rangeInterval;
		alignment = rangeEnd;
		colour = rangeStart;
		rangeInterval = null;
		rangeEnd = null;
		rangeStart = null;
	}
	if (typeof rangeInterval == 'string') { // Optional rangeInterval
		format = size;
		size = alignment;
		alignment = colour;
		colour = rangeInterval;
		rangeInterval = null;
	}
	if (typeof alignment == 'number') { // Optional alignment
		format = size;
		size = alignment;
		alignment = null;
	}
	this._axis = axis;
	this._labels = labels;
	this._positions = positions;
	this._range = (rangeStart != null ? [rangeStart, rangeEnd, rangeInterval] : null);
	this._color = colour;
	this._alignment = alignment;
	this._size = size;
	this._drawing = null;
	this._tickColor = null;
	this._tickLength = null;
	this._format = format;
}

$.extend(GChartAxis.prototype, {

	/* Get/set the axis position.
	   @param  axis  (string) the axis position: top, bottom, left, right
	   @return  (GChartAxis) the axis object or
	            (string) the axis position (if no parameters specified) */
	axis: function(axis) {
		if (arguments.length == 0) {
			return this._axis;
		}
		this._axis = axis;
		return this;
	},
	
	/* Get/set the axis labels.
	   @param  labels  (string[]) the labels for this axis
	   @return  (GChartAxis) the axis object or
	            (string[]) the axis labels (if no parameters specified) */
	labels: function(labels) {
		if (arguments.length == 0) {
			return this._labels;
		}
		this._labels = labels;
		return this;
	},

	/* Get/set the axis label positions.
	   @param  positions  (number[]) the positions of the labels
	   @return  (GChartAxis) the axis object or
	            (number[]) the axis label positions (if no parameters specified) */
	positions: function(positions) {
		if (arguments.length == 0) {
			return this._positions;
		}
		this._positions = positions;
		return this;
	},

	/* Get/set the axis range.
	   @param  rangeStart     (number) start of range
	   @param  rangeEnd       (number) end of range
	   @param  rangeInterval  (number, optional) interval between values in the range
	   @return  (GChartAxis) the axis object or
	            (number[3]) the axis range start, end, and interval (if no parameters specified) */
	range: function(start, end, interval) {
		if (arguments.length == 0) {
			return this._range;
		}
		this._range = [start, end, interval];
		return this;
	},

	/* Get/set the axis style.
	   @param  colour     (string) the axis colour
	   @param  alignment  (string, optional) the labels' alignment
	   @param  size       (number, optional) the labels' size
	   @return  (GChartAxis) the axis object or
	            (object) the axis style with attributes color, alignment, and size
				(if no parameters specified) */
	style: function(colour, alignment, size) {
		if (arguments.length == 0) {
			return (!this._color && !this._alignment && !this._size ? null :
				{color: this._color, alignment: this._alignment, size: this._size});
		}
		this._color = colour;
		this._alignment = alignment;
		this._size = size;
		return this;
	},

	/* Get/set the axis drawing control.
	   @param  drawing  (string) the drawing control: line, ticks, both
	   @return  (GChartAxis) the axis object or
	            (string) the axis drawing control (if no parameters specified) */
	drawing: function(drawing) {
		if (arguments.length == 0) {
			return this._drawing;
		}
		this._drawing = drawing;
		return this;
	},

	/* Get/set the axis tick style.
	   @param  colour  (string) the colour of the tick marks
	   @param  length  (number, optional) the length of the tick marks,
	                   negative values draw inside the chart or
					   (string, optional) list of lengths, comma-separated
	   @return  (GChartAxis) the axis object or
	            (object) the axis tick style with attributes color and length
				(if no parameters specified) */
	ticks: function(colour, length) {
		if (arguments.length == 0) {
			return (!this._tickColor && !this._tickLength ? null :
				{color: this._tickColor, length: this._tickLength});
		}
		this._tickColor = colour;
		this._tickLength = length;
		return this;
	},

	/* Get/set the number format for the axis.
	   @param  type        (object) containing all these settings or
	                       (string) 'f' for floating point, 'p' for percentage,
	                       'e' for scientific notation, 'c<CUR>' for currency (as specified by CUR)
	   @param  prefix      (string, optional) text appearing before the number
	   @param  suffix      (string, optional - can only be present if prefix is present)
	                       text appearing after the number
	   @param  precision   (number, optional) the number of decimal places
	   @param  showX       (boolean, optional) true to show the x-value, false for the y-value
	   @param  zeroes      (boolean, optional - can only be present if showX is present)
	                       true to display trailing zeroes
	   @param  separators  (boolean, optional - can only be present if showX and zeroes are present)
	                       true to display group separators
	   @return  (GChartAxis) the axis object or
	            (object) the axis format (if no parameters specified) */
	format: function(type, prefix, suffix, precision, showX, zeroes, separators) {
		if (arguments.length == 0) {
			return this._format;
		}
		this._format = initNumberFormat(type, prefix, suffix, precision, showX, zeroes, separators);
		return this;
	}
});

/* Initialise a number format specification. */
function initNumberFormat(type, prefix, suffix, precision, showX, zeroes, separators) {
	if (typeof type == 'object') {
		return type;
	}
	if (typeof prefix == 'number') {
		separators = showX;
		zeroes = precision;
		showX = suffix;
		precision = prefix;
		suffix = '';
		prefix = '';
	}
	if (typeof prefix == 'boolean') {
		separators = precision;
		zeroes = suffix;
		showX = prefix;
		precision = 0;
		suffix = '';
		prefix = '';
	}
	if (typeof suffix == 'number') {
		separators = zeroes;
		zeroes = showX;
		showX = precision;
		precision = suffix;
		suffix = '';
	}
	if (typeof suffix == 'boolean') {
		separators = showX;
		zeroes = precision;
		showX = suffix;
		precision = 0;
		suffix = '';
	}
	if (typeof precision == 'boolean') {
		separators = zeroes;
		zeroes = showX;
		showX = precision;
		precision = 0;
	}
	return {type: type, prefix: prefix || '', suffix: suffix || '', precision: precision || '',
		showX: showX || false, zeroes: zeroes || false, separators: separators || false};
}

/* jQuery extend now ignores nulls!
   @param  target  (object) the object to extend
   @param  props   (object) the new attributes to add
   @return  (object) the updated object */
function extendRemove(target, props) {
	$.extend(target, props);
	for (var name in props) {
		if (props[name] == null) {
			target[name] = null;
		}
	}
	return target;
}

/* Attach the Google chart functionality to a jQuery selection.
   @param  command  (string) the command to run (optional, default 'attach')
   @param  options  (object) the new settings to use for these Google chart instances
   @return  (jQuery object) for chaining further calls */
$.fn.gchart = function(options) {
	var otherArgs = Array.prototype.slice.call(arguments, 1);
	if (options == 'current') {
		return $.gchart['_' + options + 'GChart'].
			apply($.gchart, [this[0]].concat(otherArgs));
	}
	return this.each(function() {
		if (typeof options == 'string') {
			$.gchart['_' + options + 'GChart'].
				apply($.gchart, [this].concat(otherArgs));
		}
		else {
			$.gchart._attachGChart(this, options);
		}
	});
};

/* Initialise the Google chart functionality. */
$.gchart = new GChart(); // singleton instance

})(jQuery);
//}}}
<!--{{{-->
<link rel="shortcut icon" href="/recipes/tscount_public/tiddlers/favicon.ico" />
<link href="/bags/tscount_public/tiddlers.atom" rel="alternate"
	type="application/atom+xml" title="tscount's public feed" />
<!--}}}-->
(function() {
var getCSRFToken = function(window) {
	// XXX: should not use RegEx - cf.
	// http://www.quirksmode.org/js/cookies.html
	// https://github.com/TiddlySpace/tiddlyspace/commit/5f4adbe009ed4bda3ce39058a3fb07de1420358d
	var regex = /^(?:.*; )?csrf_token=([^(;|$)]*)(?:;|$)/;
	var match = regex.exec(document.cookie);
	var csrf_token = null;
	if (match && (match.length === 2)) {
		csrf_token = match[1];
	}

	return csrf_token;
};

if (typeof config !== 'undefined' && config.extensions &&
		config.extensions.tiddlyspace &&
		config.extensions.tiddlyspace.getCSRFToken === null) {
	config.extensions.tiddlyspace.getCSRFToken = getCSRFToken;
} else {
	window.getCSRFToken = getCSRFToken;
}
})(window);
iVBORw0KGgoAAAANSUhEUgAAADEAAAAwCAYAAAC4wJK5AAAAIGNIUk0AAHomAACAhAAA+gAAAIDoAAB1MAAA6mAAADqYAAAXcJy6UTwAAAAEZ0FNQQAAsY58+1GTAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAAOxAAADsQBlSsOGwAACvZJREFUeNrtWWtsW+UZfs6JnfgaO47jOInTXJrSNEkvdOUm2jEXJJC2VaUrEhpopNImfkzA/rAN+NNJY5vGj20a0n4wBIEixsaAafuxSUWG0a6wAqW59ZamaWInTmInduw4ji/n7P2+4+M48SVuWmA/eCXrnGMff+d9vvf9nvd5vwN8Zf8fJlzvAEc9Hs2yD/eJMu6SIXUIELbJQCv9VLXyFGEesjxBx//IsnRZEMXjv3jI/dmXDuLp1zy7IONRcu4BuqzdwIMvy5CPpQTxj79+2O39QkE884pnryzIv6HTPWt/q6iogNlsgkFXBV2VDkKFgEQiCUlKIxKNIRZbQiqVWvu3ZQjy61JS/NmvjrjHPlcQR//sMSWWpT/QXx6kS436vdFgQGNjPerr7NDrdBBFsegYsiwjEonCO+XHzGwAy8uJ3J8XaewfVbrw8lG3O3XDQTxzzHM7OfAXOnWp39lsVmxpa4XVatlQCkiShEn/DK5OeBGNLq4AFXC8Kik8cPSIO3TDQDx9zPMwTeFL6uzr9Tr0dG7lIG6EsehM+CZxceQK0ul0hgdwFZJw+NnvuT8uZ4yKMgBQCkHHrl2NTuze2QOj0XDj6JE8tlRXo6HegdBChFJsmX1tpek9dOeh3rdPvN03t2EQT73qOShAfk0F0NHeips62kvm/PWYVqtBU4MTi4uLiC7G2FcGwnfgjkO9fz35Vt/CNYP46UueVlGU/06nJnbdedNmtLVs4rP2uRYtGt9JEckBYqUp+/rdB3pffe9vfUUXe8FpFTR8DdjZ+SZXE1qaXV9oBd7R0wV7bY16uWdZg+euKRJPv+r5Ps334+ycDbS9u7PsCKRSaWKbGVy64sXZoVFcGJnAyJVJBIJhxBMJWMzGstKRPa+2pga+qWnOYvT0W+862Hvy3+/0ja4LgkmIdIRTqZU9bM/undBqNGUBYM6+f6ofE5OzCIWjvMglkyl+DEcWMTU9h0ujPp77tTXV646n0VDhNJngn55RqXf33Y/3vvBeX59UMp0SPjxIUoLpHjQ3NVLVrVqfIiUZJz8axCdnL/JIqKavImfNOph02lWR+vTsJQ42995ixjLBYbeplz1xL+4pCHiVQ5AfYYnDotDW0lxWBE78d5CKVlCZEVHA/h3NuG1rA5xWA79mNhtewocXpvDuZ+NIpiWa3Tmc+ngYe2/tgSCWTtWO9jbMBOZ4PSG2/Al99c+i6fTjYx5XhYzfMl+cDjuaqCaUk0IXL3uzM//Egd24o7MBZn3lqnVkpGhsbapBh9OMQCCIFouMTbolaBZ8EMJTkOd9kBcobZbCfCqFCoqeqLhWWVlJ6RlGbCnO1kbrHd/pfXEt5WYjoZWlg/R3jZJKTesCSNOC6x8ezUbgh9/chbb6wrkei8Xg8/kwOTmJXXU5KS0TayYzzJmMQ45HIIeneckWrQ0QbMSKWj2llY3IYV5xWOIp9XJBEJIsbhYEmSagQrZYzOvS0ZWrfr5wme3raioIgDHL2NgYJiYm+HmusRk2m8200LVZoNFoVLmPUkeanwRCUxBtzaiz1+P8xcuZVSzdVRQEAdjLQ6/XC+XQ4FxoJaJ7u/Mjx+TD4OAgFhZW7rNYLKR4G0l32TiIvOiSdpqZmeFRi0QiCpjgOKooQiaDHlGS8qSpbi+1sDkrmU3l6aL5UDS7FtgiXqWpqeL29/cjHo8r9+j1aG9vh8PhKK2BqB9paCBScDrh9Xp5FHn/sTiPbosWpxmGjJ/FQNiRYaZyTE0lQ6Umy0LMmONnzpyh35P8uq6uDp2dncT7mrIrNiOF5uZmDnpgYIBHxSwmsY2E8/C8ouVKyg41R8sRbDyXEynKYzm7BlgKqQDq6+vR3d19TQByrYrq1I4dO3gkmTVQwBuNZWinRDJR1gNqrFwbYmk5BX+IizUefp7LrOmurcW2bduuWzSytbN9+3aearxuEH94PB57sXRiCaxLJcvrDG3Was5QvOAN+fDtPc2chdQHd3V1FQUQHQtgbsCLpekwUrEEREpJI9WR2ptbYHTV5N1vNBrR1taGkZERaJVpZ0Xvybxit+/+Rx6mamKXqDSSal13+iwWI9dCLIUmAhE4K2NIxJWIsAgw+lxri955jP7pI0yfvIQlfxjJSBzpeBKpxWV+HTxzFfHZCCwd9VTwVieJiXQUY60MVbf39vb+ri+jo1buFOUPeXosxYXcnrcokxAB7OhqV9YH1ZdISGnAqqlLs9vtefdHRmcx8soJ7mzuAtZSdc8lhtDwJLz/GizIXIyeM8bkxLfy00kS34cg97LT6dkAITeuC6SjrZHUaRC6eBCqHy6XKy+NktFlXHnzNKSUUvCMtdWwtTqho2iq90YDYUwPX0Wa0plFxP61VhgaV/fxjHrHx8fVy3vp886qSKREHGcHLtiCc2UvPCbiXDbdSh9Qm7+PxpxiacMj5axF487N0BMx5II12S1wbF0RnYFPxgquDXWBU9b35LGTsgsnv8nOw+EFqrSR8jidQuCwKJLdYDAUpNMwKdhsMdrcUHTBmxxWiBrFyUXffOF7TCb1tLMgxYqS+KJ6fuHyaPk8uLy49gGrO76YQtsaYiGNrrJkkavQKiCkRGGWVGuGWpzzQPz8EfdxtnnFtdFciOv48nbC0lknCjYtBsXxdDLNc76kOl5W0q5Cpy17DvM1hig8pq6N/uFzclzZB1pnlIqMFEkW/NncVpfdKFuYChYPaCSWrf76unVb2GhREL/8rvu8LAvPKzOXEobOXeAPL60PjFnlWshYEVM7uMCoH/GFWGFROT67AryjrmhvkrHzJbdsqtJ4ig68brBm5OzAUEkgok4pbKwfUJXrqvFsRtTdotQUmeT2xKeXMD8xk02tFOX/7EUvFjJtrs5RjZpuV8H+hD0jE9XSII4ecccpCPdTBR9T6kYQ/YPDeY1N1gwrm8rT09MFb2m6twcWal1VIMzp0Q8GMHpyEFdODHBQ6lpoPbi7YO8dDAZzfThZEgSz5464/SkI+2goLpD8MwGcOv0pq+j5rGKi2iAq1Do1NZXdGF5rbYdvQYN7G90qZtdIKp7IRplpqNZDe6B3Ft5pV7UZL2ui+GZZG8qsId93uPdd6t1ZX2tje0jeST8VHBHV5pxixY4yzVAszJsY1pNYrdaCFGpqqUXtzk1cG0nEVqwuaKv1sPW4sOnAzVwIFrJQKMRVcgb8W/v37+8rCwSzD97q87O9UEnELqY02KyxdeKfnuW+s5cszGlBX63sWEgp/kAGIofTV+ugKi3M7XVcWjhu24y6PW2o7nBAo68s+i6DdYoq+9HzHiXxN76h112Zrf7f86337E6dBg1OBxrrHajWSpC9A7w3Zt+zPqBQRK7VhoaGeO+diebzbrf7sbLfTxSISv+dB3rfEESZSrPQxXdQaJaYRPFN+XF1KgC5ohJWbYqyS+KLnIFhsnwjzREb+9y5c1kAbKuLxnmAopC4rhePqj35ksep0Uq9giw8lNExWdHUShA3W1YGr6mpwZYtW7iAK9cYlZ4/fz7bKZJ5CQAFwT2y4RePJdPsFU+PIEr3SJLYktn6aXXoYe+iTMoQUVbhsr6bHVU1uvbVF3Oa7XSw2c+pTUUB3DAQxYx64U5y5AWm2NeyFIsK+6hpxook26NaW4vo//+ghfwDAuDf8IvHGwTmG+TcE+TwferrszLsY7r/WXL+nXXbgS/yDRDbpSAwh+n0NnKwJyOnXZlNikAmbd6j4xtMG7mv8X32V/Zl2/8AlGCJNTw3pK8AAAAASUVORK5CYII=
ColorPalette
StyleSheet
SiteSubtitle
GettingStarted
SiteTitle
MainMenu
SiteIcon
DefaultTiddlers
ViewTemplate
PageTemplate
SideBarOptions
EditTemplate
SiteInfo
SideBarTabs
ToolbarCommands
a TiddlySpace
<!DOCTYPE html>
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
	<title>This Space</title>
	<link href="/bags/common/tiddlers/profile.css" type='text/css' rel='stylesheet' >
	<link href="/bags/common/tiddlers/admin.css" type='text/css' rel='stylesheet' >
</head>
<body>
<div id="container">
	<div id="text-html" class="main section">
		<a class="app" href="/">home</a>
		<div class="left">
		<h2>About this space <button class='toggleNext'></button></h2>
		<div id="siteinfo"></div>
		<h2>Site Icon</h2>
		<div>
			<img id="siteicon" class="siteicon">
			<form id="upload" method="POST" enctype="multipart/form-data">
				<input type="hidden" name="title" value="SiteIcon" />
				<input type="hidden" name="tags" value="excludeLists">
				<input type="hidden" name="csrf_token" class="csrf" />
				<input type="file" name="file" accept="image/*" />
				<input class="btn" type="submit" value="upload" />
			</form>
			<div id="dropzone">Drop file here
				<img class="notloading" src="/bags/common/tiddlers/ajax-loader.gif" alt="submitting SiteIcon" />
			</div>
		</div>
		<h2>Vital Statistics</h2>
		<div id="info">please wait while information is loaded about this space...</div>
		</div>
		<div class="right">
		<div class="ts-membership">
			<h2>
				Add Member
				<a href="http://docs.tiddlyspace.com/What%20is%20a%20member%3F" title="What is a Member?" class="help">What is a Member?</a>
			</h2>
			<div>
				<p>Add a new member to your space by entering their name below. Enter a space name instead and prefix with @ to add everyone who is already a member of that space.</p>
				<form class="ts-members">
					<input class="inputBox" type="text" name="username">
					<input type="submit" value="Add Member" class="btn" />
				</form>
			</div>
			<h2>
				Existing Members <button class='toggleNext'></button>
			</h2>
			<div>
				Your space currently has the following members: 
				<ul class="ts-members"></ul>
			</div>
			<h2>
				Include Space
				<a class="help" href="http://docs.tiddlyspace.com/What%20is%20space%20inclusion%3F" title="What is inclusion?">What is Inclusion?</a>
			</h2>
			<form class="ts-includes">
				<input class="inputBox" type="text" name="spacename">
				<input type="submit" value="Include Space" class="btn" />
			</form>
		</div>
		<div>
			<h2>Included Spaces <button class='toggleNext'></button></h2>
			<div>
			This space includes the following spaces:
			<ul class="ts-includes"></ul>
			</div>
		</div>
		</div>
		<div class="clear"></div>
	</div>
</div>
<script src='/bags/common/tiddlers/backstage.js'></script>
<script src='/bags/common/tiddlers/jquery.js'></script>
<script src='/bags/tiddlyspace/tiddlers/chrjs'></script>
<script src='/bags/common/tiddlers/chrjs.space'></script>
<script src='/bags/common/tiddlers/chrjs.users'></script>
<script src='/bags/common/tiddlers/chrjs.identities'></script>
<script src='/bags/tiddlyspace/tiddlers/TiddlySpaceCSRF'></script>
<script src='/bags/common/tiddlers/jquery-form.js'></script>
<script src="/bags/common/tiddlers/siteiconupload.js"></script>
<script src="/bags/common/tiddlers/ts.js"></script>
<script src="/status.js"></script>
<script src="/bags/common/tiddlers/space.js"></script>
<!--[if lt IE 8]>
<script type="text/javascript" src="/bags/common/tiddlers/json2.js"></script>
<![endif]-->
</body>
</html>
A space with some automated info on how many users and spaces there are, via SomeInfo
/***
|''Name''|ErrorHandlerPlugin|
|''Version''|0.4.3|
|''Author''|Jon Robson|
|''Description''|Localised tiddler save errors including edit conflict resolution.|
|''CoreVersion''|2.6.1|
|''Requires''|TiddlySpaceConfig|
***/
//{{{
(function($) {

var tiddlyspace = config.extensions.tiddlyspace;
var currentSpace = tiddlyspace.currentSpace.name;
tiddlyspace.getLocalTitle = function(title, workspace, suffix) {
	var endsWith = config.extensions.BinaryTiddlersPlugin.endsWith;
	if(!suffix) {
		var isPublic = endsWith(workspace, "_public");
		suffix = tiddlyspace.resolveSpaceName(workspace);
		if(currentSpace == suffix) {
			suffix = isPublic ? "public" : "private";
		} else {
			suffix = "@%0".format(suffix);
		}
	}
	return "%0 *(%1)*".format(title, suffix);
};

var sssp = config.extensions.ServerSideSavingPlugin;

var msgs = config.messages.editConflict = {
	loading: "Loading..",
	resolve: "[[Edit Conflict]]@glossary: this tiddler may have been changed by someone else.",
	reviewDiff: "review (recommended)",
	reviewDiffTooltip: "review changes made to this tiddler",
	reviewDiffError: "error retrieving revision.",
	save: "overwrite",
	saveTooltip: "make this revision the top revision of this tiddler",
	discard: "cancel",
	discardTooltip: "undo changes to this tiddler and get most recent version",
	diffTitle: "%0",
	diffFieldTitle: "%0 - fields",
	diffTextTitle: "%0 - text",
	updating: "updating your version...",
	diffHeader: ["Review the changes that have been made whilst you were editing this tiddler. ",
		"Fold relevant changes back into your version.\n",
		"{{removed{Red}}} highlight shows content removed. ",
		"{{added{Green}}} highlight shows content added.\n"].join(""),
	diffTextHeader: "View changes in text",
	diffFieldsHeader: "View changes in fields"
};

var plugin = config.extensions.errorHandler = {
	diffTags: ["excludeLists", "excludeMissing", "excludeSearch"],
	displayMessage: function(message, tiddler, context) {
		var desc = context && context.httpStatus ? context.statusText :
			sssp.locale.connectionError;
		var reportArea = plugin.reportError(tiddler.title);
		var msg = $("<div />").appendTo(reportArea);
		if(message == "saveConflict") {
			wikify(msgs.resolve, msg[0]);
			var choiceArea = $("<div />").appendTo(reportArea)[0];
			plugin.editConflictHandler(choiceArea, tiddler);
		} else {
			msg.text(sssp.locale[message].format(tiddler.title, desc));
		}
	},
	editConflictHandler: function(container, tiddler) {
		var title = tiddler.title;
		var myrev = tiddler.fields["server.page.revision"];
		// note user now needs to edit, fix problem and save. 
		// TODO: make sure this gets reset in save callback
		store.getTiddler(title).fields["server.page.revision"] = "false";

		var diffBtn = createTiddlyButton(container, msgs.reviewDiff, msgs.reviewDiffTooltip, function(ev) {
			var title = $(ev.target).data("title");
			plugin.displayDiff(ev.target, store.getTiddler(title), myrev);
		});
		var saveBtn = createTiddlyButton(container, msgs.save, msgs.saveTooltip, function(ev) {
				var title = $(ev.target).data("title");
				var tid = store.saveTiddler(store.getTiddler(title));
				autoSaveChanges(null, [tid]);
			});
		var ignoreBtn = createTiddlyButton(container, msgs.discard, msgs.discardTooltip, function(ev) {
			var title = $(ev.target).text(msgs.updating).data("title");
			plugin.resetToServerVersion(store.getTiddler(title));
		});
		$([diffBtn, ignoreBtn, saveBtn]).data("title", title);
	},
	getDiffTiddlerTexts: function(diffText) {
		var chunks = diffText.split("\n  \n");
		if(chunks.length < 2) {
			return [chunks[0], ""];
		} else {
			var diffFieldsText = "{{diff{\n%0\n}}}".format(chunks[0]);
			diffText = '{{diff{\n%0\n}}}'.format(chunks.splice(1, chunks.length).join("\n"));
			return [diffText, diffFieldsText];
		}
	},
	makeDiffTiddler: function(title, diff) {
		var newTiddler = new Tiddler(title);
		var tags = plugin.diffTags;
		newTiddler.text = msgs.loading;
		newTiddler.fields.doNotSave = true;
		newTiddler.tags = diff ? tags.concat(["diff"]) : tags;
		newTiddler = store.saveTiddler(newTiddler);
		$.extend(store.getTiddler(title).fields,
			config.defaultCustomFields); // allow option to save it
		return newTiddler;
	},
	displayDiff: function(src, tiddler, latestRevision) {
		var adaptor = tiddler.getAdaptor();
		var title = tiddler.title;
		var ts = new Date().formatString("0hh:0mm:0ss");
		var suffix = "edit conflict %0".format(ts);
		var diffTitle = tiddlyspace.getLocalTitle(msgs.diffTitle.format(title), "", suffix);
		var diffTextTitle = tiddlyspace.getLocalTitle(msgs.diffTextTitle.format(title), "", suffix);
		var diffFieldsTitle = tiddlyspace.getLocalTitle(msgs.diffFieldTitle.format(title), "", suffix);
		plugin.makeDiffTiddler(diffTextTitle, true);
		plugin.makeDiffTiddler(diffFieldsTitle, true);
		var newTiddler = plugin.makeDiffTiddler(diffTitle, false);
		newTiddler.text = ['%0\n<<slider chkViewDiffText "%1" "%2">>\n',
			'<<slider chkViewDiffField "%3" "%4">>'].join("").
			format(msgs.diffHeader, diffTextTitle, msgs.diffTextHeader,
				diffFieldsTitle, msgs.diffFieldsHeader);
		store.saveTiddler(newTiddler);

		var callback = function(r) {
			var text = plugin.getDiffTiddlerTexts(r);
			store.getTiddler(diffTextTitle).text = text[0];
			store.getTiddler(diffFieldsTitle).text = text[1];
			story.refreshTiddler(diffTitle, null, true);
		};
		var workspace = "bags/%0".format(tiddler.fields["server.bag"]);
		ajaxReq({
			type: "get",
			dataType: "text",
			url: "/diff?format=unified&rev1=%0/%1/%2&rev2=%0/%1".format(workspace, title, latestRevision),
			success: callback,
			error: function() {
				displayMessage(msgs.reviewDiffError);
			}
		});
		story.displayTiddler(src, diffTitle);
	},
	resetToServerVersion: function(tiddler) {
		var adaptor = tiddler.getAdaptor();
		var ctx = { 
			host: tiddler.fields["server.host"],
			workspace: "bags/" + tiddler.fields["server.bag"]
		};
		adaptor.getTiddler(tiddler.title, ctx, null, function(context) {
			store.saveTiddler(context.tiddler);
			story.refreshTiddler(tiddler.title);
			store.setDirty(false);
		});
	},
	reportError: function(title) {
		var el = story.getTiddler(title);
		if(!el) {
			el = story.displayTiddler(null, title);
		}
		return $("<div />").addClass("error annotation").prependTo(el)[0];
	}
};

sssp.reportFailure = function(message, tiddler, context) {
	config.options.chkViewDiffText = config.options.chkViewDiffText === undefined ?
		true : config.options.chkViewDiffText;
	config.options.chkViewDiffFields = config.options.chkViewDiffFields || false;
	plugin.displayMessage(message, tiddler, context);
};

})(jQuery);
//}}}
|Date|Users|Spaces|
|20110801|2426|4498|
|20110802|2431|4505|
|20110803|2445|4528|
|20110804|2461|4546|
|20110805|2474|4559|
|20110806|2487|4576|
|20110807|2492|4583|
|20110808|2498|4589|
|20110809|2504|4598|
|20110810|2511|4617|
|20110811|2520|4633|
|20110812|2525|4640|
|20110813|2541|4662|
|20110814|2545|4669|
|20110815|2548|4674|
|20110816|2555|4683|
|20110817|2560|4691|
|20110818|2566|4700|
|20110819|2578|4715|
|20110820|2585|4726|
|20110821|2590|4733|
|20110822|2598|4745|
|20110823|2618|4766|
|20110824|2669|4820|
|20110825|2693|4851|
|20110826|2732|4896|
|20110827|2773|4940|
|20110828|2791|4969|
|20110829|2803|4983|
|20110830|2821|5001|
|20110831|2831|5014|
|Date|Users|Spaces|Created|Modified|Tiddlertime|Searchtime|
|20120201|4364|6907|291|501|278.8|1976.4|
|20120202|4374|6920|240|491|285.9|2369.3|
|20120203|4382|6933|1012|1135|282.8|2182.3|
|20120204|4391|6942|201|297|284.9|2198.4|
|20120205|4398|6951|477|562|278.7|3210.1|
|20120206|4409|6964|554|727|321.4|3490.3|
|20120207|4429|6982|491|838|287.6|1937|
|20120208|4437|6992|362|736|556.5|1977.5|
|20120209|4442|7002|275|481|352.6|1698.3|
|20120210|4453|7015|267|584|287.9|1564.4|
|20120211|4460|7025|361|524|283.1|1904|
|20120212|4466|7033|162|313|287.2|1438.2|
|20120213|4473|7044|478|741|288.4|2070.7|
|20120214|4482|7058|1466|1744|1605|932.1|
|20120215|4491|7069|493|708|287.9|3032|
|20120216|4497|7076|254|483|286|4214|
|20120217|4504|7083|313|494|285.3|2336.3|
|20120218|4509|7089|217|370|284.3|1820.2|
|20120219|4521|7102|278|397|283.8|1896.6|
|20120220|4530|7113|1694|1856|335.1|4166.1|
|20120221|4541|7125|481|1199|1482.8|3515.8|
|20120222|4561|7146|1047|1199|283.1|2606|
|20120223|4566|7155|614|758|286.3|4405.9|
|20120224|4574|7167|295|434|283.8|1537.3|
|20120225|4581|7175|379|524|289.1|1942|
|20120226|4587|7181|366|471|280.5|2424.6|
|20120227|4594|7189|301|436|288.7|3183.1|
|20120228|4606|7198|406|604|285|3324.5|
|20120229|4610|7203|211|371|288.2|2694.5|
|~ViewToolbar|+editTiddler +cloneTiddler > fields refreshTiddler changeToPublic changeToPrivate revisions syncing permalink references jump closeOthers < closeTiddler|
|~EditToolbar|+saveTiddler saveDraft -cancelTiddler deleteTiddler|
|~RevisionToolbar|> fields revert|
HelloThere
SomeInfo
|Date|Users|Spaces|Created|Modified|Tiddlertime|Searchtime|
|20130401|6952|10421|91|169|668.7|259|
|20130402|6957|10429|384|484|315.8|8419.25|
|20130403|6962|10435|435|510|328.2|7423.45|
|20130404|6970|10445|267|377|313.9|2778.31|
|20130405|6978|10454|158|247|320.3|17606|
|20130406|6982|10461|232|315|329.4|2935.76|
|20130407|6987|10466|216|271|324|5573.34|
|20130408|6997|10482|482|617|321|10153.3|
|20130409|7008|10496|400|549|344.7|2857.06|
|20130410|7012|10501|382|527|315.3|2822.57|
|20130411|7019|10508|194|317|335.7|2879.47|
|20130412|7056|10545|531|801|312.6|3102.38|
|20130413|7059|10548|69|135|319.2|4077.6|
|20130414|7065|10555|168|376|312.5|326.05|
|20130415|7074|10565|1031|1256|315.4|3004.09|
|20130416|7084|10578|479|659|320.1|2834.56|
|20130421|7096|10595|117|183|
|20130421|7098|10597|145|218|
|20130422|7104|10605|398|498|
|20130423|7110|10611|151|276|
|20130424|7119|10622|224|358|
|20130425|7126|10629|153|246|
|20130426|7135|10643|368|533|
|20130427|7138|10648|132|231|
|20130428|7140|10651|55|98|
|20130429|7148|10663|207|308|
|20130430|7156|10673|203|284|
|Date|Users|Spaces|Created|Modified|
|20111101|3574|5897|366|485|
|20111102|3582|5913|164|249|
|20111103|3594|5931|897|1020|
|20111104|3605|5942|555|734|
|20111105|3609|5948|504|546|
|20111106|3617|5957|182|637|
|20111107|3635|5976|439|636|
|20111108|3645|5991|180|285|
|20111109|3656|6007|177|256|
|20111110|3668|6024|250|317|
|20111111|3678|6035|185|233|
|20111112|3684|6041|158|263|
|20111113|3688|6047|157|204|
|20111114|3690|6050|107|241|
|20111115|3694|6060|298|370|
|20111116|3704|6075|231|315|
|20111117|3718|6091|368|453|
|20111118|3729|6107|303|442|
|20111119|3736|6114|119|163|
|20111120|3742|6120|733|781|
|20111121|3751|6132|224|329|
|20111122|3758|6140|158|248|
|20111123|3765|6149|212|347|
|20111124|3776|6161|614|726|
|20111125|3783|6170|201|281|
|20111126|3795|6184|174|243|
|20111127|3802|6194|139|268|
|20111128|3809|6201|150|266|
|20111129|3820|6210|130|213|
|20111130|3828|6222|235|335|
|Date|Users|Spaces|Created|Modified|
|20111001|3265|5526|223|233|
|20111002|3273|5541|494|529|
|20111003|3282|5549|406|547|
|20111004|3313|5590|1154|1361|
|20111005|3325|5606|355|679|
|20111006|3340|5624|818|1039|
|20111007|3348|5634|726|829|
|20111008|3353|5639|105|251|
|20111009|3357|5643|87|139|
|20111010|3373|5661|1042|1193|
|20111011|3385|5674|306|482|
|20111012|3399|5691|483|587|
|20111013|3411|5703|443|605|
|20111014|3421|5714|628|740|
|20111015|3423|5718|960|1027|
|20111016|3430|5726|656|745|
|20111017|3436|5734|370|516|
|20111018|3446|5745|219|368|
|20111019|3457|5757|370|510|
|20111020|3465|5769|1307|1589|
|20111021|3473|5778|288|409|
|20111022|3483|5789|137|167|
|20111023|3490|5799|558|603|
|20111024|3501|5815|650|808|
|20111025|3520|5838|375|530|
|20111026|3528|5848|677|876|
|20111027|3535|5855|250|350|
|20111028|3544|5864|448|619|
|20111029|3551|5871|585|610|
|20111030|3557|5878|129|191|
|20111031|3566|5887|691|888|
|Date|Users|Spaces|Created|Modified|Tiddlertime|Searchtime|
|20111201|3839|6237|227|336|0|0|
|20111202|3847|6248|358|535|0|0|
|20111203|3855|6256|121|189|0|0|
|20111204|3860|6261|76|150|0|0|
|20111205|3870|6274|396|515|0|0|
|20111206|3881|6290|235|361|0|0|
|20111207|3890|6300|182|256|0|0|
|20111208|3896|6308|163|261|0|0|
|20111209|3903|6317|151|265|0|0|
|20111210|3908|6323|155|196|0|0|
|20111211|3912|6332|172|264|0|0|
|20111212|3919|6342|683|1858|0|0|
|20111213|3926|6352|638|753|0|0|
|20111214|3929|6359|373|615|0|0|
|20111215|3939|6383|478|722|0|0|
|20111216|3961|6409|775|893|0|0|
|20111217|3968|6415|270|489|0|0|
|20111218|3974|6422|250|307|0|0|
|20111219|3987|6440|540|630|0|0|
|20111220|3996|6452|791|952|1206.2|5709.3|
|20111221|3996|6455|186|275|311.5|2289.2|
|20111222|4005|6474|1323|1392|655|3689.4|
|20111223|4014|6479|1062|1296|303.2|1945.5|
|20111224|4017|6483|67|196|302.4|2568.2|
|20111225|4023|6490|545|605|301.3|3445.3|
|20111226|4025|6495|225|358|304.8|2451.8|
|20111227|4035|6508|330|419|313.5|2613.3|
|20111228|4046|6519|540|954|421.9|1748.1|
|20111229|4065|6535|529|813|441.2|6109.4|
|20111230|4068|6542|104|356|281.9|2889.7|
|20111231|4072|6547|77|137|279.3|2470.2|
|Date|Users|Spaces|Created|Modified|Tiddlertime|Searchtime|
|20120801|5576|8573|222|326|315.6|190.56|
|20120802|5581|8585|393|529|314.4|6985.16|
|20120803|5588|8592|181|290|310.3|6759.74|
|20120804|5591|8596|339|467|318.9|2504.18|
|20120805|5596|8602|94|208|309.5|6823.71|
|20120806|5602|8611|195|316|311.2|2283.92|
|20120807|5607|8622|252|392|310.3|2469.72|
|20120808|5610|8631|497|630|307.3|2463.41|
|20120809|5627|8655|378|539|304.3|2494|
|20120810|5630|8660|110|426|303.4|229.62|
|20120811|5635|8665|215|315|304|9422.31|
|20120812|5643|8673|769|933|508.3|2491.65|
|20120813|5646|8677|264|372|303.3|2478.09|
|20120814|5649|8681|124|267|311.4|2362.09|
|20120815|5651|8685|290|423|315.9|221.57|
|20120816|5656|8693|280|395|310.5|254.06|
|20120817|5661|8698|89|344|312|214.51|
|20120818|5663|8700|43|118|313.7|208.85|
|20120819|5669|8708|125|163|309.1|2567.38|
|20120820|5671|8711|111|201|305.8|2665.18|
|20120821|5677|8719|257|351|311.7|249.78|
|20120822|5683|8727|151|272|306.3|2288.99|
|20120823|5689|8734|187|336|317.1|2484.47|
|20120824|5695|8741|309|589|316|2759.29|
|20120825|5697|8743|100|251|319|8197.96|
|20120826|5702|8748|86|175|496.8|2417.23|
|20120827|5708|8758|433|551|312.5|2333.2|
|20120828|5717|8776|267|374|306.2|251.31|
|20120829|5725|8784|129|224|23202.8|416.41|
|20120830|5736|8797|220|307|312.1|2410.82|
|20120831|5740|8804|157|212|299.6|2299.3|
|Date|Users|Spaces|Created|Modified|Tiddlertime|Searchtime|
|20120101|4078|6553|97|180|281.4|3226.5|
|20120102|4083|6559|92|164|279.6|2398.3|
|20120103|4090|6567|452|646|281.2|1989.8|
|20120104|4103|6581|474|761|287.5|2197.4|
|20120105|4110|6592|575|653|310.9|1707|
|20120106|4116|6608|623|753|281.2|2780.5|
|20120107|4123|6623|2692|2913|282.7|1673.7|
|20120108|4132|6636|906|1048|276|2935.8|
|20120109|4141|6648|316|448|282.4|1991.6|
|20120110|4150|6659|724|962|279.8|922.2|
|20120111|4163|6679|483|640|279.7|1818.2|
|20120112|4166|6683|731|864|278|2130.2|
|20120113|4172|6691|844|987|282.2|1648|
|20120114|4177|6696|138|208|520.8|2574.2|
|20120115|4185|6704|225|337|284.3|2403.9|
|20120116|4197|6718|651|1000|280.8|8031.8|
|20120117|4217|6740|461|890|281.6|2112.5|
|20120118|4230|6755|496|675|285.3|1403.8|
|20120119|4244|6774|428|728|279.2|5650.2|
|20120120|4255|6787|945|1195|495.5|3112.3|
|20120121|4265|6799|308|390|285.9|2696.5|
|20120122|4268|6802|221|411|273.7|4004.9|
|20120123|4283|6820|500|826|293.3|2029.7|
|20120124|4288|6828|876|1093|276.2|2154.5|
|20120125|4307|6838|662|902|287.1|1945.8|
|20120126|4318|6851|421|570|286.9|3188.4|
|20120127|4328|6862|322|543|277.1|4250.8|
|20120128|4331|6866|198|378|714.1|3774.7|
|20120129|4338|6875|254|469|282.8|1173.7|
|20120130|4348|6887|720|903|279.2|1877.5|
|20120131|4357|6900|845|1110|281.1|1877.5|
Welcome to a space providing the basics for the [[jquery google charts plugin|http://keith-wood.name/gChart.html]]. See [[an HTML page|/gChartBasic.html]] for an intro. A plugin, ChartTablePlugin, is provided as an example of how to use the charting to turn a table into a chart.

See also @charts for an alternative.
|Date|Users|Spaces|Created|Modified|Tiddlertime|Searchtime|
|20120301|4617|7210|250|454|291|5163.2|
|20120302|4626|7222|548|804|289.3|1773|
|20120303|4636|7232|204|384|286.1|1983.8|
|20120304|4641|7238|404|616|289.3|3095.7|
|20120305|4646|7244|329|570|285.1|1868.7|
|20120306|4650|7250|404|698|280.9|4236.6|
|20120307|4656|7259|384|622|314.7|3343.2|
|20120308|4657|7262|294|464|312.7|1875.5|
|20120309|4661|7269|223|315|312.7|1309.1|
|20120310|4667|7275|140|255|326.7|4126|
|20120311|4671|7279|836|990|593|1246.3|
|20120312|4677|7288|354|705|314|3063.6|
|20120313|4709|7325|693|1004|310|3171.6|
|20120314|4717|7333|412|704|318.8|2759.3|
|20120315|4740|7357|573|708|314|2302.1|
|20120316|4749|7372|528|705|309.4|2921.8|
|20120317|4759|7383|201|304|314.8|2022.6|
|20120318|4765|7390|177|277|311.8|0|
|20120319|4772|7399|419|524|314.1|1688.1|
|20120320|4784|7424|810|1041|438.5|2350.7|
|20120322|4804|7445|0|0|312.6|15584.6|
|20120323|4814|7457|254|427|309.5|15693.1|
|20120324|4820|7464|149|236|314.7|15332|
|20120325|4823|7469|575|674|318|15025.1|
|20120326|4834|7481|364|809|311.5|15321.7|
|20120327|4845|7517|830|1068|304.4|15792.1|
|20120328|4860|7532|223|360|472.1|0|
|20120329|4875|7553|442|605|301.7|16295|
|20120330|4878|7561|574|707|827.1|16687.6|
|20120331|4882|7570|295|443|457.9|1598.1|
/***
|''Name''|TiddlySpaceInitialization|
|''Version''|0.7.2|
|''Description''|Initializes new TiddlySpaces the first time they are created|
|''Status''|@@beta@@|
|''Source''|http://github.com/TiddlySpace/tiddlyspace/blob/master/src/plugins/TiddlySpaceInit.js|
|''CoreVersion''|2.6.1|
|''Requires''|TiddlySpaceConfig RandomColorPalettePlugin chrjs ImageMacroPlugin|
!TODO
* robust error notification and recovery
!MarkupPreHead
<!--{{{-->
<link rel="shortcut icon" href="/recipes/%0_public/tiddlers/favicon.ico" />
<link href="/bags/%0_public/tiddlers.atom" rel="alternate"
	type="application/atom+xml" title="%0's public feed" />
<link rel="canonical" href="%1/" />
<!--}}}-->
!Code
***/
//{{{
(function($) {

var versionField = "tiddlyspaceinit_version";
var markupPreHead = store.getTiddlerText(tiddler.title + "##MarkupPreHead", "");
var tiddlyspace = config.extensions.tiddlyspace;
var currentSpace = tiddlyspace.currentSpace;
var tweb = config.extensions.tiddlyweb;

var plugin = config.extensions.TiddlySpaceInit = {
	version: "0.6",
	SiteTitle: "%0",
	SiteSubtitle: "a TiddlySpace",
	flagTitle: "%0SetupFlag",
	flagWarning: "Please do not modify this tiddler; it was created " +
		"automatically upon space creation.",

	dispatch: function(ev) {
		var title = plugin.flagTitle.format([currentSpace.name]);
		config.annotations[title] = plugin.flagWarning;
		if(currentSpace.type != "private") {
			return;
		}
		var tiddlers = [];
		var tid = store.getTiddler(title);
		if(tid) {
			curVersion = parseFloat(tid.fields[versionField]);
			reqVersion = parseFloat(plugin.version);
			if(curVersion < reqVersion) {
				plugin.update(curVersion, tid);
				tid.fields[versionField] = plugin.version;
				tid.incChangeCount();
				tid = store.saveTiddler(tid);
				tiddlers.push(tid);
			}
		} else { // first run
			tid = new Tiddler(title);
			tid.tags = ["excludeLists", "excludeSearch", "excludePublisher"];
			tid.fields = $.extend({}, config.defaultCustomFields);
			tid.fields[versionField] = plugin.version;
			tid.text = "@@%0@@".format([plugin.flagWarning]);
			tid = store.saveTiddler(tid);
			tiddlers = tiddlers.concat(plugin.firstRun(), tid);
		}
		autoSaveChanges(null, tiddlers);
	},
	update: function(curVersion, flagTiddler) {
		if(curVersion < 0.2) {
			this.createAvatar();
		}
		if(curVersion < 0.3) {
			flagTiddler.tags.pushUnique("excludePublisher"); // XXX: never persisted
		}
		if(curVersion < 0.5) { // v0.4 was faulty
			this.setupMarkupPreHead();
		}
		if(curVersion < 0.6) {
			this.purgeSystemSettings();
		}
	},
	pubTid: {
		tags: ["excludeLists", "excludeSearch"],
		fields: $.extend({}, config.defaultCustomFields, {
			"server.workspace": tiddlyspace.getCurrentWorkspace("public")
		})
	},
	makeTiddlerIfNot: function(tiddler) {
		if (!store.tiddlerExists(tiddler.title)) {
			$.extend(true, tiddler, plugin.pubTid);
			return [store.saveTiddler(tiddler)];
		} else {
			return [];
		}
	},
	firstRun: function() {
		var tiddlers = [];
		// generate Site*itle
		$.each(["SiteTitle", "SiteSubtitle"], function(i, item) {
			var tid = new Tiddler(item);
			tid.text = plugin[item].format([currentSpace.name]);
			tiddlers.push.apply(tiddlers,
				plugin.makeTiddlerIfNot(tid));
		});
		// generate public ColorPalette
		var tid = new Tiddler("ColorPalette");
		tid.text = config.macros.RandomColorPalette.generatePalette({
			saturation_pale: 0.67, saturation_light: 0.53,
			saturation_mid: 0.43, saturation_dark: 0.06,
			pale: 0.99, light: 0.85, mid: 0.5, dark: 0.31
		},
			false);
		tiddlers.push.apply(tiddlers, plugin.makeTiddlerIfNot(tid));
		this.createAvatar();
		this.setupMarkupPreHead();
		return tiddlers;
	},
	// remove _cookie slices (TiddlyWiki 2.6.2 beta 6 remnants)
	purgeSystemSettings: function() {
		var ss = store.getTiddler("SystemSettings");
		if(ss) {
			var lines = ss.text.split("\n");
			var persistentOptions = $.grep(lines, function(line, i) {
				return line.indexOf("_cookie:") == -1;
			});
			ss.text = persistentOptions.join("\n");
			ss = store.saveTiddler(ss);
			autoSaveChanges(null, [ss]);
		}
	},
	createAvatar: function() {
		var avatar = "SiteIcon";
		var host = tweb.host;
		var notify = function(xhr, error, exc) {
			displayMessage("ERROR: could not create avatar - " + // TODO: i18n
				"%0: %1".format([xhr.statusText, xhr.responseText]));
			// TODO: resolve!?
		};

		var pubBag = tiddlyspace.getCurrentBag("public");
		var tid = new tiddlyweb.Tiddler(avatar);
		tid.bag = new tiddlyweb.Bag(pubBag, host);

		var callback = function(data, status, xhr) {}; // avatar already exists; do nothing
		var errback = function(xhr, error, exc) {
			if(xhr.status != 404) {
				return;
			}
			// copy default avatar
			var _notify = function(tid, status, xhr) {
				displayMessage("created avatar"); // TODO: i18n
				var image = config.macros.image;
				if(image && image.refreshImage) {
					var uri = "/%0/tiddlers/SiteIcon".
						format(tiddlyspace.getCurrentWorkspace("public"));
					image.refreshImage(uri);
					image.refreshImage("SiteIcon");
				}
			};
			var _callback = function(tid, status, xhr) {
				tid.title = avatar;
				tid.bag.name = pubBag;
				delete tid.etag;
				tid.put(_notify, notify); // TODO: add to current session document (via adaptor?)
			};
			tweb.getUserInfo(function(user) {
				var avatarTitle = currentSpace.name == user.name ?
					"defaultUserIcon" : "defaultSiteIcon";
				var tid = new tiddlyweb.Tiddler(avatarTitle);
				tid.bag = new tiddlyweb.Bag("common", host);
				tid.get(_callback, notify);
			});
		};
		tid.get(callback, errback);
	},
	setupMarkupPreHead: function() {
		var pubWorkspace = tiddlyspace.getCurrentWorkspace("public");
		var existing = store.getTiddler("MarkupPreHead");
		if(!existing || existing.fields["server.workspace"] != pubWorkspace) {
			tweb.getStatus(function(status) {
				var tid = new Tiddler("MarkupPreHead");
				tid.text = markupPreHead.format(currentSpace.name, tiddlyspace.getHost(status.server_host,
					currentSpace.name));
				tid.tags = ["excludeLists"];
				tid.fields = $.extend({}, config.defaultCustomFields);
				tid.fields["server.workspace"] = pubWorkspace;
				tid.fields["server.page.revision"] = "false";
				tid = store.saveTiddler(tid);
				autoSaveChanges(null, [tid]);
			});
		}
	}
};

$(document).bind("startup", plugin.dispatch);

})(jQuery);
//}}}
|Date|Users|Spaces|Created|Modified|Tiddlertime|Searchtime|
|20120501|5108|7884|271|379|308.9|1520.9|
|20120502|5109|7886|149|244|310.2|17246.1|
|20120503|5118|7897|757|895|309.8|16748.4|
|20120504|5121|7901|122|228|470.6|16179|
|20120505|5124|7904|51|164|317|17729.9|
|20120506|5126|7906|608|693|313.4|2675.3|
|20120507|5127|7907|56|179|299.8|1772.7|
|20120508|5131|7921|489|584|308.6|16623.9|
|20120509|5137|7928|167|203|312.1|1745.5|
|20120510|5144|7941|259|315|316.9|22066.3|
|20120511|5150|7949|296|340|313|2041.6|
|20120512|5155|7955|151|197|318.4|16909.4|
|20120513|5159|7959|108|141|311.6|16700.6|
|20120514|5164|7969|542|717|322.3|16835.5|
|20120515|5169|7975|277|573|303.5|17525.6|
|20120516|5171|7982|584|656|317.2|1714.7|
|20120517|5178|7990|733|1056|310.2|2010.8|
|20120518|5180|7995|151|239|307.4|16817.1|
|20120519|5183|8001|175|227|309.5|16567.4|
|20120520|5187|8006|113|223|348.4|17946.1|
|20120521|5196|8016|289|383|417.3|18251.6|
|20120522|5201|8024|849|956|306.7|16699.5|
|20120523|5209|8033|1235|1397|318.2|17451|
|20120524|5217|8046|434|624|314.3|17816.8|
|20120525|5223|8056|279|438|396|18118.4|
|20120526|5227|8061|88|146|317.6|16946.2|
|20120527|5230|8065|923|967|311|17099.1|
|20120528|5240|8083|331|417|321.6|16283.4|
|20120529|5250|8099|234|304|308.1|17117.3|
|20120530|5257|8109|232|346|313.4|17976.7|
|20120531|5268|8125|297|401|312.3|16963.3|
|Date|Users|Spaces|Created|Modified|Tiddlertime|Searchtime|
|20120401|4890|7581|372|489|306.9|16411.3|
|20120402|4905|7599|441|581|324.3|17226.6|
|20120403|4912|7626|492|659|390.9|18970.8|
|20120404|4913|7628|132|254|319.5|2121.1|
|20120405|4921|7638|470|595|313.9|18034.1|
|20120406|4929|7650|478|583|321.8|17300|
|20120407|4933|7657|130|211|312.9|16919.3|
|20120408|4935|7659|187|242|318.9|16510.9|
|20120409|4941|7665|220|574|431|16589.9|
|20120410|4944|7669|130|270|308.6|16534.5|
|20120411|4953|7679|264|355|314.7|16114.2|
|20120412|4961|7691|533|677|319.1|16072.5|
|20120413|4964|7695|154|222|315.7|15855.5|
|20120414|4967|7698|356|418|321.1|1949.8|
|20120415|4971|7703|140|194|320.5|16837.2|
|20120416|4983|7715|344|495|316.7|18157.7|
|20120417|4994|7731|315|491|315.9|16157.8|
|20120418|5003|7743|155|266|307.5|17588.5|
|20120419|5008|7750|299|394|307|16133.7|
|20120420|5021|7768|311|833|316.5|18523|
|20120421|5024|7775|216|379|311|1924|
|20120422|5031|7783|655|736|308.2|18209.8|
|20120423|5045|7800|270|426|317.6|17872.5|
|20120424|5054|7812|177|303|316.7|188176|
|20120425|5063|7823|305|467|310.3|2168.3|
|20120426|5068|7834|195|310|308.7|16533|
|20120427|5080|7847|162|254|319.6|17686.9|
|20120428|5082|7850|80|115|761.2|1804.9|
|20120429|5085|7853|511|634|316.4|18143.7|
|20120430|5092|7865|332|501|311|2664|
|Date|Users|Spaces|Created|Modified|Tiddlertime|Searchtime|
|20120701|5454|8372|98|183|306.7|1805.08|
|20120702|5462|8381|443|571|314.6|1738.03|
|20120703|5462|8385|343|533|307.7|1960.01|
|20120704|5466|8390|1403|1664|312.9|233.66|
|20120705|5469|8394|221|347|315.8|216.66|
|20120706|5471|8398|481|615|313.8|2305.35|
|20120707|5475|8407|192|352|310.1|2229.52|
|20120708|5478|8414|232|347|312.7|2278.79|
|20120709|5486|8425|592|729|317|2163.08|
|20120710|5491|8431|373|681|302|2088.5|
|20120711|5492|8436|261|418|316.4|2265.15|
|20120712|5498|8447|328|480|318.3|2257.33|
|20120713|5502|8453|622|742|315.1|2101.33|
|20120714|5507|8459|159|263|302.5|2175.69|
|20120715|5510|8462|177|308|318.4|2214.82|
|20120716|5514|8466|615|728|314|169.84|
|20120717|5519|8476|460|612|306.6|2350.27|
|20120718|5524|8483|292|478|307.9|205.71|
|20120719|5528|8490|300|457|315.4|2424.23|
|20120720|5531|8501|340|447|308.7|2225.42|
|20120721|5532|8502|56|146|318.2|2182.74|
|20120722|5535|8506|105|208|902.2|2193.25|
|20120723|5541|8514|261|369|312.5|2287.9|
|20120724|5544|8520|707|923|312.4|2344.09|
|20120725|5544|8520|81|167|310.7|251.75|
|20120726|5549|8529|178|412|308.4|2483.86|
|20120727|5557|8541|211|295|316.3|7386.29|
|20120728|5561|8545|79|279|725.1|2368.8|
|20120729|5565|8553|115|389|310.3|2454.22|
|20120730|5570|8559|146|277|311|227.33|
|20120731|5572|8563|179|284|310.3|2178.66|
|20120801|5576|8573|222|326|315.6|190.56|
|Date|Users|Spaces|Created|Modified|Tiddlertime|Searchtime|
|20120601|5272|8130|163|273|590.1|168.86|
|20120602|5276|8135|90|168|316.5|1685.82|
|20120603|5281|8141|154|263|312.3|1819.95|
|20120604|5287|8154|253|519|318.1|1702.66|
|20120605|5289|8161|160|252|316.4|1880.38|
|20120606|5297|8171|241|314|310.7|1933.73|
|20120607|5308|8183|355|609|311.1|8711.58|
|20120608|5316|8193|1232|1439|308.5|1837.46|
|20120609|5321|8202|273|343|316.5|839.28|
|20120610|5323|8204|129|235|328.1|1704.39|
|20120611|5333|8217|273|391|311.4|1830.38|
|20120612|5337|8224|259|410|317.8|1886.09|
|20120613|5344|8233|1233|1349|313|1920.06|
|20120614|5351|8236|212|371|311|1947.6|
|20120615|5357|8243|178|241|320.8|1759.63|
|20120616|5359|8246|90|403|311.2|1773.95|
|20120617|5367|8255|189|269|531.1|1738.64|
|20120618|5371|8259|187|319|321|217.89|
|20120619|5380|8270|445|513|308|1750.61|
|20120620|5384|8275|309|494|318.2|1806.74|
|20120621|5396|8291|547|706|321.7|2025.37|
|20120622|5406|8305|1015|1114|321|13003.6|
|20120623|5409|8308|67|179|300.8|1782.84|
|20120624|5412|8313|113|206|317.4|1934.67|
|20120625|5416|8320|1100|1977|309.3|1763.91|
|20120626|5429|8337|324|454|525.8|2565.18|
|20120627|5434|8343|209|363|459.3|1786.76|
|20120628|5441|8354|326|442|327.6|1889.3|
|20120629|5451|8365|217|315|318.9|47302|
|20120630|5453|8370|102|181|311.7|1764.33|
/***
!Notes
This is an experimental tool to process a table and turn it into a line chart using @jquery-gchart 

It should be capable of dealing with multiple series. This would translate to a table with multiple columns.
!Code
***/
//{{{
(function($) {
    var colorIndex = ['red', 'green', 'blue', 'lime', 'navy', 'olive', 'orange', 'purple'];
    var macro = config.macros.charttable = {
        handler: function(place, macroName, params, wikifier, paramString) {
            var dataSource = params[0] || 'SomeInfo';
            var rawData = store.getTiddlerText(dataSource);
            var data = macro.parseData(rawData);
            macro.drawChart(place, data);
        },
        parseData: function(data) {
            // parse input make dict output
            var max = 0;
            var min = 9999999;
            var lines = data.split("\n");
            var struct = lines.shift();
            struct = struct.replace(/^\|\s*/, '').replace(/\s*\|\s*$/, '');
            var headers = struct.split(/\s*\|\s*/);
            headers.shift();
            var series = [];
            $.each(headers, function(index, header) {
                series.push({"label": header, data: [], color: colorIndex[index]});
                //series.push({"label": header, data: []});
            });
            var labels = [];
            $.each(lines, function(index, line) {
                line = line.replace(/^\|\s*/, '').replace(/\s*\|\s*$/, '');
                var chunks = line.split(/\s*\|\s*/);
                labels.push(chunks.shift());
                $.each(chunks, function(index, chunk) {
                    var ser = series[index];
                    chunk = parseInt(chunk);
                    max = max > chunk ? max : chunk;
                    min = min < chunk ? min : chunk;
                    ser.data.push(chunk);
                });
            });
            return {
                "max": max,
                "min": min, 
                "labels": labels,
                "series": series
            };
        },
        drawChart: function(place, data) {
            var container = $("<div />").appendTo(place);
            container.gchart({
                type: 'line',
                height: 250,
                maxValue: data.max,
                minValue: data.min,
                dataLabels: data.labels,
                series: $.each(data.series, function(index, item) {
                    //$.gchart.series(item.title, item.data, item.color);
                    $.gchart.series(item);
                }),
                axes: [$.gchart.axis('left', data.min, data.max),
                    $.gchart.axis('bottom', data.labels)],
                legend: 'right',
            });
        }
    };
})(jQuery);
//}}}
|Date|Users|Spaces|
|20101201|705|1697|
|20110101|837|1998|
|20110201|960|2247|
|20110301|1060|2422|
|20110401|1285|2786|
|20110501|1520|3151|
|20110601|1784|3525|
|20110701|2116|4061|
|20110801|2426|4498|
|20110901|2849|5038|
|20111001|3265|5526|
|20111101|3574|5897|
|20111201|3839|6237|
|20120101|4078|6553|
|20120201|4364|6907|
|20120301|4617|7210|
|20120401|4890|7581|
|20120501|5108|7884|
|20120601|5272|8130|
|20120701|5454|8372|
|20120801|5576|8573|
|20120901|5743|8809|
|20121001|5911|9039|
|20121101|6083|9237|
|20121201|6281|9496|
|20130101|6427|9668|
|20130201|6629|9961|
|20130301|6770|10166|
|20130401|6952|10421|
|20130501|7167|10686|
|Date|Users|Spaces|Created|Modified|Tiddlertime|Searchtime|
|20121001|5911|9039|190|315|307.1|248.93|
|20121002|5913|9041|161|291|333.9|209.64|
|20121003|5920|9051|270|384|311.6|2385.28|
|20121004|5924|9056|363|477|309.7|2455.63|
|20121005|5926|9058|487|751|309.1|7211.73|
|20121006|5929|9061|52|111|335.7|7007.01|
|20121007|5934|9066|99|211|311|2618.15|
|20121008|5937|9071|224|397|307.8|2477.51|
|20121009|5945|9079|279|397|62696.6|13758.9|
|20121010|5948|9083|154|255|316|7038.93|
|20121011|5953|9089|100|205|1236.2|2848.34|
|20121012|5956|9093|140|297|317.5|2659.44|
|20121013|5960|9097|75|185|314.3|2560.45|
|20121014|5964|9102|430|527|320.3|2447.75|
|20121015|5967|9107|132|207|315.5|2549.82|
|20121016|5974|9114|141|211|319.2|2482.96|
|20121017|5979|9121|140|230|486.9|457.98|
|20121018|5985|9131|335|493|305.2|183.04|
|20121019|5998|9146|277|405|313.6|2392.97|
|20121020|6004|9152|114|199|532.9|3675.41|
|20121021|6008|9156|116|201|903.3|311.74|
|20121022|6023|9171|588|665|310|2334.19|
|20121023|6029|9179|367|456|317|2415.2|
|20121024|6035|9185|153|247|310.6|158.41|
|20121025|6044|9195|236|352|316.1|2577.33|
|20121026|6051|9204|326|401|315.4|2421.04|
|20121027|6054|9207|96|237|5812.1|2498.55|
|20121028|6060|9213|328|422|308.8|234.36|
|20121029|6069|9222|381|632|309.4|2491.3|
|20121030|6073|9226|308|390|310.5|2492.28|
|20121031|6077|9230|144|274|332|2395.53|
/***
|''Name''|TiddlySpaceBackstage|
|''Version''|0.8.0|
|''Description''|Provides a TiddlySpace version of the backstage and a homeLink macro|
|''Status''|@@beta@@|
|''Contributors''|Jon Lister, Jon Robson, Colm Britton|
|''Source''|http://github.com/TiddlySpace/tiddlyspace/raw/master/src/plugins/TiddlySpaceBackstage.js|
|''Requires''|TiddlySpaceConfig ImageMacroPlugin TiddlySpaceViewTypes|
!StyleSheet
.tiddler .error.annotation .button{
	display: inline-block;
}

#backstageArea {
	z-index: 49;
	color: white;
	background-color: black;
	background: -webkit-gradient(linear,left bottom,left top,color-stop(0, #222),color-stop(0.5, #333),color-stop(1, #555));
	background: -moz-linear-gradient(center bottom,#222 0%, #333 50%, #555 100%);
	filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#ff555555, endColorstr=#ff222222);
	-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#ff555555, endColorstr=#ff222222)";
	height: 25px;
	padding: 0;
}

#backstageButton {
	overflow: hidden;
}

#backstageButton #backstageShow,
#backstageButton #backstageHide {
	margin: 0px;
	padding: 0px;
}

#backstageButton #backstageShow:hover,
#backstageButton #backstageHide:hover {
	background: none;
	color: none;
}

#backstageButton img,
#backstageButton svg {
	width: 24px;
	height: 24px;
}

#messageArea {
	top: 50px;
}

#backstageToolbar {
	position: relative;
}

#backstageArea a {
	padding: 0px;
	margin-left: 0px;
	color: white;
	background: none;
}

#backstageArea a:hover {
	background-color: white;
}

#backstage ol,
#backstage ul {
	padding: auto;
}

#backstageButton a {
	margin: 0;
}

.backstagePanelBody ul {
	padding: 5px;
	margin: 5px;
}

#backstage #backstagePanel {
	margin-left: 5%;
	padding: 0em;
	margin-right: 5%;
}

#backstageToolbar a {
	position: relative;
}

#backstageArea a.backstageSelTab,
#backstageToolbar .backstageTask {
	line-height: 25px;
	color: #767676;
}

.backstageTask .externalImage,
.backstageTask .image {
	display: inline;
}

#backstageToolbar a span {
	z-index: 2;
}

a.backstageTask {
	display: inline;
        margin-left: 1em !important;
}

.backstagePanelBody .button {
	display: inline-block;
	margin-right: 10px;
}

.backstagePanelBody {
	margin: 0 0 0 0.6em;
	padding: 0.4em 0.5em 1px 0.5em;
}

#backstage table {
	margin: auto;
}

#backstage .wizard table {
	border: 0px;
	margin: 0;
}

#backstage div  li.listLink {
	border: 0px;
	width: 78%;
	font-size: 0.7em;
}

#backstage div li.listTitle {
	font-weight: bold;
	text-decoration: underline;
	font-size: 1em;
	background: #ccc;
	width: 100%;
}

#backstage fieldset {
	border: solid 1px [[ColorPalette::Background]];
}

#backstage .viewer table,#backstage table.twtable {
	border: 0px;
}

#backstageToolbar img {
	padding: 0;
}

#backstage .wizard,
#backstage .wizardFooter {
	background: none;
}

.viewer td, .viewer tr, .twtable td, .twtable tr {
	border: 1px solid #eee;
}

#backstage .inlineList ul li {
	background-color: [[ColorPalette::Background]];
	border: solid 1px [[ColorPalette::TertiaryMid]];
	display: block;
	float: left;
	list-style: none;
	margin-right: 1em;
	padding: 0.5em;
}

.backstageClear, .inlineList form {
	clear: both;
	display: block;
	margin-top: 3em;
}

.tiddlyspaceMenu {
	text-align: center;
}

span.chunkyButton {
	display: inline-block;
	padding: 0;
	margin: 0;
	border: solid 2px #000;
	background-color: #04b;
}

span.chunkyButton a.button, span.chunkyButton a:active.button {
	white-space: nowrap;
	font-weight: bold;
	font-size: 1.8em;
	color: #fff;
	text-align: center;
	padding: 0.5em 0.5em;
	margin: 0;
	border-style: none;
	display: block;
}

span.chunkyButton:hover {
	background-color: #014;
}

span.chunkyButton a.button:hover {
	border-style: none;
	background: none;
	color: #fff;
}

#backstage .unpluggedSpaceTab .wizard,
.unpluggedSpaceTab .wizard {
	background: white;
	border: 2px solid #CCC;
	padding: 5px;
}

.syncKey .keyItem {
	border: 1px solid black;
	display: inline-block;
	margin: 0.2em;
	padding: 0.1em 0.1em 0.1em 0.1em;
}

.keyHeading {
	font-size: 2em;
	font-weight: bold;
	margin: 0.4em 0em -0.2em;
}

.unpluggedSpaceTab .putToServer,
.unpluggedSpaceTab .notChanged {
	display: none;
}

.tiddlyspaceMenu ul {
	margin: 0;
	padding: 0;
}

.tiddlyspaceMenu ul li {
	list-style: none;
}

.unsyncedChanges .unsyncedList {
	display: block;
}

.unsyncedList {
	display: none;
}
!Code
***/
//{{{
(function ($) {
    var name = "StyleSheet" + tiddler.title;
    config.shadowTiddlers[name] = "/*{{{*/\n%0\n/*}}}*/".
        format(store.getTiddlerText(tiddler.title + "##StyleSheet")); // this accesses the StyleSheet section of the current tiddler (the plugin that contains it)
    store.addNotification(name, refreshStyles);

    if (!config.extensions.tiddlyweb.status.tiddlyspace_version) { // unplugged
        config.extensions.tiddlyweb.status.tiddlyspace_version = "<unknown>";
        config.extensions.tiddlyweb.status.server_host = {
            url:config.extensions.tiddlyweb.host }; // TiddlySpaceLinkPlugin expects this
    }
    var disabled_tasks_for_nonmembers = ["tiddlers", "plugins", "batch", "sync"];

    var tweb = config.extensions.tiddlyweb;
    var tiddlyspace = config.extensions.tiddlyspace;
    var currentSpace = tiddlyspace.currentSpace.name;
    var imageMacro = config.macros.image;

    if (config.options.chkBackstage === undefined) {
        config.options.chkBackstage = false;
    }

// Set up Backstage
    config.tasks = {};
    config.tasks.status = {
        text:"status",
        tooltip:"TiddlySpace Info",
        content:"<<tiddler Backstage##Menu>>"
    };
    config.tasks.tiddlers = {
        text:"tiddlers",
        tooltip:"tiddlers control panel",
        content:"<<tiddler Backstage##BackstageTiddlers>>"
    };
    config.tasks.plugins = {
        text:"plugins",
        tooltip:"Manage installed plugins",
        content:"<<tiddler Backstage##Plugins>>"
    };
    config.tasks.batch = {
        text:"batch",
        tooltip:"Batch manage public/private tiddlers",
        content:"<<tiddler Backstage##BatchOps>>"
    };
    config.tasks.tweaks = {
        text:"tweaks",
        tooltip:"Tweak TiddlyWiki behaviors",
        content:"<<tiddler Backstage##Tweaks>>"
    };
    config.tasks.exportTiddlers = {
        text:"import/export",
        tooltip:"Import/export tiddlers from/to a TiddlyWiki",
        content:"<<tiddler Backstage##ImportExport>>"
    };
    config.tasks.sync = {
        text:"sync",
        tooltip:"Check Sync status",
        content:"<<tiddler Backstage##SpaceUnplugged>>"
    };

    if (window.location.protocol === "file:") {
        config.unplugged = true;
    }

    config.backstageTasks = ["status", "tiddlers", "plugins",
        "batch", "tweaks", "exportTiddlers", "sync"];

    config.messages.backstage.prompt = "";
// initialize state
    var _show = backstage.show;
    backstage.show = function () {
        // selectively hide backstage tasks and tabs based on user status
        var tasks = $("#backstageToolbar .backstageTask").show();
        var bs = backstage.tiddlyspace;
        if (!config.unplugged) {
            tweb.getUserInfo(function (user) {
                if (user.anon) {
                    jQuery.each(disabled_tasks_for_nonmembers, function (i, task) {
                        var taskIndex = config.backstageTasks.indexOf(task);
                        if (taskIndex !== -1) {
                            config.backstageTasks.splice(taskIndex, 1);
                        }
                    });
                    config.messages.memberStatus = bs.locale.loggedout;
                } else {
                    config.messages.memberStatus = readOnly ?
                        bs.locale.nonmember : bs.locale.member;
                }
            });
        } else {
            config.messages.memberStatus = bs.locale.unplugged;
        }

        // display backstage
        return _show.apply(this, arguments);
    };
    if (readOnly) {
        jQuery.each(disabled_tasks_for_nonmembers, function (i, task) {
            var taskIndex = config.backstageTasks.indexOf(task);
            if (taskIndex !== -1) {
                config.backstageTasks.splice(taskIndex, 1);
            }
        });
    }

    var tasks = config.tasks;
    var commonUrl = "/bags/common/tiddlers/%0";

    backstage.tiddlyspace = {
        locale:{
            member:"You are a member of this space.",
            nonmember:"You are not a member of this space.",
            loggedout:"You are currently logged out of TiddlySpace.",
            unplugged:"You are unplugged."
        },
        showButton:function () {
            var showBtn = $("#backstageShow")[0];
            var altText = $(showBtn).text();
            $(showBtn).empty();
            imageMacro.renderImage(showBtn, "backstage.svg",
                { altImage:commonUrl.format("backstage.png"), alt:altText});
        },
        hideButton:function () {
            var hideBtn = $("#backstageHide")[0];
            var altText = $(hideBtn).text();
            $(hideBtn).empty();
            imageMacro.renderImage(hideBtn, "close.svg",
                { altImage:commonUrl.format("close.png"), alt:altText, width:24, height:24 });
        }
    };

    var _init = backstage.init;
    backstage.init = function () {
        _init.apply(this, arguments);
        var init = function (user) {
            var bs = backstage.tiddlyspace;
            bs.showButton();
            bs.hideButton();
        };
        tweb.getUserInfo(init);
    };

    var home = config.macros.homeLink = {
        locale:{
            linkText:"your home space"
        },
        handler:function (place) {
            var container = $("<span />").appendTo(place)[0];
            tweb.getUserInfo(function (user) {
                if (!user.anon && user.name !== currentSpace) {
                    createSpaceLink(container, user.name, null, home.locale.linkText);
                }
            });
        }
    };

    config.macros.exportSpace = {
        handler:function (place, macroName, params) {
            var filename = params[0] ||
                "/tiddlers.wiki?download=%0.html".format(currentSpace);
            $('<a class="button">download</a>').// XXX: i18n
                attr("href", filename).appendTo(place);
        }
    };

}(jQuery));
//}}}
|Date|Users|Spaces|
|20110701|2116|4061|
|20110702|2127|4078|
|20110703|2134|4093|
|20110704|2138|4100|
|20110705|2154|4119|
|20110706|2166|4136|
|20110707|2171|4147|
|20110708|2184|4169|
|20110709|2193|4182|
|20110710|2199|4194|
|20110711|2206|4204|
|20110712|2218|4221|
|20110713|2233|4245|
|20110714|2245|4263|
|20110715|2261|4286|
|20110716|2271|4304|
|20110717|2277|4313|
|20110718|2281|4317|
|20110719|2296|4341|
|20110720|2310|4357|
|20110721|2314|4368|
|20110722|2324|4381|
|20110723|2334|4395|
|20110724|2341|4404|
|20110725|2347|4410|
|20110726|2358|4423|
|20110727|2367|4434|
|20110728|2378|4443|
|20110729|2393|4459|
|20110730|2401|4470|
|20110731|2416|4486|
/***
|''Name''|ServerSideSavingPlugin|
|''Description''|server-side saving|
|''Author''|FND|
|''Version''|0.6.5|
|''Status''|stable|
|''Source''|http://svn.tiddlywiki.org/Trunk/association/plugins/ServerSideSavingPlugin.js|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''CoreVersion''|2.5.3|
|''Keywords''|serverSide|
!Notes
This plugin relies on a dedicated adaptor to be present.
The specific nature of this plugin depends on the respective server.
!Revision History
!!v0.1 (2008-11-24)
* initial release
!!v0.2 (2008-12-01)
* added support for local saving
!!v0.3 (2008-12-03)
* added Save to Web macro for manual synchronization
!!v0.4 (2009-01-15)
* removed ServerConfig dependency by detecting server type from the respective tiddlers
!!v0.5 (2009-08-25)
* raised CoreVersion to 2.5.3 to take advantage of core fixes
!!v0.6 (2010-04-21)
* added notification about cross-domain restrictions to ImportTiddlers
!To Do
* conflict detection/resolution
* rename to ServerLinkPlugin?
* document deletion/renaming convention
!Code
***/
//{{{
(function($) {

readOnly = false; //# enable editing over HTTP

var plugin = config.extensions.ServerSideSavingPlugin = {};

plugin.locale = {
	saved: "%0 saved successfully",
	saveError: "Error saving %0: %1",
	saveConflict: "Error saving %0: edit conflict",
	deleted: "Removed %0",
	deleteError: "Error removing %0: %1",
	deleteLocalError: "Error removing %0 locally",
	removedNotice: "This tiddler has been deleted.",
	connectionError: "connection could not be established",
	hostError: "Unable to import from this location due to cross-domain restrictions."
};

plugin.sync = function(tiddlers) {
	tiddlers = tiddlers && tiddlers[0] ? tiddlers : store.getTiddlers();
	$.each(tiddlers, function(i, tiddler) {
		var changecount = parseInt(tiddler.fields.changecount, 10);
		if(tiddler.fields.deleted === "true" && changecount === 1) {
			plugin.removeTiddler(tiddler);
		} else if(tiddler.isTouched() && !tiddler.doNotSave() &&
				tiddler.getServerType() && tiddler.fields["server.host"]) { // XXX: server.host could be empty string
			delete tiddler.fields.deleted;
			plugin.saveTiddler(tiddler);
		}
	});
};

plugin.saveTiddler = function(tiddler) {
	try {
		var adaptor = this.getTiddlerServerAdaptor(tiddler);
	} catch(ex) {
		return false;
	}
	var context = {
		tiddler: tiddler,
		changecount: tiddler.fields.changecount,
		workspace: tiddler.fields["server.workspace"]
	};
	var serverTitle = tiddler.fields["server.title"]; // indicates renames
	if(!serverTitle) {
		tiddler.fields["server.title"] = tiddler.title;
	} else if(tiddler.title != serverTitle) {
		return adaptor.moveTiddler({ title: serverTitle },
			{ title: tiddler.title }, context, null, this.saveTiddlerCallback);
	}
	var req = adaptor.putTiddler(tiddler, context, {}, this.saveTiddlerCallback);
	return req ? tiddler : false;
};

plugin.saveTiddlerCallback = function(context, userParams) {
	var tiddler = context.tiddler;
	if(context.status) {
		if(tiddler.fields.changecount == context.changecount) { //# check for changes since save was triggered
			tiddler.clearChangeCount();
		} else if(tiddler.fields.changecount > 0) {
			tiddler.fields.changecount -= context.changecount;
		}
		plugin.reportSuccess("saved", tiddler);
		store.setDirty(false);
	} else {
		if(context.httpStatus == 412) {
			plugin.reportFailure("saveConflict", tiddler);
		} else {
			plugin.reportFailure("saveError", tiddler, context);
		}
	}
};

plugin.removeTiddler = function(tiddler) {
	try {
		var adaptor = this.getTiddlerServerAdaptor(tiddler);
	} catch(ex) {
		return false;
	}
	var context = {
		host: tiddler.fields["server.host"],
		workspace: tiddler.fields["server.workspace"],
		tiddler: tiddler
	};
	var req = adaptor.deleteTiddler(tiddler, context, {}, this.removeTiddlerCallback);
	return req ? tiddler : false;
};

plugin.removeTiddlerCallback = function(context, userParams) {
	var tiddler = context.tiddler;
	if(context.status) {
		if(tiddler.fields.deleted === "true") {
			store.deleteTiddler(tiddler.title);
		} else {
			plugin.reportFailure("deleteLocalError", tiddler);
		}
		plugin.reportSuccess("deleted", tiddler);
		store.setDirty(false);
	} else {
		plugin.reportFailure("deleteError", tiddler, context);
	}
};

plugin.getTiddlerServerAdaptor = function(tiddler) { // XXX: rename?
	var type = tiddler.fields["server.type"] || config.defaultCustomFields["server.type"];
	return new config.adaptors[type]();
};

plugin.reportSuccess = function(msg, tiddler) {
	displayMessage(plugin.locale[msg].format([tiddler.title]));
};

plugin.reportFailure = function(msg, tiddler, context) {
	var desc = (context && context.httpStatus) ? context.statusText :
		plugin.locale.connectionError;
	displayMessage(plugin.locale[msg].format([tiddler.title, desc]));
};

config.macros.saveToWeb = { // XXX: hijack existing sync macro?
	locale: { // TODO: merge with plugin.locale?
		btnLabel: "save to web",
		btnTooltip: "synchronize changes",
		btnAccessKey: null
	},

	handler: function(place, macroName, params, wikifier, paramString, tiddler) {
		createTiddlyButton(place, this.locale.btnLabel, this.locale.btnTooltip,
			plugin.sync, null, null, this.locale.btnAccessKey);
	}
};

// hijack saveChanges to trigger remote saving
var _saveChanges = saveChanges;
saveChanges = function(onlyIfDirty, tiddlers) {
	if(window.location.protocol == "file:") {
		_saveChanges.apply(this, arguments);
	} else {
		plugin.sync(tiddlers);
	}
};

// override removeTiddler to flag tiddler as deleted -- XXX: use hijack to preserve compatibility?
TiddlyWiki.prototype.removeTiddler = function(title) { // XXX: should override deleteTiddler instance method?
	var tiddler = this.fetchTiddler(title);
	if(tiddler) {
		tiddler.tags = ["excludeLists", "excludeSearch", "excludeMissing"];
		tiddler.text = plugin.locale.removedNotice;
		tiddler.fields.deleted = "true"; // XXX: rename to removed/tiddlerRemoved?
		tiddler.fields.changecount = "1";
		this.notify(title, true);
		this.setDirty(true);
	}
};

// hijack ImportTiddlers wizard to handle cross-domain restrictions
var _onOpen = config.macros.importTiddlers.onOpen;
config.macros.importTiddlers.onOpen = function(ev) {
	var btn = $(resolveTarget(ev));
	var url = btn.closest(".wizard").find("input[name=txtPath]").val();
	if(window.location.protocol != "file:" && url.indexOf("://") != -1) {
		var host = url.split("/")[2];
		var macro = config.macros.importTiddlers;
		if(host != window.location.host) {
			btn.text(macro.cancelLabel).attr("title", macro.cancelPrompt);
			btn[0].onclick = macro.onCancel;
			$('<span class="status" />').text(plugin.locale.hostError).insertAfter(btn);
			return false;
		}
	}
	return _onOpen.apply(this, arguments);
};

})(jQuery);
//}}}
/***
|''Name''|RevisionsCommandPlugin|
|''Description''|provides access to tiddler revisions|
|''Author''|FND|
|''Contributors''|Martin Budden|
|''Version''|0.3.3|
|''Status''|@@beta@@|
|''Source''|http://svn.tiddlywiki.org/Trunk/association/plugins/RevisionsCommandPlugin.js|
|''CodeRepository''|http://svn.tiddlywiki.org/Trunk/association/plugins/|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''CoreVersion''|2.6.0|
|''Keywords''|serverSide|
!Usage
Extend [[ToolbarCommands]] with {{{revisions}}}.
!Revision History
!!v0.1 (2009-07-23)
* initial release (renamed from experimental ServerCommandsPlugin)
!!v0.2 (2010-03-04)
* suppressed wikification in diff view
!!v0.3 (2010-04-07)
* restored wikification in diff view
* added link to side-by-side diff view
!To Do
* strip server.* fields from revision tiddlers
* resolve naming conflicts
* i18n, l10n
* code sanitizing
* documentation
!Code
***/
//{{{
(function($) {

jQuery.twStylesheet(".diff { white-space: pre, font-family: monospace }",
	{ id: "diff" });

var cmd = config.commands.revisions = {
	type: "popup",
	hideShadow: true,
	text: "revisions",
	tooltip: "display tiddler revisions",
	revTooltip: "", // TODO: populate dynamically?
	loadLabel: "loading...",
	loadTooltip: "loading revision list",
	selectLabel: "select",
	selectTooltip: "select revision for comparison",
	selectedLabel: "selected",
	compareLabel: "compare",
	linkLabel: "side-by-side view",
	revSuffix: " [rev. #%0]",
	diffSuffix: " [diff: #%0 #%1]",
	dateFormat: "YYYY-0MM-0DD 0hh:0mm",
	listError: "revisions could not be retrieved",

	handlePopup: function(popup, title) {
		title = this.stripSuffix("rev", title);
		title = this.stripSuffix("diff", title);
		var tiddler = store.getTiddler(title);
		var type = _getField("server.type", tiddler);
		var adaptor = new config.adaptors[type]();
		var limit = null; // TODO: customizable
		var context = {
			host: _getField("server.host", tiddler),
			workspace: _getField("server.workspace", tiddler)
		};
		var loading = createTiddlyButton(popup, cmd.loadLabel, cmd.loadTooltip);
		var params = { popup: popup, loading: loading, origin: title };
		adaptor.getTiddlerRevisionList(title, limit, context, params, this.displayRevisions);
	},

	displayRevisions: function(context, userParams) {
		removeNode(userParams.loading);
		if(context.status) {
			var callback = function(ev) {
				var e = ev || window.event;
				var revision = resolveTarget(e).getAttribute("revision");
				context.adaptor.getTiddlerRevision(tiddler.title, revision, context,
					userParams, cmd.displayTiddlerRevision);
			};
			var table = createTiddlyElement(userParams.popup, "table");
			for(var i = 0; i < context.revisions.length; i++) {
				var tiddler = context.revisions[i];
				var row = createTiddlyElement(table, "tr");
				var timestamp = tiddler.modified.formatString(cmd.dateFormat);
				var revision = tiddler.fields["server.page.revision"];
				var cell = createTiddlyElement(row, "td");
				createTiddlyButton(cell, timestamp, cmd.revTooltip, callback, null,
					null, null, { revision: revision });
				cell = createTiddlyElement(row, "td", null, null, tiddler.modifier);
				cell = createTiddlyElement(row, "td");
				createTiddlyButton(cell, cmd.selectLabel, cmd.selectTooltip,
					cmd.revisionSelected, null, null, null,
					{ index:i, revision: revision, col: 2 });
				cmd.context = context; // XXX: unsafe (singleton)!?
			}
		} else {
			$("<li />").text(cmd.listError).appendTo(userParams.popup);
		}
	},

	revisionSelected: function(ev) {
		var e = ev || window.event;
		e.cancelBubble = true;
		if(e.stopPropagation) {
			e.stopPropagation();
		}
		var n = resolveTarget(e);
		var index = n.getAttribute("index");
		var col = n.getAttribute("col");
		while(!index || !col) {
			n = n.parentNode;
			index = n.getAttribute("index");
			col = n.getAttribute("col");
		}
		cmd.revision = n.getAttribute("revision");
		var table = n.parentNode.parentNode.parentNode;
		var rows = table.childNodes;
		for(var i = 0; i < rows.length; i++) {
			var c = rows[i].childNodes[col].firstChild;
			if(i == index) {
				if(c.textContent) {
					c.textContent = cmd.selectedLabel;
				} else {
					c.text = cmd.selectedLabel;
				}
			} else {
				if(c.textContent) {
					c.textContent = cmd.compareLabel;
				} else {
					c.text = cmd.compareLabel;
				}
				c.onclick = cmd.compareSelected;
			}
		}
	},

	compareSelected: function(ev) {
		var e = ev || window.event;
		var n = resolveTarget(e);
		var context = cmd.context;
		context.rev1 = n.getAttribute("revision");
		context.rev2 = cmd.revision;
		context.tiddler = context.revisions[n.getAttribute("index")];
		context.format = "unified";
		context.adaptor.getTiddlerDiff(context.tiddler.title, context,
			context.userParams, cmd.displayTiddlerDiffs);
	},

	displayTiddlerDiffs: function(context, userParams) {
		var tiddler = context.tiddler;
		tiddler.title += cmd.diffSuffix.format([context.rev1, context.rev2]);
		tiddler.text = "{{diff{\n" + context.diff + "\n}}}";
		tiddler.tags = ["diff"];
		tiddler.fields.doNotSave = "true"; // XXX: correct?
		if(!store.getTiddler(tiddler.title)) {
			store.addTiddler(tiddler);
		}
		var src = story.getTiddler(userParams.origin);
		var tiddlerEl = story.displayTiddler(src, tiddler);
		var uri = context.uri.replace("format=unified", "format=horizontal");
		var link = $('<a target="_blank" />').attr("href", uri).text(cmd.linkLabel);
		$(".viewer", tiddlerEl).prepend(link);
	},

	displayTiddlerRevision: function(context, userParams) {
		var tiddler = context.tiddler;
		tiddler.title += cmd.revSuffix.format([tiddler.fields["server.page.revision"]]);
		tiddler.fields.doNotSave = "true"; // XXX: correct?
		if(!store.getTiddler(tiddler.title)) {
			store.addTiddler(tiddler);
		}
		var src = story.getTiddler(userParams.origin);
		story.displayTiddler(src, tiddler);
	},

	stripSuffix: function(type, title) {
		var str = cmd[type + "Suffix"];
		var i = str.indexOf("%0");
		i = title.indexOf(str.substr(0, i));
		if(i != -1) {
			title = title.substr(0, i);
		}
		return title;
	}
};

var _getField = function(name, tiddler) {
	return tiddler.fields[name] || config.defaultCustomFields[name];
};

})(jQuery);
//}}}
/***
|''Name''|TiddlySpaceFilters|
|''Description''|provide TiddlySpace-specific filter extensions|
|''Author''|Jon Robson|
|''Version''|0.6.1|
|''Status''|@@beta@@|
|''CoreVersion''|2.6.2|
|''Requires''|TiddlySpaceConfig|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
!Usage
{{{
<<tsList Private>>
<<tsList Public>>
<<tsList Draft>>
}}}
!Code
***/
//{{{
(function($) {

var tiddlyspace = config.extensions.tiddlyspace;
var privateBag = tiddlyspace.getCurrentBag("private");
var publicBag = tiddlyspace.getCurrentBag("public");

config.filterHelpers = {
	is: {
		"private": function(tiddler) {
			var bag = tiddler.fields["server.bag"];
			return bag == privateBag;
		},
		"public": function(tiddler) {
			var bag = tiddler.fields["server.bag"];
			return bag == publicBag;
		},
		draft: function(tiddler) {
			var fields = tiddler.fields;
			var bag = fields["server.bag"];
			return (privateBag == bag && fields["publish.name"]) ? true : false;
		},
		local: function(tiddler) {
			return config.filterHelpers.is["public"](tiddler) ||
				config.filterHelpers.is["private"](tiddler);
		},
		unsynced: function(tiddler) {
			return tiddler ? tiddler.isTouched() : false;
		}
	}
};

config.filters.is = function(results, match) {
	var candidates = store.getTiddlers("title");
	var type = match[3];
	for (var i = 0; i < candidates.length; i++) {
		var tiddler = candidates[i];
		var helper = config.filterHelpers.is[type];
		if(helper && helper(tiddler)) {
			results.pushUnique(tiddler);
		}
	}
	return results;
};

})(jQuery);
//}}}
/***
|''Name''|DiffFormatter|
|''Description''|highlighting of text comparisons|
|''Author''|FND|
|''Version''|0.9.0|
|''Status''|beta|
|''Source''|http://svn.tiddlywiki.org/Trunk/contributors/FND/formatters/DiffFormatter.js|
|''CodeRepository''|http://svn.tiddlywiki.org/Trunk/contributors/FND/|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''Keywords''|formatting|
!Description
Highlights changes in a unified [[diff|http://en.wikipedia.org/wiki/Diff#Unified_format]].
!Notes
Based on Martin Budden's [[DiffFormatterPlugin|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/formatters/DiffFormatterPlugin.js]].
!Usage
The formatter is applied to blocks wrapped in <html><code>{{{diff{..}}}</code></html> within tiddlers tagged with "diff".
!Revision History
!!v0.9 (2010-04-07)
* initial release; fork of DiffFormatterPlugin
!StyleSheet
.diff { white-space: pre; font-family: monospace; }
.diff ins, .diff del { display: block; text-decoration: none; }
.diff ins { background-color: #dfd; }
.diff del { background-color: #fdd; }
.diff .highlight { background-color: [[ColorPalette::SecondaryPale]]; }
!Code
***/
//{{{
(function() {

config.shadowTiddlers.StyleSheetDiffFormatter = store.getTiddlerText(tiddler.title + "##StyleSheet");
store.addNotification("StyleSheetDiffFormatter", refreshStyles);

var formatters = [{
		name: "diffWrapper",
		match: "^\\{\\{diff\\{\n", // XXX: suboptimal
		termRegExp: /(.*\}\}\})$/mg,
		handler: function(w) {
			var el = createTiddlyElement(w.output, "div", null, "diff");
			w.subWikifyTerm(el, this.termRegExp);
		}
	}, {
		name: "diffRange",
		match: "^(?:@@|[+\\-]{3}) ",
		lookaheadRegExp: /^(?:@@|[+\-]{3}) .*\n/mg,
		handler: function(w) {
			createTiddlyElement(w.output, "div", null, "highlight").
				innerHTML = "&#8230;";
			this.lookaheadRegExp.lastIndex = w.matchStart;
			var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
			if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
				w.nextMatch = this.lookaheadRegExp.lastIndex;
			}
		}
	}, {
		name: "diffAdded",
		match: "^\\+",
		termRegExp: /(\n)/mg,
		handler: function(w) {
			var el = createTiddlyElement(w.output, "ins", null, "added");
			w.subWikifyTerm(el, this.termRegExp);
		}
	}, {
		name: "diffRemoved",
		match: "^-",
		termRegExp: /(\n)/mg,
		handler: function(w) {
			var el = createTiddlyElement(w.output, "del", null, "removed");
			w.subWikifyTerm(el, this.termRegExp);
		}
	}
];

config.parsers.diffFormatter = new Formatter(formatters);
config.parsers.diffFormatter.format = "diff";
config.parsers.diffFormatter.formatTag = "diff";

})();
//}}}
|Date|Users|Spaces|Created|Modified|Tiddlertime|Searchtime|
|20120901|5743|8809|102|156|318|2393.03|
|20120902|5746|8812|182|268|313.9|6417.05|
|20120903|5750|8817|109|235|314.4|213.67|
|20120904|5758|8827|198|301|430.2|2292.89|
|20120905|5764|8835|2230|2344|310|2227.5|
|20120906|5770|8849|310|460|416.3|2430.16|
|20120907|5774|8857|1119|1305|5847.3|2725.81|
|20120908|5788|8872|275|447|567.8|253.52|
|20120909|5790|8876|474|597|317.7|7292.54|
|20120910|5796|8882|1305|1452|307.6|2538|
|20120911|5805|8891|385|1079|325.3|2438.68|
|20120912|5812|8901|317|428|313.3|2367.22|
|20120913|5821|8912|403|586|310.5|2602.61|
|20120914|5829|8923|854|985|321.2|2588.82|
|20120915|5834|8932|381|492|332.3|2605.49|
|20120916|5840|8941|833|1038|304.8|2535.58|
|20120917|5846|8954|1517|1675|329.4|7156.97|
|20120918|5857|8967|553|751|305.5|2592.87|
|20120919|5863|8973|311|424|316.4|2288.38|
|20120920|5869|8980|522|694|316|247.31|
|20120921|5875|8989|398|558|311.7|2462.69|
|20120922|5876|8991|111|194|476.4|2461.37|
|20120923|5879|8994|51|160|311.4|2386.35|
|20120924|5884|9001|233|334|311.4|6757.89|
|20120925|5888|9007|190|315|322.2|2472.67|
|20120926|5899|9020|2297|2500|311.5|2375.99|
|20120927|5902|9023|104|231|319.9|1409.05|
|20120928|5902|9025|429|531|311.7|184.37|
|20120929|5904|9029|233|327|306.4|2432.9|
|20120930|5910|9036|252|347|315.4|2584.39|
|Date|Users|Spaces|
|20120501|5108|7884|
|20120601|5272|8130|
|20120701|5454|8372|
|20120801|5576|8573|
|20120901|5743|8809|
|20121001|5911|9039|
|20121101|6083|9237|
|20121201|6281|9496|
|20130101|6427|9668|
|20130201|6629|9961|
|20130301|6770|10166|
|20130401|6952|10421|
|20130501|7167|10686|
/***
|''Name''|TiddlySpaceCloneCommand|
|''Version''|0.5.8|
|''Description''|provides a toolbar command for cloning external tiddlers|
|''Status''|stable|
|''Source''|http://github.com/TiddlySpace/tiddlyspace/raw/master/src/plugins/TiddlySpaceCloneCommand.js|
|''Requires''|TiddlySpaceConfig TiddlySpaceFilters|
!Code
***/
//{{{
(function($) {

var cmd = config.commands;
var tiddlyspace = config.extensions.tiddlyspace;

var fieldsCache = {};

cmd.cloneTiddler = {
	text: cmd.editTiddler.text,
	tooltip: "Create a copy of this tiddler in the current space",
	errorMsg: "Error publishing %0: %1",

	isEnabled: function(tiddler) {
		return !config.filterHelpers.is.local(tiddler) && !readOnly;
	},
	handler: function(ev, src, title) {
		var tiddler = store.getTiddler(title);
		if(tiddler) {
			fieldsCache[title] = $.extend({}, tiddler.fields);
			tiddler.fields["server.workspace"] = tiddlyspace.getCurrentWorkspace(config.options.chkPrivateMode ?
		"private" : "public");
			tiddler.fields["server.permissions"] = "read, write, create"; // no delete
			delete tiddler.fields["server.page.revision"];
			delete tiddler.fields["server.title"];
			delete tiddler.fields["server.etag"];
			// special handling for pseudo-shadow tiddlers
			if(tiddlyspace.coreBags.contains(tiddler.fields["server.bag"])) {
				tiddler.tags.remove("excludeLists");
			}
		} else { // ensure workspace is the current space
			var el = story.findContainingTiddler(src);
			el = $(el);
			var fields = el.attr("tiddlyfields");
			if(fields) { // inherited via TiddlyLink
				fields = fields.decodeHashMap();
				fields["server.workspace"] = config.
					defaultCustomFields["server.workspace"];
			} else {
				fields = config.defaultCustomFields;
			}
			fields = String.encodeHashMap(fields);
			el.attr("tiddlyfields", fields);
		}
		cmd.editTiddler.handler.apply(this, arguments);
		if(tiddler) {
			tiddler.fields["server.permissions"] += ", delete";
		}
		return false;
	}
};

cmd.editTiddler.isEnabled = function(tiddler) {
	return !cmd.cloneTiddler.isEnabled.apply(this, arguments);
};

// hijack cancelTiddler to restore original fields
var _cancelHandler = cmd.cancelTiddler.handler;
cmd.cancelTiddler.handler = function(ev, src, title) {
	var tiddler = store.getTiddler(title);
	if(tiddler) {
		tiddler.fields = fieldsCache[title] || tiddler.fields;
		delete fieldsCache[title];
	}
	return _cancelHandler.apply(this, arguments);
};

// hijack saveTiddler to clear unused fields stash
var _saveHandler = cmd.saveTiddler.handler;
cmd.saveTiddler.handler =  function(ev, src, title) {
	delete fieldsCache[title];
	return _saveHandler.apply(this, arguments);
};

})(jQuery);
//}}}
|Date|Users|Spaces|Created|Modified|
|20130501|7167|10686|155|306|
|20130502|7174|10694|222|454|
|20130503|7186|10707|214|309|
|20130504|7189|10712|130|239|
|20130505|7189|10715|135|219|
|20130506|7198|10725|242|312|
|20130507|7212|10741|205|324|
|20130508|7223|10756|338|438|
|20130509|7234|10768|367|460|
|20130510|7237|10772|266|380|
|20130511|7241|10776|234|287|
|20130512|7246|10783|132|218|
|20130513|7257|10795|324|425|
|20130514|7263|10802|175|297|
|20130515|7280|10822|442|556|
|20130516|7288|10833|383|502|
|20130517|7291|10836|293|390|
|20130518|7293|10838|54|114|
|20130519|7294|10839|77|126|
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
|Date|Users|Spaces|Created|Modified|Tiddlertime|Searchtime|
|20130201|6629|9961|1168|1272|329.7|2774.65|
|20130202|6634|9967|131|275|7234.9|228.61|
|20130203|6639|9972|675|940|320.5|211.84|
|20130204|6645|9982|1081|1280|320.7|2791.75|
|20130205|6653|9990|390|569|321.6|9811.29|
|20130206|6657|9998|602|781|331.1|2863.51|
|20130207|6661|10005|274|529|320|266.4|
|20130208|6669|10015|234|440|322.9|2825.73|
|20130209|6673|10019|175|341|324.7|3021.32|
|20130210|6676|10022|114|246|321.3|271.56|
|20130211|6679|10028|479|663|321.4|2997.02|
|20130212|6686|10036|412|637|1674.8|2928.76|
|20130213|6689|10040|242|610|722|2852.87|
|20130214|6712|10065|779|966|319.7|2863.81|
|20130215|6716|10070|305|581|327.9|2956.03|
|20130216|6720|10075|277|403|319.8|5623.27|
|20130217|6726|10081|258|372|321.2|7791.85|
|20130218|6728|10087|695|782|324.7|2833|
|20130219|6732|10096|398|531|330|3016.27|
|20130220|6739|10106|605|720|327.9|8945.25|
|20130221|6742|10111|2380|2569|326.5|2930.32|
|20130222|6745|10114|358|500|330.9|228.52|
|20130223|6751|10124|418|487|321.7|7251.04|
|20130224|6754|10130|284|455|325.1|3075.38|
|20130225|6756|10133|274|401|322.2|2825.72|
|20130226|6760|10147|444|595|645.1|2969.98|
|20130227|6763|10153|342|490|318.4|2971.1|
|20130228|6767|10160|302|419|318.9|3944.18|
/***
|''Name''|BinaryTiddlersPlugin|
|''Description''|renders base64-encoded binary tiddlers as images or links|
|''Author''|FND|
|''Version''|0.3.2|
|''Status''|@@beta@@|
|''Source''|http://svn.tiddlywiki.org/Trunk/association/plugins/BinaryTiddlersPlugin.js|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''CoreVersion''|2.5|
!Code
***/
//{{{
(function($) {

var ctfield = "server.content-type";

var plugin = config.extensions.BinaryTiddlersPlugin = {
	isWikiText: function(tiddler) {
		var ctype = tiddler.fields[ctfield];
		if(ctype) {
			if (ctype == 'text/x-tiddlywiki') return true;
			return !this.isBinary(tiddler) && !this.isTextual(ctype);
		} else {
			return true;
		}
	},
	// NB: pseudo-binaries are considered non-binary here
	isBinary: function(tiddler) {
		var ctype = tiddler.fields[ctfield];
		return ctype ? !this.isTextual(ctype) : false;
	},
	isTextual: function(ctype) {
		return ctype.indexOf("text/") == 0
			|| this.endsWith(ctype, "+xml")
			|| ctype == 'application/json'
			|| ctype == 'application/javascript';
	},
	endsWith: function(str, suffix) {
		return str.length >= suffix.length &&
			str.substr(str.length - suffix.length) == suffix;
	},
        isLink: function(tiddler) {
            return this.isBinary(tiddler) && tiddler.text.indexOf("<html>") != -1
        }
};

// Disable edit for linked tiddlers (for now)
// This will be changed to a GET then PUT
config.commands.editTiddler.isEnabled = function(tiddler) {
    var existingTest = config.commands.editTiddler.isEnabled;
    if (existingTest) {
        return existingTest && !plugin.isLink(tiddler);
    } else {
        return !plugin.isLink(tiddler);
    }
};

// hijack text viewer to add special handling for binary tiddlers
var _view = config.macros.view.views.wikified;
config.macros.view.views.wikified = function(value, place, params, wikifier,
		paramString, tiddler) {
	var ctype = tiddler.fields["server.content-type"];
	if(params[0] == "text" && ctype && ctype !== 'text/x-tiddlywiki' && !tiddler.tags.contains("systemConfig") && !plugin.isLink(tiddler)) {
		var el;
		if(plugin.isBinary(tiddler)) {
			var uri = "data:%0;base64,%1".format([ctype, tiddler.text]); // TODO: fallback for legacy browsers
			if(ctype.indexOf("image/") == 0) {
				el = $("<img />").attr("alt", tiddler.title).attr("src", uri);
			} else {
				el = $("<a />").attr("href", uri).text(tiddler.title);
			}
		} else {
			el = $("<pre />").text(tiddler.text);
		}
		el.appendTo(place);
	} else {
		_view.apply(this, arguments);
	}
};

// hijack edit macro to disable editing of binary tiddlers' body
var _editHandler = config.macros.edit.handler;
config.macros.edit.handler = function(place, macroName, params, wikifier,
		paramString, tiddler) {
	if(params[0] == "text" && plugin.isBinary(tiddler)) {
		return false;
	} else {
		_editHandler.apply(this, arguments);
	}
};

// hijack autoLinkWikiWords to ignore binary tiddlers
var _autoLink = Tiddler.prototype.autoLinkWikiWords;
Tiddler.prototype.autoLinkWikiWords = function() {
	return plugin.isWikiText(this) ? _autoLink.apply(this, arguments) : false;
};

})(jQuery);
//}}}