Welcome to TiddlyWiki created by Jeremy Ruston, Copyright © 2007 UnaMesa Association
I'm changing the way I run this site from [[Wordpress|http://www,wordpress.com]] to [[TiddlyWiki|http://www.tiddlywiki.org]], for various reasons - mainly just boredom and hacker curiosity, I guess :-) That means some things might not work well for a while, so can I apologise in advance.
As a consolation, I'm also moving more into [[open notebook science|http://en.wikipedia.org/wiki/Open_notebook_science]] and sharing my [[research notebook|research.html]] online.
!About me
I am, in no particular order, a computer science academic, wannabe mathematician, amateur photographer and cook.
[[Biography|Biography]]
Publications [[by type|http://www.simondobson.org/static/sd.html]] and [[by year|http://www.simondobson.org/static/sd-by-year.html]]
[[Contact details|sd]]
[[Research]]
[[Photography|http://www.culfaddastudios.com]]
text/plain
.txt .text .js .vbs .asp .cgi .pl
----
text/html
.htm .html .hta .htx .mht
----
text/comma-separated-values
.csv
----
text/javascript
.js
----
text/css
.css
----
text/xml
.xml .xsl .xslt
----
image/gif
.gif
----
image/jpeg
.jpg .jpe .jpeg
----
image/png
.png
----
image/bmp
.bmp
----
image/tiff
.tif .tiff
----
audio/basic
.au .snd
----
audio/wav
.wav
----
audio/x-pn-realaudio
.ra .rm .ram
----
audio/x-midi
.mid .midi
----
audio/mp3
.mp3
----
audio/m3u
.m3u
----
video/x-ms-asf
.asf
----
video/avi
.avi
----
video/mpeg
.mpg .mpeg
----
video/quicktime
.qt .mov .qtvr
----
application/pdf
.pdf
----
application/rtf
.rtf
----
application/postscript
.ai .eps .ps
----
application/wordperfect
.wpd
----
application/mswrite
.wri
----
application/msexcel
.xls .xls3 .xls4 .xls5 .xlw
----
application/msword
.doc
----
application/mspowerpoint
.ppt .pps
----
application/x-director
.swa
----
application/x-shockwave-flash
.swf
----
application/x-zip-compressed
.zip
----
application/x-gzip
.gz
----
application/x-rar-compressed
.rar
----
application/octet-stream
.com .exe .dll .ocx
----
application/java-archive
.jar
/***
|Name|AttachFilePlugin|
|Source|http://www.TiddlyTools.com/#AttachFilePlugin|
|Documentation|http://www.TiddlyTools.com/#AttachFilePluginInfo|
|Version|4.0.0|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires|AttachFilePluginFormatters, AttachFileMIMETypes|
|Overrides||
|Description|Store binary files as base64-encoded tiddlers with fallback links for separate local and/or remote file storage|
Store or link binary files (such as jpg, gif, pdf or even mp3) within your TiddlyWiki document and then use them as images or links from within your tiddler content.
> Important note: As of version 3.6.0, in order to //render// images and other binary attachments created with this plugin, you must also install [[AttachFilePluginFormatters]], which extends the behavior of the TiddlyWiki core formatters for embedded images ({{{[img[tooltip|image]]}}}), linked embedded images ({{{[img[tooltip|image][link]]}}}), and external/"pretty" links ({{{[[label|link]]}}}), so that these formatter will process references to attachment tiddlers as if a normal file reference had been provided. |
!!!!!Documentation
>see [[AttachFilePluginInfo]]
!!!!!Inline interface (live)
>see [[AttachFile]] (shadow tiddler)
><<tiddler AttachFile>>
!!!!!Revisions
<<<
2009.06.04 [4.0.0] changed attachment storage format to use //sections// instead of embedded substring markers.
|please see [[AttachFilePluginInfo]] for additional revision details|
2005.07.20 [1.0.0] Initial Release
<<<
!!!!!Code
***/
// // version
//{{{
version.extensions.AttachFilePlugin= {major: 4, minor: 0, revision: 0, date: new Date(2009,6,4)};
// shadow tiddler
config.shadowTiddlers.AttachFile="<<attach inline>>";
// add 'attach' backstage task (insert before built-in 'importTask')
if (config.tasks) { // for TW2.2b or above
config.tasks.attachTask = {
text: "attach",
tooltip: "Attach a binary file as a tiddler",
content: "<<attach inline>>"
}
config.backstageTasks.splice(config.backstageTasks.indexOf("importTask"),0,"attachTask");
}
config.macros.attach = {
// // lingo
//{{{
label: "attach file",
tooltip: "Attach a file to this document",
linkTooltip: "Attachment: ",
typeList: "AttachFileMIMETypes",
titlePrompt: " enter tiddler title...",
MIMEPrompt: "<option value=''>select MIME type...</option><option value='editlist'>[edit list...]</option>",
localPrompt: " enter local path/filename...",
URLPrompt: " enter remote URL...",
tiddlerErr: "Please enter a tiddler title",
sourceErr: "Please enter a source path/filename",
storageErr: "Please select a storage method: embedded, local or remote",
MIMEErr: "Unrecognized file format. Please select a MIME type",
localErr: "Please enter a local path/filename",
URLErr: "Please enter a remote URL",
fileErr: "Invalid path/file or file not found",
tiddlerFormat: '!usage\n{{{%0}}}\n%0\n!notes\n%1\n!type\n%2\n!file\n%3\n!url\n%4\n!data\n%5\n',
//}}}
// // macro definition
//{{{
handler:
function(place,macroName,params) {
if (params && !params[0])
{ createTiddlyButton(place,this.label,this.tooltip,this.toggleAttachPanel); return; }
var id=params.shift();
this.createAttachPanel(place,id+"_attachPanel",params);
document.getElementById(id+"_attachPanel").style.position="static";
document.getElementById(id+"_attachPanel").style.display="block";
},
//}}}
//{{{
createAttachPanel:
function(place,panel_id,params) {
if (!panel_id || !panel_id.length) var panel_id="_attachPanel";
// remove existing panel (if any)
var panel=document.getElementById(panel_id); if (panel) panel.parentNode.removeChild(panel);
// set styles for this panel
setStylesheet(this.css,"attachPanel");
// create new panel
var title=""; if (params && params[0]) title=params.shift();
var types=this.MIMEPrompt+this.formatListOptions(store.getTiddlerText(this.typeList)); // get MIME types
panel=createTiddlyElement(place,"span",panel_id,"attachPanel",null);
var html=this.html.replace(/%id%/g,panel_id);
html=html.replace(/%title%/g,title);
html=html.replace(/%disabled%/g,title.length?"disabled":"");
html=html.replace(/%IEdisabled%/g,config.browser.isIE?"disabled":"");
html=html.replace(/%types%/g,types);
panel.innerHTML=html;
if (config.browser.isGecko) { // FF3 FIXUP
document.getElementById("attachSource").style.display="none";
document.getElementById("attachFixPanel").style.display="block";
}
return panel;
},
//}}}
//{{{
toggleAttachPanel:
function (e) {
if (!e) var e = window.event;
var parent=resolveTarget(e).parentNode;
var panel = document.getElementById("_attachPanel");
if (panel==undefined || panel.parentNode!=parent)
panel=config.macros.attach.createAttachPanel(parent,"_attachPanel");
var isOpen = panel.style.display=="block";
if(config.options.chkAnimate)
anim.startAnimating(new Slider(panel,!isOpen,e.shiftKey || e.altKey,"none"));
else
panel.style.display = isOpen ? "none" : "block" ;
e.cancelBubble = true;
if (e.stopPropagation) e.stopPropagation();
return(false);
},
//}}}
//{{{
formatListOptions:
function(text) {
if (!text || !text.trim().length) return "";
// get MIME list content from text
var parts=text.split("\n----\n");
var out="";
for (var p=0; p<parts.length; p++) {
var lines=parts[p].split("\n");
var label=lines.shift(); // 1st line=display text
var value=lines.shift(); // 2nd line=item value
out +='<option value="%1">%0</option>'.format([label,value]);
}
return out;
},
//}}}
// // interface definition
//{{{
css:
".attachPanel { display: none; position:absolute; z-index:10; width:35em; right:105%; top:0em;\
background-color: #eee; color:#000; font-size: 8pt; line-height:110%;\
border:1px solid black; border-bottom-width: 3px; border-right-width: 3px;\
padding: 0.5em; margin:0em; -moz-border-radius:1em;-webkit-border-radius:1em; text-align:left }\
.attachPanel form { display:inline;border:0;padding:0;margin:0; }\
.attachPanel select { width:99%;margin:0px;font-size:8pt;line-height:110%;}\
.attachPanel input { width:98%;padding:0px;margin:0px;font-size:8pt;line-height:110%}\
.attachPanel textarea { width:98%;margin:0px;height:2em;font-size:8pt;line-height:110%}\
.attachPanel table { width:100%;border:0;margin:0;padding:0;color:inherit; }\
.attachPanel tbody, .attachPanel tr, .attachPanel td { border:0;margin:0;padding:0;color:#000; }\
.attachPanel .box { border:1px solid black; padding:.3em; margin:.3em 0px; background:#f8f8f8; \
-moz-border-radius:5px;-webkit-border-radius:5px; }\
.attachPanel .chk { width:auto;border:0; }\
.attachPanel .btn { width:auto; }\
.attachPanel .btn2 { width:49%; }\
",
//}}}
//{{{
html:
'<form>\
attach from source file\
<input type="file" id="attachSource" name="source" size="56"\
onChange="config.macros.attach.onChangeSource(this)">\
<div id="attachFixPanel" style="display:none"><!-- FF3 FIXUP -->\
<input type="text" id="attachFixSource" style="width:90%"\
title="Enter a path/file to attach"\
onChange="config.macros.attach.onChangeSource(this);">\
<input type="button" style="width:7%" value="..."\
title="Enter a path/file to attach"\
onClick="config.macros.attach.askForFilename(document.getElementById(\'attachFixSource\'));">\
</div><!--end FF3 FIXUP-->\
<div class="box">\
<table style="border:0"><tr style="border:0"><td style="border:0;text-align:right;width:1%;white-space:nowrap">\
embed data <input type=checkbox class=chk name="useData" %IEdisabled% \
onclick="if (!this.form.MIMEType.value.length)\
this.form.MIMEType.selectedIndex=this.checked?1:0; "> \
</td><td style="border:0">\
<select size=1 name="MIMEType" \
onchange="this.title=this.value; if (this.value==\'editlist\')\
{ this.selectedIndex=this.form.useData.checked?1:0; story.displayTiddler(null,config.macros.attach.typeList,2); return; }">\
<option value=""></option>\
%types%\
</select>\
</td></tr><tr style="border:0"><td style="border:0;text-align:right;width:1%;white-space:nowrap">\
local link <input type=checkbox class=chk name="useLocal"\
onclick="this.form.local.value=this.form.local.defaultValue=this.checked?config.macros.attach.localPrompt:\'\';"> \
</td><td style="border:0">\
<input type=text name="local" size=15 autocomplete=off value=""\
onchange="this.form.useLocal.checked=this.value.length" \
onkeyup="this.form.useLocal.checked=this.value.length" \
onfocus="if (!this.value.length) this.value=config.macros.attach.localPrompt; this.select()">\
</td></tr><tr style="border:0"><td style="border:0;text-align:right;width:1%;white-space:nowrap">\
remote link <input type=checkbox class=chk name="useURL"\
onclick="this.form.URL.value=this.form.URL.defaultValue=this.checked?config.macros.attach.URLPrompt:\'\';\"> \
</td><td style="border:0">\
<input type=text name="URL" size=15 autocomplete=off value=""\
onfocus="if (!this.value.length) this.value=config.macros.attach.URLPrompt; this.select()"\
onchange="this.form.useURL.checked=this.value.length;"\
onkeyup="this.form.useURL.checked=this.value.length;">\
</td></tr></table>\
</div>\
<table style="border:0"><tr style="border:0"><td style="border:0;text-align:right;vertical-align:top;width:1%;white-space:nowrap">\
notes \
</td><td style="border:0" colspan=2>\
<textarea name="notes" style="width:98%;height:3.5em;margin-bottom:2px"></textarea>\
</td><tr style="border:0"><td style="border:0;text-align:right;width:1%;white-space:nowrap">\
attach as \
</td><td style="border:0" colspan=2>\
<input type=text name="tiddlertitle" size=15 autocomplete=off value="%title%"\
onkeyup="if (!this.value.length) { this.value=config.macros.attach.titlePrompt; this.select(); }"\
onfocus="if (!this.value.length) this.value=config.macros.attach.titlePrompt; this.select()" %disabled%>\
</td></tr></tr><tr style="border:0"><td style="border:0;text-align:right;width:1%;white-space:nowrap">\
add tags \
</td><td style="border:0">\
<input type=text name="tags" size=15 autocomplete=off value="" onfocus="this.select()">\
</td><td style="width:40%;text-align:right;border:0">\
<input type=button class=btn2 value="attach"\
onclick="config.macros.attach.onClickAttach(this)"><!--\
--><input type=button class=btn2 value="close"\
onclick="var panel=document.getElementById(\'%id%\'); if (panel) panel.parentNode.removeChild(panel);">\
</td></tr></table>\
</form>',
//}}}
// // control processing
//{{{
onChangeSource:
function(here) {
var form=here.form;
var list=form.MIMEType;
var theFilename = here.value;
var theExtension = theFilename.substr(theFilename.lastIndexOf('.')).toLowerCase();
// if theFilename is in current document folder, remove path prefix and use relative reference
var h=document.location.href; folder=getLocalPath(decodeURIComponent(h.substr(0,h.lastIndexOf("/")+1)));
if (theFilename.substr(0,folder.length)==folder) theFilename='./'+theFilename.substr(folder.length);
else theFilename='file:///'+theFilename; // otherwise, use absolute reference
theFilename=theFilename.replace(/\\/g,"/"); // fixup: change \ to /
form.useLocal.checked = true;
form.local.value = theFilename;
form.useData.checked = !form.useData.disabled;
list.selectedIndex=1;
for (var i=0; i<list.options.length; i++) // find matching MIME type
if (list.options[i].value.indexOf(theExtension)!=-1) { list.selectedIndex = i; break; }
if (!form.tiddlertitle.disabled)
form.tiddlertitle.value=theFilename.substr(theFilename.lastIndexOf('/')+1); // get tiddlername from filename
},
//}}}
//{{{
onClickAttach:
function (here) {
clearMessage();
// get input values
var form=here.form;
var src=form.source; if (config.browser.isGecko) src=document.getElementById("attachFixSource");
src=src.value!=src.defaultValue?src.value:"";
var when=(new Date()).formatString(config.macros.timeline.dateFormat);
var title=form.tiddlertitle.value;
var local = form.local.value!=form.local.defaultValue?form.local.value:"";
var url = form.URL.value!=form.URL.defaultValue?form.URL.value:"";
var notes = form.notes.value;
var tags = "attachment excludeMissing "+form.tags.value;
var useData=form.useData.checked;
var useLocal=form.useLocal.checked;
var useURL=form.useURL.checked;
var mimetype = form.MIMEType.value.length?form.MIMEType.options[form.MIMEType.selectedIndex].text:"";
// validate checkboxes and get filename
if (useData) {
if (src.length) { if (!theLocation) var theLocation=src; }
else { alert(this.sourceErr); src.focus(); return false; }
}
if (useLocal) {
if (local.length) { if (!theLocation) var theLocation = local; }
else { alert(this.localErr); form.local.focus(); return false; }
}
if (useURL) {
if (url.length) { if (!theLocation) var theLocation = url; }
else { alert(this.URLErr); form.URL.focus(); return false; }
}
if (!(useData||useLocal||useURL))
{ form.useData.focus(); alert(this.storageErr); return false; }
if (!theLocation)
{ src.focus(); alert(this.sourceErr); return false; }
if (!title || !title.trim().length || title==this.titlePrompt)
{ form.tiddlertitle.focus(); alert(this.tiddlerErr); return false; }
// if not already selected, determine MIME type based on filename extension (if any)
if (useData && !mimetype.length && theLocation.lastIndexOf('.')!=-1) {
var theExt = theLocation.substr(theLocation.lastIndexOf('.')).toLowerCase();
var theList=form.MIMEType;
for (var i=0; i<theList.options.length; i++)
if (theList.options[i].value.indexOf(theExt)!=-1)
{ var mimetype=theList.options[i].text; theList.selectedIndex=i; break; }
}
// attach the file
return this.createAttachmentTiddler(src, when, notes, tags, title,
useData, useLocal, useURL, local, url, mimetype);
},
getMIMEType:
function(src,def) {
var ext = src.substr(src.lastIndexOf('.')).toLowerCase();
var list=store.getTiddlerText(this.typeList);
if (!list || !list.trim().length) return def;
// get MIME list content from tiddler
var parts=list.split("\n----\n");
for (var p=0; p<parts.length; p++) {
var lines=parts[p].split("\n");
var mime=lines.shift(); // 1st line=MIME type
var match=lines.shift(); // 2nd line=matching extensions
if (match.indexOf(ext)!=-1) return mime;
}
return def;
},
createAttachmentTiddler:
function (src, when, notes, tags, title, useData, useLocal, useURL, local, url, mimetype, noshow) {
if (useData) { // encode the data
if (!mimetype.length) {
alert(this.MIMEErr);
form.MIMEType.selectedIndex=1; form.MIMEType.focus();
return false;
}
var d = this.readFile(src); if (!d) { return false; }
displayMessage('encoding '+src);
var encoded = this.encodeBase64(d);
displayMessage('file size='+d.length+' bytes, encoded size='+encoded.length+' bytes');
}
var usage=(mimetype.substr(0,5)=="image"?'[img[%0]]':'[[%0|%0]]').format([title]);
var theText=this.tiddlerFormat.format([
usage, notes.length?notes:'//none//', mimetype,
useLocal?local.replace(/\\/g,'/'):'', useURL?url:'',
useData?('data:'+mimetype+';base64,'+encoded):'' ]);
store.saveTiddler(title,title,theText,config.options.txtUserName,new Date(),tags);
var panel=document.getElementById("attachPanel"); if (panel) panel.style.display="none";
if (!noshow) { story.displayTiddler(null,title); story.refreshTiddler(title,null,true); }
displayMessage('attached "'+title+'"');
return true;
},
//}}}
// // base64 conversion
//{{{
encodeBase64:
function (d) {
if (!d) return null;
// encode as base64
var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
var out="";
var chr1,chr2,chr3="";
var enc1,enc2,enc3,enc4="";
for (var count=0,i=0; i<d.length; ) {
chr1=d.charCodeAt(i++);
chr2=d.charCodeAt(i++);
chr3=d.charCodeAt(i++);
enc1=chr1 >> 2;
enc2=((chr1 & 3) << 4) | (chr2 >> 4);
enc3=((chr2 & 15) << 2) | (chr3 >> 6);
enc4=chr3 & 63;
if (isNaN(chr2)) enc3=enc4=64;
else if (isNaN(chr3)) enc4=64;
out+=keyStr.charAt(enc1)+keyStr.charAt(enc2)+keyStr.charAt(enc3)+keyStr.charAt(enc4);
chr1=chr2=chr3=enc1=enc2=enc3=enc4="";
}
return out;
},
decodeBase64: function(input) {
var out="";
var chr1,chr2,chr3;
var enc1,enc2,enc3,enc4;
var i = 0;
// remove all characters that are not A-Z, a-z, 0-9, +, /, or =
input=input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
do {
enc1=keyStr.indexOf(input.charAt(i++));
enc2=keyStr.indexOf(input.charAt(i++));
enc3=keyStr.indexOf(input.charAt(i++));
enc4=keyStr.indexOf(input.charAt(i++));
chr1=(enc1 << 2) | (enc2 >> 4);
chr2=((enc2 & 15) << 4) | (enc3 >> 2);
chr3=((enc3 & 3) << 6) | enc4;
out=out+String.fromCharCode(chr1);
if (enc3!=64) out=out+String.fromCharCode(chr2);
if (enc4!=64) out=out+String.fromCharCode(chr3);
} while (i<input.length);
return out;
},
//}}}
// // I/O functions
//{{{
readFile: // read local BINARY file data
function(filePath) {
if(!window.Components) { return null; }
try { netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); }
catch(e) { alert("access denied: "+filePath); return null; }
var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
try { file.initWithPath(filePath); } catch(e) { alert("cannot read file - invalid path: "+filePath); return null; }
if (!file.exists()) { alert("cannot read file - not found: "+filePath); return null; }
var inputStream = Components.classes["@mozilla.org/network/file-input-stream;1"].createInstance(Components.interfaces.nsIFileInputStream);
inputStream.init(file, 0x01, 00004, null);
var bInputStream = Components.classes["@mozilla.org/binaryinputstream;1"].createInstance(Components.interfaces.nsIBinaryInputStream);
bInputStream.setInputStream(inputStream);
return(bInputStream.readBytes(inputStream.available()));
},
//}}}
//{{{
writeFile:
function(filepath,data) {
// TBD: decode base64 and write BINARY data to specified local path/filename
return(false);
},
//}}}
//{{{
askForFilename: // for FF3 fixup
function(target) {
var msg=config.messages.selectFile;
if (target && target.title) msg=target.title; // use target field tooltip (if any) as dialog prompt text
// get local path for current document
var path=getLocalPath(document.location.href);
var p=path.lastIndexOf("/"); if (p==-1) p=path.lastIndexOf("\\"); // Unix or Windows
if (p!=-1) path=path.substr(0,p+1); // remove filename, leave trailing slash
var file=""
var result=window.mozAskForFilename(msg,path,file,true); // FF3 FIXUP ONLY
if (target && result.length) // set target field and trigger handling
{ target.value=result; target.onchange(); }
return result;
}
};
//}}}
//{{{
if (window.mozAskForFilename===undefined) { // also defined by CoreTweaks (for ticket #604)
window.mozAskForFilename=function(msg,path,file,mustExist) {
if(!window.Components) return false;
try {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
var nsIFilePicker = window.Components.interfaces.nsIFilePicker;
var picker = Components.classes['@mozilla.org/filepicker;1'].createInstance(nsIFilePicker);
picker.init(window, msg, mustExist?nsIFilePicker.modeOpen:nsIFilePicker.modeSave);
var thispath = Components.classes['@mozilla.org/file/local;1'].createInstance(Components.interfaces.nsILocalFile);
thispath.initWithPath(path);
picker.displayDirectory=thispath;
picker.defaultExtension='';
picker.defaultString=file;
picker.appendFilters(nsIFilePicker.filterAll|nsIFilePicker.filterText|nsIFilePicker.filterHTML);
if (picker.show()!=nsIFilePicker.returnCancel)
var result=picker.file.persistentDescriptor;
}
catch(ex) { displayMessage(ex.toString()); }
return result;
}
}
//}}}
/***
|Name|AttachFilePluginFormatters|
|Source|http://www.TiddlyTools.com/#AttachFilePluginFormatters|
|Version|4.0.0|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1.3|
|Type|plugin|
|Requires||
|Overrides|'image' and 'prettyLink' formatters, TiddlyWiki.prototype.getRecursiveTiddlerText|
|Description|run-time library for displaying attachment tiddlers|
This plugin provides "stand-alone" processing for //rendering// attachment tiddlers created by [[AttachFilePlugin]]. Attachment tiddlers are tagged with<<tag attachment>>and contain binary file content (e.g., jpg, gif, pdf, mp3, etc.) that has been stored directly as base64 text-encoded data or can be loaded from external files stored on a local filesystem or remote web server.
NOTE: This plugin does not include the "control panel" and supporting functions needed to //create// new attachment tiddlers. Those features are provided by [[AttachFilePlugin]], which can be installed while building your document, and then safely omitted to reduce the overall file size when you publish your finished document (assuming you don't intend to create any additional attachment tiddlers in that document)
!!!!!Formatters
<<<
This plugin extends the behavior of the following TiddlyWiki core "wikify()" formatters:
* embedded images: {{{[img[tooltip|image]]}}}
* linked embedded images: {{{[img[tooltip|image][link]]}}}
* external/"pretty" links: {{{[[label|link]]}}}
''Please refer to AttachFilePlugin (source: http://www.TiddlyTools.com/#AttachFilePlugin) for additional information.''
<<<
!!!!!Revisions
<<<
2009.06.04 [4.0.0] changed attachment storage format to use //sections// instead of embedded substring markers.
2008.01.08 [*.*.*] plugin size reduction: documentation moved to ...Info
2007.12.04 [*.*.*] update for TW2.3.0: replaced deprecated core functions, regexps, and macros
2007.10.29 [3.7.0] more code reduction: removed upload handling from AttachFilePlugin (saves ~7K!)
2007.10.28 [3.6.0] removed duplicate formatter code from AttachFilePlugin (saves ~10K!) and updated documentation accordingly. This plugin ([[AttachFilePluginFormatters]]) is now //''required''// in order to display attached images/binary files within tiddler content.
2006.05.20 [3.4.0] through 2007.03.01 [3.5.3] sync with AttachFilePlugin
2006.05.13 [3.2.0] created from AttachFilePlugin v3.2.0
<<<
!!!!!Code
***/
// // version
//{{{
version.extensions.AttachFilePluginFormatters= {major: 4, minor: 0, revision: 0, date: new Date(2009,6,4)};
//}}}
//{{{
if (config.macros.attach==undefined) config.macros.attach= { };
//}}}
//{{{
if (config.macros.attach.isAttachment==undefined) config.macros.attach.isAttachment=function (title) {
var tiddler = store.getTiddler(title);
if (tiddler==undefined || tiddler.tags==undefined) return false;
return (tiddler.tags.indexOf("attachment")!=-1);
}
//}}}
//{{{
// test for local file existence - returns true/false without visible error display
if (config.macros.attach.fileExists==undefined) config.macros.attach.fileExists=function(f) {
if(window.Components) { // MOZ
try { netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); }
catch(e) { return false; } // security access denied
var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
try { file.initWithPath(f); }
catch(e) { return false; } // invalid directory
return file.exists();
}
else { // IE
var fso = new ActiveXObject("Scripting.FileSystemObject");
return fso.FileExists(f);
}
}
//}}}
//{{{
if (config.macros.attach.getAttachment==undefined) config.macros.attach.getAttachment=function(title) {
// extract embedded data, local and remote links (if any)
var text=store.getTiddlerText(title,'');
var embedded=store.getTiddlerText(title+'##data','').trim();
var locallink=store.getTiddlerText(title+'##file','').trim();
var remotelink=store.getTiddlerText(title+'##url','').trim();
// backward-compatibility for older attachments (pre 4.0.0)
var startmarker="---BEGIN_DATA---\n";
var endmarker="\n---END_DATA---";
var pos=0; var endpos=0;
if ((pos=text.indexOf(startmarker))!=-1 && (endpos=text.indexOf(endmarker))!=-1)
embedded="data:"+(text.substring(pos+startmarker.length,endpos)).replace(/\n/g,'');
if ((pos=text.indexOf("/%LOCAL_LINK%/"))!=-1)
locallink=text.substring(text.indexOf("|",pos)+1,text.indexOf("]]",pos));
if ((pos=text.indexOf("/%REMOTE_LINK%/"))!=-1)
remotelink=text.substring(text.indexOf("|",pos)+1,text.indexOf("]]",pos));
// if there is a data: URI defined (not supported by IE)
if (embedded.length && !config.browser.isIE) return embedded;
// document is being served remotely... use remote URL (if any) (avoids security alert)
if (remotelink.length && document.location.protocol!="file:")
return remotelink;
// local link only... return link without checking file existence (avoids security alert)
if (locallink.length && !remotelink.length)
return locallink;
// local link, check for file exist... use local link if found
if (locallink.length) {
locallink=locallink.replace(/^\.[\/\\]/,''); // strip leading './' or '.\' (if any)
if (this.fileExists(getLocalPath(locallink))) return locallink;
// maybe local link is relative... add path from current document and try again
var pathPrefix=document.location.href; // get current document path and trim off filename
var slashpos=pathPrefix.lastIndexOf("/"); if (slashpos==-1) slashpos=pathPrefix.lastIndexOf("\\");
if (slashpos!=-1 && slashpos!=pathPrefix.length-1) pathPrefix=pathPrefix.substr(0,slashpos+1);
if (this.fileExists(getLocalPath(pathPrefix+locallink))) return locallink;
}
// no embedded data, no local (or not found), fallback to remote URL (if any)
if (remotelink.length) return remotelink;
// attachment URL doesn't resolve, just return input as is
return title;
}
//}}}
//{{{
if (config.macros.attach.init_formatters==undefined) config.macros.attach.init_formatters=function() {
if (this.initialized) return;
// find the formatter for "image" and replace the handler
for (var i=0; i<config.formatters.length && config.formatters[i].name!="image"; i++);
if (i<config.formatters.length) config.formatters[i].handler=function(w) {
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source)
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) // Simple bracketted link
{
var e = w.output;
if(lookaheadMatch[5])
{
var link = lookaheadMatch[5];
// ELS -------------
var external=config.formatterHelpers.isExternalLink(link);
if (external)
{
if (config.macros.attach.isAttachment(link))
{
e = createExternalLink(w.output,link);
e.href=config.macros.attach.getAttachment(link);
e.title = config.macros.attach.linkTooltip + link;
}
else
e = createExternalLink(w.output,link);
}
else
e = createTiddlyLink(w.output,link,false,null,w.isStatic);
// ELS -------------
addClass(e,"imageLink");
}
var img = createTiddlyElement(e,"img");
if(lookaheadMatch[1])
img.align = "left";
else if(lookaheadMatch[2])
img.align = "right";
if(lookaheadMatch[3])
img.title = lookaheadMatch[3];
img.src = lookaheadMatch[4];
// ELS -------------
if (config.macros.attach.isAttachment(lookaheadMatch[4]))
img.src=config.macros.attach.getAttachment(lookaheadMatch[4]);
// ELS -------------
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
}
//}}}
//{{{
// find the formatter for "prettyLink" and replace the handler
for (var i=0; i<config.formatters.length && config.formatters[i].name!="prettyLink"; i++);
if (i<config.formatters.length) {
config.formatters[i].handler=function(w) {
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
var e;
var text = lookaheadMatch[1];
if(lookaheadMatch[3]) {
// Pretty bracketted link
var link = lookaheadMatch[3];
if (config.macros.attach.isAttachment(link)) {
e = createExternalLink(w.output,link);
e.href=config.macros.attach.getAttachment(link);
e.title=config.macros.attach.linkTooltip+link;
}
else e = (!lookaheadMatch[2] && config.formatterHelpers.isExternalLink(link))
? createExternalLink(w.output,link)
: createTiddlyLink(w.output,link,false,null,w.isStatic);
} else {
e = createTiddlyLink(w.output,text,false,null,w.isStatic);
}
createTiddlyText(e,text);
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
}
} // if "prettyLink" formatter found
this.initialized=true;
}
//}}}
//{{{
config.macros.attach.init_formatters(); // load time init
//}}}
//{{{
if (TiddlyWiki.prototype.coreGetRecursiveTiddlerText==undefined) {
TiddlyWiki.prototype.coreGetRecursiveTiddlerText = TiddlyWiki.prototype.getRecursiveTiddlerText;
TiddlyWiki.prototype.getRecursiveTiddlerText = function(title,defaultText,depth) {
return config.macros.attach.isAttachment(title)?
config.macros.attach.getAttachment(title):this.coreGetRecursiveTiddlerText.apply(this,arguments);
}
}
//}}}
/***
|Name|AttachFilePluginInfo|
|Source|http://www.TiddlyTools.com/#AttachFilePlugin|
|Documentation|http://www.TiddlyTools.com/#AttachFilePluginInfo|
|Version|4.0.0|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|Documentation for AttachFilePlugin|
Store or link binary files (such as jpg, gif, pdf or even mp3) within your TiddlyWiki document and then use them as images or links from within your tiddler content.
!!!!!Inline interface (live)
>see [[AttachFile]] (shadow tiddler)
><<tiddler AttachFile>>
!!!!!Syntax
<<<
''To display the attach file control panel, simply view the [[AttachFile]] shadow tiddler that is automatically created by the plugin, and contains an instance of the inline control panel.''. Or, you can write:
{{{
<<attach inline>>
}}}
in any tiddler to display the control panel embedded within that tiddler. Note: you can actually use any unique identifier in place of the "inline" keyword. Each unique id creates a separate instance of the controls. If the same ID is used in more than one tiddler, then the control panel is automatically moved to the most recently rendered location. Or, you can write:
{{{
<<attach>>
}}}
(with no ID parameter) in SidebarOptions. This adds a command link that opens the controls as a floating panel, positioned directly to the left of the sidebar.
<<<
!!!!!Usage
<<<
Binary file content can be stored in three different locations:
#embedded in the attachment tiddler (encoded as base64)
#on your filesystem (a 'local link' path/filename)
#on a web server (a 'remote link' URL)
The plugin creates an "attachment tiddler" for each file you attach. Regardless of where you store the binary content, your document can refer to the attachment tiddler rather than using a direct file or URL reference in your embedded image or external links, so that changing document locations will not require updating numerous tiddlers or copying files from one system to another.
> Important note: As of version 3.6.0, in order to //render// images and other binary attachments created with this plugin, you must also install [[AttachFilePluginFormatters]], which extends the behavior of the TiddlyWiki core formatters for embedded images ({{{[img[tooltip|image]]}}}), linked embedded images ({{{[img[tooltip|image][link]]}}}), and external/"pretty" links ({{{[[label|link]]}}}), so that these formatter will process references to attachment tiddlers as if a normal file reference had been provided. |
When you attach a file, a tiddler (tagged with<<tag attachment>>) is generated (using the source filename as the tiddler's title). The tiddler contains //''base64 text-encoded binary data''//, surrounded by {{{/%...%/}}} comment markers (so they are not visible when viewing the tiddler). The tiddler also includes summary details about the file: when it was attached, by whom, etc. and, if the attachment is an image file (jpg, gif, or png), the image is automatically displayed below the summary information.
>Note: although you can edit an attachment tiddler, ''don't change any of the encoded content below the attachment header'', as it has been prepared for use in the rest of your document, and even changing a single character can make the attachment unusable. //If needed, you ''can'' edit the header information or even the MIME type declaration in the attachment data, but be very careful not to change any of the base64-encoded binary data.//
With embedded data, your TW document can be completely self-contained...unfortunately, embedding just a few moderately-sized binary files using base64 text-encoding can dramatically increase the size of your document. To avoid this problem, you can create attachment tiddlers that define external local filesystem (file://) and/or remote web server (http://) 'reference' links, without embedding the binary data directly in the tiddler (i.e., uncheck "embed data" in the 'control panel').
These links provide an alternative source for the binary data: if embedded data is not found (or you are running on Internet Explorer, which does not currently support using embedded data), then the plugin tries the local filesystem reference. If a local file is not found, then the remote reference (if any) is used. This "fallback" approach also lets you 'virtualize' the external links in your document, so that you can access very large binary content such as PDFs, MP3's, and even *video* files, by using just a 'remote reference link' without embedding any data or downloading huge files to your hard disk.
Of course, when you //do// download an attached file, the local copy will be used instead of accessing a remote server each time, thereby saving bandwidth and allowing you to 'go mobile' without having to edit any tiddlers to alter the link locations...
<<<
!!!!!Syntax / Examples
<<<
To embed attached files as images or link to them from other tiddlers, use the standard ~TiddlyWiki image syntax ({{{[img[tooltip|filename]]}}}), linked image syntax ({{{[img[tooltip|filename][tiddlername]]}}}) , or "external link" syntax ({{{[[text|URL]]}}}), replacing the filename or URL that is normally entered with the title of an attachment tiddler.
embedded image data:
>{{{[img[Meow|AttachFileSample]]}}}
>[img[Meow|AttachFileSample]]
embedded image data with link to larger remote image:
>{{{[img[click for larger view|AttachFileSample][AttachFileSample2]]}}}
>[img[click for larger view|AttachFileSample][AttachFileSample2]]
'external' link to embedded image data:
>{{{[[click to view attachment|AttachFileSample]]}}}
>[[click to view attachment|AttachFileSample]]
'external' link to remote image:
>{{{[[click to view attachment|AttachFileSample2]]}}}
>[[click to view attachment|AttachFileSample2]]
regular ~TiddlyWiki links to attachment tiddlers:
>{{{[[AttachFileSample]]}}} [[AttachFileSample]]
>{{{[[AttachFileSample2]]}}} [[AttachFileSample2]]
<<<
!!!!!Defining MIME types
<<<
When you select a source file, a ''[[MIME|http://en.wikipedia.org/wiki/MIME]]'' file type is automatically suggested, based on filename extension. The AttachFileMIMETypes tiddler defines the list of MIME types that will be recognized by the plugin. Each MIME type definition consists of exactly two lines of text: the official MIME type designator (e.g., "text/plain", "image/gif", etc.), and a space-separated list of file extensions associated with that type. List entries are separated by "----" (horizontal rules).
<<<
!!!!!Known Limitations
<<<
Internet Explorer does not support the data: URI scheme, and cannot use the //embedded// data to render images or links. However, you can still use the local/remote link definitions to create file attachments that are stored externally. In addition, while it is relatively easy to read local //text// files, reading binary files is not directly supported by IE's FileSystemObject (FSO) methods, and other file I/O techniques are subject to security barriers or require additional MS proprietary technologies (like ASP or VB) that make implementation more difficult. As a result, you cannot //create// new attachment tiddlers using IE.
<<<
!!!!!Installation
<<<
Import (or copy/paste) the following tiddlers into your document:
* [[AttachFilePlugin]] (tagged with <<tag systemConfig>>)
* [[AttachFilePluginFormatters]] ("runtime distribution library") (tagged with <<tag systemConfig>>)
* [[AttachFileSample]] and [[AttachFileSample2]] //(tagged with <<tag attachment>>)//
* [[AttachFileMIMETypes]] //(defines binary file types)//
> Important note: As of version 3.6.0, in order to //render// images and other binary attachments created with this plugin, you must also install [[AttachFilePluginFormatters]], which extends the behavior of the TiddlyWiki core formatters for embedded images ({{{[img[tooltip|image]]}}}), linked embedded images ({{{[img[tooltip|image][link]]}}}), and external/"pretty" links ({{{[[label|link]]}}}), so that these formatter will process references to attachment tiddlers as if a normal file reference had been provided. |
<<<
!!!!!Revisions
<<<
2009.06.04 [4.0.0] changed attachment storage format to use //sections// instead of embedded substring markers.
2008.07.21 [3.9.0] Fixup for FireFox 3: use HTML with separate text+button control instead of type='file' control
2008.05.12 [3.8.1] automatically add 'attach' task to backstage (moved from BackstageTweaks)
2008.04.09 [3.8.0] in onChangeSource(), if source matches current document folder, use relative reference for local link. Also, disable 'embed' when using IE (which //still// doesn't support data: URI)
2008.04.07 [3.7.3] fixed typo in HTML for 'local file link' so that clicking in input field doesn't erase current path/file (if any)
2008.04.07 [3.7.2] auto-create AttachFile shadow tiddler for inline interface
2008.01.08 [*.*.*] plugin size reduction: documentation moved to ...Info
2007.12.04 [*.*.*] update for TW2.3.0: replaced deprecated core functions, regexps, and macros
2007.12.03 [3.7.1] in createAttachmentTiddler(), added optional "noshow" flag to suppress display of newly created tiddlers.
2007.10.29 [3.7.0] code reduction: removed support for built-in upload to server... on-line hosting of binary attachments is left to the document author, who can upload/host files using 3rd-party web-based services (e.g. www.flickr.com, ) or stand-alone applications (e.g., FTP).
2007.10.28 [3.6.0] code reduction: removed duplicate definition of image and prettyLink formatters. Rendering of attachment tiddlers now //requires// installation of AttachFilePluginFormatters
2007.03.01 [3.5.3] use apply() to invoke hijacked function
2007.02.25 [3.5.2] in hijack of "prettyLink", fix version check for TW2.2 compatibility (prevent incorrect use of fallback handler)
2007.01.09 [3.5.1] onClickAttach() refactored to create separate createAttachmentTiddler() API for use with FileDropPluginHandlers
2006.11.30 [3.5.0] in getAttachment(), for local references, add check for file existence and fallback to remote URL if local file not found. Added fileExists() to encapsulate FF vs. IE local file test function (IE FSO object code is TBD).
2006.11.29 [3.4.8] in hijack for PrettyLink, 'simple bracketed link' opens tiddler instead of external link to attachment
2006.11.29 [3.4.7] in readFile(), added try..catch around initWithPath() to handle invalid/non-existent paths better.
2006.11.09 [3.4.6] REAL FIX for TWv2.1.3: incorporate new TW2.1.3 core "prettyLink" formatter regexp handling logic and check for version < 2.1.3 with fallback to old plugin code. Also, cleanup table layout in HTML (added "border:0" directly to table elements to override stylesheet)
2006.11.08 [3.4.5] TEMPORARY FIX for TWv2.1.3: disable hijack of wikiLink formatter due to changes in core wikiLink regexp definition. //Links to attachments are broken, but you can still use {{{[img[TiddlerName]]}}} to render attachments as images, as well as {{{background:url('[[TiddlerName]]')}}} in CSS declarations for background images.//
2006.09.10 [3.4.4] update formatters for 2.1 compatibility (use this.lookaheadRegExp instead of temp variable)
2006.07.24 [3.4.3] in prettyLink formatter, added check for isShadowTiddler() to fix problem where shadow links became external links.
2006.07.13 [3.4.2] in getAttachment(), fixed stripping of newlines so data: used in CSS will work
2006.05.21 [3.4.1] in getAttachment(), fixed substring() to extract data: URI (was losing last character, which broken rendering of SOME images)
2006.05.20 [3.4.0] hijack core getRecursiveTiddlerText() to support rendering attachments in stylesheets (e.g. {{{url([[AttachFileSample]])}}})
2006.05.20 [3.3.6] add "description" feature to easily include notes in attachment tiddler (you can always edit to add them later... but...)
2006.05.19 [3.3.5] add "attach as" feature to change default name for attachment tiddlers. Also, new optional param to specify tiddler name (disables editing)
2006.05.16 [3.3.0] completed XMLHttpRequest handling for GET or POST to configurable server scripts
2006.05.13 [3.2.0] added interface for upload feature. Major rewrite of code for clean object definitions. Major improvements in UI interaction and validation.
2006.05.09 [3.1.1] add wikifer support for using attachments in links from "linked image" syntax: {{{[img[tip|attachment1][attachment2]]}}}
2006.05.09 [3.1.0] lots of code changes: new options for attachments that use embedded data and/or links to external files (local or remote)
2006.05.03 [3.0.2] added {{{/%...%/}}} comments around attachment data to hide it when viewing attachment tiddler.
2006.02.05 [3.0.1] wrapped wikifier hijacks in initAttachmentFormatters() function to eliminate globals and avoid FireFox 1.5.0.1 crash bug when referencing globals
2005.12.27 [3.0.0] Update for TW2.0. Automatically add 'excludeMissing' tag to attachments
2005.12.16 [2.2.0] Dynamically create/remove attachPanel as needed to ensure only one instance of interface elements exists, even if there are multiple instances of macro embedding.
2005.11.20 [2.1.0] added wikifier handler extensions for "image" and "prettyLink" to render tiddler attachments
2005.11.09 [2.0.0] begin port from old ELS Design adaptation based on ~TW1.2.33
2005.07.20 [1.0.0] Initial release (as adaptation)
<<<
!Biography
Simon Dobson is a co-founder of the Systems Research Group at UCD Dublin, Ireland's largest university. His research centres around adaptive pervasive computing and novel programming techniques, addressing both theory and practice and being supported by an extensive record of published work (including papers in CACM, TAAS, JPDC, PERVASIVE, PERCOM and ECOOP) and primary authorship on grants worth over EUR 3M as well as collaborating in grants worth a further EUR 40M, feeding around EUR 1.5M directly into his own research programme. His serves on the steering or programme committees of many international conferences and workshops including ICAC, ICOST, MUCS and MPAC; is a reviewer for journals including ACM Transactions on Autonomous and Adaptive Systems, SOFTWARE - Practice and Experience, and Computer Communications; has been an invited editor for special issues of Computer Networks, IJIPT and JNSM; sits on the editorial boards of the Journal of Network and Systems Management and the International Journal of Autonomous and Adaptive Communications Systems; and participates in a number of EU strategic workshops and working groups. He is National Director and vice-president of the European Research Consortium for Informatics and Mathematics, a board member of the Autonomic Communication Forum, and a member of the IBEC/ICT Ireland standing committee on academic/industrial research and development. He also founded and ran a research-driven start-up company. He holds a BSc and DPhil in computer science, is a Chartered Fellow of the British Computer Society, a Chartered Engineer, and member of the IEEE and ACM.
([[Short|http://www.simondobson.org/static/short-cv.pdf]] and [[full|http://www.simondobson.org/static/medium-cv.pdf]] CVs.)
!License
[img[license.png][http://creativecommons.org/licenses/by-nc-sa/3.0/]]
This work is licensed under a [[Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License|http://creativecommons.org/licenses/by-nc-sa/3.0/]]
/%
|Name|EmbedTiddlers|
|Source|http://www.TiddlyTools.com/#EmbedTiddlers|
|Version|1.2.2|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|script|
|Requires|InlineJavascriptPlugin|
|Overrides||
|Description|transclude a list of tiddlers in a specific order|
usage:
<<tiddler EmbedTiddlers with: "TiddlerName [[TiddlerName with spaces]] TiddlerName ...">>
or
<<tiddler EmbedTiddlers with: @TiddlerName>>
or
<<tiddler EmbedTiddlers with: =tagValue sortby>>
where
@TiddlerName
specifies a //separate// tiddler containing the space-separated,
bracketed list of tiddlers to transclude (e.g., DefaultTiddlers)
=tagValue
embeds all tiddlers tagged with the indicated value
sortby (optional)
specifies a tiddler field for sorting the results (default="title")
"+" or "-" prefix indicates the sort direction (ascending/descending),
e.g., "-modified" sorts by tiddler modification date, most recent first
Note: if MatchTagsPlugin is installed, you can use FULL BOOLEAN LOGIC EXPRESSIONS
in place of the "tagValue" (following the leading "="). However, because the boolean
expression will contain spaces, it MUST be enclosed in [[...]], like this:
<<tiddler EmbedTiddlers with: [[=settings AND NOT systemConfig]]>>
%/<script>
var list='$1';
var sortby='title'; if ('$2'!='$'+'2') sortby='$2';
var tids=[];
if (list.substr(0,1)=='=') {
var fn=store.getMatchingTiddlers||store.getTaggedTiddlers;
var tagged=store.sortTiddlers(fn.apply(store,[list.substr(1)]),sortby);
for (var t=0; t<tagged.length; t++) tids.push(tagged[t].title);
} else {
if (list.substr(0,1)=='@') list=store.getTiddlerText(list.substr(1),'');
var tids=list.readBracketedList();
}
var out='';
for (var i=0; i<tids.length; i++) out+='<<tiddler [['+tids[i]+']]>>';
return out;
</script>
/***
|Name|ExternalTiddlersPlugin|
|Source|http://www.TiddlyTools.com/#ExternalTiddlersPlugin|
|Documentation|http://www.TiddlyTools.com/#ExternalTiddlersPluginInfo|
|Version|1.3.1|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires|TemporaryTiddlersPlugin (optional, recommended)|
|Overrides|config.macros.tiddler.handler|
|Options|##Configuration|
|Description|retrieve and wikify content from external files or remote URLs|
This plugin extends the {{{<<tiddler>>}}} macro syntax so you can retrieve and wikify content directly from external files or remote URLs. You can also define alternative "fallback" sources to provide basic "import on demand" handling by automatically creating/importing tiddler content from external sources when the specified ~TiddlerName does not already exist in your document.
!!!!!Documentation
>see [[ExternalTiddlersPluginInfo]]
!!!!!Configuration
<<<
<<option chkExternalTiddlersImport>> automatically create/import tiddlers when using external fallback references
{{{usage: <<option chkExternalTiddlersImport>>}}}
<<option chkExternalTiddlersQuiet>> don't display messages when adding tiddlers ("quiet mode")
{{{usage: <<option chkExternalTiddlersQuiet>>}}}
<<option chkExternalTiddlersTemporary>> tag retrieved tiddlers as 'temporary'(requires [[TemporaryTiddlersPlugin]])
{{{usage: <<option chkExternalTiddlersTemporary>>}}}
tag retrieved tiddlers with: <<option txtExternalTiddlersTags>>
{{{usage: <<option txtExternalTiddlersTags>>}}}
__password-protected server settings //(optional, if needed)//:__
>username: <<option txtRemoteUsername>> password: <<option txtRemotePassword>>
>{{{usage: <<option txtRemoteUsername>> <<option txtRemotePassword>>}}}
>''note: these settings are also used by [[LoadTiddlersPlugin]] and [[ImportTiddlersPlugin]]''
<<<
!!!!!Revisions
<<<
2008.10.27 [1.3.1] in insertTiddler(), fixed Safari bug by replacing static Array.concat(...) with new Array().concat(...)
|please see [[ExternalTiddlersPluginInfo]] for additional revision details|
2007.11.25 [1.0.0] initial release - moved from CoreTweaks
<<<
!!!!!Code
***/
//{{{
version.extensions.ExternalTiddlersPlugin= {major: 1, minor: 3, revision: 1, date: new Date(2008,10,27)};
// optional automatic import/create for missing tiddlers
if (config.options.chkExternalTiddlersImport==undefined) config.options.chkExternalTiddlersImport=true;
if (config.options.chkExternalTiddlersTemporary==undefined) config.options.chkExternalTiddlersTemporary=true;
if (config.options.chkExternalTiddlersQuiet==undefined) config.options.chkExternalTiddlersQuiet=false;
if (config.options.txtExternalTiddlersTags==undefined) config.options.txtExternalTiddlersTags="external";
if (config.options.txtRemoteUsername==undefined) config.options.txtRemoteUsername="";
if (config.options.txtRemotePassword==undefined) config.options.txtRemotePassword="";
config.macros.tiddler.externalTiddlers_handler = config.macros.tiddler.handler;
config.macros.tiddler.handler = function(place,macroName,params,wikifier,paramString,tiddler)
{
params = paramString.parseParams("name",null,true,false,true);
var names = params[0]["name"];
var list = names[0];
var items = list.split("|");
var className = names[1] ? names[1] : null;
var args = params[0]["with"];
// UTILITY FUNCTIONS
function extract(text,tids) { // get tiddler source content from plain text or TW doc
if (!text || !tids || !tids.length) return text; // no text or no tiddler list... return text as-is
var remoteStore=new TiddlyWiki();
if (!remoteStore.importTiddlyWiki(text)) return text; // not a TW document... return text as-is
var out=[]; for (var t=0;t<tids.length;t++)
{ var txt=remoteStore.getTiddlerText(tids[t]); if (txt) out.push(txt); }
return out.join("\n");
}
function substitute(text,args) { // replace "substitution markers" ($1-$9) with macro param values (if any)
if (!text || !args || !args.length) return text;
var n=args.length; if (n>9) n=9;
for(var i=0; i<n; i++) { var re=new RegExp("\\$" + (i + 1),"mg"); text=text.replace(re,args[i]); }
return text;
}
function addTiddler(src,text,tids) { // extract tiddler(s) from text and create local copy
if (!config.options.chkExternalTiddlersImport) return; // not enabled... do nothing
if (!text || !tids || !tids.length) return; // no text or no tiddler list... do nothing
var remoteStore=new TiddlyWiki();
if (!remoteStore.importTiddlyWiki(text)) // not a TW document... create a single tiddler from text
makeTiddler(src,text,tids[0]);
else // TW document with "permaview-like" suffix... copy tiddler(s) from remote store
for (var t=0;t<tids.length;t++)
insertTiddler(src,remoteStore.getTiddler(tids[t]));
return;
}
function makeTiddler(src,text,title) { // create a new tiddler object from text
var who=config.options.txtUserName; var when=new Date();
var msg="/%\n\nThis tiddler was automatically created using ExternalTiddlersPlugin\n";
msg+="by %0 on %1\nsource: %2\n\n%/";
var tags=config.options.txtExternalTiddlersTags.readBracketedList();
if (config.options.chkExternalTiddlersTemporary) tags.pushUnique(config.options.txtTemporaryTag);
store.saveTiddler(null,title,msg.format([who,when,src])+text,who,when,tags,{});
if (!config.options.chkExternalTiddlersQuiet) displayMessage("Created new tiddler '"+title+"' from text file "+src);
}
function insertTiddler(src,t) { // import a single tiddler object into the current document store
if (!t) return;
var who=config.options.txtUserName; var when=new Date();
var msg="/%\n\nThis tiddler was automatically imported using ExternalTiddlersPlugin\n";
msg+="by %0 on %1\nsource: %2\n\n%/";
var newtags=new Array().concat(t.tags,config.options.txtExternalTiddlersTags.readBracketedList());
if (config.options.chkExternalTiddlersTemporary) newtags.push(config.options.txtTemporaryTag);
store.saveTiddler(null,t.title,msg.format([who,when,src])+t.text,t.modifier,t.modified,newtags,t.fields);
if (!config.options.chkExternalTiddlersQuiet) displayMessage("Imported tiddler '"+t.title+"' from "+src);
}
function getGUID() // create a Globally Unique ID (for async reference to DOM elements)
{ return new Date().getTime()+Math.random().toString(); }
// loop through "|"-separated list of alternative tiddler/file/URL references until successful
var fallback="";
for (var i=0; i<items.length; i++) { var src=items[i];
// if tiddler (or shadow) exists, replace reference list with current source name and apply core handler
if (store.getTiddlerText(src)) {
arguments[2][0]=src; // params[] array
var p=arguments[4].split(list); arguments[4]=p[0]+src+p[1]; // paramString
this.externalTiddlers_handler.apply(this,arguments);
break; // stop processing alternatives
}
// tiddler doesn't exist, and not an external file/URL reference... skip it
if (!config.formatterHelpers.isExternalLink(src)) {
if (!fallback.length) fallback=src; // title to use when importing external tiddler
continue;
}
// separate 'permaview' list of tiddlers (if any) from file/URL (i.e., '#name name name..." suffix)
var p=src.split("#"); src=p[0]; var tids=p[1]?p[1].readBracketedList(false):[];
// if reference is to a remotely hosted document or the current document is remotely hosted...
if (src.substr(0,4)=="http" || document.location.protocol.substr(0,4)=="http") {
if (src.substr(0,4)!="http") // fixup URL for relative remote references
{ var h=document.location.href; src=h.substr(0,h.lastIndexOf("/")+1)+src; }
var wrapper = createTiddlyElement(place,"span",getGUID(),className); // create placeholder for async rendering
var callback=function(success,params,text,src,xhr) { // ASYNC CALLBACK
if (!success) { displayMessage(xhr.status); return; } // couldn't read remote file... report the error
if (params.fallback.length)
addTiddler(params.url,text,params.tids.length?params.tids:[params.fallback]); // import tiddler
var wrapper=document.getElementById(params.id); if (!wrapper) return;
wikify(substitute(extract(text,params.tids),params.args),wrapper); // ASYNC RENDER
};
var callbackparams={ url:src, id:wrapper.id, args:args, tids:tids, fallback:fallback } // ASYNC PARAMS
var name=config.options.txtRemoteUsername; // optional value
var pass=config.options.txtRemotePassword; // optional value
var x=doHttp("GET",src,null,null,name,pass,callback,callbackparams,null)
if (typeof(x)=="string") // couldn't start XMLHttpRequest... report error
{ displayMessage("error: cannot access "+src); displayMessage(x); }
break; // can't tell if async read will succeed.... stop processing alternatives anyway.
}
else { // read file from local filesystem
var text=loadFile(getLocalPath(src));
if (!text) { // couldn't load file... fixup path for relative reference and retry...
var h=document.location.href;
var text=loadFile(getLocalPath(decodeURIComponent(h.substr(0,h.lastIndexOf("/")+1)))+src);
}
if (text) { // test it again... if file was loaded OK, render it in a class wrapper
if (fallback.length) // create new tiddler using primary source name (if any)
addTiddler(src,text,tids.length?tids:[fallback]);
var wrapper=createTiddlyElement(place,"span",null,className);
wikify(substitute(extract(text,tids),args),wrapper); // render
break; // stop processing alternatives
}
}
}
};
//}}}
/***
|Name|InlineJavascriptPlugin|
|Source|http://www.TiddlyTools.com/#InlineJavascriptPlugin|
|Documentation|http://www.TiddlyTools.com/#InlineJavascriptPluginInfo|
|Version|1.9.5|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|Insert Javascript executable code directly into your tiddler content.|
''Call directly into TW core utility routines, define new functions, calculate values, add dynamically-generated TiddlyWiki-formatted output'' into tiddler content, or perform any other programmatic actions each time the tiddler is rendered.
!!!!!Documentation
>see [[InlineJavascriptPluginInfo]]
!!!!!Revisions
<<<
2009.04.11 [1.9.5] pass current tiddler object into wrapper code so it can be referenced from within 'onclick' scripts
2009.02.26 [1.9.4] in $(), handle leading '#' on ID for compatibility with JQuery syntax
|please see [[InlineJavascriptPluginInfo]] for additional revision details|
2005.11.08 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.InlineJavascriptPlugin= {major: 1, minor: 9, revision: 5, date: new Date(2009,4,11)};
config.formatters.push( {
name: "inlineJavascript",
match: "\\<script",
lookahead: "\\<script(?: src=\\\"((?:.|\\n)*?)\\\")?(?: label=\\\"((?:.|\\n)*?)\\\")?(?: title=\\\"((?:.|\\n)*?)\\\")?(?: key=\\\"((?:.|\\n)*?)\\\")?( show)?\\>((?:.|\\n)*?)\\</script\\>",
handler: function(w) {
var lookaheadRegExp = new RegExp(this.lookahead,"mg");
lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = lookaheadRegExp.exec(w.source)
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
var src=lookaheadMatch[1];
var label=lookaheadMatch[2];
var tip=lookaheadMatch[3];
var key=lookaheadMatch[4];
var show=lookaheadMatch[5];
var code=lookaheadMatch[6];
if (src) { // external script library
var script = document.createElement("script"); script.src = src;
document.body.appendChild(script); document.body.removeChild(script);
}
if (code) { // inline code
if (show) // display source in tiddler
wikify("{{{\n"+lookaheadMatch[0]+"\n}}}\n",w.output);
if (label) { // create 'onclick' command link
var link=createTiddlyElement(w.output,"a",null,"tiddlyLinkExisting",wikifyPlainText(label));
var fixup=code.replace(/document.write\s*\(/gi,'place.bufferedHTML+=(');
link.code="function _out(place,tiddler){"+fixup+"\n};_out(this,this.tiddler);"
link.tiddler=w.tiddler;
link.onclick=function(){
this.bufferedHTML="";
try{ var r=eval(this.code);
if(this.bufferedHTML.length || (typeof(r)==="string")&&r.length)
var s=this.parentNode.insertBefore(document.createElement("span"),this.nextSibling);
if(this.bufferedHTML.length)
s.innerHTML=this.bufferedHTML;
if((typeof(r)==="string")&&r.length) {
wikify(r,s,null,this.tiddler);
return false;
} else return r!==undefined?r:false;
} catch(e){alert(e.description||e.toString());return false;}
};
link.setAttribute("title",tip||"");
var URIcode='javascript:void(eval(decodeURIComponent(%22(function(){try{';
URIcode+=encodeURIComponent(encodeURIComponent(code.replace(/\n/g,' ')));
URIcode+='}catch(e){alert(e.description||e.toString())}})()%22)))';
link.setAttribute("href",URIcode);
link.style.cursor="pointer";
if (key) link.accessKey=key.substr(0,1); // single character only
}
else { // run script immediately
var fixup=code.replace(/document.write\s*\(/gi,'place.innerHTML+=(');
var c="function _out(place,tiddler){"+fixup+"\n};_out(w.output,w.tiddler);";
try { var out=eval(c); }
catch(e) { out=e.description?e.description:e.toString(); }
if (out && out.length) wikify(out,w.output,w.highlightRegExp,w.tiddler);
}
}
w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
}
}
} )
//}}}
// // Backward-compatibility for TW2.1.x and earlier
//{{{
if (typeof(wikifyPlainText)=="undefined") window.wikifyPlainText=function(text,limit,tiddler) {
if(limit > 0) text = text.substr(0,limit);
var wikifier = new Wikifier(text,formatter,null,tiddler);
return wikifier.wikifyPlain();
}
//}}}
// // GLOBAL FUNCTION: $(...) -- 'shorthand' convenience syntax for document.getElementById()
//{{{
if (typeof($)=='undefined') { function $(id) { return document.getElementById(id.replace(/^#/,'')); } }
//}}}
[img[sd's mugshot|sd-lr.jpg]]
<<tiddler AboutMe>>
<<tiddler Copyright>>
<<upload>>
<div class='header' macro='gradient vert #eeeeff #8888ff'>
<div class='headerShadow'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
<div class='headerForeground'>
</div>
</div>
<div id='mainMenu' style="width: 250px;">
<div refresh='content' tiddler='MainMenu'></div>
</div>
<div id='sidebar' style="width: 200px;">
<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>
<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>
</div>
<div id='displayArea' style="margin-left: 260px; margin-right: 210px;">
<div id='messageArea'></div>
<div id='tiddlerDisplay'></div>
</div>
/***
|''Name:''|PasswordOptionPlugin|
|''Description:''|Extends TiddlyWiki options with non encrypted password option.|
|''Version:''|1.0.2|
|''Date:''|Apr 19, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#PasswordOptionPlugin|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0 (Beta 5)|
***/
//{{{
version.extensions.PasswordOptionPlugin = {
major: 1, minor: 0, revision: 2,
date: new Date("Apr 19, 2007"),
source: 'http://tiddlywiki.bidix.info/#PasswordOptionPlugin',
author: 'BidiX (BidiX (at) bidix (dot) info',
license: '[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D]]',
coreVersion: '2.2.0 (Beta 5)'
};
config.macros.option.passwordCheckboxLabel = "Save this password on this computer";
config.macros.option.passwordInputType = "password"; // password | text
setStylesheet(".pasOptionInput {width: 11em;}\n","passwordInputTypeStyle");
merge(config.macros.option.types, {
'pas': {
elementType: "input",
valueField: "value",
eventName: "onkeyup",
className: "pasOptionInput",
typeValue: config.macros.option.passwordInputType,
create: function(place,type,opt,className,desc) {
// password field
config.macros.option.genericCreate(place,'pas',opt,className,desc);
// checkbox linked with this password "save this password on this computer"
config.macros.option.genericCreate(place,'chk','chk'+opt,className,desc);
// text savePasswordCheckboxLabel
place.appendChild(document.createTextNode(config.macros.option.passwordCheckboxLabel));
},
onChange: config.macros.option.genericOnChange
}
});
merge(config.optionHandlers['chk'], {
get: function(name) {
// is there an option linked with this chk ?
var opt = name.substr(3);
if (config.options[opt])
saveOptionCookie(opt);
return config.options[name] ? "true" : "false";
}
});
merge(config.optionHandlers, {
'pas': {
get: function(name) {
if (config.options["chk"+name]) {
return encodeCookie(config.options[name].toString());
} else {
return "";
}
},
set: function(name,value) {config.options[name] = decodeCookie(value);}
}
});
// need to reload options to load passwordOptions
loadOptionsCookie();
/*
if (!config.options['pasPassword'])
config.options['pasPassword'] = '';
merge(config.optionsDesc,{
pasPassword: "Test password"
});
*/
//}}}
/***
|Name|Plugin: Scientific Notation|
|Created by|BobMcElrath|
|Email|my first name at my last name dot org|
|Location|http://bob.mcelrath.org/tiddlyjsmath-2.0.3.html|
|Version|1.0|
|Requires|[[TiddlyWiki|http://www.tiddlywiki.com]] ≥ 2.0.3, [[jsMath|http://www.math.union.edu/~dpvc/jsMath/]] ≥ 3.0, [[Plugin: jsMath]]|
!Description
This plugin will render numbers expressed in scientific notation, such as {{{3.5483e12}}} using the jsMath plugin to display it in an intuitive way such as 3.5483e12. You may customize the number of significant figures displayed, as well as "normalize" numbers so that {{{47392.387e9}}} is displayed as 47392.387e9.
!Installation
Install the Requirements, above, add this tiddler to your tiddlywiki, and give it the {{{systemConfig}}} tag.
!History
* 1-Feb-06, version 1.0, Initial release
!Code
***/
//{{{
config.formatters.push({
name: "scientificNotation",
match: "\\b[0-9]+\\.[0-9]+[eE][+-]?[0-9]+\\b",
element: "span",
className: "math",
normalize: true, // set to 'true' to convert numbers to X.XXX \times 10^{y}
sigfigs: 3, // with this many digits in the mantissa
handler: function(w) {
var snRegExp = new RegExp("\\b([0-9]+(?:\\.[0-9]+)?)[eE]([-0-9+]+)\\b");
var mymatch = snRegExp.exec(w.matchText);
var mantissa = mymatch[1];
var exponent = parseInt(mymatch[2]);
// normalize the number.
if(this.normalize) {
mantissa = parseFloat(mantissa);
while(mantissa > 10.0) {
mantissa = mantissa / 10.0;
exponent++;
}
while(mantissa < 1.0) {
mantissa = mantissa * 10.0;
exponent--;
}
var sigfigsleft = this.sigfigs;
mantissa = parseInt(mantissa) + "." + (Math.round(Math.pow(10,this.sigfigs-1)*mantissa)+"").substr(1,this.sigfigs-1);
}
var e = document.createElement(this.element);
e.className = this.className;
if(exponent == 0) {
e.appendChild(document.createTextNode(mantissa));
} else {
e.appendChild(document.createTextNode(mantissa + "\\times 10^{" + exponent + "}"));
}
w.output.appendChild(e);
}
});
//}}}
!Research
My main current research interests are in autonomous and adaptive systems - the area sometimes known as //autonomic computing and communications//. Specifically, this includes
* Sensor networks, especially for environmental sensing and when embedded into materials.
* Adaptive management, using models of the physical world to derive management and control models for systems.
* Pervasive computing, situation recognition and uncertain reasoning.
* Programming in the face of uncertainty, especially as regards integrating uncertain reasoning into middleware, platforms and programming languages.
My [[research notebook|research.html]] is on-line, as an experiment in [[open notebook science|http://en.wikipedia.org/wiki/Open_notebook_science]].
<script>
var list='journal';
var sortby='-modified';
var max = 5;
var fn=store.getMatchingTiddlers||store.getTaggedTiddlers;
var tagged=store.sortTiddlers(fn.apply(store,[list]),sortby);
if(tagged.length > max) tagged = tagged.slice(1,max);
story.displayTiddlers('top', tagged, null, false);
story.closeTiddler('ShowRecentJournalEntries', false);
</script>
Aut tace aut loquere meliora silentio
/***
Home page theme
Modified from DevFireTheme by Simon Dobson
***/
/*{{{*/
body {
background: #eeeeff;
font-size: 9pt;
}
/*}}}*/
/***
!Link styles /% ============================================================= %/
***/
/*{{{*/
a,
a.button,
#mainMenu a.button,
#sidebarOptions .sliderPanel a{
color: #6699cc;
border: 0;
background: transparent;
}
a:hover,
a.button:hover,
#mainMenu a.button:hover,
#sidebarOptions .sliderPanel a:hover
#sidebarOptions .sliderPanel a:active{
color: #4444ff;
border: 0;
border-bottom: #4444ff 1px dashed;
background: transparent;
text-decoration: none;
}
#displayArea .button.highlight{
color: #4444ff;
background: #ddddff;
}
/*}}}*/
/***
!Header styles /% ============================================================= %/
***/
/*{{{*/
.header {
border-bottom: 2px solid #8888ff;
color: #444444;
}
.headerForeground a {
color: #444444;
}
.header a:hover {
border-bottom: 1px dashed #ddddff;
}
.siteTitle {
font-size: 3em;
color: #444444;
text-decoration: none;
font-weight: bold;
}
.siteSubtitle {
font-size: 1.1em;
color: #444444;
text-decoration: none;
font-weight: normal;
}
/*}}}*/
/***
!Main menu styles /% ============================================================= %/
***/
/*{{{*/
#mainMenu {color: #444444; padding: 0em 0em 0em 1em; text-align: left; font-size: 9pt;}
#mainMenu h1{
color: #34353e;
font-size: 1.1em;
}
#mainMenu li,#mainMenu ul{
list-style: none;
margin: 0;
padding: 0;
}
/*}}}*/
/***
!Sidebar styles /% ============================================================= %/
***/
/*{{{*/
#sidebar {
right: 0;
color: #444444;
padding: 0em 1em 0em 0em;
border: 2px solid #8888ff;
border-width: 0 0 2px 2px;
font-size: 9pt;
}
#sidebarOptions {
background-color: #eeeeff;
padding: 0;
}
#sidebarOptions a{
margin: 0;
color: #6699cc;
border: 0;
}
#sidebarOptions a:hover {
color: #4c4c4c;
}
#sidebarOptions a:active {
color: #ffbf00;
background-color: transparent;
}
#sidebarOptions .sliderPanel {
background-color: #ddddff;
margin: 0;
}
#sidebarTabs {background-color: #eeeeff;}
#sidebarTabs .tabSelected {
padding: 3px 3px;
cursor: default;
color: #444444;
background-color: #ddddff;
}
#sidebarTabs .tabUnselected {
color: #444444;
background-color: #eeeeff;
padding: 0 4px;
}
#sidebarTabs .tabUnselected:hover,
#sidebarTabs .tabContents {
background-color: #ddddff;
}
.listTitle{color: #444444;}
#sidebarTabs .tabContents a{
color: #444444;
}
#sidebarTabs .tabContents a:hover{
color: #4444ff;
background: transparent;
}
#sidebarTabs .txtMoreTab .tabSelected,
#sidebarTabs .txtMoreTab .tab:hover,
#sidebarTabs .txtMoreTab .tabContents{
color: #444444;
background: #ddddff;
}
#sidebarTabs .txtMoreTab .tabUnselected {
color: #444444;
background: #ddddff;
}
.tab.tabSelected, .tab.tabSelected:hover{color: #444444; border: 0; background-color: #eeeeff;cursor:default;}
.tab.tabUnselected {background-color: #eeeeff;}
.tab.tabUnselected:hover{color:#eeeeff; border: 0;background-color: #4444ff;}
.tabContents {
background-color: #eeeeff;
border: 0;
}
.tabContents .tabContents{background: #ddddff;}
.tabContents .tabSelected{background: #ddddff;}
.tabContents .tabUnselected{background: #eeeeff;}
.tabContents .tab:hover{background: #eeeeff;}
/*}}}*/
/***
!Message area styles /% ============================================================= %/
***/
/*{{{*/
#messageArea {background-color: #ddddff; color: #fff; border: 2px solid #8888ff;}
#messageArea a:link, #messageArea a:visited {color: #ffbf00; text-decoration:none;}
#messageArea a:hover {color: #ff7f00;}
#messageArea a:active {color: #ff7f00;}
#messageArea .messageToolbar a{
border: 1px solid #8888ff;
background: #ddddff;
}
/*}}}*/
/***
!Popup styles /% ============================================================= %/
***/
/*{{{*/
.popup {color: #444444; background-color: #ddddff; border: 1px solid #8888ff;}
.popup li.disabled{color: #444444;}
.popup a {color: #6699cc; }
.popup a:hover { background: transparent; color: #4444ff; border: 0;}
.popup hr {color: #ffbf00; background: #ffbf00;}
/*}}}*/
/***
!Tiddler Display styles /% ============================================================= %/
***/
/*{{{*/
.title{color: #444444; font-size: 1.1em;}
h1, h2, h3, h4, h5 {
color: #444444;
background-color: transparent;
border-bottom: 1px solid #444444;
}
.subtitle{
font-size: 0.9em;
color: #444444;
}
.viewer {color: #444444; font-size: 9pt; }
.viewer table{background: #ddddff; color: #444444;}
.viewer th {background-color: #ddddff; color: #444444;}
.viewer pre, .viewer code {font-size: 1em; color: #444444; background-color: #ddddff; border: 1px solid #8888ff;}
.viewer hr {color: #444444;}
.tiddler .button {color: #6699cc;}
.tiddler .button:hover { color: #4444ff; background-color: #eeeeff;}
.tiddler .button:active {color: #4444ff; background-color: #eeeeff;}
.toolbar {
color: #444444;
}
.toolbar a.button,
.toolbar a.button:hover,
.toolbar a.button:active,
.editorFooter a{
border: 0;
}
.footer {
color: #444444;
}
.selected .footer {
color: #4444ff;
}
.highlight, .marked {
color: #000;
background-color: #ffffff;
}
.editorFooter {
color: #444444;
}
.tab{
-moz-border-radius-topleft: 3px;
-moz-border-radius-topright: 3px;
}
.tagging,
.tagged{
background: #ddddff;
border: 1px solid #8888ff;
}
.selected .tagging,
.selected .tagged{
background-color: #ddddff;
border: 1px solid #8888ff;
}
.tagging .listTitle,
.tagged .listTitle{
color: #444444;
}
.tagging .button,
.tagged .button{
color: #444444;
border: 0;
padding: 0;
}
.tagging .button:hover,
.tagged .button:hover{
background: transparent;
}
.selected .isTag .tagging.simple,
.selected .tagged.simple,
.isTag .tagging.simple,
.tagged.simple {
float: none;
display: inline;
border: 0;
background: transparent;
color: #444444;
margin: 0;
}
.cascade {
background: #ddddff;
color: #444444;
border: 1px solid #8888ff;
}
/*}}}*/
/***
!jsMath styles /% ============================================================= %/
***/
/*{{{*/
.viewer {
line-height: 125%;
font-family: serif;
font-size: 9pt;
}
/*}}}*/
!System monitoring with metric-correlation models: problems and solutions
Rapid fault diagnosis in enterprise-scale systems
* Long-term invariants and correlations break when fault occurs
* Linear models (again) - but the majority of correlations //are// linear
Critical factors affecting the effectiveness of linear models
* Varying coefficients: coefficients of model change over time
* Multi-variable correlations: high cost of identification $O(n^k)$
* Missing variables: strong correlations can appear that are actually dependent on another, unobserved variable
* Non-constant residual variance (heteroscedasticity): variance varies with value, typically increasing, while still showing a clear linear trend; violates key assumptions of many techniques (//e.g.// constant errors), confidence intervals become invalid; but can be a very strong signal of the existence of varying coefficients and missing variables
Detecting non-constant residual error: White test, Goldfeld-Quandt test, ...
Generalised least squares can model linear systems with heteroscedastcity
* Learn the coefficients offline
* Use sliding windows (Wilcoxon rank-sum test) to look for varying coefficients: large windows lead to more false positives and longer assessment delays
Miao Jiang, Mohammad Munawar, Thomas Reidemeister and Paul Ward. System monitoring with metric-correlation models: problems and solutions. In Proceedings of the 6th International Conference on Autonomic Computing and Communciations. Barcelona ES. ACM Press. 2009.
<<cloud tags systemConfig systemConfigDisable sdTheme DiscoveryPackage TiddlyHomeSystem systemTiddlers toRSS AttachFilePackage Doc settings systemServer pluginInfo NavigationPackage news News navigation upload IconPackage ThemePackage WoodshopPackage Upload ImportExportPackage excludeMissing temporary attachment image>>
/***
|Name|TagCloudPlugin|
|Source|http://www.TiddlyTools.com/#TagCloudPlugin|
|Version|1.6.0|
|Author|Eric Shulman|
|Original Author|Clint Checketts|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|present a 'cloud' of tags (or links) using proportional font display|
!Usage
<<<
{{{
<<cloud type action:... limit:... tag tag tag ...>>
<<cloud type action:... limit:... +TiddlerName>>
<<cloud type action:... limit:... =tagvalue>>
}}}
where:
* //type// is a keyword, one of:
** ''tags'' (default) - displays a cloud of tags, based on frequency of use
** ''links'' - displays a cloud of tiddlers, based on number of links //from// each tiddler
** ''references'' - displays a cloud of tiddlers, based on number of links //to// each tiddler
* ''action:popup'' (default) - clicking a cloud item shows a popup with links to related tiddlers<br>//or//<br> ''action:goto'' - clicking a cloud item immediately opens the tiddler corresponding to that item
* ''limit:N'' (optional) - restricts the cloud display to only show the N most popular tags/links
* ''tag tag tag...'' (or ''title title title'' if ''links''/''references'' is used)<br>shows all tags/links in the document //except// for those listed as macro parameters
* ''+TiddlerName''<br>shows tags/links read from a space-separated, bracketed list stored in a separate tiddler.
* ''=tagvalue'' (//only if type=''tags''//)<br>shows only tags that are themselves tagged with the indicated tag value (i.e., ~TagglyTagging usage)
//note: for backward-compatibility, you can also use the macro {{{<<tagCloud ...>>}}} in place of {{{<<cloud ...>>}}}//
<<<
!Examples
<<<
//all tags excluding<<tag systemConfig>>, <<tag excludeMissing>> and <<tag script>>//
{{{<<cloud systemConfig excludeMissing script>>}}}
{{groupbox{<<cloud systemConfig excludeMissing script>>}}}
//top 10 tags excluding<<tag systemConfig>>, <<tag excludeMissing>> and <<tag script>>//
{{{<<cloud limit:10 systemConfig excludeMissing script>>}}}
{{groupbox{<<cloud limit:10 systemConfig excludeMissing script>>}}}
//tags listed in// [[FavoriteTags]]
{{{<<cloud +FavoriteTags>>}}}
{{groupbox{<<cloud +FavoriteTags>>}}}
//links to tiddlers tagged with 'package'//
{{{<<cloud action:goto =package>>}}}
{{groupbox{<<cloud action:goto =package>>}}}
//top 20 most referenced tiddlers//
{{{<<cloud references limit:20>>}}}
{{groupbox{<<cloud references limit:20>>}}}
//top 20 tiddlers that contain the most links//
{{{<<cloud links limit:20>>}}}
{{groupbox{<<cloud links limit:20>>}}}
<<<
!Revisions
<<<
2009.02.26 [1.6.0] added {{{action:...}}} parameter to apply popup vs. goto action when clicking cloud items
2009.02.05 [1.5.0] added ability to show links or back-links (references) instead of tags and renamed macro to {{{<<cloud>>}}} to reflect more generalized usage.
2008.12.16 [1.4.2] corrected group calculation to prevent 'group=0' error
2008.12.16 [1.4.1] revised tag filtering so excluded tags don't affect calculations
2008.12.15 [1.4.0] added {{{limit:...}}} parameter to restrict the number of tags displayed to the top N most popular
2008.11.15 [1.3.0] added {{{+TiddlerName}}} parameter to include only tags that are listed in the indicated tiddler
2008.09.05 [1.2.0] added '=tagname' parameter to include only tags that are themselves tagged with the specified value (i.e., ~TagglyTagging usage)
2008.07.03 [1.1.0] added 'segments' property to macro object. Extensive code cleanup
<<<
!Code
***/
//{{{
version.extensions.TagCloudPlugin= {major: 1, minor: 6 , revision: 0, date: new Date(2009,2,26)};
//Originally created by Clint Checketts, contributions by Jonny Leroy and Eric Shulman
//Currently maintained and enhanced by Eric Shulman
//}}}
//{{{
config.macros.cloud = {
tagstip: "%1 tiddlers tagged with '%0'",
refslabel: " (%0 references)",
refstip: "%1 tiddlers have links to '%0'",
linkslabel: " (%0 links)",
linkstip: "'%0' has links to %1 other tiddlers",
groups: 9,
init: function() {
config.macros.tagCloud=config.macros.cloud; // for backward-compatibility
config.shadowTiddlers.TagCloud='<<cloud>>';
config.shadowTiddlers.StyleSheetTagCloud=
'/*{{{*/\n'
+'.tagCloud span {line-height: 3.5em; margin:3px;}\n'
+'.tagCloud1{font-size: 80%;}\n'
+'.tagCloud2{font-size: 100%;}\n'
+'.tagCloud3{font-size: 120%;}\n'
+'.tagCloud4{font-size: 140%;}\n'
+'.tagCloud5{font-size: 160%;}\n'
+'.tagCloud6{font-size: 180%;}\n'
+'.tagCloud7{font-size: 200%;}\n'
+'.tagCloud8{font-size: 220%;}\n'
+'.tagCloud9{font-size: 240%;}\n'
+'/*}}}*/\n';
setStylesheet(store.getTiddlerText('StyleSheetTagCloud'),'tagCloudsStyles');
},
getLinks: function(tiddler) { // get list of links to existing tiddlers and shadows
if (!tiddler.linksUpdated) tiddler.changed();
var list=[]; for (var i=0; i<tiddler.links.length; i++) {
var title=tiddler.links[i];
if (store.isShadowTiddler(title)||store.tiddlerExists(title))
list.push(title);
}
return list;
},
handler: function(place,macroName,params) {
// unpack params
var inc=[]; var ex=[]; var limit=0; var action='popup';
var links=(params[0]&¶ms[0].toLowerCase()=='links'); if (links) params.shift();
var refs=(params[0]&¶ms[0].toLowerCase()=='references'); if (refs) params.shift();
if (params[0]&¶ms[0].substr(0,7).toLowerCase()=='action:')
action=params.shift().substr(7).toLowerCase();
if (params[0]&¶ms[0].substr(0,6).toLowerCase()=='limit:')
limit=parseInt(params.shift().substr(6));
if (params.length) {
if (params[0].substr(0,1)=='+') { // get tag list from tiddler
var inc=store.getTiddlerText(params[0].substr(1),'').readBracketedList();
} else if (params[0].substr(0,1)=='=') { // get tag list using tagged tags
var tagged=store.getTaggedTiddlers(params[0].substr(1));
for (var t=0; t<tagged.length; t++) inc.push(tagged[t].title);
} else ex=params; // exclude params
}
// get all items, include/exclude specific items
var items=[];
var list=(links||refs)?store.getTiddlers('title','excludeLists'):store.getTags();
for (var t=0; t<list.length; t++) {
var title=(links||refs)?list[t].title:list[t][0];
if (links) var count=this.getLinks(list[t]).length;
else if (refs) var count=store.getReferringTiddlers(title).length;
else var count=list[t][1];
if ((!inc.length||inc.contains(title))&&(!ex.length||!ex.contains(title)))
items.push({ title:title, count:count });
}
if(!items.length) return;
// sort by decending count, limit results (optional)
items=items.sort(function(a,b){return(a.count==b.count)?0:(a.count>b.count?-1:1);});
while (limit && items.length>limit) items.pop();
// find min/max and group size
var most=items[0].count;
var least=items[items.length-1].count;
var groupSize=(most-least+1)/this.groups;
// sort by title and draw the cloud of items
items=items.sort(function(a,b){return(a.title==b.title)?0:(a.title>b.title?1:-1);});
var cloudWrapper = createTiddlyElement(place,'div',null,'tagCloud',null);
for (var t=0; t<items.length; t++) {
cloudWrapper.appendChild(document.createTextNode(' '));
var group=Math.ceil((items[t].count-least)/groupSize)||1;
var className='tagCloudtag tagCloud'+group;
var tip=refs?this.refstip:links?this.linkstip:this.tagstip;
tip=tip.format([items[t].title,items[t].count]);
if (action=='goto') { // TAG/LINK/REFERENCES GOTO
var btn=createTiddlyLink(cloudWrapper,items[t].title,true,className);
btn.title=tip;
btn.style.fontWeight='normal';
} else if (!links&&!refs) { // TAG POPUP
var btn=createTiddlyButton(cloudWrapper,items[t].title,tip,onClickTag,className);
btn.setAttribute('tag',items[t].title);
} else { // LINK/REFERENCES POPUP
var btn=createTiddlyButton(cloudWrapper,items[t].title,tip,
function(ev) { var e=ev||window.event; var cmt=config.macros.cloud;
var popup = Popup.create(this);
var title = this.getAttribute('tiddler');
var count = this.getAttribute('count');
var refs = this.getAttribute('refs')=='T';
var links = this.getAttribute('links')=='T';
var label = (refs?cmt.refslabel:cmt.linkslabel).format([count]);
createTiddlyLink(popup,title,true);
createTiddlyText(popup,label);
createTiddlyElement(popup,'hr');
if (refs) {
popup.setAttribute('tiddler',title);
config.commands.references.handlePopup(popup,title);
}
if (links) {
var tiddler = store.fetchTiddler(title);
var links=config.macros.cloud.getLinks(tiddler);
for(var i=0;i<links.length;i++)
createTiddlyLink(createTiddlyElement(popup,'li'),
links[i],true);
}
Popup.show();
e.cancelBubble=true; if(e.stopPropagation) e.stopPropagation();
return false;
}, className);
btn.setAttribute('tiddler',items[t].title);
btn.setAttribute('count',items[t].count);
btn.setAttribute('refs',refs?'T':'F');
btn.setAttribute('links',links?'T':'F');
btn.title=tip;
}
}
}
};
//}}}
/***
|Name|TemporaryTiddlersPlugin|
|Source|http://www.TiddlyTools.com/#TemporaryTiddlersPlugin|
|Version|1.1.2|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides|SaverBase.prototype.externalize()|
|Options|##Configuration|
|Description|blocks tiddlers tagged with "temporary" from being saved into the TW file|
!!!!!Usage
<<<
When the TW document is saved (either to local disk or remote URL), any tiddlers tagged with "temporary" will be skipped over, so that they are not written to the file. To keep a temporary tiddler, simply edit it and remove the tag before saving the file. This feature can be combined with various plugins that can automatically create new tiddlers, such as [[SearchOptionsPlugin]] ([[SearchResults]]) and [[ImportTiddlersPlugin]] ([[ImportedTiddlers]]) so that these transient results are not retained when you save you document.
You can also use this tag with the {{{<<loadTiddlers>>}}} macro and the //auto-tagging// features provided by [[ImportTiddlersPlugin]], so that each time you open your document, you can automatically retrieve an up-to-date set of common tiddlers that are stored in another document (either local or via remote URL), without those tiddlers being retained when you save your document.
<<<
!!!!!Configuration
<<<
When saving the document:
<<option chkTemporaryQuiet>> Suppress reporting of individual temporary tiddlers that have not been saved
<<option chkTemporaryKeep>> Keep temporary tiddlers (i.e., ignore the 'temporary' tag)
Enter a tag value to use when marking tiddlers as temporary: <<option txtTemporaryTag>>
<<<
!!!!!Revisions
<<<
2008.11.14 [1.1.2] added "nnn temporary tiddlers not saved" summary message
2008.04.08 [1.1.1] don't automatically add configuration options to AdvancedOptions tiddler
2008.03.01 [1.1.0] added support for recognizing 'temporary' flag stored as a tiddler *field* (as an optional alternative to using a tag)
2007.02.08 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.TemporaryTiddlersPlugin= {major: 1, minor: 1, revision: 2, date: new Date(2008,11,14)};
// configuration defaults
if (config.options.chkTemporaryKeep ==undefined) config.options.chkTemporaryKeep =false;
if (config.options.chkTemporaryQuiet==undefined) config.options.chkTemporaryQuiet=true;
if (config.options.txtTemporaryTag==undefined) config.options.txtTemporaryTag="temporary";
// lingo
config.messages.TemporaryWarning = "'%0' ...temporary tiddler";
config.messages.TemporarySummary = "%0 temporary tiddlers will not be saved";
// core override
SaverBase.prototype.externalize = function(store)
{
var results=[]; var totaltemps=0;
var tiddlers=store.getTiddlers("title");
for (var t=0; t<tiddlers.length; t++) {
if (config.options.chkTemporaryKeep||!(tiddlers[t].fields['temporary']||tiddlers[t].isTagged(config.options.txtTemporaryTag)))
results.push(this.externalizeTiddler(store, tiddlers[t]));
else {
if (!config.options.chkTemporaryQuiet) // notify user that tiddler won't be saved
displayMessage(config.messages.TemporaryWarning.format([tiddlers[t].title]));
totaltemps++;
}
}
if (totaltemps) displayMessage(config.messages.TemporarySummary.format([totaltemps]));
return results.join("\n");
}
//}}}
/***
|''Name:''|TiddlerNotesPlugin|
|''Description:''|Add notes to tiddlers without modifying the original content|
|''Author:''|Saq Imtiaz ( lewcid@gmail.com )|
|''Source:''|http://tw.lewcid.org/#TiddlerNotesPlugin|
|''Code Repository:''|http://tw.lewcid.org/svn/plugins|
|''Version:''|2.1|
|''Date:''|26/10/07|
|''License:''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|''~CoreVersion:''|2.2.3|
!!Concept:
*The TiddlerNotesPlugin allows you to add notes to tiddlers, without needing to edit the original tiddler. This means that your original content will remain unaltered, and if you update it in the future, you won’t lose your notes. Notes are stored in separate tiddlers, but can be viewed and edited from within the original tiddler.
*For a tiddler titled "~MySlide", the notes are by default saved in a tiddler titled "~MySlide-Notes" and is given a tag of "Notes". The suffix and tags of the notes tiddlers are customizable. You can have one or multiple notes per tiddlers. So it is possible to have for example, teacher's notes and student's notes in the same file.
*Notes can be configured to start off blank, or pre-filled with the contents of the original tiddler.
!!Usage:
*{{{<<notes>>}}} is the simplest usage form.
* additional optional parameters include:
**{{{heading:}}} the heading to use for the notes box
**{{{tag:}}} the tag to be given to the notes tiddler
**{{{suffix:}}} the suffix to be used when naming the notes tiddler
* a full macro call could look like: {{{<<notes heading:"My Notes" tag:"NoteTiddlers" suffix:"Comments">>}}}
* To avoid adding {{{<<notes>>}}} to each tiddler you want notes for, you could add the macro call to the ViewTemplate
** below the line {{{<div class='viewer' macro='view text wikified'></div>}}} add the following line: <br> {{{<div class='viewer' macro='notes'></div>}}}
** Used in combination with the ~HideWhenPlugin or ~PublisherPlugin, you could have notes be shown only for tiddlers with specific tags. The ~PublisherPlugin would allow you for instance to only have the ~TeachersNotes visible to the teacher, and the ~StudentsNotes for the same tiddler visible to the Student.
!!Configuration
*<<option chkPrefillNotes>> Enable to pre-fill notes with the original tiddler's contents
!!Demo:
* [[MySlide]]
***/
// /%
//!BEGIN-PLUGIN-CODE
if (!config.options.chkPrefillNotes)
config.options.chkPrefillNotes = false;
function createTiddlyElement(theParent,theElement,theID,theClass,theText,attribs)
{
var e = document.createElement(theElement);
if(theClass != null)
e.className = theClass;
if(theID != null)
e.setAttribute("id",theID);
if(theText != null)
e.appendChild(document.createTextNode(theText));
if(attribs){
for(var n in attribs){
e.setAttribute(n,attribs[n]);
}
}
if(theParent != null)
theParent.appendChild(e);
return e;
}
function createTiddlyButton(theParent,theText,theTooltip,theAction,theClass,theId,theAccessKey,attribs)
{
var theButton = document.createElement("a");
if(theAction) {
theButton.onclick = theAction;
theButton.setAttribute("href","javascript:;");
}
if(theTooltip)
theButton.setAttribute("title",theTooltip);
if(theText)
theButton.appendChild(document.createTextNode(theText));
if(theClass)
theButton.className = theClass;
else
theButton.className = "button";
if(theId)
theButton.id = theId;
if(attribs){
for(var n in attribs){
e.setAttribute(n,attribs[n]);
}
}
if(theParent)
theParent.appendChild(theButton);
if(theAccessKey)
theButton.setAttribute("accessKey",theAccessKey);
return theButton;
}
config.macros.notes={
cancelWarning: "Are you sure you want to abandon changes to your notes for '%0'?",
editLabel: "edit notes",
editTitle: "double click to edit",
saveLabel: "save notes",
saveTitle: "double click to save",
cancelLabel: "cancel",
heading: "Notes",
suffix: "Notes",
tag: "Notes",
saveNotes: function(ev){
e = ev? ev : window.event;
var theTarget = resolveTarget(e);
if (theTarget.nodeName.toLowerCase() == "textarea")
return false;
var title = story.findContainingTiddler(theTarget).getAttribute("tiddler");
story.setDirty(title,false);
var box = document.getElementById("notesContainer"+title);
var textarea = document.getElementById("notesTextArea"+title);
if(textarea.getAttribute("oldText")!=textarea.value && !hasClass(theTarget,"cancelNotesButton")){
var suffix = box.getAttribute("suffix");
var t = store.getTiddler(title+"-"+suffix);
store.saveTiddler(title+"-"+suffix,title+"-"+suffix,textarea.value,config.options.txtUserName,new Date(),t?t.tags:box.getAttribute("tag"),t?t.fields:{});
}
story.refreshTiddler(title,1,true);
autoSaveChanges(true);
return false;
},
editNotes: function(box,tiddler){
removeChildren(box);
story.setDirty(tiddler,true);
box.title = this.saveTitle;
box.ondblclick = this.saveNotes;
createTiddlyButton(box,this.cancelLabel,this.cancelLabel,this.saveNotes,"cancelNotesButton");
createTiddlyButton(box,this.saveLabel,this.saveLabel,this.saveNotes,"saveNotesButton");
wikify("!!"+box.getAttribute("heading")+"\n",box);
addClass(box,"editor");
var wrapper1 = createTiddlyElement(null,"fieldset",null,"fieldsetFix");
var wrapper2 = createTiddlyElement(wrapper1,"div");
var e = createTiddlyElement(wrapper2,"textarea","notesTextArea"+tiddler);
var v = store.getValue(tiddler+"-"+box.getAttribute("suffix"),"text");
if(!v)
v = config.options.chkPrefillNotes? store.getValue(tiddler,"text"):'';
e.value = v;
e.setAttribute("oldText",v);
var rows = 10;
var lines = v.match(/\n/mg);
var maxLines = Math.max(parseInt(config.options.txtMaxEditRows),5);
if(lines != null && lines.length > rows)
rows = lines.length + 5;
rows = Math.min(rows,maxLines);
e.setAttribute("rows",rows);
box.appendChild(wrapper1);
},
editNotesButtonOnclick: function(e){
var title = story.findContainingTiddler(this).getAttribute("tiddler");
var box = document.getElementById("notesContainer"+title);
config.macros.notes.editNotes(box,title);
return false;
},
ondblclick : function(ev){
e = ev? ev : window.event;
var theTarget = resolveTarget(e);
var title = story.findContainingTiddler(theTarget).getAttribute("tiddler");
var box = document.getElementById("notesContainer"+title);
config.macros.notes.editNotes(box,title);
e.cancelBubble = true;
if(e.stopPropagation) e.stopPropagation();
return false;
},
handler : function(place,macroName,params,wikifier,paramString,tiddler){
params = paramString.parseParams("anon",null,true,false,false);
var heading = getParam(params,"heading",this.heading);
var tag = getParam(params,"tag",this.tag);
var suffix = getParam(params,"suffix",this.suffix);
var box = createTiddlyElement(place,"div","notesContainer"+tiddler.title,"TiddlerNotes",null,{"source":tiddler.title,params:paramString,heading:heading,tag:tag,suffix:suffix});
createTiddlyButton(box,this.editLabel,this.editLabel,this.editNotesButtonOnclick,"editNotesButton");
wikify("!!"+heading+"\n",box);
box.title=this.editTitle;
box.ondblclick = this.ondblclick;
wikify("<<tiddler [["+tiddler.title+"-"+suffix+"]]>>",box);
}
};
Story.prototype.old_notes_closeTiddler = Story.prototype.closeTiddler;
Story.prototype.closeTiddler = function(title,animate,unused){
if(story.isDirty(title)) {
if(!confirm(config.macros.notes.cancelWarning.format([title])))
return false;
}
return this.old_notes_closeTiddler.apply(this,arguments);
}
setStylesheet(".TiddlerNotes {\n"+ " background:#eee;\n"+ " border:1px solid #ccc;\n"+ " padding:10px;\n"+ " margin:15px;\n"+ "}\n"+ "\n"+ ".cancelNotesButton,.editNotesButton, .saveNotesButton {\n"+ " float:right;\n"+ " border:1px solid #ccc;\n"+ " padding:2px 5px;\n"+ "}\n"+ "\n"+ ".saveNotesButton{\n"+ " margin-right:0.5em;\n"+ "}\n"+ "\n"+ ".TiddlerNotes.editor textarea{\n"+ " border:1px solid #ccc;\n"+ "}","NotesPluginStyles");
//!END-PLUGIN-CODE
// %/
| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |
| 26/06/2009 17:59:50 | sd | [[index.html|file:///Users/sd/research/notebook/index.html]] | [[store.php|http://www.simondobson.org/store.php]] | . | [[index.html | http://www.simondobson.org/index.html]] | |
/***
|''Name:''|UploadPlugin|
|''Description:''|Save to web a TiddlyWiki|
|''Version:''|4.1.4|
|''Date:''|2008-08-11|
|''Source:''|http://tiddlywiki.bidix.info/#UploadPlugin|
|''Documentation:''|http://tiddlywiki.bidix.info/#UploadPluginDoc|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0|
|''Requires:''|PasswordOptionPlugin|
***/
//{{{
version.extensions.UploadPlugin = {
major: 4, minor: 1, revision: 4,
date: new Date("2008-08-11"),
source: 'http://tiddlywiki.bidix.info/#UploadPlugin',
author: 'BidiX (BidiX (at) bidix (dot) info',
coreVersion: '2.2.0'
};
//
// Environment
//
if (!window.bidix) window.bidix = {}; // bidix namespace
bidix.debugMode = false; // true to activate both in Plugin and UploadService
//
// Upload Macro
//
config.macros.upload = {
// default values
defaultBackupDir: '', //no backup
defaultStoreScript: "store.php",
defaultToFilename: "index.html",
defaultUploadDir: ".",
authenticateUser: true // UploadService Authenticate User
};
config.macros.upload.label = {
promptOption: "Save and Upload this TiddlyWiki with UploadOptions",
promptParamMacro: "Save and Upload this TiddlyWiki in %0",
saveLabel: "save to web",
saveToDisk: "save to disk",
uploadLabel: "upload"
};
config.macros.upload.messages = {
noStoreUrl: "No store URL in parmeters or options",
usernameOrPasswordMissing: "Username or password missing"
};
config.macros.upload.handler = function(place,macroName,params) {
if (readOnly)
return;
var label;
if (document.location.toString().substr(0,4) == "http")
label = this.label.saveLabel;
else
label = this.label.uploadLabel;
var prompt;
if (params[0]) {
prompt = this.label.promptParamMacro.toString().format([this.destFile(params[0],
(params[1] ? params[1]:bidix.basename(window.location.toString())), params[3])]);
} else {
prompt = this.label.promptOption;
}
createTiddlyButton(place, label, prompt, function() {config.macros.upload.action(params);}, null, null, this.accessKey);
};
config.macros.upload.action = function(params)
{
// for missing macro parameter set value from options
if (!params) params = {};
var storeUrl = params[0] ? params[0] : config.options.txtUploadStoreUrl;
var toFilename = params[1] ? params[1] : config.options.txtUploadFilename;
var backupDir = params[2] ? params[2] : config.options.txtUploadBackupDir;
var uploadDir = params[3] ? params[3] : config.options.txtUploadDir;
var username = params[4] ? params[4] : config.options.txtUploadUserName;
var password = config.options.pasUploadPassword; // for security reason no password as macro parameter
// for still missing parameter set default value
if ((!storeUrl) && (document.location.toString().substr(0,4) == "http"))
storeUrl = bidix.dirname(document.location.toString())+'/'+config.macros.upload.defaultStoreScript;
if (storeUrl.substr(0,4) != "http")
storeUrl = bidix.dirname(document.location.toString()) +'/'+ storeUrl;
if (!toFilename)
toFilename = bidix.basename(window.location.toString());
if (!toFilename)
toFilename = config.macros.upload.defaultToFilename;
if (!uploadDir)
uploadDir = config.macros.upload.defaultUploadDir;
if (!backupDir)
backupDir = config.macros.upload.defaultBackupDir;
// report error if still missing
if (!storeUrl) {
alert(config.macros.upload.messages.noStoreUrl);
clearMessage();
return false;
}
if (config.macros.upload.authenticateUser && (!username || !password)) {
alert(config.macros.upload.messages.usernameOrPasswordMissing);
clearMessage();
return false;
}
bidix.upload.uploadChanges(false,null,storeUrl, toFilename, uploadDir, backupDir, username, password);
return false;
};
config.macros.upload.destFile = function(storeUrl, toFilename, uploadDir)
{
if (!storeUrl)
return null;
var dest = bidix.dirname(storeUrl);
if (uploadDir && uploadDir != '.')
dest = dest + '/' + uploadDir;
dest = dest + '/' + toFilename;
return dest;
};
//
// uploadOptions Macro
//
config.macros.uploadOptions = {
handler: function(place,macroName,params) {
var wizard = new Wizard();
wizard.createWizard(place,this.wizardTitle);
wizard.addStep(this.step1Title,this.step1Html);
var markList = wizard.getElement("markList");
var listWrapper = document.createElement("div");
markList.parentNode.insertBefore(listWrapper,markList);
wizard.setValue("listWrapper",listWrapper);
this.refreshOptions(listWrapper,false);
var uploadCaption;
if (document.location.toString().substr(0,4) == "http")
uploadCaption = config.macros.upload.label.saveLabel;
else
uploadCaption = config.macros.upload.label.uploadLabel;
wizard.setButtons([
{caption: uploadCaption, tooltip: config.macros.upload.label.promptOption,
onClick: config.macros.upload.action},
{caption: this.cancelButton, tooltip: this.cancelButtonPrompt, onClick: this.onCancel}
]);
},
options: [
"txtUploadUserName",
"pasUploadPassword",
"txtUploadStoreUrl",
"txtUploadDir",
"txtUploadFilename",
"txtUploadBackupDir",
"chkUploadLog",
"txtUploadLogMaxLine"
],
refreshOptions: function(listWrapper) {
var opts = [];
for(i=0; i<this.options.length; i++) {
var opt = {};
opts.push();
opt.option = "";
n = this.options[i];
opt.name = n;
opt.lowlight = !config.optionsDesc[n];
opt.description = opt.lowlight ? this.unknownDescription : config.optionsDesc[n];
opts.push(opt);
}
var listview = ListView.create(listWrapper,opts,this.listViewTemplate);
for(n=0; n<opts.length; n++) {
var type = opts[n].name.substr(0,3);
var h = config.macros.option.types[type];
if (h && h.create) {
h.create(opts[n].colElements['option'],type,opts[n].name,opts[n].name,"no");
}
}
},
onCancel: function(e)
{
backstage.switchTab(null);
return false;
},
wizardTitle: "Upload with options",
step1Title: "These options are saved in cookies in your browser",
step1Html: "<input type='hidden' name='markList'></input><br>",
cancelButton: "Cancel",
cancelButtonPrompt: "Cancel prompt",
listViewTemplate: {
columns: [
{name: 'Description', field: 'description', title: "Description", type: 'WikiText'},
{name: 'Option', field: 'option', title: "Option", type: 'String'},
{name: 'Name', field: 'name', title: "Name", type: 'String'}
],
rowClasses: [
{className: 'lowlight', field: 'lowlight'}
]}
};
//
// upload functions
//
if (!bidix.upload) bidix.upload = {};
if (!bidix.upload.messages) bidix.upload.messages = {
//from saving
invalidFileError: "The original file '%0' does not appear to be a valid TiddlyWiki",
backupSaved: "Backup saved",
backupFailed: "Failed to upload backup file",
rssSaved: "RSS feed uploaded",
rssFailed: "Failed to upload RSS feed file",
emptySaved: "Empty template uploaded",
emptyFailed: "Failed to upload empty template file",
mainSaved: "Main TiddlyWiki file uploaded",
mainFailed: "Failed to upload main TiddlyWiki file. Your changes have not been saved",
//specific upload
loadOriginalHttpPostError: "Can't get original file",
aboutToSaveOnHttpPost: 'About to upload on %0 ...',
storePhpNotFound: "The store script '%0' was not found."
};
bidix.upload.uploadChanges = function(onlyIfDirty,tiddlers,storeUrl,toFilename,uploadDir,backupDir,username,password)
{
var callback = function(status,uploadParams,original,url,xhr) {
if (!status) {
displayMessage(bidix.upload.messages.loadOriginalHttpPostError);
return;
}
if (bidix.debugMode)
alert(original.substr(0,500)+"\n...");
// Locate the storeArea div's
var posDiv = locateStoreArea(original);
if((posDiv[0] == -1) || (posDiv[1] == -1)) {
alert(config.messages.invalidFileError.format([localPath]));
return;
}
bidix.upload.uploadRss(uploadParams,original,posDiv);
};
if(onlyIfDirty && !store.isDirty())
return;
clearMessage();
// save on localdisk ?
if (document.location.toString().substr(0,4) == "file") {
var path = document.location.toString();
var localPath = getLocalPath(path);
saveChanges();
}
// get original
var uploadParams = new Array(storeUrl,toFilename,uploadDir,backupDir,username,password);
var originalPath = document.location.toString();
// If url is a directory : add index.html
if (originalPath.charAt(originalPath.length-1) == "/")
originalPath = originalPath + "index.html";
var dest = config.macros.upload.destFile(storeUrl,toFilename,uploadDir);
var log = new bidix.UploadLog();
log.startUpload(storeUrl, dest, uploadDir, backupDir);
displayMessage(bidix.upload.messages.aboutToSaveOnHttpPost.format([dest]));
if (bidix.debugMode)
alert("about to execute Http - GET on "+originalPath);
var r = doHttp("GET",originalPath,null,null,username,password,callback,uploadParams,null);
if (typeof r == "string")
displayMessage(r);
return r;
};
bidix.upload.uploadRss = function(uploadParams,original,posDiv)
{
var callback = function(status,params,responseText,url,xhr) {
if(status) {
var destfile = responseText.substring(responseText.indexOf("destfile:")+9,responseText.indexOf("\n", responseText.indexOf("destfile:")));
displayMessage(bidix.upload.messages.rssSaved,bidix.dirname(url)+'/'+destfile);
bidix.upload.uploadMain(params[0],params[1],params[2]);
} else {
displayMessage(bidix.upload.messages.rssFailed);
}
};
// do uploadRss
if(config.options.chkGenerateAnRssFeed) {
var rssPath = uploadParams[1].substr(0,uploadParams[1].lastIndexOf(".")) + ".xml";
var rssUploadParams = new Array(uploadParams[0],rssPath,uploadParams[2],'',uploadParams[4],uploadParams[5]);
var rssString = generateRss();
// no UnicodeToUTF8 conversion needed when location is "file" !!!
if (document.location.toString().substr(0,4) != "file")
rssString = convertUnicodeToUTF8(rssString);
bidix.upload.httpUpload(rssUploadParams,rssString,callback,Array(uploadParams,original,posDiv));
} else {
bidix.upload.uploadMain(uploadParams,original,posDiv);
}
};
bidix.upload.uploadMain = function(uploadParams,original,posDiv)
{
var callback = function(status,params,responseText,url,xhr) {
var log = new bidix.UploadLog();
if(status) {
// if backupDir specified
if ((params[3]) && (responseText.indexOf("backupfile:") > -1)) {
var backupfile = responseText.substring(responseText.indexOf("backupfile:")+11,responseText.indexOf("\n", responseText.indexOf("backupfile:")));
displayMessage(bidix.upload.messages.backupSaved,bidix.dirname(url)+'/'+backupfile);
}
var destfile = responseText.substring(responseText.indexOf("destfile:")+9,responseText.indexOf("\n", responseText.indexOf("destfile:")));
displayMessage(bidix.upload.messages.mainSaved,bidix.dirname(url)+'/'+destfile);
store.setDirty(false);
log.endUpload("ok");
} else {
alert(bidix.upload.messages.mainFailed);
displayMessage(bidix.upload.messages.mainFailed);
log.endUpload("failed");
}
};
// do uploadMain
var revised = bidix.upload.updateOriginal(original,posDiv);
bidix.upload.httpUpload(uploadParams,revised,callback,uploadParams);
};
bidix.upload.httpUpload = function(uploadParams,data,callback,params)
{
var localCallback = function(status,params,responseText,url,xhr) {
url = (url.indexOf("nocache=") < 0 ? url : url.substring(0,url.indexOf("nocache=")-1));
if (xhr.status == 404)
alert(bidix.upload.messages.storePhpNotFound.format([url]));
if ((bidix.debugMode) || (responseText.indexOf("Debug mode") >= 0 )) {
alert(responseText);
if (responseText.indexOf("Debug mode") >= 0 )
responseText = responseText.substring(responseText.indexOf("\n\n")+2);
} else if (responseText.charAt(0) != '0')
alert(responseText);
if (responseText.charAt(0) != '0')
status = null;
callback(status,params,responseText,url,xhr);
};
// do httpUpload
var boundary = "---------------------------"+"AaB03x";
var uploadFormName = "UploadPlugin";
// compose headers data
var sheader = "";
sheader += "--" + boundary + "\r\nContent-disposition: form-data; name=\"";
sheader += uploadFormName +"\"\r\n\r\n";
sheader += "backupDir="+uploadParams[3] +
";user=" + uploadParams[4] +
";password=" + uploadParams[5] +
";uploaddir=" + uploadParams[2];
if (bidix.debugMode)
sheader += ";debug=1";
sheader += ";;\r\n";
sheader += "\r\n" + "--" + boundary + "\r\n";
sheader += "Content-disposition: form-data; name=\"userfile\"; filename=\""+uploadParams[1]+"\"\r\n";
sheader += "Content-Type: text/html;charset=UTF-8" + "\r\n";
sheader += "Content-Length: " + data.length + "\r\n\r\n";
// compose trailer data
var strailer = new String();
strailer = "\r\n--" + boundary + "--\r\n";
data = sheader + data + strailer;
if (bidix.debugMode) alert("about to execute Http - POST on "+uploadParams[0]+"\n with \n"+data.substr(0,500)+ " ... ");
var r = doHttp("POST",uploadParams[0],data,"multipart/form-data; ;charset=UTF-8; boundary="+boundary,uploadParams[4],uploadParams[5],localCallback,params,null);
if (typeof r == "string")
displayMessage(r);
return r;
};
// same as Saving's updateOriginal but without convertUnicodeToUTF8 calls
bidix.upload.updateOriginal = function(original, posDiv)
{
if (!posDiv)
posDiv = locateStoreArea(original);
if((posDiv[0] == -1) || (posDiv[1] == -1)) {
alert(config.messages.invalidFileError.format([localPath]));
return;
}
var revised = original.substr(0,posDiv[0] + startSaveArea.length) + "\n" +
store.allTiddlersAsHtml() + "\n" +
original.substr(posDiv[1]);
var newSiteTitle = getPageTitle().htmlEncode();
revised = revised.replaceChunk("<title"+">","</title"+">"," " + newSiteTitle + " ");
revised = updateMarkupBlock(revised,"PRE-HEAD","MarkupPreHead");
revised = updateMarkupBlock(revised,"POST-HEAD","MarkupPostHead");
revised = updateMarkupBlock(revised,"PRE-BODY","MarkupPreBody");
revised = updateMarkupBlock(revised,"POST-SCRIPT","MarkupPostBody");
return revised;
};
//
// UploadLog
//
// config.options.chkUploadLog :
// false : no logging
// true : logging
// config.options.txtUploadLogMaxLine :
// -1 : no limit
// 0 : no Log lines but UploadLog is still in place
// n : the last n lines are only kept
// NaN : no limit (-1)
bidix.UploadLog = function() {
if (!config.options.chkUploadLog)
return; // this.tiddler = null
this.tiddler = store.getTiddler("UploadLog");
if (!this.tiddler) {
this.tiddler = new Tiddler();
this.tiddler.title = "UploadLog";
this.tiddler.text = "| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |";
this.tiddler.created = new Date();
this.tiddler.modifier = config.options.txtUserName;
this.tiddler.modified = new Date();
store.addTiddler(this.tiddler);
}
return this;
};
bidix.UploadLog.prototype.addText = function(text) {
if (!this.tiddler)
return;
// retrieve maxLine when we need it
var maxLine = parseInt(config.options.txtUploadLogMaxLine,10);
if (isNaN(maxLine))
maxLine = -1;
// add text
if (maxLine != 0)
this.tiddler.text = this.tiddler.text + text;
// Trunck to maxLine
if (maxLine >= 0) {
var textArray = this.tiddler.text.split('\n');
if (textArray.length > maxLine + 1)
textArray.splice(1,textArray.length-1-maxLine);
this.tiddler.text = textArray.join('\n');
}
// update tiddler fields
this.tiddler.modifier = config.options.txtUserName;
this.tiddler.modified = new Date();
store.addTiddler(this.tiddler);
// refresh and notifiy for immediate update
story.refreshTiddler(this.tiddler.title);
store.notify(this.tiddler.title, true);
};
bidix.UploadLog.prototype.startUpload = function(storeUrl, toFilename, uploadDir, backupDir) {
if (!this.tiddler)
return;
var now = new Date();
var text = "\n| ";
var filename = bidix.basename(document.location.toString());
if (!filename) filename = '/';
text += now.formatString("0DD/0MM/YYYY 0hh:0mm:0ss") +" | ";
text += config.options.txtUserName + " | ";
text += "[["+filename+"|"+location + "]] |";
text += " [[" + bidix.basename(storeUrl) + "|" + storeUrl + "]] | ";
text += uploadDir + " | ";
text += "[[" + bidix.basename(toFilename) + " | " +toFilename + "]] | ";
text += backupDir + " |";
this.addText(text);
};
bidix.UploadLog.prototype.endUpload = function(status) {
if (!this.tiddler)
return;
this.addText(" "+status+" |");
};
//
// Utilities
//
bidix.checkPlugin = function(plugin, major, minor, revision) {
var ext = version.extensions[plugin];
if (!
(ext &&
((ext.major > major) ||
((ext.major == major) && (ext.minor > minor)) ||
((ext.major == major) && (ext.minor == minor) && (ext.revision >= revision))))) {
// write error in PluginManager
if (pluginInfo)
pluginInfo.log.push("Requires " + plugin + " " + major + "." + minor + "." + revision);
eval(plugin); // generate an error : "Error: ReferenceError: xxxx is not defined"
}
};
bidix.dirname = function(filePath) {
if (!filePath)
return;
var lastpos;
if ((lastpos = filePath.lastIndexOf("/")) != -1) {
return filePath.substring(0, lastpos);
} else {
return filePath.substring(0, filePath.lastIndexOf("\\"));
}
};
bidix.basename = function(filePath) {
if (!filePath)
return;
var lastpos;
if ((lastpos = filePath.lastIndexOf("#")) != -1)
filePath = filePath.substring(0, lastpos);
if ((lastpos = filePath.lastIndexOf("/")) != -1) {
return filePath.substring(lastpos + 1);
} else
return filePath.substring(filePath.lastIndexOf("\\")+1);
};
bidix.initOption = function(name,value) {
if (!config.options[name])
config.options[name] = value;
};
//
// Initializations
//
// require PasswordOptionPlugin 1.0.1 or better
bidix.checkPlugin("PasswordOptionPlugin", 1, 0, 1);
// styleSheet
setStylesheet('.txtUploadStoreUrl, .txtUploadBackupDir, .txtUploadDir {width: 22em;}',"uploadPluginStyles");
//optionsDesc
merge(config.optionsDesc,{
txtUploadStoreUrl: "Url of the UploadService script (default: store.php)",
txtUploadFilename: "Filename of the uploaded file (default: in index.html)",
txtUploadDir: "Relative Directory where to store the file (default: . (downloadService directory))",
txtUploadBackupDir: "Relative Directory where to backup the file. If empty no backup. (default: ''(empty))",
txtUploadUserName: "Upload Username",
pasUploadPassword: "Upload Password",
chkUploadLog: "do Logging in UploadLog (default: true)",
txtUploadLogMaxLine: "Maximum of lines in UploadLog (default: 10)"
});
// Options Initializations
bidix.initOption('txtUploadStoreUrl','');
bidix.initOption('txtUploadFilename','');
bidix.initOption('txtUploadDir','');
bidix.initOption('txtUploadBackupDir','');
bidix.initOption('txtUploadUserName','');
bidix.initOption('pasUploadPassword','');
bidix.initOption('chkUploadLog',true);
bidix.initOption('txtUploadLogMaxLine','10');
// Backstage
merge(config.tasks,{
uploadOptions: {text: "upload", tooltip: "Change UploadOptions and Upload", content: '<<uploadOptions>>'}
});
config.backstageTasks.push("uploadOptions");
//}}}
UploadTiddlerPlugin and [[storeTiddler.php]] "upload" or "save to web" a single tiddler by updating, inserting or deleting a single tiddler in a TiddlyWiki file located on the web.
@@Now UploadTiddlerPlugin is able to Upload a Tiddler even if TiddlyWiki is located on a local file.@@
![[UploadTiddlerPlugin]]
*is activated by @@chkUploadTiddler option: <<option chkUploadTiddler>>@@
* to be abe to Upload a Tiddler even if the TiddlyWiki is located on local file@@chkUploadTiddlerFromFile option: <<option chkUploadTiddlerFromFile>>@@
*uses @@txtUploadTiddlerStoreUrl: <<option txtUploadTiddlerStoreUrl>>@@
*override TiddlyWiki.prototype.saveTiddler and deleteTiddler core functions
*uses the same options as UploadPlugin.
*do an XmlHttpRequest POST to storeTiddler.php only with the corresponding tiddler in storeArea format.
![[storeTiddler.php]]
*Username and password are checked
*[[storeTiddler.php]] parses TiddlyWiki file
*tiddler is updated, inserted or deleted in the tiddler array
*optionally create and clean backup file
*write updated TiddlyWiki file
!UploadTiddlerPlugin and UploadPlugin
*The paradigm of UploadTiddlerPlugin and [[storeTiddler.php]] is exactly the same as UploadPlugin and [[store.php]]
*No concurrency managed
*Full compatible with UploadPlugin
*[[storeTiddler.php]] can be use to remotly update a TiddlyWiki. storeTiddler.php
*a GET to [[storeTiddler.php]] display a form to upload a tiddler in a TiddlyWiki
/***
|''Name:''|UploadTiddlerPlugin|
|''Description:''|Upload a tiddler and Update a remote TiddlyWiki |
|''Version:''|1.2.2|
|''Date:''|2008-09-13|
|''Source:''|http://tiddlywiki.bidix.info/#UploadTiddlerPlugin|
|''Usage:''|Uses {{{<<uploadOptions>>}}}<br>with those UploadTiddler Options : <br>chkUploadTiddler: <<option chkUploadTiddler>><br>txtUploadTiddlerStoreUrl: <<option txtUploadTiddlerStoreUrl>><br>chkUploadTiddlerFromFile: <<option chkUploadTiddlerFromFile>>|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''[[License]]:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''CoreVersion:''|2.3.0|
***/
//{{{
version.extensions.UploadTiddlerPlugin = {
major: 1, minor: 2, revision: 2,
date: new Date("2008-09-13"),
source: 'http://tiddlywiki.bidix.info/#UploadTiddlerPlugin',
author: 'BidiX (BidiX (at) bidix (dot) info',
coreVersion: '2.3.0'
};
if (!window.bidix) window.bidix = {}; // bidix namespace
bidix.debugMode = false;
bidix.uploadTiddler = {
messages: {
aboutToSaveTiddler: "About to update tiddler '%0'...",
aboutToRemotelySaveTiddler: "About to REMOTELY update tiddler '%0'...",
storeTiddlerNotFound: "Script store tiddler '%0' not found",
tiddlerSaved: "Tiddler '%0' updated in '%1' using '%2' "
},
upload: function(title,tiddler,oldTitle) {
var callback = function(status,params,responseText,url,xhr) {
if (xhr.status == 404) {
alert(bidix.uploadTiddler.messages.storeTiddlerNotFound.format([url]));
return;
}
if ((bidix.debugMode) || (responseText.indexOf("Debug mode") >= 0 )) {
alert(responseText);
if (responseText.indexOf("Debug mode") >= 0 )
responseText = responseText.substring(responseText.indexOf("\n\n")+2);
} else if (responseText.charAt(0) != '0')
alert(responseText);
else
displayMessage(bidix.uploadTiddler.messages.tiddlerSaved.format([params[0], params[1], params[2]]));
store.setDirty(false);
}
if ((config.options['chkUploadTiddler']) &&
((document.location.toString().substr(0,4) == "http") || config.options['chkUploadTiddlerFromFile'])) {
clearMessage();
if (document.location.toString().substr(0,4) != "http")
displayMessage(bidix.uploadTiddler.messages.aboutToRemotelySaveTiddler.format([title]));
else
displayMessage(bidix.uploadTiddler.messages.aboutToSaveTiddler.format([title]));
var ExtTiddler = null;
var html = null;
if (tiddler) {
ExtTiddler = store.getSaver().externalizeTiddler(store,tiddler);
html = wikifyStatic(tiddler.text,null,tiddler).htmlEncode();
}
var form = "title="+encodeURIComponent(title);
form = form + "&tiddler="+(ExtTiddler?encodeURIComponent(ExtTiddler):'');
form = form + "&html="+(html?encodeURIComponent(html):'');
var filename = (config.options['txtUploadFilename']?config.options['txtUploadFilename']:'index.html');
form = form +"&oldTitle="+encodeURIComponent(oldTitle);
form = form +"&fileName="+encodeURIComponent(filename);
form = form +"&backupDir="+encodeURIComponent(config.options['txtUploadBackupDir']);
form = form +"&user="+encodeURIComponent(config.options['txtUploadUserName']);
form = form +"&password="+encodeURIComponent(config.options['pasUploadPassword']);
form = form +"&uploadir="+encodeURIComponent(config.options['txtUploadDir']);
form = form +"&debug="+encodeURIComponent(0);
var storeScript = (config.options.txtUploadTiddlerStoreUrl
? config.options.txtUploadTiddlerStoreUrl : 'storeTiddler.php');
var r = doHttp("POST",storeScript,form+"\n",'application/x-www-form-urlencoded',
config.options['txtUploadUserName'],config.options['pasUploadPassword'],callback,Array(title,filename, storeScript),null);
}
}
}
TiddlyWiki.prototype.saveTiddler_bidix = TiddlyWiki.prototype.saveTiddler;
TiddlyWiki.prototype.saveTiddler = function(oldTitle,newTitle,newBody,modifier,modified,tags,fields,clearChangeCount,created) {
var tiddler = TiddlyWiki.prototype.saveTiddler_bidix.apply(this,arguments);
var title = (newTitle?newTitle:oldTitle);
if (oldTitle == title)
oldTitle = '';
bidix.uploadTiddler.upload(title, tiddler, oldTitle);
}
TiddlyWiki.prototype.removeTiddler_bidix =TiddlyWiki.prototype.removeTiddler;
TiddlyWiki.prototype.removeTiddler = function(title) {
TiddlyWiki.prototype.removeTiddler_bidix.apply(this,arguments);
bidix.uploadTiddler.upload(title, null);
}
//
// Initializations
//
bidix.initOption = function(name,value) {
if (!config.options[name])
config.options[name] = value;
};
// styleSheet
setStylesheet('.txtUploadTiddlerStoreUrl {width: 22em;}',"uploadTiddlerPluginStyles");
//optionsDesc
merge(config.optionsDesc,{
txtUploadTiddlerStoreUrl: "Url of the UploadTiddlerService script (default: storeTiddler.php)",
chkUploadTiddler: "Do per Tiddler upload using txtUploadTiddlerStoreUrl (default: false)",
chkUploadTiddlerFromFile: "Upload tiddler even if TiddlyWiki is located on local file (default: false)"
});
// Options Initializations
bidix.initOption('txtUploadTiddlerStoreUrl','');
bidix.initOption('chkUploadTiddler','');
bidix.initOption('chkUploadTiddlerFromFile','');
// add options in backstage UploadOptions
if (config.macros.uploadOptions) {
if (config.macros.uploadOptions.options) {
config.macros.uploadOptions.options.push("txtUploadTiddlerStoreUrl","chkUploadTiddler", "chkUploadTiddlerFromFile");
}
}
//}}}
!usage
{{{[img[license.png]]}}}
[img[license.png]]
!notes
//none//
!type
image/png
!file
!url
!data
data:image/png;base64,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
!Dr Simon Dobson
UCD Systems Research Group
[[UCD Complex and Adaptive Systems Laboratory|http://casl.ucd.ie]]
[[Clarity, the Centre for Sensor Web Technologies|http://www.clarity-centre.org]]
[[Lero, the Irish Software Engineering Research Centre|http://www.lero.ie]]
[[The On-line Dublin Computer Science Summer School|http://www.odcsss.ie]]
s: School of Computer Science and Informatics, UCD Dublin, Belfield, Dublin 4, Ireland
e: [[simon.dobson@ucd.ie|mailto:simon.dobson@ucd.ie]]
w: http://www.simondobson.org, [[Facebook|http://www.facebook.com/simoninireland]], [[Twitter|http://twitter.com/simoninireland]], [[LinkedIn|http://www.linkedin.com/profile?viewProfile=&key=7632144]], [[Google Scholar|http://scholar.google.com/scholar?as_q=&num=20&btnG=Search+Scholar&as_epq=&as_oq=&as_eq=&as_occt=any&as_sauthors=%22Simon+dobson%22&as_publication=&as_ylo=&as_yhi=&as_allsubj=some&as_subj=eng&hl=en&lr=]], [[DBLP|http://www.informatik.uni-trier.de/~ley/db/indices/a-tree/d/Dobson:Simon_A=.html]]
pgp: [[Public key|http://www.simondobson.org/static/publickey.asc]]
t: +353 1 716 5360
skype: simoninireland
!usage
{{{[img[sd-lr.jpg]]}}}
[img[sd-lr.jpg]]
!notes
//none//
!type
image/jpeg
!file
file:////Users/sd/Desktop/sd-lr.jpg
!url
!data
data:image/jpeg;base64,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CQk8YXJyYXk+CgkJCTxkaWN0PgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFnZUZvcm1hdC5QTUhvcml6b250YWxSZXM8L2tleT4KCQkJCTxyZWFsPjcyPC9yZWFsPgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJPGludGVnZXI+MDwvaW50ZWdlcj4KCQkJPC9kaWN0PgoJCTwvYXJyYXk+Cgk8L2RpY3Q+Cgk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNT3JpZW50YXRpb248L2tleT4KCTxkaWN0PgoJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5jcmVhdG9yPC9rZXk+CgkJPHN0cmluZz5jb20uYXBwbGUuam9idGlja2V0PC9zdHJpbmc+CgkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJheTwva2V5PgoJCTxhcnJheT4KCQkJPGRpY3Q+CgkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNT3JpZW50YXRpb248L2tleT4KCQkJCTxpbnRlZ2VyPjE8L2ludGVnZXI+CgkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuc3RhdGVGbGFnPC9rZXk+CgkJCQk8aW50ZWdlcj4wPC9pbnRlZ2VyPgoJCQk8L2RpY3Q+CgkJPC9hcnJheT4KCTwvZGljdD4KCTxrZXk+Y29tLmFwcGxlLnByaW50LlBhZ2VGb3JtYXQuUE1TY2FsaW5nPC9rZXk+Cgk8ZGljdD4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCTxzdHJpbmc+Y29tLmFwcGxlLmpvYnRpY2tldDwvc3RyaW5nPgoJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQk8YXJyYXk+CgkJCTxkaWN0PgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFnZUZvcm1hdC5QTVNjYWxpbmc8L2tleT4KCQkJCTxyZWFsPjE8L3JlYWw+CgkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuc3RhdGVGbGFnPC9rZXk+CgkJCQk8aW50ZWdlcj4wPC9pbnRlZ2VyPgoJCQk8L2RpY3Q+CgkJPC9hcnJheT4KCTwvZGljdD4KCTxrZXk+Y29tLmFwcGxlLnByaW50LlBhZ2VGb3JtYXQuUE1WZXJ0aWNhbFJlczwva2V5PgoJPGRpY3Q+CgkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNyZWF0b3I8L2tleT4KCQk8c3RyaW5nPmNvbS5hcHBsZS5qb2J0aWNrZXQ8L3N0cmluZz4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuaXRlbUFycmF5PC9rZXk+CgkJPGFycmF5PgoJCQk8ZGljdD4KCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50LlBhZ2VGb3JtYXQuUE1WZXJ0aWNhbFJlczwva2V5PgoJCQkJPHJlYWw+NzI8L3JlYWw+CgkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuc3RhdGVGbGFnPC9rZXk+CgkJCQk8aW50ZWdlcj4wPC9pbnRlZ2VyPgoJCQk8L2RpY3Q+CgkJPC9hcnJheT4KCTwvZGljdD4KCTxrZXk+Y29tLmFwcGxlLnByaW50LlBhZ2VGb3JtYXQuUE1WZXJ0aWNhbFNjYWxpbmc8L2tleT4KCTxkaWN0PgoJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5jcmVhdG9yPC9rZXk+CgkJPHN0cmluZz5jb20uYXBwbGUuam9idGlja2V0PC9zdHJpbmc+CgkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJheTwva2V5PgoJCTxhcnJheT4KCQkJPGRpY3Q+CgkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNVmVydGljYWxTY2FsaW5nPC9rZXk+CgkJCQk8cmVhbD4xPC9yZWFsPgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJPGludGVnZXI+MDwvaW50ZWdlcj4KCQkJPC9kaWN0PgoJCTwvYXJyYXk+Cgk8L2RpY3Q+Cgk8a2V5PmNvbS5hcHBsZS5wcmludC5zdWJUaWNrZXQucGFwZXJfaW5mb190aWNrZXQ8L2tleT4KCTxkaWN0PgoJCTxrZXk+UE1QUERQYXBlckNvZGVOYW1lPC9rZXk+CgkJPGRpY3Q+CgkJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5jcmVhdG9yPC9rZXk+CgkJCTxzdHJpbmc+Y29tLmFwcGxlLmpvYnRpY2tldDwvc3RyaW5nPgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuaXRlbUFycmF5PC9rZXk+CgkJCTxhcnJheT4KCQkJCTxkaWN0PgoJCQkJCTxrZXk+UE1QUERQYXBlckNvZGVOYW1lPC9rZXk+CgkJCQkJPHN0cmluZz5BNDwvc3RyaW5nPgoJCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5zdGF0ZUZsYWc8L2tleT4KCQkJCQk8aW50ZWdlcj4wPC9pbnRlZ2VyPgoJCQkJPC9kaWN0PgoJCQk8L2FycmF5PgoJCTwvZGljdD4KCQk8a2V5PlBNVGlvZ2FQYXBlck5hbWU8L2tleT4KCQk8ZGljdD4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNyZWF0b3I8L2tleT4KCQkJPHN0cmluZz5jb20uYXBwbGUuam9idGlja2V0PC9zdHJpbmc+CgkJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQkJPGFycmF5PgoJCQkJPGRpY3Q+CgkJCQkJPGtleT5QTVRpb2dhUGFwZXJOYW1lPC9rZXk+CgkJCQkJPHN0cmluZz5pc28tYTQ8L3N0cmluZz4KCQkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuc3RhdGVGbGFnPC9rZXk+CgkJCQkJPGludGVnZXI+MDwvaW50ZWdlcj4KCQkJCTwvZGljdD4KCQkJPC9hcnJheT4KCQk8L2RpY3Q+CgkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFnZUZvcm1hdC5QTUFkanVzdGVkUGFnZVJlY3Q8L2tleT4KCQk8ZGljdD4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNyZWF0b3I8L2tleT4KCQkJPHN0cmluZz5jb20uYXBwbGUuam9idGlja2V0PC9zdHJpbmc+CgkJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQkJPGFycmF5PgoJCQkJPGRpY3Q+CgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFnZUZvcm1hdC5QTUFkanVzdGVkUGFnZVJlY3Q8L2tleT4KCQkJCQk8YXJyYXk+CgkJCQkJCTxyZWFsPjAuMDwvcmVhbD4KCQkJCQkJPHJlYWw+MC4wPC9yZWFsPgoJCQkJCQk8cmVhbD43ODM8L3JlYWw+CgkJCQkJCTxyZWFsPjU1OTwvcmVhbD4KCQkJCQk8L2FycmF5PgoJCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5zdGF0ZUZsYWc8L2tleT4KCQkJCQk8aW50ZWdlcj4wPC9pbnRlZ2VyPgoJCQkJPC9kaWN0PgoJCQk8L2FycmF5PgoJCTwvZGljdD4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNQWRqdXN0ZWRQYXBlclJlY3Q8L2tleT4KCQk8ZGljdD4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNyZWF0b3I8L2tleT4KCQkJPHN0cmluZz5jb20uYXBwbGUuam9idGlja2V0PC9zdHJpbmc+CgkJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQkJPGFycmF5PgoJCQkJPGRpY3Q+CgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFnZUZvcm1hdC5QTUFkanVzdGVkUGFwZXJSZWN0PC9rZXk+CgkJCQkJPGFycmF5PgoJCQkJCQk8cmVhbD4tMTg8L3JlYWw+CgkJCQkJCTxyZWFsPi0xODwvcmVhbD4KCQkJCQkJPHJlYWw+ODI0PC9yZWFsPgoJCQkJCQk8cmVhbD41Nzc8L3JlYWw+CgkJCQkJPC9hcnJheT4KCQkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuc3RhdGVGbGFnPC9rZXk+CgkJCQkJPGludGVnZXI+MDwvaW50ZWdlcj4KCQkJCTwvZGljdD4KCQkJPC9hcnJheT4KCQk8L2RpY3Q+CgkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFwZXJJbmZvLlBNUGFwZXJOYW1lPC9rZXk+CgkJPGRpY3Q+CgkJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5jcmVhdG9yPC9rZXk+CgkJCTxzdHJpbmc+Y29tLmFwcGxlLmpvYnRpY2tldDwvc3RyaW5nPgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuaXRlbUFycmF5PC9rZXk+CgkJCTxhcnJheT4KCQkJCTxkaWN0PgoJCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50LlBhcGVySW5mby5QTVBhcGVyTmFtZTwva2V5PgoJCQkJCTxzdHJpbmc+aXNvLWE0PC9zdHJpbmc+CgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI+CgkJCQk8L2RpY3Q+CgkJCTwvYXJyYXk+CgkJPC9kaWN0PgoJCTxrZXk+Y29tLmFwcGxlLnByaW50LlBhcGVySW5mby5QTVVuYWRqdXN0ZWRQYWdlUmVjdDwva2V5PgoJCTxkaWN0PgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCQk8c3RyaW5nPmNvbS5hcHBsZS5qb2J0aWNrZXQ8L3N0cmluZz4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJheTwva2V5PgoJCQk8YXJyYXk+CgkJCQk8ZGljdD4KCQkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYXBlckluZm8uUE1VbmFkanVzdGVkUGFnZVJlY3Q8L2tleT4KCQkJCQk8YXJyYXk+CgkJCQkJCTxyZWFsPjAuMDwvcmVhbD4KCQkJCQkJPHJlYWw+MC4wPC9yZWFsPgoJCQkJCQk8cmVhbD43ODM8L3JlYWw+CgkJCQkJCTxyZWFsPjU1OTwvcmVhbD4KCQkJCQk8L2FycmF5PgoJCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5zdGF0ZUZsYWc8L2tleT4KCQkJCQk8aW50ZWdlcj4wPC9pbnRlZ2VyPgoJCQkJPC9kaWN0PgoJCQk8L2FycmF5PgoJCTwvZGljdD4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYXBlckluZm8uUE1VbmFkanVzdGVkUGFwZXJSZWN0PC9rZXk+CgkJPGRpY3Q+CgkJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5jcmVhdG9yPC9rZXk+CgkJCTxzdHJpbmc+Y29tLmFwcGxlLmpvYnRpY2tldDwvc3RyaW5nPgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuaXRlbUFycmF5PC9rZXk+CgkJCTxhcnJheT4KCQkJCTxkaWN0PgoJCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50LlBhcGVySW5mby5QTVVuYWRqdXN0ZWRQYXBlclJlY3Q8L2tleT4KCQkJCQk8YXJyYXk+CgkJCQkJCTxyZWFsPi0xODwvcmVhbD4KCQkJCQkJPHJlYWw+LTE4PC9yZWFsPgoJCQkJCQk8cmVhbD44MjQ8L3JlYWw+CgkJCQkJCTxyZWFsPjU3NzwvcmVhbD4KCQkJCQk8L2FycmF5PgoJCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5zdGF0ZUZsYWc8L2tleT4KCQkJCQk8aW50ZWdlcj4wPC9pbnRlZ2VyPgoJCQkJPC9kaWN0PgoJCQk8L2FycmF5PgoJCTwvZGljdD4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYXBlckluZm8ucHBkLlBNUGFwZXJOYW1lPC9rZXk+CgkJPGRpY3Q+CgkJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5jcmVhdG9yPC9rZXk+CgkJCTxzdHJpbmc+Y29tLmFwcGxlLmpvYnRpY2tldDwvc3RyaW5nPgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuaXRlbUFycmF5PC9rZXk+CgkJCTxhcnJheT4KCQkJCTxkaWN0PgoJCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50LlBhcGVySW5mby5wcGQuUE1QYXBlck5hbWU8L2tleT4KCQkJCQk8c3RyaW5nPkE0PC9zdHJpbmc+CgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI+CgkJCQk8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NBK+W0klP1P2SXywkkp+p0l8sJJKfpe0dJMhpqbYSZNcbge/0EGoOGgO5o4cOCP+qXzckkp//9kAOEJJTQQhAAAAAABVAAAAAQEAAAAPAEEAZABvAGIAZQAgAFAAaABvAHQAbwBzAGgAbwBwAAAAEwBBAGQAbwBiAGUAIABQAGgAbwB0AG8AcwBoAG8AcAAgAEMAUwAyAAAAAQA4QklNBAYAAAAAAAcAAgAAAAEBAP/hOm5odHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+Cjx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IjMuMS4xLTExMiI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOnhhcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIgogICAgICAgICAgICB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyI+CiAgICAgICAgIDx4YXBNTTpEb2N1bWVudElEPnV1aWQ6Qjc1MUE5QzE1NUNCMTFERUI1MEJDQzZEOEFGRTUzQjY8L3hhcE1NOkRvY3VtZW50SUQ+CiAgICAgICAgIDx4YXBNTTpJbnN0YW5jZUlEPnV1aWQ6Qjc1MUE5QzI1NUNCMTFERUI1MEJDQzZEOEFGRTUzQjY8L3hhcE1NOkluc3RhbmNlSUQ+CiAgICAgICAgIDx4YXBNTTpEZXJpdmVkRnJvbSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgIDxzdFJlZjppbnN0YW5jZUlEPnV1aWQ6Qjc1MUE5QzA1NUNCMTFERUI1MEJDQzZEOEFGRTUzQjY8L3N0UmVmOmluc3RhbmNlSUQ+CiAgICAgICAgICAgIDxzdFJlZjpkb2N1bWVudElEPnV1aWQ6Qjc1MUE5QzA1NUNCMTFERUI1MEJDQzZEOEFGRTUzQjY8L3N0UmVmOmRvY3VtZW50SUQ+CiAgICAgICAgIDwveGFwTU06RGVyaXZlZEZyb20+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp4YXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iPgogICAgICAgICA8eGFwOkNyZWF0ZURhdGU+MjAwOS0wNi0wOFQxNDozNDo1NCswMTowMDwveGFwOkNyZWF0ZURhdGU+CiAgICAgICAgIDx4YXA6TW9kaWZ5RGF0ZT4yMDA5LTA2LTA4VDE0OjM0OjU0KzAxOjAwPC94YXA6TW9kaWZ5RGF0ZT4KICAgICAgICAgPHhhcDpNZXRhZGF0YURhdGU+MjAwOS0wNi0wOFQxNDozNDo1NCswMTowMDwveGFwOk1ldGFkYXRhRGF0ZT4KICAgICAgICAgPHhhcDpDcmVhdG9yVG9vbD5BZG9iZSBQaG90b3Nob3AgQ1MyIE1hY2ludG9zaDwveGFwOkNyZWF0b3JUb29sPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KICAgICAgICAgPGRjOmZvcm1hdD5pbWFnZS9qcGVnPC9kYzpmb3JtYXQ+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczpwaG90b3Nob3A9Imh0dHA6Ly9ucy5hZG9iZS5jb20vcGhvdG9zaG9wLzEuMC8iPgogICAgICAgICA8cGhvdG9zaG9wOkNvbG9yTW9kZT4xPC9waG90b3Nob3A6Q29sb3JNb2RlPgogICAgICAgICA8cGhvdG9zaG9wOkhpc3RvcnkvPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICAgICA8dGlmZjpYUmVzb2x1dGlvbj4xODAwMDAwLzEwMDAwPC90aWZmOlhSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpZUmVzb2x1dGlvbj4xODAwMDAwLzEwMDAwPC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpSZXNvbHV0aW9uVW5pdD4yPC90aWZmOlJlc29sdXRpb25Vbml0PgogICAgICAgICA8dGlmZjpOYXRpdmVEaWdlc3Q+MjU2LDI1NywyNTgsMjU5LDI2MiwyNzQsMjc3LDI4NCw1MzAsNTMxLDI4MiwyODMsMjk2LDMwMSwzMTgsMzE5LDUyOSw1MzIsMzA2LDI3MCwyNzEsMjcyLDMwNSwzMTUsMzM0MzI7NkQxMDNCQkY2MzFEQjhBNjhEMjEyODFFNDE5NTFFMDU8L3RpZmY6TmF0aXZlRGlnZXN0PgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+MjUwPC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjE4NTwvZXhpZjpQaXhlbFlEaW1lbnNpb24+CiAgICAgICAgIDxleGlmOkNvbG9yU3BhY2U+LTE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6TmF0aXZlRGlnZXN0PjM2ODY0LDQwOTYwLDQwOTYxLDM3MTIxLDM3MTIyLDQwOTYyLDQwOTYzLDM3NTEwLDQwOTY0LDM2ODY3LDM2ODY4LDMzNDM0LDMzNDM3LDM0ODUwLDM0ODUyLDM0ODU1LDM0ODU2LDM3Mzc3LDM3Mzc4LDM3Mzc5LDM3MzgwLDM3MzgxLDM3MzgyLDM3MzgzLDM3Mzg0LDM3Mzg1LDM3Mzg2LDM3Mzk2LDQxNDgzLDQxNDg0LDQxNDg2LDQxNDg3LDQxNDg4LDQxNDkyLDQxNDkzLDQxNDk1LDQxNzI4LDQxNzI5LDQxNzMwLDQxOTg1LDQxOTg2LDQxOTg3LDQxOTg4LDQxOTg5LDQxOTkwLDQxOTkxLDQxOTkyLDQxOTkzLDQxOTk0LDQxOTk1LDQxOTk2LDQyMDE2LDAsMiw0LDUsNiw3LDgsOSwxMCwxMSwxMiwxMywxNCwxNSwxNiwxNywxOCwyMCwyMiwyMywyNCwyNSwyNiwyNywyOCwzMDs1RjUzNkRBMTE4RDY2NDZFNDA5QkY3RUZBNjUxQTA5NjwvZXhpZjpOYXRpdmVEaWdlc3Q+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIAo8P3hwYWNrZXQgZW5kPSJ3Ij8+/+4ADkFkb2JlAGSAAAAAAP/bAEMACAYGBgYGCAYGCAwIBwgMDgoICAoOEA0NDg0NEBEMDAwMDAwRDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDP/AAAsIALkA+gEBEQD/3QAEACD/xADSAAAABwEBAQEBAAAAAAAAAAAEBQMCBgEABwgJCgsQAAIBAwMCBAIGBwMEAgYCcwECAxEEAAUhEjFB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