Welcome to TiddlyWiki created by Jeremy Ruston; Copyright © 2004-2007 Jeremy Ruston, Copyright © 2007-2011 UnaMesa Association
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
[[AttachFilePlugin]] reads binary data from locally-stored files (e.g., images, PDFs, mp3's, etc.) and converts it to base64-encoded text that is stored in tiddlers tagged with<<tag attachment>>. [[AttachFilePluginFormatters]] allows you to use those tiddlers in place of the external path/file references that are normally part of the image and external links wiki syntax.
[[FileDropPlugin]] and [[FileDropPluginConfig]] allow you to quickly create attachment tiddlers simply by dragging files directly from your system's desktop folder display and dropping it onto an open TiddlyWiki document. Text files are automatically created as simple tiddlers, while binary files are automatically encoded and attached.
/***
|Name|AttachFilePlugin|
|Source|http://www.TiddlyTools.com/#AttachFilePlugin|
|Documentation|http://www.TiddlyTools.com/#AttachFilePluginInfo|
|Version|4.0.1|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Requires|AttachFilePluginFormatters, AttachFileMIMETypes|
|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
<<<
2011.02.14 4.0.1 fix OSX error: use picker.file.path
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: 1, date: new Date(2011,2,14)};
// 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.path;
}
catch(ex) { displayMessage(ex.toString()); }
return result;
}
}
//}}}
/***
|Name|AttachFilePluginFormatters|
|Source|http://www.TiddlyTools.com/#AttachFilePluginFormatters|
|Version|4.0.1|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1.3|
|Type|plugin|
|Description|run-time library for displaying attachment tiddlers|
Runtime 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: after creating new attachment tiddlers, you can remove [[AttachFilePlugin]], as long as you retain //this// tiddler (so that images can be rendered later on).
!!!!!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.10.10 [4.0.1] in fileExists(), check for IE to avoid hanging Chrome during startup
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: 1, date: new Date(2009,10,10)};
//}}}
//{{{
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 if (config.browser.isIE) { // IE
var fso = new ActiveXObject("Scripting.FileSystemObject");
return fso.FileExists(f);
}
else return true; // other browsers: assume file exists
}
//}}}
//{{{
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);
}
}
//}}}
!usage
{{{[img[AttachFileSample]]}}}
[img[AttachFileSample]]
!notes
example of encoded data attachment
!type
image/gif
!file
./images/meow.gif
!url
http://www.TiddlyTools.com/images/meow.gif
!data
data:image/gif;base64,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
!usage
{{{[img[AttachFileSample2]]}}}
[img[AttachFileSample2]]
!notes
example of external attachment (no embedded data)
!type
image/jpg
!file
./images/meow2.jpg
!url
http://www.TiddlyTools.com/images/meow2.jpg
!data
/%
!info
|Name|CycleThemes|
|Source|http://www.TiddlyTools.com/#CycleThemes|
|Version|2.0.0|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|transclusion|
|Description|creates command link to cycle through systemThemes|
Usage
<<<
{{{
<<tiddler CycleThemes>>
<<tiddler CycleThemes with: label "theme theme theme">>
}}}
*''label'' (optional)<br>text of command link. default='next theme'
*''"theme theme theme"'' (optional)<br>list of theme tiddlers to cycle through. default=[[StyleSheet]] plus all tiddlers tagged with<<tag systemTheme>>, except those tagged with<<tag excludeTheme>>or<<tag excludeLists>>
<<<
Examples
<<<
*Cycle through all themes:<br>{{{<<tiddler CycleThemes>>}}}<br><<tiddler CycleThemes##show with: 'next theme' >>
*Toggle between two themes:<br>{{{<<tiddler CycleThemes with: "toggle" "StyleSheet Plain">>}}}<br><<tiddler CycleThemes##show with: "toggle" "StyleSheet Plain">>
*Apply a theme:<br>{{{<<tiddler CycleThemes with: "default" StyleSheet>>}}}<br><<tiddler CycleThemes##show with: "use default StyleSheet" StyleSheet>>
<<<
!end
!show
<html><nowiki><a href="javascript:;"
onmouseover="
this.title='current theme: '+config.options.txtTheme;
this.href='javascript:void(eval(decodeURIComponent(%22(function(){try{('
+encodeURIComponent(encodeURIComponent(this.onclick))
+')()}catch(e){alert(e.description?e.description:e.toString())}})()%22)))';"
onclick="
var titles='$2'.readBracketedList();
if ('$2'=='$'+'2') {
var tids=store.getTaggedTiddlers('systemTheme');
titles=tids.map(function(t){return t.tags.contains('excludeTheme','excludeLists')?null:t.title;});
titles.pushUnique('StyleSheet');
}
var curr=titles.indexOf(config.options.txtTheme);
var next=curr+1>=titles.length?0:curr+1;
while(!titles[next] && next!=curr) next=next+1>=titles.length?0:next+1;
story.switchTheme(titles[next]);
return false;"
>$1</a></html>
!end
%/<<tiddler {{var src='CycleThemes'; src+(tiddler&&tiddler.title==src?'##info':'##show')}}
with: {{'$1'=='$'+'1'?'next theme':'$1'}} "$2">>
/***
|''Navn:''|DanishTranslationPlugin|
|''Beskrivelse:''|Translation of TiddlyWiki into Danish|
|''Forfatter:''|MartinBudden (mjbudden (at) gmail (dot) com)|
|''Kilde:''|www.example.com |
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/association/locales/core/en/locale.en.js |
|''Version:''|0.3.7|
|''Dato:''|Jul 6, 2007|
|''Kommentarer:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev |
|''Licens:''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]] |
|''~CoreVersion:''|2.4|
***/
//{{{
//--
//-- Translateable strings
//--
// Strings in "double quotes" should be translated; strings in 'single quotes' should be left alone
config.locale = "da"; // W3C language tag
if (config.options.txtUserName == 'YourName') // do not translate this line, but do translate the next line
merge(config.options,{txtUserName: "DitNavn"});
merge(config.tasks,{
save: {text: "gem", tooltip: "Gem dine Ʀndringer til denne TiddlyWiki", action: saveChanges},
sync: {text: "synk", tooltip: "SynkronisƩr Ʀndringer med andre TiddlyWiki filer og servere", content: '<<sync>>'},
importTask: {text: "importƩr", tooltip: "ImportƩr tiddlers og plugins fra andre TiddlyWiki filer og servere", content: '<<importTiddlers>>'},
tweak: {text: "Tilpas", tooltip: "Tilpas TiddlyWikis udseende og opfĆørsel", content: '<<options>>'},
upgrade: {text: "upgradƩr", tooltip: "Upgrader TiddlyWikis kerne kode", content: '<<upgrade>>'},
plugins: {text: "udvidelser", tooltip: "AdministrƩr installerede udvidelser", content: '<<plugins>>'}
});
// Options that can be set in the options panel and/or cookies
merge(config.optionsDesc,{
txtUserName: "Brugernavn til signering af dine Ʀndringer",
chkRegExpSearch: "Avend almindelige udtryk til sĆøgninger",
chkCaseSensitiveSearch: "Forskel pƄ store og smƄ bogstaver",
chkIncrementalSearch: "Bogstav for bogstav-sĆøgning",
chkAnimate: "Anvend animationer",
chkSaveBackups: "Gem en backupfil nƄr der gemmes Ʀndringer",
chkAutoSave: "Gem automatisk Ʀndringer",
chkGenerateAnRssFeed: "Lav et RSS feed nƄr der gemmes Ʀndringer",
chkSaveEmptyTemplate: "Lav en tom skabelon nƄr der gemmes Ʀndringer",
chkOpenInNewWindow: "Ć
ben internet links i et nyt vindue",
chkToggleLinks: "NƄr man klikker pƄ et link i Ƅbne tiddlers lukkes de",
chkHttpReadOnly: "Skjul redigeringsværktøjer nÄr den vises over HTTP",
chkForceMinorUpdate: "OpdatƩr ikke brugernavn og dato nƄr tiddlers bliver Ʀndrede",
chkConfirmDelete: "Bed om bekræftelse før tiddlers slettes",
chkInsertTabs: "Brug tab tasten til at indsƦtte tab tegn istedet for at hoppe imellem felter",
txtBackupFolder: "Navn pƄ mappe til brug for backups",
txtMaxEditRows: "Maximum antal af rƦkker i edit bokse",
txtFileSystemCharSet: "Default tegnsƦt til at gemme Ʀndringer (Kun i Firefox/Mozilla)"});
merge(config.messages,{
customConfigError: "Der opstod problemer ved loading af udvidelser. Se PluginManager for detaljer",
pluginError: "Fejl: %0",
pluginDisabled: "Ikke udført fordi det er slÄet fra via 'systemConfigDisable' tag",
pluginForced: "UdfĆørt fordi det er tvunget via 'systemConfigForce' tag",
pluginVersionError: "Ikke udført fordi denne udvidelse kræver en nyere udgave af TiddlyWiki",
nothingSelected: "Intet er valgt. Du er nødt til at vælge en eller flere ting først",
savedSnapshotError: "Det ser ud som om denne TiddlyWiki er blevet gemt forkert. Se venligst http://www.tiddlywiki.com/#DownloadSoftware for details",
subtitleUnknown: "(ukendt)",
undefinedTiddlerToolTip: "Tiddleren '%0' findes ikke endnu",
shadowedTiddlerToolTip: "Tiddleren '%0' findes ikke endnu, men har en foruddefineret skygge vƦrdi",
tiddlerLinkTooltip: "%0 - %1, %2",
externalLinkTooltip: "Internet link til %0",
noTags: "Der er ingen taggede tiddlere",
notFileUrlError: "Du er nødt til at gemme denne TiddlyWiki til en fil før du kan gemme ændringer",
cantSaveError: "Det er ikke muligt at gemme ændringer. Mulige grunde indbefatter:\n- din browser understøtter det ikke (Firefox, Internet Explorer, Safari og Opera virker alle fint hvis de er konfigurerede korrekt)\n- stien til din TiddlyWiki fil indeholder ulovlige tegn\n- TiddlyWiki HTML filen er blevet flyttet eller omdøbt",
invalidFileError: "Den originale fil '%0' lader ikke til at vƦre en rigtig TiddlyWiki",
backupSaved: "Backup gemt",
backupFailed: "Det lykkedes IKKE at gemme en backup fil",
rssSaved: "RSS feed gemt",
rssFailed: "Det lykkedes IKKE at gemme et RSS feed",
emptySaved: "Tom skabelon gemt",
emptyFailed: "Det lykkedes IKKE at gemme en tom skabelon",
mainSaved: "Hoved TiddlyWiki fil gemt",
mainFailed: "Det lykkedes IKKE at gemme hoved TiddlyWiki filen. Dine Ʀndringer er IKKE blevet gemt",
macroError: "Fejl i makro <<\%0>>",
macroErrorDetails: "Fejl ved udfĆørsel af makro <<\%0>>:\n%1",
missingMacro: "Ingen sƄdan makro",
overwriteWarning: "En tiddler med navnet '%0' findes allerede. VƦlg OK for at overskrive den",
unsavedChangesWarning: "ADVARSEL! Der er ugemte Ʀmdringer i TiddlyWikien\n\nVƦlg OK for at gemme\nVƦlg FORTRYD for at afvise",
confirmExit: "--------------------------------\n\nDer er ugemte Ʀndringer i TiddlyWikien. Hvis du fortsƦtter vil du miste disse Ʀndringer\n\n--------------------------------",
saveInstructions: "GemĆndringer",
unsupportedTWFormat: "Ikke understĆøttet TiddlyWiki format '%0'",
tiddlerSaveError: "Fejl ved forsøg pÄ at gemme tiddler '%0'",
tiddlerLoadError: "Fejl ved load af tiddler '%0'",
wrongSaveFormat: "Kan ikke gemme med formatet '%0'. Bruger standard format til at gemme.",
invalidFieldName: "Ikke tilladt feltnavn %0",
fieldCannotBeChanged: "Felt '%0' kan ikke Ʀndres",
loadingMissingTiddler: "Forsøger at hente tiddleren '%0' fra '%1' serveren ved:\n\n'%2' i arbejdsomrÄdet '%3'",
upgradeDone: "Opgradering til version %0 er nu fuldfĆørt\n\nKlik 'OK' for at genopfriske den nyligt opgraderede TiddlyWiki"});
merge(config.messages.messageClose,{
text: "luk",
tooltip: "luk dette meddelelsesomrƄde"});
config.messages.backstage = {
open: {text: "bagscenen", tooltip: "Ć
ben bagsceneomrƄdet for at Ʀndre pƄ nogle grundlƦggende indstillinger"},
close: {text: "luk", tooltip: "Luk bagsceneomrƄdet"},
prompt: "bagscenen: ",
decal: {
edit: {text: "edit", tooltip: "RedigƩr tiddleren '%0'"}
}
};
config.messages.listView = {
tiddlerTooltip: "Klik for at se hele denne tiddlers tekst",
previewUnavailable: "(forhƄndsvisning er ikke tilgƦngelig)"
};
config.messages.dates.months = ["Januar", "Februar", "Marts", "April", "Maj", "Juni", "Juli", "August", "September", "Oktober", "November","December"];
config.messages.dates.days = ["SĆøndag", "Mandag", "Tirsdag", "Onsdag", "Torsdag", "Fredag", "LĆørdag"];
config.messages.dates.shortMonths = ["Jan", "Feb", "Mar", "Apr", "Maj", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dec"];
config.messages.dates.shortDays = ["SĆøn", "Man", "Tir", "Ons", "Tor", "Fre", "LĆør"];
// suffixes for dates, eg "1ste","2den","3die"..."30te","31te"
config.messages.dates.daySuffixes = ["ste","den","die","te","te","te","te","te","te","te",
"te","te","te","te","te","te","te","te","te","te",
"ste","den","die","te","te","te","te","te","te","te",
"te"];
config.messages.dates.am = "formiddag";
config.messages.dates.pm = "eftermiddag";
merge(config.messages.tiddlerPopup,{
});
merge(config.views.wikified.tag,{
labelNoTags: "ingen tags",
labelTags: "tags: ",
openTag: "Ć
ben tag '%0'",
tooltip: "Vis tiddlere der er taggede med '%0'",
openAllText: "Ć
ben alle",
openAllTooltip: "Ć
ben alle disse tiddlere",
popupNone: "Ingen andre tiddlere er taggede med '%0'"});
merge(config.views.wikified,{
defaultText: "Tiddleren '%0' findes ikke endnu. Dobbelt-klik for at lave den",
defaultModifier: "(mangler)",
shadowModifier: "(indbygget skygge tiddler)",
dateFormat: "DD MMM YYYY", // use this to change the date format for your locale, eg "YYYY MMM DD", do not translate the Y, M or D
createdPrompt: "lavet"});
merge(config.views.editor,{
tagPrompt: "Skriv tags delt med mellemrum, [[brug 2 dobbelte firkantede klammer]] om nĆødvendigt, eller tilfĆøj allerede eksisterende",
defaultText: "Skriv teksten til '%0'"});
merge(config.views.editor.tagChooser,{
text: "tags",
tooltip: "Vælg eksisterende tags som tilføjelse til denne tiddler",
popupNone: "Der er ikke defineret nogen tags",
tagTooltip: "TilfĆøj tagget '%0'"});
merge(config.messages,{
sizeTemplates:
[
{unit: 1024*1024*1024, template: "%0\u00a0GB"},
{unit: 1024*1024, template: "%0\u00a0MB"},
{unit: 1024, template: "%0\u00a0KB"},
{unit: 1, template: "%0\u00a0B"}
]});
merge(config.macros.search,{
label: "sĆøg",
prompt: "SĆøg i denne TiddlyWiki",
accessKey: "F",
successMsg: "Der er fundet %0 tiddlere som matcher %1",
failureMsg: "Der er ikke fundet nogen tiddlere som matcher %0"});
merge(config.macros.tagging,{
label: "tagger: ",
labelNotTag: "tagger ikke",
tooltip: "Liste over tiddlere der er taggede med '%0'"});
merge(config.macros.timeline,{
dateFormat: "DD MMM YYYY"});// use this to change the date format for your locale, eg "YYYY MMM DD", do not translate the Y, M or D
merge(config.macros.allTags,{
tooltip: "Vis tiddlere der er taggede med '%0'",
noTags: "Der er ingen taggede tiddlere"});
config.macros.list.all.prompt = "Alle tiddlere i alfabetisk orden";
config.macros.list.missing.prompt = "Tiddlere der linkes til men som ikke er definerede";
config.macros.list.orphans.prompt = "Tiddlere som der ikke linkes til fra nogen andre tiddlere";
config.macros.list.shadowed.prompt = "Tiddlere som er skyggede med grundlƦggende indhold";
config.macros.list.touched.prompt = "Tiddlere som er blevet Ʀndret lokalt ";
merge(config.macros.closeAll,{
label: "luk alle",
prompt: "Luk alle viste tiddlere (bortset fra dem, der aktuelt er Ƅbne for redigering)"});
merge(config.macros.permaview,{
label: "vis permalink",
prompt: "Lav et link til en URL som henter alle de netop nu synlige tiddlere"});
merge(config.macros.saveChanges,{
label: "gem Ʀndringer",
prompt: "Gem alle tiddlere for at lave en ny TiddlyWiki",
accessKey: "S"});
merge(config.macros.newTiddler,{
label: "ny tiddler",
prompt: "Lav en ny tiddler",
title: "Ny Tiddler",
accessKey: "N"});
merge(config.macros.newJournal,{
label: "ny journal",
prompt: "Lav en ny tiddler ud fra nuvƦrende dato og tid",
accessKey: "J"});
merge(config.macros.options,{
wizardTitle: "Tilpas avancerede muligheder",
step1Title: "Disse muligheder gemmes i cookies i din browser",
step1Html: "<input type='hidden' name='markList'></input><br><input type='checkbox' checked='false' name='chkUnknown'>Show unknown options</input>",
unknownDescription: "//(ukendt)//",
listViewTemplate: {
columns: [
{name: 'Option', field: 'option', title: "Option", type: 'String'},
{name: 'Description', field: 'description', title: "Description", type: 'WikiText'},
{name: 'Name', field: 'name', title: "Name", type: 'String'}
],
rowClasses: [
{className: 'lowlight', field: 'lowlight'}
]}
});
merge(config.macros.plugins,{
wizardTitle: "Administrer udvidelser",
step1Title: "Aktive udvidelser",
step1Html: "<input type='hidden' name='markList'></input>", // DO NOT TRANSLATE
skippedText: "(Denne udvidelse er ikke blevet aktiveret fordi den fĆørst er blevet tilfĆøjet efter start)",
noPluginText: "Der er ikke installeret nogen udvidelser",
confirmDeleteText: "Er du sikker pƄ at du vil slette disse udvidelser:\n\n%0",
removeLabel: "Fjern systemConfig tag",
removePrompt: "Fjern systemConfig tag",
deleteLabel: "slet",
deletePrompt: "Slet disse tiddlere permanent",
listViewTemplate: {
columns: [
{name: 'Selected', field: 'Selected', rowName: 'title', type: 'Selector'},
{name: 'Tiddler', field: 'tiddler', title: "Tiddler", type: 'Tiddler'},
{name: 'Size', field: 'size', tiddlerLink: 'size', title: "Size", type: 'Size'},
{name: 'Forced', field: 'forced', title: "Forced", tag: 'systemConfigForce', type: 'TagCheckbox'},
{name: 'Disabled', field: 'disabled', title: "Disabled", tag: 'systemConfigDisable', type: 'TagCheckbox'},
{name: 'Executed', field: 'executed', title: "Loaded", type: 'Boolean', trueText: "Yes", falseText: "No"},
{name: 'Startup Time', field: 'startupTime', title: "Startup Time", type: 'String'},
{name: 'Error', field: 'error', title: "Status", type: 'Boolean', trueText: "Error", falseText: "OK"},
{name: 'Log', field: 'log', title: "Log", type: 'StringList'}
],
rowClasses: [
{className: 'error', field: 'error'},
{className: 'warning', field: 'warning'}
]}
});
merge(config.macros.toolbar,{
moreLabel: "mere",
morePrompt: "Vis flere muligheder"
});
merge(config.macros.refreshDisplay,{
label: "genopfrisk",
prompt: "Genopfrisk hele TiddlyWikiens udseende"
});
merge(config.macros.importTiddlers,{
readOnlyWarning: "Du kan ikke importere til en lÄst TiddlyWiki fil. Prøv at Äbne den fra en fil:// URL",
wizardTitle: "Importer tiddlere fra en anden fil eller server",
step1Title: "Trin 1: Find serveren eller TiddlyWiki filen",
step1Html: "Vælg servertypen: <select name='selTypes'><option value=''>Choose...</option></select><br>Indskriv webadresse eller sti her: <input type='text' size=50 name='txtPath'><br>...eller søg efter en fil: <input type='file' size=50 name='txtBrowse'><br><hr>...eller vælg et forudbestemt feed: <select name='selFeeds'><option value=''>Vælg...</option></select>",
openLabel: "Ƅbn",
openPrompt: "Ć
bn forbindelsen til denne fil eller server",
openError: "Der var problemer med at hente tiddlywiki filen",
statusOpenHost: "Forbinder til hosten",
statusGetWorkspaceList: "Henter en liste over tilgƦngelige arbejdsomrƄder",
step2Title: "Trin 2: VƦlg arbejdsomrƄde",
step2Html: "Indskriv et navn pƄ arbejdsomrƄdet: <input type='text' size=50 name='txtWorkspace'><br>...eller vƦlg et der allerede er der: <select name='selWorkspace'><option value=''>Choose...</option></select>",
cancelLabel: "fortryd",
cancelPrompt: "Fortryd denne import",
statusOpenWorkspace: "Ć
ben arbejdsomrƄdet",
statusGetTiddlerList: "Henter listen over tilgƦngelige tiddlere",
errorGettingTiddlerList: "Fejl ved hentning af liste over tiddlere, klik Fortryd for at prĆøve igen",
step3Title: "Trin 3: VƦlg hvilke tiddlere der skal importeres",
step3Html: "<input type='hidden' name='markList'></input><br><input type='checkbox' checked='true' name='chkSync'>Keep these tiddlers linked to this server so that you can synchronise subsequent changes</input><br><input type='checkbox' name='chkSave'>Save the details of this server in a 'systemServer' tiddler called:</input> <input type='text' size=25 name='txtSaveTiddler'>",
importLabel: "importer",
importPrompt: "Importer disse tiddlere",
confirmOverwriteText: "Er du sikker pƄ at du vil overskrive disse tiddlere:\n\n%0",
step4Title: "Trin 4: Importerer %0 tiddler(e)",
step4Html: "<input type='hidden' name='markReport'></input>", // DO NOT TRANSLATE
doneLabel: "udfĆørt",
donePrompt: "Luk denne wizard",
statusDoingImport: "Importerer tiddlere",
statusDoneImport: "Alle tiddlere er importede",
systemServerNamePattern: "%2 on %1",
systemServerNamePatternNoWorkspace: "%1",
confirmOverwriteSaveTiddler: "Tiddleren '%0' findes allerede. Klik 'OK' for at overskrive den med detaljerne fra denne server, eller 'Fortryd' for at efterlade uƦndret",
serverSaveTemplate: "|''Type:''|%0|\n|''URL:''|%1|\n|''Workspace:''|%2|\n\nDenne tiddler blev lavet automatisk for at skrive denne servers detaljer",
serverSaveModifier: "(System)",
listViewTemplate: {
columns: [
{name: 'Selected', field: 'Selected', rowName: 'title', type: 'Selector'},
{name: 'Tiddler', field: 'tiddler', title: "Tiddler", type: 'Tiddler'},
{name: 'Size', field: 'size', tiddlerLink: 'size', title: "Size", type: 'Size'},
{name: 'Tags', field: 'tags', title: "Tags", type: 'Tags'}
],
rowClasses: [
]}
});
merge(config.macros.upgrade,{
wizardTitle: "Opgrader TiddlyWikis kerne kode",
step1Title: "Opdater eller reparer denne TiddlyWiki til sidste nye udgivelse",
step1Html: "Du er ved at opgradere til sidste nye udgave af TiddlyWikis kerne kode (from <a href='%0' class='externalLink' target='_blank'>%1</a>). Dit indhold vil blive bibeholdt under opgraderinen.<br><br>BemƦrk at opgraderinger kan konfikte med gamle udvidelser. Hvis du fƄr problemer med den opgraderede fil se her <a href='http://www.tiddlywiki.org/wiki/CoreUpgrades' class='externalLink' target='_blank'>http://www.tiddlywiki.org/wiki/CoreUpgrades</a>",
errorCantUpgrade: "Kan ikke opgradere denne TiddlyWiki. Du kan kun opgradere en TiddlyWiki fil som er gemt lokalt pƄ en pc",
errorNotSaved: "Du skal gemme ændringer før du kan gennemføre en opgradering",
step2Title: "BekrƦft opgraderingsdetaljer",
step2Html_downgrade: "Du er ved at nedgradere til TiddlyWiki version %0 fra %1.<br><br>Nedgradering til en Ʀldre udgave af kerne koden er IKKE tilrƄdeligt",
step2Html_restore: "Denne tiddlyWike bruger allerede den sidste nye kerne kode (%0).<br><br>Du kan fortsætte med opgraderingen for at sikre dig at koden ikke er blevet ødelagt",
step2Html_upgrade: "Du er ved at opgradere til TiddlyWiki version %0 fra %1",
upgradeLabel: "opgrader",
upgradePrompt: "Forbered opgraderingsprocessen",
statusPreparingBackup: "Forbereder backup",
statusSavingBackup: "Gemmer backup fil",
errorSavingBackup: "Der var problemer med at gemme backup filen",
statusLoadingCore: "Loader kernekoden",
errorLoadingCore: "Fejl ved load af kernekoden",
errorCoreFormat: "Fejl ved den nye kernekode",
statusSavingCore: "Gemmer den nye kernekode",
statusReloadingCore: "Genloader den nye kernekode",
startLabel: "start",
startPrompt: "Start opgraderingsprocessen",
cancelLabel: "fortryd",
cancelPrompt: "Fortryd opgraderingsprocessen",
step3Title: "Opgradering afbrudt",
step3Html: "Du har afbrudt opgraderingsprocessen"
});
merge(config.macros.sync,{
listViewTemplate: {
columns: [
{name: 'Selected', field: 'selected', rowName: 'title', type: 'Selector'},
{name: 'Tiddler', field: 'tiddler', title: "Tiddler", type: 'Tiddler'},
{name: 'Server Type', field: 'serverType', title: "Server type", type: 'String'},
{name: 'Server Host', field: 'serverHost', title: "Server host", type: 'String'},
{name: 'Server Workspace', field: 'serverWorkspace', title: "Server workspace", type: 'String'},
{name: 'Status', field: 'status', title: "Synchronisation status", type: 'String'},
{name: 'Server URL', field: 'serverUrl', title: "Server URL", text: "View", type: 'Link'}
],
rowClasses: [
],
buttons: [
{caption: "SynkronisƩr disse tiddlere", name: 'sync'}
]},
wizardTitle: "Synkroniser med internet servere og filer",
step1Title: "VƦlg hvilke tiddlere du vil synkronisere",
step1Html: "<input type='hidden' name='markList'></input>", // DO NOT TRANSLATE
syncLabel: "synk",
syncPrompt: "SynkronisƩr disse tiddlere",
hasChanged: "Ćndret imens den var koblet fra",
hasNotChanged: "UƦndret imens den var koblet fra",
syncStatusList: {
none: {text: "...", color: "gennemsigtig", display:null},
changedServer: {text: "Ćndret pĆ„ serveren", color: '#8080ff', display:null},
changedLocally: {text: "Ćndret imens den var koblet fra", color: '#80ff80', display:null},
changedBoth: {text: "Ʀndret imens den var koblet fra ogsƄ pƄ serveren", color: '#ff8080', display:null},
notFound: {text: "Ikke fundet pƄ serveren", color: '#ffff80', display:null},
putToServer: {text: "Gemt update pƄ serveren", color: '#ff80ff', display:null},
gotFromServer: {text: "Hentet update fra serveren", color: '#80ffff', display:null}
}
});
merge(config.commands.closeTiddler,{
text: "luk",
tooltip: "Luk denne tiddler"});
merge(config.commands.closeOthers,{
text: "luk andre",
tooltip: "Luk alle andre tiddlere"});
merge(config.commands.editTiddler,{
text: "redigƩr",
tooltip: "RedigƩr denne tiddler",
readOnlyText: "se",
readOnlyTooltip: "Se denne tiddlers kilde"});
merge(config.commands.saveTiddler,{
text: "fƦrdig",
tooltip: "Gem Ʀndringer til denne tiddler"});
merge(config.commands.cancelTiddler,{
text: "fortryd",
tooltip: "Fortryd Ʀndringer til denne tiddler",
warning: "Er du sikker pƄ at du vil fortryde dine Ʀndringer til '%0'?",
readOnlyText: "fƦrdig",
readOnlyTooltip: "Se tiddlere normalt"});
merge(config.commands.deleteTiddler,{
text: "slet",
tooltip: "Slet denne tiddler",
warning: "Er du sikker pƄ at du vil slette '%0'?"});
merge(config.commands.permalink,{
text: "permalink",
tooltip: "Permalink til denne tiddler"});
merge(config.commands.references,{
text: "referencer",
tooltip: "Vis tiddlere som linker til denne tiddler",
popupNone: "Ingen referencer"});
merge(config.commands.jump,{
text: "spring",
tooltip: "Spring til en anden tiddler"});
merge(config.commands.syncing,{
text: "synkroniserer",
tooltip: "Kontroller synkronisering af denne tiddler med en server eller en fil",
currentlySyncing: "<div>Currently syncing via <span class='popupHighlight'>'%0'</span> to:</"+"div><div>host: <span class='popupHighlight'>%1</span></"+"div><div>workspace: <span class='popupHighlight'>%2</span></"+"div>", // Note escaping of closing <div> tag
notCurrentlySyncing: "Sykroniserer ikke lige nu",
captionUnSync: "Stop synkronisering af denne tiddler",
chooseServer: "SynkronisƩr denne tiddler med en anden server:",
currServerMarker: "\u25cf ",
notCurrServerMarker: " "});
merge(config.commands.fields,{
text: "felter",
tooltip: "Vis denne tiddlers udvidede felter",
emptyText: "Der er ingen udvidede felter til rƄdighed for denne tiddler",
listViewTemplate: {
columns: [
{name: 'Field', field: 'field', title: "Field", type: 'String'},
{name: 'Value', field: 'value', title: "Value", type: 'String'}
],
rowClasses: [
],
buttons: [
]}});
merge(config.shadowTiddlers,{
DefaultTiddlers: "[[Kom i gang]]",
MainMenu: "[[Kom i gang]]\n\n\n^^~TiddlyWiki version <<version>>\nĆĀ© 2007 [[UnaMesa|http://www.unamesa.org/]]^^",
"Kom i gang": "For at komme i gang med denne tomme tiddlywiki, skal du ændre pÄ de følgende tiddlere:\n* SiteTitle & SiteSubtitle: Sidens titel og undertitel, som vist øverst (efter de er gemt, vil de ogsÄ vise sig i browserens titelmenu)\n* MainMenu: er hovedmenuen (er oftest placeret til venstre)\n* DefaultTiddlers: Indeholder navnene pÄ de tiddlere du vilhave skal starte op nÄr du Äbner TiddlyWiki\nDu skal ogsÄ skrive dit brugernavn for at signere dine redigeringer: <<option txtUserName>>",
SiteTitle: "Min TiddlyWiki",
SiteSubtitle: "en genbrugelig ikke-liniƦr personlig web notesbog",
SiteUrl: "http://www.tiddlywiki.com/",
OptionsPanel: "Disse muligheder for at ændre pÄ TiddlyWiki bliver gemt i din browser\n\nDit brugernavn til at signere dine ændringer. Skriv det som et WikiOrd (f.eks. PerPoulsen)\n<<option txtUserName>>\n\n<<option chkSaveBackups>> Gem backups\n<<option chkAutoSave>> Gem automatisk\n<<option chkRegExpSearch>> Regexp search\n<<option chkCaseSensitiveSearch>> Søg m forskel pÄ store og smÄ bogstaver\n<<option chkAnimate>> Tillad animationer\n\n----\nSe ogsÄ [[Avancerede muligheder|AdvancedOptions]]",
SideBarOptions: '<<search>><<closeAll>><<permaview>><<newTiddler>><<newJournal "DD MMM YYYY" "journal">><<saveChanges>><<slider chkSliderOptionsPanel OptionsPanel "muligheder \u00bb" "Tilpas TiddlyWikis avancerede muligheder">>',
SideBarTabs: '<<tabs txtMainTab "Tidslinie" "Tidslinie" TabTimeline "Alle" "Alle tiddlere" TabAll "Tags" "Alle tags" TabTags "Flere" "Flere lister" TabMore>>',
TabMore: '<<tabs txtMoreTab "Manglende" "Manglende tiddlere" TabMoreMissing "Uden tilknytning" "Tiddlere" TabMoreOrphans "Skyggede" "Skyggede tiddlere" TabMoreShadowed>>'
});
merge(config.annotations,{
AdvancedOptions: "Denne skygge tiddler giver adgang til flere avancerede muligheder",
ColorPalette: "Disse vƦrdier i denne skyggetiddler bestemmer hvilket farveskema, der bliver brugt til ~TiddlyWikis brugerflade",
DefaultTiddlers: "Tiddlere som er listede i denne skyggetiddler vil automatisk blive vist nƄr ~TiddlyWiki starter op",
EditTemplate: "HTML skabelonen i denne skyggetiddler bestemmer hvordan tiddlere ser ud nƄr de bliver redigerede",
GettingStarted: "Denne skyggetiddler giver instruktioner om grundlƦggende anvendelse",
ImportTiddlers: "Denne skyggetiddler giver mulighed for at importere tiddlere",
MainMenu: "Denne tiddler bliver brugt til at definere indholdet af hoved menuen i venstre side af skƦrmen",
MarkupPreHead: "Denne tiddler bliver indsat i toppen af <head> sektionen pƄ TiddlyWiki HTML filen",
MarkupPostHead: "Denne tiddler bliver indsat i bunden af <head> sektionen pƄ TiddlyWiki HTML filen",
MarkupPreBody: "Denne tiddler bliver indsat i toppen af<body> sektionen pƄ TiddlyWiki HTML filen",
MarkupPostBody: "Denne tiddler bliver indsat i slutningen af <body> sektionen pƄ TiddlyWiki HTML filen umiddelbart efter script blokken",
OptionsPanel: "Denne skyggetiddler bliver brugt til indholdet af muligheder skydepanelet i hĆøjre side",
PageTemplate: "HTML skabelonen i denne skyggetiddler bestemmer det overordnede ~TiddlyWiki layout",
PluginManager: "Denne skyggetiddler giver adgang til udvidelsesadministrationen",
SideBarOptions: "Denne skyggetiddler bruges til indholdet af muligheder panelet i hĆøjre sidemenu",
SideBarTabs: "Denne skyggetiddler bruges til indholdet af fanebladspanelet i hĆøjre sidemenu",
SiteSubtitle: "Denne skyggetiddler bruges som anden del af sidens titel",
SiteTitle: "Denne skyggetiddler bruges som fĆørste del af sidens titel",
SiteUrl: "Denne skyggetiddler bør sættes til den fulde mÄl-URL til publikation",
StyleSheetColors: "Denne skyggetiddler indeholder CSS definitionerne der bestemmer farverne pĆ„ side elementerne. ''REDIGĆR IKKE DENNE TIDDLER'', lav i stedet dine Ʀndringer i StyleSheet skyggetiddleren",
StyleSheet: "Denne tiddler kan indeholde specialle CSS definitioner",
StyleSheetLayout: "Denne skyggetiddler indeholder CSS definitioner der bestemmer layoutet pĆ„ side elementer. ''REDIGĆR IKKE DENNE TIDDLER'', lav i stedet dine Ʀndringer i StyleSheet skyggetiddleren",
StyleSheetLocale: "Denne skyggetiddler indeholder CSS definitioner relateret til lokale oversƦttelser",
StyleSheetPrint: "Denne skyggetiddler indeholder CSS definitioner til print",
TabAll: "Denne skyggetiddler indeholder hvad der er i 'Alle' fanen i hĆøjre sidemenu",
TabMore: "Denne skyggetiddler indeholder hvad der er i 'Flere' fanen i hĆøjre sidemenu",
TabMoreMissing: "Denne skyggetiddler indeholder hvad der er i 'Mangler' fanen i hĆøjre sidemenu",
TabMoreOrphans: "Denne skyggetiddler indeholder hvad der er i 'Mangler tilknytning' fanen i hĆøjre sidemenu",
TabMoreShadowed: "Denne skyggetiddler indeholder hvad der er i 'Skyggede' fanen i hĆøjre sidemenu",
TabTags: "Denne skyggetiddler indeholder hvad der er i 'Tags' fanen i hĆøjre sidemenu",
TabTimeline: "Denne skyggetiddler indeholder hvad der er i 'Tidslinie' fanen i hĆøjre sidemenu",
ToolbarCommands: "Denne skyggetiddler bestemmer hvilke værktøjer der vises i tiddleres værktøjslinier",
ViewTemplate: "HTML skabelonen i denne skyggetiddler bestemmer hvordan tiddlere ser ud"
});
//}}}
| !panelname| !x | !y | !w | !h | !z | !fold | !hover |h
| searchresults| 294| 26| 434| auto| 139| | |
| Kom i gang| 115| 223| 687| auto| 250| ā | |
| cloth052.jpg| 230| 267| 361| auto| 256| ā | |
| tabs| -92| 271| 216| auto| 306| | |
| MoveableTheme| 60| 305| 664| auto| 350| | |
| mainmenu| 14| 48| auto| auto| 351| | |
| header| 394| 40| 258| 21| 352| | |
| options| -66| 29| 188| auto| 354| | |
| basket| 584| 97| 77| 42| 355| | |
[[MoveableTheme]]
[[Kom i gang]]
[[cloth052.jpg]]
/***
|Name|[[DragScrollPlugin]]|
|Source|http://www.TiddlyTools.com/#DragScrollPlugin|
|Documentation|http://www.TiddlyTools.com/#DragScrollPlugin|
|Version|1.0.0|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Description|use SHIFT-DRAG to scroll the browser window|
DragScrollPlugin allows you to use your mouse to scroll the browser window by grabbing anywhere on the background of the document while holding the SHIFT key.
!!!!!Documentation
<<<
Whenever your page contains extra-wide content that does not 'wrap' onto extra lines, in can result in both horizontal and vertical scrollbars. Unfortunately, using each scrollbar separately to navigate across the page can become very tedious and makes it more difficult to interact with your content in a flexible and effective manner.
''Drag-scrolling allows you to move in both the horizontal and vertical direction at the same time, simply by holding SHIFT while clicking and dragging the mouse across the page.''
<<<
!!!!!Configuration
<<<
<<option chkDragScroll>> enable //drag-scrolling//
<<<
!!!!!Revisions
<<<
2008.12.01 [1.0.0] Initial public release
<<<
!!!!!Code
***/
//{{{
version.extensions.DragScrollPlugin= {major: 1, minor: 0, revision: 0, date: new Date(2008,12,01)};
if (!config.dragscroll) { // only once
config.dragscroll={
// use to end event handling for processed events
processed: function(ev) {
var ev=ev||window.event;
if (ev) { ev.cancelBubble=true; if (ev.stopPropagation) ev.stopPropagation(); }
return false;
},
// MOUSE DOWN - SET CURSOR, SAVE SCROLL DATA
savedMouseDown: document.onmousedown,
mousedown: function(ev) {
var ev=ev||window.event; var target=resolveTarget(ev); var d=config.dragscroll;
var scroll=ev.shiftKey&&config.options.chkDragScroll;
var skip=['input','option','textarea'].contains(target.nodeName.toLowerCase());
if (!scroll||skip) { // handle event normally
if (d.savedMouseDown!=undefined) return d.savedMouseDown.apply(target,arguments);
else return;
}
d.mX=!config.browser.isIE?ev.pageX:ev.clientX; d.sX=findScrollX();
d.mY=!config.browser.isIE?ev.pageY:ev.clientY; d.sY=findScrollY();
d.scrolling=true; document.body.style.cursor='move';
return config.dragscroll.processed(ev);
},
// MOUSE MOVE - UPDATE SCROLL DATA AND SCROLL THE WINDOW
savedMouseMove: document.onmousemove,
mousemove: function(ev) {
var ev=ev||window.event; var target=resolveTarget(ev); var d=config.dragscroll;
if (!d.scrolling || !ev.shiftKey) { // NOT SCROLLING
if (d.savedMouseMove!=undefined) return d.savedMouseMove.apply(target,arguments);
else return;
}
// set scroll pos based on diff between new and old (x,y)
var mx=!config.browser.isIE?ev.pageX:ev.clientX;
var my=!config.browser.isIE?ev.pageY:ev.clientY;
var sx=!config.browser.isIE?findScrollX():d.sX;
var sy=!config.browser.isIE?findScrollY():d.sY;
window.scrollTo(sx-mx+d.mX,sy-my+d.mY);
return config.dragscroll.processed(ev);
},
// MOUSEUP - CLEAR THE DRAG DATA, RESET THE CURSOR
savedMouseUp: document.onmouseup,
mouseup: function(ev) {
var ev=ev||window.event; var target=resolveTarget(ev); var d=config.dragscroll;
var wasScrolling=d.scrolling; d.scrolling=false; document.body.style.cursor='auto';
if (d.savedMouseUp!=undefined) return d.savedMouseUp.apply(target,arguments);
if (wasScrolling) return config.dragscroll.processed(ev);
return;
}
}
// DEFAULT SETTING (ENABLED)
if (config.options.chkDragScroll===undefined) config.options.chkDragScroll=true;
// HIJACK MOUSE HANDLERS
document.onmousedown=config.dragscroll.mousedown;
document.onmousemove=config.dragscroll.mousemove;
document.onmouseup =config.dragscroll.mouseup;
}
//}}}
/***
|Name|FileDropPlugin|
|Source|http://www.TiddlyTools.com/#FileDropPlugin|
|Version|2.1.4|
|Author|BradleyMeck and Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Description|drag-and-drop files/directories to create tiddlers|
''requires FireFox or another Mozilla-compatible browser.''
!!!!!Usage
<<<
This plugin automatically creates tiddlers from files that are dropped onto an open TiddlyWiki document. You can drop multiple selected files and/or folders to create many tiddlers at once. New tiddler titles are created using the filename of each dropped file (i.e., omitting the path). If a title is already in use, you are prompted to enter a new title for that file. If you drop a folder, you will be asked if you want to create a simple 'directory list' of files in a single tiddler or create one tiddler for each file in that folder.
By default, it is assumed that all dropped files contain text. However, if [[AttachFilePlugin]], [[AttachFilePluginFormatters]] and [[AttachFileMIMETypes]] are installed, then you can drop ''//binary data files//'' as well as text files. If the MIME type of a dropped file is not "text/plain", then AttachFilePlugin is used to create an 'attachment' tiddler, rather than creating a simple text tiddler.
When creating text tiddlers, you can embed a //link// to the original external file at the top of the new tiddler, in addition to (or instead of) the text content itself. The format for this link (see Configuration, below) uses embedded ''//replacement markers//'' that allow you to generate a variety of wiki-formatted output, where:
*%0 = filename (without path)
*%1 = local """file://...""" URL
*%2 = local path and filename (OS-native format)
*%3 = relative path (if subdirectory of current document directory)
*%4 = file size
*%5 = file date
*%6 = current date
*%7 = current ~TiddlyWiki username
*\n = newline
By default, the link format uses the filename (%0) and local URL (%1), enclosed within a //hidden section// syntax, like this:
{{{
/%
!link
[[%0|%1]]
!end
%/
}}}
This permits the link to be embedded along with the text content, without changing the appearance of that content when the tiddler is viewed. To display the link in your tiddler content, use:
{{{
<<tiddler TiddlerName##link>>
}}}
<<<
!!!!!Configuration
<<<
__FileDropPlugin options:__
<<option chkFileDropContent>>Copy file content into tiddlers if smaller than: <<option txtFileDropDataLimit>> bytes
//(note: excess text content will be truncated, oversized binary files will skipped, 0=no limit)//
<<option chkFileDropLink>>Generate external links to files, using this format:{{editor{<html><nowiki><textarea rows="4" onchange="
config.macros.option.propagateOption('txtFileDropLinkFormat','value',this.value.escapeLineBreaks(),'input');
"></textarea></html><<tiddler {{
var ta=place.lastChild.getElementsByTagName('textarea')[0];
var v=config.options.txtFileDropLinkFormat.unescapeLineBreaks();
ta.value=v;
"";}}>>}}}<<option chkFileDropTrimFilename>>Omit file extensions from tiddler titles
<<option chkFileDropDisplay>>Automatically display newly created tiddlers
Tag newly created tiddlers with: <<option txtFileDropTags>>
__FileDropPlugin+AttachFilePlugin options:__ //(binary file data as encoded 'base64' text)//
<<option chkFileDropAttachLocalLink>> attachment includes reference to local path/filename
>Note: if the plugin does not seem to work, enter ''about:config'' in the Firefox address bar, and make sure that {{{signed.applets.codebase_principal_support}}} is set to ''true''
<<<
!!!!!Examples (custom handler functions)
<<<
Adds a single file with confirmation and prompting for title:
{{{
config.macros.fileDrop.addEventListener('application/x-moz-file',
function(nsiFile) {
var msg='You have dropped the file:\n'
+nsiFile.path+'\n'
+'onto the page, it will be imported as a tiddler. Is that ok?'
if(confirm(msg)) {
var newDate = new Date();
var title = prompt('what would you like to name the tiddler?');
store.saveTiddler(title,title,loadFile(nsiFile.path),config.options.txtUserName,newDate,[]);
}
return true;
});
}}}
Adds a single file without confirmation, using path/filename as tiddler title:
{{{
config.macros.fileDrop.addEventListener('application/x-moz-file',
function(nsiFile) {
var newDate = new Date();
store.saveTiddler(nsiFile.path,nsiFile.path,loadFile(nsiFile.path),config.options.txtUserName,newDate,[]);
story.displayTiddler(null,nsiFile.path)
return true;
});
}}}
<<<
!!!!!Revisions
<<<
2010.03.06 2.1.4 added event listener for 'dragover' (for FireFox 3.6+)
2009.10.10 2.1.3 fixed IE code error
2009.10.08 2.1.2 fixed chkFileDropContent bypass handling for binary attachments
2009.10.07 2.1.0 added chkFileDropContent and chkFileDropLink/txtFileDropLinkFormat
2009.08.19 2.0.0 fixed event listener registration for FireFox 3.5+. Also, merged with FileDropPluginConfig, with code cleanup/reduction
2008.08.11 1.5.1 added chkFileDropAttachLocalLink option to allow suppression of local path/file link
2007.xx.xx *.*.* add suspend/resume of notifications to improve performance when multiple files are handled
2007.01.01 0.9.9 extensions for AttachFilePlugin
2006.11.04 0.1.1 initial release by Bradley Meck
<<<
!!!!!Code
***/
//{{{
version.extensions.FileDropPlugin={major:2, minor:1, revision:4, date: new Date(2010,3,6)};
config.macros.fileDrop = {
customDropHandlers: [],
addEventListener: function(paramflavor,func,inFront) {
var obj={}; obj.flavor=paramflavor; obj.handler=func;
if (!inFront) this.customDropHandlers.push(obj);
else this.customDropHandlers.shift(obj);
},
dragDropHandler: function(evt) {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
var dragService = Components.classes['@mozilla.org/widget/dragservice;1'].getService(Components.interfaces.nsIDragService);
var dragSession = dragService.getCurrentSession();
var transferObject = Components.classes['@mozilla.org/widget/transferable;1'].createInstance();
transferObject = transferObject.QueryInterface(Components.interfaces.nsITransferable);
transferObject.addDataFlavor('application/x-moz-file');
var numItems = dragSession.numDropItems;
if (numItems>1) {
clearMessage();
displayMessage('Reading '+numItems+' files...');
store.suspendNotifications();
}
for (var i = 0; i < numItems; i++) {
dragSession.getData(transferObject, i);
var dataObj = {};
var dropSizeObj = {};
for(var ind=0; ind<config.macros.fileDrop.customDropHandlers.length; ind++) {
var item = config.macros.fileDrop.customDropHandlers[ind];
if(dragSession.isDataFlavorSupported(item.flavor)) {
transferObject.getTransferData(item.flavor, dataObj, dropSizeObj);
var droppedFile = dataObj.value.QueryInterface(Components.interfaces.nsIFile);
var result = item.handler.call(item,droppedFile);
evt.stopPropagation();
evt.preventDefault();
if (result) break;
}
}
}
if (numItems>1) {
store.resumeNotifications();
store.notifyAll();
displayMessage(numItems+' files have been processed');
}
}
}
//}}}
/***
!!!!!window event handlers
***/
//{{{
if(!window.event) {
window.addEventListener('dragdrop', // FireFox3.1-
config.macros.fileDrop.dragDropHandler, true);
window.addEventListener('drop', // FireFox3.5+
config.macros.fileDrop.dragDropHandler, true);
window.addEventListener('dragover', // FireFox3.6+
function(e){e.stopPropagation();e.preventDefault();}, true);
}
//}}}
/***
!!!!!handler for files, directories and binary attachments (see [[AttachFilePlugin]])
***/
//{{{
var defaults={
chkFileDropDisplay: true,
chkFileDropTrimFilename: false,
chkFileDropContent: true,
chkFileDropLink: true,
txtFileDropLinkFormat: '/%\\n!link\\n[[%0|%1]]\\n!end\\n%/',
txtFileDropDataLimit: '32768',
chkFileDropAttachLocalLink: true,
txtFileDropTags: ''
};
for (var id in defaults) if (config.options[id]===undefined)
config.options[id]=defaults[id];
config.macros.fileDrop.addEventListener('application/x-moz-file',function(nsiFile) {
var co=config.options; // abbrev
var header='Index of %0\n^^(as of %1)^^\n|!filename| !size | !modified |\n';
var item='|[[%0|%1]]| %2|%3|\n';
var footer='Total of %0 bytes in %1 files\n';
var now=new Date();
var files=[nsiFile];
if (nsiFile.isDirectory()) {
var folder=nsiFile.directoryEntries;
var files=[];
while (folder.hasMoreElements()) {
var f=folder.getNext().QueryInterface(Components.interfaces.nsILocalFile);
if (f instanceof Components.interfaces.nsILocalFile && !f.isDirectory()) files.push(f);
}
var msg=nsiFile.path.replace(/\\/g,'/')+'\n\n';
msg+='contains '+files.length+' files... ';
msg+='select OK to attach all files or CANCEL to create a list...';
if (!confirm(msg)) { // create a list in a tiddler
var title=nsiFile.leafName; // tiddler name is last directory name in path
while (title && title.length && store.tiddlerExists(title)) {
if (confirm(config.messages.overwriteWarning.format([title]))) break;
title=prompt('Enter a new tiddler title',nsiFile.path.replace(/\\/g,'/'));
}
if (!title || !title.length) return true; // cancelled
var text=header.format([nsiFile.path.replace(/\\/g,'/'),now.toLocaleString()]);
var total=0;
for (var i=0; i<files.length; i++) { var f=files[i];
var name=f.leafName;
if (co.chkFileDropTrimFilename)
{ var p=name.split('.'); if (p.length>1) p.pop(); name=p.join('.'); }
var path='file:///'+f.path.replace(/\\/g,'/');
var size=f.fileSize; total+=size;
var when=new Date(f.lastModifiedTime).formatString('YYYY.0MM.0DD 0hh:0mm:0ss');
text+=item.format([name,path,size,when]);
}
text+=footer.format([total,files.length]);
var newtags=co.txtFileDropTags?co.txtFileDropTags.readBracketedList():[];
store.saveTiddler(null,title,text,co.txtUserName,now,newtags);
if (co.chkFileDropDisplay) story.displayTiddler(null,title);
return true;
}
}
if (files.length>1) store.suspendNotifications();
for (i=0; i<files.length; i++) {
var file=files[i];
if (file.isDirectory()) continue; // skip over nested directories
var type='text/plain';
var title=file.leafName; // tiddler name is file name
if (co.chkFileDropTrimFilename)
{ var p=title.split('.'); if (p.length>1) p.pop(); title=p.join('.'); }
var name=file.leafName;
var path=file.path;
var url='file:///'+path.replace(/\\/g,'/');
var size=file.fileSize;
var when=new Date(file.lastModifiedTime);
var now=new Date();
var who=config.options.txtUserName;
var h=document.location.href;
var cwd=getLocalPath(decodeURIComponent(h.substr(0,h.lastIndexOf('/')+1)));
var relpath=path.startsWith(cwd)?'./'+path.substr(cwd.length):path;
while (title && title.length && store.tiddlerExists(title)) {
if (confirm(config.messages.overwriteWarning.format([title]))) break;
title=prompt('Enter a new tiddler title',path.replace(/\\/g,'/'));
}
if (!title || !title.length) continue; // cancelled
if (config.macros.attach) {
type=config.macros.attach.getMIMEType(name,'');
if (!type.length)
type=prompt('Unknown file type. Enter a MIME type','text/plain');
if (!type||!type.length) continue; // cancelled
}
var newtags=co.txtFileDropTags?co.txtFileDropTags.readBracketedList():[];
if (type=='text/plain' || !co.chkFileDropContent) {
var txt=''; var fmt=co.txtFileDropLinkFormat.unescapeLineBreaks();
if (co.chkFileDropLink) txt+=fmt.format([name,url,path,relpath,size,when,now,who]);
if (co.chkFileDropContent) {
var out=loadFile(path); var lim=co.txtFileDropDataLimit;
txt+=co.txtFileDropDataLimit?out.substr(0,lim):out;
if (size>lim) txt+='\n----\nfilesize ('+size+')'
+' is larger than FileDrop limit ('+lim+')...\n'
+'additional content has been omitted';
}
store.saveTiddler(null,title,txt,co.txtUserName,now,newtags);
} else {
var embed=co.chkFileDropContent
&& (!co.txtFileDropDataLimit||size<co.txtFileDropDataLimit);
newtags.push('attachment'); newtags.push('excludeMissing');
config.macros.attach.createAttachmentTiddler(path,
now.formatString(config.macros.timeline.dateFormat),
'attached by FileDropPlugin', newtags, title,
embed, co.chkFileDropAttachLocalLink, false,
relpath, '', type,!co.chkFileDropDisplay);
}
if (co.chkFileDropDisplay) story.displayTiddler(null,title);
}
if (files.length>1) { store.resumeNotifications(); store.notifyAll(); }
return true;
})
//}}}
/***
|Name|ImageSizePlugin|
|Source|http://www.TiddlyTools.com/#ImageSizePlugin|
|Version|1.2.3|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Description|adds support for resizing images|
This plugin adds optional syntax to scale an image to a specified width and height and/or interactively resize the image with the mouse.
!!!!!Usage
<<<
The extended image syntax is:
{{{
[img(w+,h+)[...][...]]
}}}
where ''(w,h)'' indicates the desired width and height (in CSS units, e.g., px, em, cm, in, or %). Use ''auto'' (or a blank value) for either dimension to scale that dimension proportionally (i.e., maintain the aspect ratio). You can also calculate a CSS value 'on-the-fly' by using a //javascript expression// enclosed between """{{""" and """}}""". Appending a plus sign (+) to a dimension enables interactive resizing in that dimension (by dragging the mouse inside the image). Use ~SHIFT-click to show the full-sized (un-scaled) image. Use ~CTRL-click to restore the starting size (either scaled or full-sized).
<<<
!!!!!Examples
<<<
{{{
[img(100px+,75px+)[images/meow2.jpg]]
}}}
[img(100px+,75px+)[images/meow2.jpg]]
{{{
[<img(34%+,+)[images/meow.gif]]
[<img(21% ,+)[images/meow.gif]]
[<img(13%+, )[images/meow.gif]]
[<img( 8%+, )[images/meow.gif]]
[<img( 5% , )[images/meow.gif]]
[<img( 3% , )[images/meow.gif]]
[<img( 2% , )[images/meow.gif]]
[img( 1%+,+)[images/meow.gif]]
}}}
[<img(34%+,+)[images/meow.gif]]
[<img(21% ,+)[images/meow.gif]]
[<img(13%+, )[images/meow.gif]]
[<img( 8%+, )[images/meow.gif]]
[<img( 5% , )[images/meow.gif]]
[<img( 3% , )[images/meow.gif]]
[<img( 2% , )[images/meow.gif]]
[img( 1%+,+)[images/meow.gif]]
{{tagClear{
}}}
<<<
!!!!!Revisions
<<<
2011.09.03 [1.2.3] bypass addStretchHandlers() if no '+' suffix is used (i.e., not resizable)
2010.07.24 [1.2.2] moved tip/dragtip text to config.formatterHelpers.imageSize object to enable customization
2009.02.24 [1.2.1] cleanup width/height regexp, use '+' suffix for resizing
2009.02.22 [1.2.0] added stretchable images
2008.01.19 [1.1.0] added evaluated width/height values
2008.01.18 [1.0.1] regexp for "(width,height)" now passes all CSS values to browser for validation
2008.01.17 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.ImageSizePlugin= {major: 1, minor: 2, revision: 3, date: new Date(2011,9,3)};
//}}}
//{{{
var f=config.formatters[config.formatters.findByField("name","image")];
f.match="\\[[<>]?[Ii][Mm][Gg](?:\\([^,]*,[^\\)]*\\))?\\[";
f.lookaheadRegExp=/\[([<]?)(>?)[Ii][Mm][Gg](?:\(([^,]*),([^\)]*)\))?\[(?:([^\|\]]+)\|)?([^\[\]\|]+)\](?:\[([^\]]*)\])?\]/mg;
f.handler=function(w) {
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source)
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
var floatLeft=lookaheadMatch[1];
var floatRight=lookaheadMatch[2];
var width=lookaheadMatch[3];
var height=lookaheadMatch[4];
var tooltip=lookaheadMatch[5];
var src=lookaheadMatch[6];
var link=lookaheadMatch[7];
// Simple bracketted link
var e = w.output;
if(link) { // LINKED IMAGE
if (config.formatterHelpers.isExternalLink(link)) {
if (config.macros.attach && config.macros.attach.isAttachment(link)) {
// see [[AttachFilePluginFormatters]]
e = createExternalLink(w.output,link);
e.href=config.macros.attach.getAttachment(link);
e.title = config.macros.attach.linkTooltip + link;
} else
e = createExternalLink(w.output,link);
} else
e = createTiddlyLink(w.output,link,false,null,w.isStatic);
addClass(e,"imageLink");
}
var img = createTiddlyElement(e,"img");
if(floatLeft) img.align="left"; else if(floatRight) img.align="right";
if(width||height) {
var x=width.trim(); var y=height.trim();
var stretchW=(x.substr(x.length-1,1)=='+'); if (stretchW) x=x.substr(0,x.length-1);
var stretchH=(y.substr(y.length-1,1)=='+'); if (stretchH) y=y.substr(0,y.length-1);
if (x.substr(0,2)=="{{")
{ try{x=eval(x.substr(2,x.length-4))} catch(e){displayMessage(e.description||e.toString())} }
if (y.substr(0,2)=="{{")
{ try{y=eval(y.substr(2,y.length-4))} catch(e){displayMessage(e.description||e.toString())} }
img.style.width=x.trim(); img.style.height=y.trim();
if (stretchW||stretchH) config.formatterHelpers.addStretchHandlers(img,stretchW,stretchH);
}
if(tooltip) img.title = tooltip;
// GET IMAGE SOURCE
if (config.macros.attach && config.macros.attach.isAttachment(src))
src=config.macros.attach.getAttachment(src); // see [[AttachFilePluginFormatters]]
else if (config.formatterHelpers.resolvePath) { // see [[ImagePathPlugin]]
if (config.browser.isIE || config.browser.isSafari) {
img.onerror=(function(){
this.src=config.formatterHelpers.resolvePath(this.src,false);
return false;
});
} else
src=config.formatterHelpers.resolvePath(src,true);
}
img.src=src;
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
}
config.formatterHelpers.imageSize={
tip: 'SHIFT-CLICK=show full size, CTRL-CLICK=restore initial size',
dragtip: 'DRAG=stretch/shrink, '
}
config.formatterHelpers.addStretchHandlers=function(e,stretchW,stretchH) {
e.title=((stretchW||stretchH)?this.imageSize.dragtip:'')+this.imageSize.tip;
e.statusMsg='width=%0, height=%1';
e.style.cursor='move';
e.originalW=e.style.width;
e.originalH=e.style.height;
e.minW=Math.max(e.offsetWidth/20,10);
e.minH=Math.max(e.offsetHeight/20,10);
e.stretchW=stretchW;
e.stretchH=stretchH;
e.onmousedown=function(ev) { var ev=ev||window.event;
this.sizing=true;
this.startX=!config.browser.isIE?ev.pageX:(ev.clientX+findScrollX());
this.startY=!config.browser.isIE?ev.pageY:(ev.clientY+findScrollY());
this.startW=this.offsetWidth;
this.startH=this.offsetHeight;
return false;
};
e.onmousemove=function(ev) { var ev=ev||window.event;
if (this.sizing) {
var s=this.style;
var currX=!config.browser.isIE?ev.pageX:(ev.clientX+findScrollX());
var currY=!config.browser.isIE?ev.pageY:(ev.clientY+findScrollY());
var newW=(currX-this.offsetLeft)/(this.startX-this.offsetLeft)*this.startW;
var newH=(currY-this.offsetTop )/(this.startY-this.offsetTop )*this.startH;
if (this.stretchW) s.width =Math.floor(Math.max(newW,this.minW))+'px';
if (this.stretchH) s.height=Math.floor(Math.max(newH,this.minH))+'px';
clearMessage(); displayMessage(this.statusMsg.format([s.width,s.height]));
}
return false;
};
e.onmouseup=function(ev) { var ev=ev||window.event;
if (ev.shiftKey) { this.style.width=this.style.height=''; }
if (ev.ctrlKey) { this.style.width=this.originalW; this.style.height=this.originalH; }
this.sizing=false;
clearMessage();
return false;
};
e.onmouseout=function(ev) { var ev=ev||window.event;
this.sizing=false;
clearMessage();
return false;
};
}
//}}}
On Sat Dec 17 2011 03:44:47 GMT+0100 (Romance Standard Time), YourName imported 4 tiddlers from
[[C:\Documents and Settings\mama\Skrivebord\empty\moveabletheme.html|C:\Documents and Settings\mama\Skrivebord\empty\moveabletheme.html]]:
<<<
#[[LoadRemoteFileThroughProxy]] - added
#[[PasswordOptionsPlugin]] - added
#[[TspotSetupPlugin]] - added
#[[UploadPlugin]] - added
<<<
For at komme i gang med denne tomme tiddlywiki, skal du ændre pÄ de følgende tiddlere:
* SiteTitle & SiteSubtitle: Sidens titel og undertitel, som vist øverst (efter de er gemt, vil de ogsÄ vise sig i browserens titelmenu)
* MainMenu: er hovedmenuen (er oftest placeret til venstre)
* DefaultTiddlers: Indeholder navnene pƄ de tiddlere du vilhave skal starte op nƄr du Ƅbner TiddlyWiki
Du skal ogsƄ skrive dit brugernavn for at signere dine redigeringer: <<option txtUserName>>
Hvis du vil Ʀndre pƄ hvilket tema der startes op med - og evt. om wikien skal vƦre redigƩrbar er det [[zzConfig]] tiddleren du skal have fat i.
/***
|''Name:''|LoadRemoteFileThroughProxy (previous LoadRemoteFileHijack)|
|''Description:''|When the TiddlyWiki file is located on the web (view over http) the content of [[SiteProxy]] tiddler is added in front of the file url. If [[SiteProxy]] does not exist "/proxy/" is added. |
|''Version:''|1.1.0|
|''Date:''|mar 17, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#LoadRemoteFileHijack|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0|
***/
//{{{
version.extensions.LoadRemoteFileThroughProxy = {
major: 1, minor: 1, revision: 0,
date: new Date("mar 17, 2007"),
source: "http://tiddlywiki.bidix.info/#LoadRemoteFileThroughProxy"};
if (!window.bidix) window.bidix = {}; // bidix namespace
if (!bidix.core) bidix.core = {};
bidix.core.loadRemoteFile = loadRemoteFile;
loadRemoteFile = function(url,callback,params)
{
if ((document.location.toString().substr(0,4) == "http") && (url.substr(0,4) == "http")){
url = store.getTiddlerText("SiteProxy", "/proxy/") + url;
}
return bidix.core.loadRemoteFile(url,callback,params);
}
//}}}
[[Kom i gang]]
<<tiddler CycleThemes with: "skift tema" "StyleSheet MoveableTheme">>
<<tiddler toggleEdit>>
<<tiddler ToggleFullScreen with: fuldSkƦrm genDan>>
[[download|/download]]
<!--{{{-->
<!--
|Name|MoveableEditTemplate|
|Source|http://www.TiddlyTools.com/#MoveableEditTemplate|
|Version||
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|template|
|Requires|MoveablePanelPlugin, EditTemplate, TaggedTemplateTweak|
|Description|add moveablePanel macro to tiddlers tagged with 'moveable'|
-->
<div class='moveablePanel'>
[[EditTemplate]]
<div macro='moveablePanel name:{{tiddler?tiddler.title:""}} height:auto'></div>
</div>
<!--}}}-->
<html><style>
#tiddlerMoveablePanelPackage .tagged { display:none; }
#tiddlerMoveablePanelPackage .viewer .content { max-height:999999em; height:auto; overflow:visible; }
</style></html>@@font-size:150%;''"free-range" tiddlers with room to roam...''@@
<<<
@@font-size:90%;line-height:120%;text-align:justify;display:block;<<tiddler QuickStart##badge with: moveable.html>>[[MoveablePanelPlugin]] turns tiddlers and other document content into '''moveable panels' that can be dragged with the mouse to //undock// them from their default //anchor points// and reposition them to almost any location on the page -- even far off screen!'' Using moveable panels, your document content can now be spread out over a wide (actually, //infinite//) area, both horizontally and vertically, allowing you to ''quickly create a complete 'web desktop' with different groupings of moveable tiddlers and menus''... all within a single TiddlyWiki document!
No matter where you place the panels, the document extents will ''automatically grow (or shrink) as needed to contain all moveable panels''. Unfortunately, ''you can only scroll in one direction at a time when using the browser window's separate horizontal and vertical scrollbars'', making navigation between far-flung panels extremely tedious and awkward. To address this, [[DragScrollPlugin]] allows you to ''scroll the browser window in both the horizontal and vertical directions at the same time, simply by holding down the SHIFT key while dragging the mouse across the page'' until the desired content is scrolled into view.
Of course, once you can move things around, you will want them to //stay there//. By itself, [[MoveablePanelPlugin]] has no memory and all panels are rendered at their original, docked anchor points each time the document is loaded into the browser. [[PanelManagerPlugin]] adds the ability to automatically ''track and record each panel's current position and size in a //panel map//, using simple wiki-formatted tables stored in tiddlers''. The current panel map is also automatically stored as a browser-cookie, so that ''wherever you place a panel, it stays there until you move it again'', even in between document sessions.
[[PanelManagerPlugin]] also adds a popup menu with lots of functions for managing individual moveable panels (e.g., 'bring to front', 'jump to panel', 'dock/undock', etc.) plus a ''powerful, graphical panel map viewer and interactive page navigator'' that allows you to load, save, edit and view //named// panel maps stored in your document. You can also scroll directly to any panel or other selected page location, anywhere on the page, by using the 'jump to panel' command or ''//compass navigation tool//'' from the Panel Manager popup menu.
You can access the Panel Manager popup map viewer at any time from the <<moveablePanel menu label:[[Panel Manager button (≡)]]>> that is added to the upper right corner of each undocked panel. You can also ''open the popup menu from //anywhere// on the page simply by using ALT+CLICK on the //background// of the page'' (i.e., not on a link or other //active// element that could respond to the click!). This permits access to the Panel Manager commands, even when there are no moveable panels visible on the screen.
@@
<<<
/***
|Name|[[MoveablePanelPlugin]]|
|Source|http://www.TiddlyTools.com/#MoveablePanelPlugin|
|Documentation|http://www.TiddlyTools.com/#MoveablePanelPluginInfo|
|Version|3.0.4|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Description|move/size any tiddler or page element|
Use the mouse to move/resize any specific tiddler content, page element, or [[floating slider panel|NestedSlidersPlugin]].
!!!!!Documentation
>see [[MoveablePanelPluginInfo]]
!!!!!Configuration
<<<
<<option chkMoveablePanelShowStatus>> show position/size while moving/resizing a panel
<<option chkMoveablePanelShowManager>> automatically add Panel Manager button to undocked panels (see [[PanelManagerPlugin]])
<<<
!!!!!Revisions
<<<
2010.12.24 3.0.4 fixed findMouseX/findMouseY for webkit browsers
|please see [[MoveablePanelPluginInfo]] for additional revision details|
2006.03.04 1.0.0 Initial public release
<<<
!!!!!Code
***/
//{{{
version.extensions.MoveablePanelPlugin= {major: 3, minor: 0, revision: 4, date: new Date(2010,12,24)};
if (config.macros.moveablePanel===undefined) config.macros.moveablePanel={};
//}}}
// // translate
//{{{
// TRANSLATORS: copy this section to MoveablePanelPluginLingoXX (where 'XX' is a language/country code)
if (config.macros.moveablePanel===undefined) config.macros.moveablePanel={};
merge(config.macros.moveablePanel,{
foldLabel: '\u2212', // minus
foldTip: 'FOLD=reduce panel size',
unfoldLabel: '+',
unfoldTip: 'UNFOLD=restore panel size',
hoverLabel: '^',
hoverTip: 'HOVER=keep panel in view when scrolling',
scrollLabel: '\u2248', // asymp
scrollTip: 'SCROLL=allow panel to move with page',
closeLabel: 'X',
closeTip: 'CLOSE=hide this panel',
dockLabel: '\u221A', // radic
dockTip: 'DOCK=reset size/position',
noPid: 'unnamed panel',
statusMsg: '%0: pos=(%1,%2)%3 size=(%4,%5) z=%6',
hoveredMsg: '[hovering]',
dockedTip: '%0: docked',
scrollMsg: '%0: pos=(%1,%2)',
msgDuration: 3000,
moveTip: '%0DRAG EDGE=move',
sizeTip: '(SHIFT=resize)',
sizeWidthTip: '(SHIFT=resize width)',
sizeHeightTip: '(SHIFT=resize height)',
clickTip: 'CLICK=bring to front, SHIFT-CLICK=send to back',
dblclickdockTip: 'DOUBLE-CLICK=dock',
dblclickunfoldTip:'DOUBLE-CLICK=unfold',
foldParam: 'fold',
hoverParam: 'hover',
nocloseParam: 'noclose',
nodockParam: 'nodock',
undockedParam: 'undocked',
jumpParam: 'jump',
dockParam: 'dock',
moveParam: 'move',
labelParam: 'label',
promptParam: 'prompt',
allParam: 'all',
nameParam: 'name',
topParam: 'top',
leftParam: 'left',
widthParam: 'width',
heightParam: 'height',
managerParam: 'manager'
});
//}}}
// // global functions (general utilities)
//{{{
// if removeCookie() function is not defined by TW core, define it here (for <TW2.5)
if (window.removeCookie===undefined) {
window.removeCookie=function(name) {
document.cookie = name+'=; expires=Thu, 01-Jan-1970 00:00:01 UTC; path=/;';
}
}
if (window.copyObject===undefined) {
window.copyObject=function(src) {
for (var i in src) this[i]=typeof src[i]!='object'?src[i]:new copyObject(src[i]);
}
}
if (window.compareObjects===undefined) {
window.compareObjects=function(a,b) {
if (a===b) return true;
if (a==undefined||b==undefined) return false;
for (var i in a) if (typeof a[i]!='object'?a[i]!==b[i]:!compareObjects(a[i],b[i])) return false;
return true;
}
}
if (window.isEmptyObject===undefined) {
window.isEmptyObject=function(src) { for (var i in src) return false; return true; }
}
// cross-browser metrics
window.findMouseX=function(ev) { if (!ev) return 0; var x=0;
if (config.browser.isIE) return ev.clientX+findScrollX();// IE
if (config.browser.isSafari) return ev.pageX+findScrollX(); // Webkit
else return ev.pageX; // Firefox/other
}
window.findMouseY=function(ev){ if (!ev) return 0; var y=0;
if (config.browser.isIE) return ev.clientY+findScrollY();// IE
if (config.browser.isSafari) return ev.pageY+findScrollY(); // Webkit
else return ev.pageY; // Firefox/other
}
//}}}
// // macro
//{{{
merge(config.macros.moveablePanel,{
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
// ALTERNATIVE OUTPUT: Panel Manager macro extensions...
if (this.manager && this.manager.handler(place,macroName,params,wikifier,paramString,tiddler))
return; // processed by PanelManager
// UNPACK KEYWORD PARAMS
var showfold =params.contains(this.foldParam);
var showhover =params.contains(this.hoverParam);
var showclose =!params.contains(this.nocloseParam);
var showdock =!params.contains(this.nodockParam);
var showmanager =params.contains(this.managerParam);
var startundocked=params.contains(this.undockedParam);
var jump =params.contains(this.jumpParam);
var dock =params.contains(this.dockParam);
var move =params.contains(this.moveParam);
var all =params.contains(this.allParam);
// UNPACK VALUE PARAMS
params=paramString.parseParams('anon',null,true,false,false);
var label =getParam(params,this.labelParam,null);
var prompt=getParam(params,this.promptParam,null);
var name =getParam(params,this.nameParam,null);
var top =getParam(params,this.topParam,null);
var left =getParam(params,this.leftParam,null);
var width =getParam(params,this.widthParam,null);
var height=getParam(params,this.heightParam,null);
// COMMANDS: JUMP, MOVE, DOCK
if (jump||move||dock) {
if (!label||!label.length) {
var p=this.findPanel(name);
if (jump) { if (p) this.scrollToPanel(p,true); else window.scrollTo(left,top); }
if (move) { this.movePanel(p,left,top,true,true); }
if (dock) { if (all) this.forAllPanels(this.dockPanel); else if (p) this.dockPanel(p); }
return;
}
var tip=(jump?this.jumpParam:move?this.moveParam:dock?this.dockParam:'')+': '+name;
var b=createTiddlyButton(place,label,prompt||tip, function(ev) {
var cmm=config.macros.moveablePanel; var p=cmm.findPanel(this.name);
if (this.jump) { if (p) cmm.scrollToPanel(p,true); else window.scrollTo(this.left,this.top); }
if (this.move) { if (p) cmm.movePanel(p,this.left,this.top,true,true); }
if (this.dock) { if (p) cmm.dockPanel(p); else if (this.all) cmm.forAllPanels(cmm.dockPanel); }
return cmm.processed(ev)
},'button');
b.jump=jump; b.move=move; b.dock=dock;
b.name=name; b.all=all; b.left=left; b.top=top;
return;
}
// PANEL SETUP
var p=this.getPanel(place);
this.cachePanel(p);
addClass(p,'moveablePanel');
p.pid=name;
p.showmanager=showmanager;
p.fixedheight=height||undefined;
p.fixedwidth=width||undefined;
this.addPanelButtons(p,showfold,showhover,showclose,showdock,showmanager);
this.addMouseHandlers(p);
if (startundocked) {
this.undockPanel(p);
if (!startingUp) { this.bringPanelToFront(p); this.scrollToPanel(p); }
}
if (this.manager) { this.manager.applyMap(p); this.manager.trackMap(p); }
this.notify(p);
},
//}}}
// // notifications
//{{{
quiet: 0, // flag to suspend/resume notifications
notify: function(p) { // notify others of panel changes
if (this.quiet) return;
if (this.manager) this.manager.notify(p); // pass notices to manager (updates viewers)
},
//}}}
// // general panel utilities
//{{{
getPanel: function(place) { // find containing panel or floating slider (use current element as fallback)
var p=place;
while (p && !(hasClass(p,'moveablePanel')||hasClass(p,'floatingPanel'))) p=p.parentNode;
return p||place;
},
getAllPanels: function(zSort) { // find 'moveablePanel' elements (optionally sort by zIndex)
var panels=[];
var sortByZindex=function(a,b){
var v1=parseInt(a.style.zIndex); if (isNaN(v1)) v1=0;
var v2=parseInt(b.style.zIndex); if (isNaN(v2)) v2=0;
return(v1==v2)?0:(v1>v2?1:-1);
}
// if native browser fn is defined, use it (*much* more efficient!)
if (document.getElementsByClassName) {
var elems=document.getElementsByClassName('moveablePanel');
for (var i=0; i<elems.length; i++) panels.push(elems[i]);
return zSort?panels.sort(sortByZindex):panels;
}
// otherwise, find all DIVs and SPANs with the right class
// NOTE: IE requires use of Enumerator() to iterate over elements, or it FREEZES UP COMPLETELY!!
var isIE=config.browser.isIE;
var elems=document.getElementsByTagName('DIV');
for (var i=isIE?new Enumerator(elems):0; isIE?!i.atEnd():(i<elems.length); isIE?i.moveNext():i++) {
var panel=isIE?i.item():elems[i];
if (hasClass(panel,'moveablePanel')) panels.push(panel);
}
var elems=document.getElementsByTagName('SPAN');
for (var i=isIE?new Enumerator(elems):0; isIE?!i.atEnd():(i<elems.length); isIE?i.moveNext():i++) {
var panel=isIE?i.item():elems[i];
if (hasClass(panel,'moveablePanel')) panels.push(panel);
}
return zSort?panels.sort(sortByZindex):panels;
},
findPanel: function(pid) { // find a named panel
var p=this.getAllPanels();
for (var i=0; i<p.length; i++) { if (pid && p[i].pid==pid) return p[i]; }
return undefined;
},
forAllPanels: function(callback) { // invoke a function on each panel
var panels=this.getAllPanels();
this.quiet++;
for (var i=0; i<panels.length; i++) callback.apply(this,[panels[i]]);
this.quiet--;
this.notify('all');
},
cachePanel: function(p) { // save original styles and handlers
if (!p.saved) p.saved={
x:p.style.left||'', y:p.style.top||'', w:p.style.width||'', h:p.style.height||'',
z:p.style.zIndex||'', pos:p.style.position||'', title: p.title,
mouseover:p.onmouseover, mouseout:p.onmouseout,
mousedown:p.onmousedown, mousemove:p.onmousemove, dblclick:p.ondblclick
};
},
restorePanel: function(p) { // restore original styles
if (!p.saved) return;
p.style.left=p.saved.x; p.style.top=p.saved.y; p.style.width=p.saved.w; p.style.height=p.saved.h;
p.style.zIndex=p.saved.z; p.style.position=p.saved.pos; p.title=p.saved.title;
removeClass(p,'folded'); removeClass(p,'hover'); removeClass(p,'undocked');
},
//}}}
// // panel metrics
//{{{
getPanelOffset: function(p) { // adjustment for child elements inside relative/floatingPanel containers
var r=new Object(); r.x=0; r.y=0; if (!p) return r;
var pp=p.parentNode; while (pp && !(pp.style&&pp.style.position=='relative')) pp=pp.parentNode;
if (pp) { r.x+=findPosX(pp); r.y+=findPosY(pp); }
var pp=p.parentNode; while (pp && !hasClass(pp,'floatingPanel')) pp=pp.parentNode;
if (pp) { r.x+=findPosX(pp); r.y+=findPosY(pp); }
return r;
},
// PROBLEM: the offsetWidth/offsetHeight do not seem to account for padding or borders
// WORKAROUND: subtract padding and border (in px) from width and height
// ISSUE: I still don't understand why this is needed...
// TBD: get padding/border values from p.style and convert to px
// NOTE: 10.6667 seems to be about 1em...
getPanelEdgeWidth:
function(p) { return 10.6667; },
getPanelEdgeHeight:
function(p) { return 10.6667; },
getPanelHeight:
function(p) { var pad=10.6667; var border=1; return p.offsetHeight-(pad*2+border*2); },
getPanelWidth:
function(p) { var pad=10.6667; var border=1; return p.offsetWidth -(pad*2+border*2); },
//}}}
// // panel stacking (zIndex)
//{{{
isStackable: function(p) { // zIndex is only effective with absolute or fixed elements
return (['absolute','fixed'].contains(p.style.position)&&!hasClass(p,'popup'));
},
normalizeStack: function(panels) { // set zIndex to correspond to stack order
for (var i=0; i<panels.length; i++) {var z=panels[i].style.zIndex;
if (z==0||z=='auto') continue; // if not stacking (e.g., 'auto', '', or null)
if (z<10000 || z>10000) continue; // use large values for "always in front/back"
if (z!=i+2) panels[i].style.zIndex=i+2;
if (this.manager) this.manager.trackMap(panels[i]);
}
return panels;
},
bringPanelToFront: function(p) { if (!p) return;
if (!this.isStackable(p)) return; // can't be stacked
var panels=this.getAllPanels(true);
// WFFL - normalizing every time works, but takes too long
// if (p.style.zIndex>panels.length+2) return; // stay in front
// this.normalizeStack(panels);
// p.style.zIndex=panels.length+2;
// WFFL - for now, just bump up the max (ignore z>10000) and normalize much less often
if (p.style.zIndex>1000) this.normalizeStack(panels);
var zMax=0; if (panels.length) {
var i=panels.length-1; zMax=parseInt(panels[i].style.zIndex);
while (zMax>10000 && i>0) zMax=parseInt(panels[--i].style.zIndex);
if (p==panels[i]) return; // already in front
if (isNaN(zMax)) zMax=0;
}
p.style.zIndex=zMax+1;
this.notify(p);
},
sendPanelToBack: function(p) { if (!p) return;
if (!this.isStackable(p)) return; // can't be stacked
var panels=this.getAllPanels(true);
// WFFL - normalizing every time works, but takes too long
// if (p.style.zIndex<2) return; // stay in back
// this.normalizeStack(panels);
// p.style.zIndex=1;
// WFFL - for now, just bump down the min (ignore z<10000) and normalize much less often
if (p.style.zIndex<1000) this.normalizeStack(panels);
var zMin=0; if (panels.length) {
var i=0; zMin=parseInt(panels[i].style.zIndex);
while (zMin<10000 && i<panels.length-1) zMin=parseInt(panels[++i].style.zIndex);
if (p==panels[i]) return; // already in back
if (isNaN(zMin)) zMin=0;
}
p.style.zIndex=zMin-1;
this.notify(p);
},
returnPanelToStack: function(p) { if (!p) return;
p.style.zIndex=p.saved?p.saved.zIndex:'';
this.notify(p);
},
//}}}
// // panel scrolling
//{{{
noScrollX: 0, // flags to disable TW built-in scrolling behavior
noScrollY: 0, // set by hijacks, cleared by ensurePanelVisible(), below
// scroll view to show panel along nearest edge of window or centered (optional)
scrollToPanel: function(p,center) { if (!p) return;
if (hasClass(p,'popup')) return; // popup=let core scrolling handle it
if (hasClass(p,'hover')) return; // hover=always in view=don't scroll
var scrollSize=findWindowWidth()-document.body.offsetWidth; // width of scrollbar
var sx=findScrollX(); var ww=findWindowWidth()-scrollSize;
var sy=findScrollY(); var wh=findWindowHeight()-scrollSize;
var px=findPosX(p); var pw=p.offsetWidth;
var py=findPosY(p); var ph=p.offsetHeight;
var nx=sx; var ny=sy; // assume no scrolling is needed
// if BR is not in view, scroll to show BR
if (px+pw>sx+ww) nx=px+pw-ww;
if (py+ph>sy+wh) ny=py+ph-wh;
// if TL not in view or too big... scroll to show TL
if (px<nx || px>nx+ww || px+pw>nx+ww) nx=px;
if (py<ny || py>ny+wh || py+ph>ny+wh) ny=py;
// optionally, center in view (if panel fits)
if (center && pw<ww) nx-=(ww-pw)/2;
if (center && ph<wh) ny-=(wh-ph)/2;
if (nx!=sx||ny!=sy) { // if we need to scroll...
window.scrollTo(nx,ny);
if (config.options.chkMoveablePanelShowStatus && !startingUp) {
var id=hasClass(p,'tiddler')?p.getAttribute('tiddler'):p.pid;
this.timedMessage(this.scrollMsg.format([id||this.noPid,px,py]),this.msgDuration);
}
this.notify(p);
}
},
// bring to front and scroll into view (with optional ASYNC)
ensurePanelVisible: function(p,delay) { if (!p) return;
if (delay && !startingUp) { // wait for core animation to complete...
if (hasClass(p,'tiddler'))
p=config.macros.moveablePanel.findPanel(p.getAttribute('tiddler'))||p;
if (!p.id) p.id=new Date().getTime()+Math.random(); // unique ID
var code='config.macros.moveablePanel.ensurePanelVisible(document.getElementById("%0"));';
setTimeout(code.format([p.id]),delay);
return;
}
// unblock scrolling and bring the panel into view
if (this.noScrollX>0) this.noScrollX--; if (this.noScrollY>0) this.noScrollY--;
if (hasClass(p,'popup')) return; // leave popups alone!
this.bringPanelToFront(p);
if (this.noScrollX+this.noScrollY==0 && !startingUp) // no scroll during document startup
this.scrollToPanel(p);
},
//}}}
// // panel status
//{{{
formatPanelStatus: function(p) {
var s=p.style; var msg=this.statusMsg.format([p.pid||this.noPid,
s.left,s.top,hasClass(p,'hover')?this.hoveredMsg:'',s.width,s.height,s.zIndex]);
return msg.replace(/(\.[0-9]+)|px/g,''); // remove decimals and 'px'
},
showPanelStatus: function(p,show) { // display panel info in titlebar while moving/sizing
if (!config.options.chkMoveablePanelShowStatus) return;
if (show) document.title=this.formatPanelStatus(p)
else refreshPageTitle();
},
timedMessage: function(msg,duration) {
document.title=msg; setTimeout('refreshPageTitle()',duration);
},
getPanelTooltip: function(p) {
return hasClass(p,'undocked')?this.formatPanelStatus(p):this.dockedTip.format([p.pid||this.noPid]);
},
//}}}
// // panel actions
//{{{
undockPanel: function(p,front) { // undocked with default pos/size
if (hasClass(p,'undocked')) return; // already undocked
// get size BEFORE undocking
p.style.width=p.fixedwidth ||(this.getPanelWidth(p)+'px');
p.style.height=p.fixedheight||(this.getPanelHeight(p)+'px');
addClass(p,'undocked'); if (!this.isStackable(p)) p.style.position='absolute'; // UNDOCK it
// set position AFTER undocking
var offset=this.getPanelOffset(p);
p.style.left=findPosX(p)-offset.x+'px'; p.style.top=findPosY(p)-offset.y+'px';
if (front) this.bringPanelToFront(p);
this.notify(p);
},
dockPanel: function(p) { // reset to docked pos/size
if (!hasClass(p,'undocked')) return; // already docked
this.restorePanel(p); // reset panel
// FOR FLOATING SLIDERS: trigger slider adjustment handler (if any)
if (hasClass(p,'floatingPanel') && window.adjustSliderPos)
window.adjustSliderPos(p.parentNode,p.button,p);
this.quiet++; if (this.manager) this.manager.trackMap(p); this.quiet--;
this.notify(p)
},
closePanel: function(p) { // dock panel, then close (for tiddlers and floating sliders)
var t=story.findContainingTiddler(p);
var isTiddler=t&&this.findPanel(t.getAttribute('tiddler'));
var isFloating=hasClass(p,'floatingPanel');
if (!isTiddler) // when closing TIDDLERS, leave them undocked (keeps size/pos)
this.dockPanel(p);
// FOR FLOATING SLIDERS: set focus and do a fake click on slider button
if (isFloating) { p.button.focus(); onClickNestedSlider({target:p.button}); }
// FOR TIDDLERS: call story.closeTiddler()
if (isTiddler) { story.closeTiddler(t.getAttribute('tiddler')); }
},
movePanel: function(p,x,y,show,centered) { if (!p) return;
this.quiet++;
this.undockPanel(p);
// adjust for child elements inside relative/floatingPanel containers
var offset=this.getPanelOffset(p);
p.style.left=x-offset.x+'px'; p.style.top=y-offset.y+'px';
if (show) { this.bringPanelToFront(p); this.scrollToPanel(p,centered); }
this.quiet--;
this.showPanelStatus(p,true);
if (this.manager) this.manager.trackMap(p);
},
foldPanel: function(p) { // toggle panel height
if (hasClass(p,'folded')) removeClass(p,'folded'); else addClass(p,'folded');
if (this.manager) this.manager.trackMap(p);
this.notify(p);
},
hoverPanel: function(p) { // toggle fixed position
if (hasClass(p,'hover')) {
removeClass(p,'hover');
var offset=this.getPanelOffset(p);
p.style.left=p.offsetLeft+findScrollX()-offset.x+'px';
p.style.top=p.offsetTop+findScrollY()-offset.y+'px';
} else {
var offset=this.getPanelOffset(p);
var ww=findWindowWidth(); var wh=findWindowHeight();
p.style.left=(p.offsetLeft-findScrollX()+offset.x)%ww+'px';
p.style.top =(p.offsetTop -findScrollY()+offset.y)%wh+'px';
addClass(p,'hover');
}
if (this.manager) this.manager.trackMap(p);
this.notify(p);
},
resetPanel: function(p) { // reset to session starting pos/size
if (this.manager) this.manager.resetPanel(p); else this.dockPanel(p);
},
//}}}
// // menu buttons
//{{{
processed: function(ev) { var ev=ev||window.event; // use to end event handling for menus and mouse actions
if (ev) { ev.cancelBubble=true; if (ev.stopPropagation) ev.stopPropagation(); } return false;
},
addPanelButtons: function(p,showfold,showhover,showclose,showdock,showmanager) {
if (p.menu) return; // only once per panel
function cmd(menu,label,tip,callback,show,arg) {
var fn=function(ev){return this.callback.apply(config.macros.moveablePanel,[this,ev,this.arg]);}
var b=createTiddlyButton(menu,label,tip,fn,'moveablePanelButton');
b.style.display=show?'inline':'none'; b.callback=callback; b.arg=arg;
return b;
}
var m=createTiddlyElement(p,'div',null,'moveablePanelMenu');
p.showfold=showfold;
p.foldbutton= cmd(m,this.foldLabel,this.foldTip,this.foldHandler,showfold);
p.unfoldbutton= cmd(m,this.unfoldLabel,this.unfoldTip,this.foldHandler,false);
p.showhover=showhover;
p.hoverbutton=cmd(m,this.hoverLabel,this.hoverTip,this.hoverHandler,showhover);
p.scrollbutton=cmd(m,this.scrollLabel,this.scrollTip,this.hoverHandler,false);
p.showdock=showdock;
p.dockbutton= cmd(m,this.dockLabel,this.dockTip,this.dockHandler,showdock);
p.showclose=showclose;
p.closebutton=cmd(m,this.closeLabel,this.closeTip,this.closeHandler,showclose);
p.showmanager=showmanager;
if (this.manager) p.managerbutton=cmd(m,this.manager.buttonLabel,this.manager.buttonTip,
this.manager.popup,showmanager,p.pid);
p.menu=m;
},
togglePanelButtons: function(p,show) { if (!p||!p.menu) return;
var undocked=hasClass(p,'undocked');
var floating=hasClass(p,'floatingPanel');
var hover=hasClass(p,'hover');
var folded=hasClass(p,'folded');
var t=story.findContainingTiddler(p);
var tiddler=t&&this.findPanel(t.getAttribute('tiddler'));
var show=show&&(undocked||floating);
p.menu.style.display=show?'inline':'none';
if (p.showfold) p.foldbutton.style.display =!folded?'inline':'none';
if (p.showfold) p.unfoldbutton.style.display= folded?'inline':'none';
if (p.showhover) p.hoverbutton.style.display =!hover?'inline':'none';
if (p.showhover) p.scrollbutton.style.display= hover?'inline':'none';
if (p.showdock) p.dockbutton.style.display =undocked?'inline':'none';
if (p.showclose) p.closebutton.style.display=floating||(tiddler&&undocked)?'inline':'none';
if (p.managerbutton) { // see [[PanelManagerPlugin]]
var show=p.showmanager||config.options.chkMoveablePanelShowManager;
p.managerbutton.style.display=show?'inline':'none';
}
},
foldHandler: function(place,ev){ var p=this.getPanel(place);
this.foldPanel(p); this.togglePanelButtons(p,true); return this.processed(ev); },
hoverHandler: function(place,ev){ var p=this.getPanel(place);
this.hoverPanel(p); this.togglePanelButtons(p,true); return this.processed(ev); },
dockHandler: function(place,ev){ var p=this.getPanel(place);
this.dockPanel(p); this.togglePanelButtons(p,true); return this.processed(ev); },
closeHandler: function(place,ev){ var p=this.getPanel(place);
this.closePanel(p); this.togglePanelButtons(p,true); return this.processed(ev); },
//}}}
// // mouse handlers
//{{{
addMouseHandlers: function(p) {
if (p.handlers) return true; // only add handlers ONCE
p.onmouseover=function(ev) { var ev=ev||window.event;
var r=config.macros.moveablePanel.mouseover(this,ev);
return r&&this.saved.mouseover?this.saved.mouseover.apply(this,arguments):true;
};
p.onmouseout=function(ev) { var ev=ev||window.event;
var r=config.macros.moveablePanel.mouseout(this,ev);
return r&&this.saved.mouseout?this.saved.mouseout.apply(this,arguments):true;
};
p.onmousemove=function(ev) { var ev=ev||window.event;
var r=config.macros.moveablePanel.mousemove(this,ev);
return r&&this.saved.mousemove?this.saved.mousemove.apply(this,arguments):true;
};
p.ondblclick=function(ev) { var ev=ev||window.event;
var r=config.macros.moveablePanel.dblclick(this,ev);
return r&&this.saved.dblclick?this.saved.dblclick.apply(this,arguments):r;
};
p.onmousedown=function(ev) { var ev=ev||window.event;
var r=config.macros.moveablePanel.mousedown(this,ev);
return r&&this.saved.mousedown?this.saved.mousedown.apply(this,arguments):r;
};
p.handlers=true;
},
isEdge: function(p,ev) { // near 'edge' of panel (or child element)?
var ev=ev||window.event; var target=resolveTarget(ev);
if (!p) return false;
// ignore form input fields
if (['input','select','option','textarea'].contains(target.nodeName.toLowerCase())) return false;
var left=findPosX(p); var top=findPosY(p);
var width=p.offsetWidth; var height=p.offsetHeight;
var x=findMouseX(ev); var y=findMouseY(ev);
if (hasClass(p,'hover')) { x-=findScrollX(); y-=findScrollY(); } // window-relative panel
if (x<left||y<top||x>=left+width||y>=top+height) { // outside of panel
if (p==target || p!=this.getPanel(target)) return false;
return this.isEdge(target,ev); // check target child element
}
var edgeW=this.getPanelEdgeWidth(p); var edgeH=this.getPanelEdgeHeight(p);
var isT=(y-top<edgeH); var isL=(x-left<edgeW);
var isB=(top+height-y<edgeH); var isR=(left+width-x<edgeW);
return isT||isL||isB||isR;
},
// temporary element during move/size keeps document from shrinking
addGhost: function(p) {
var g=document.getElementById('moveablePanelGhost');
if (!g) g=createTiddlyElement(document.body,'div','moveablePanelGhost','moveablePanelGhost');
var border=1; // note: must match CSS for 'moveablePanelGhost' WFFL-HACK
g.style.left=findPosX(p)+'px';
g.style.top=findPosY(p)+'px';
g.style.width=((p.offsetWidth-border*2)||0)+'px';
g.style.height=((p.offsetHeight-border*2)||0)+'px';
},
clearGhost: function() {
var e=document.getElementById('moveablePanelGhost');
if (e) e.parentNode.removeChild(e);
},
// MOUSEOVER=SHOW MENU
mouseover: function(place,ev) { var ev=ev||window.event;
var p=this.getPanel(place);
addClass(p,'selected'); // shows toolbar-classed items
this.togglePanelButtons(p,true);
return true;
},
// MOUSEOUT=HIDE MENU
mouseout: function(place,ev) { var ev=ev||window.event;
var p=this.getPanel(place);
removeClass(p,'selected'); // hides toolbar-classed items
this.togglePanelButtons(p,false);
return true;
},
// MOUSEMOVE=SHOW MENU AND SET CURSOR/TIP
mousemove: function(place,ev) { var ev=ev||window.event;
var p=this.getPanel(place);
p.style.cursor='auto'; p.title=p.saved?p.saved.title:'';
if (!this.isEdge(p,ev)) return true;
var fw=p.fixedwidth; if (fw==null) fw=undefined;
var fh=p.fixedheight; if (fh==null) fh=undefined;
p.title=this.moveTip.format([p.pid?p.pid+': ':'']);
if (fw===undefined&&fh===undefined) p.title+=' '+this.sizeTip;
else if (fw===undefined) p.title+=' '+this.sizeWidthTip;
else if (fh===undefined) p.title+=' '+this.sizeHeightTip;
if (hasClass(p,'undocked')) {
p.title+=', '+this.clickTip+', ';
p.title+=hasClass(p,'folded')?this.dblclickunfoldTip:this.dblclickdockTip;
}
p.style.cursor='move';
if (ev.shiftKey&&!(fw&&fh)) { // set resizing cursor (if not fixed width/height)
var left=findPosX(p); var top=findPosY(p);
var width=p.offsetWidth; var height=p.offsetHeight;
var x=findMouseX(ev); var y=findMouseY(ev);
if (hasClass(p,'hover')) { x-=findScrollX(); y-=findScrollY(); } // window-relative panel
var edgeW=this.getPanelEdgeWidth(p); var edgeH=this.getPanelEdgeHeight(p);
var isT=(y-top<edgeH); var isL=(x-left<edgeW);
var isB=(top+height-y<edgeH); var isR=(left+width-x<edgeW);
p.style.cursor=(fh===undefined?(isT?'n':(isB?'s':'')):'')
+(fw===undefined?(isL?'w':(isR?'e':'')):'')+'-resize';
}
return true;
},
// DOUBLE-CLICK=DOCK OR UNFOLD
dblclick: function(place,ev) { var ev=ev||window.event;
var p=this.getPanel(place);
if (!this.isEdge(p,ev)) return true;
// if folded... unfold, otherwise... undock
if (hasClass(p,'folded')) this.foldPanel(p); else this.dockPanel(p);
this.togglePanelButtons(p,false);
return this.processed(ev);
},
// MOUSEDOWN=START MOVE/SIZE, CLICK=BRING TO FRONT, SHIFT-CLICK=SEND TO BACK
mousedown: function(place,ev) { var ev=ev||window.event;
var p=this.getPanel(place);
// CLICK ALWAYS BRINGS TO FRONT
this.quiet++;
this.bringPanelToFront(p);
if (this.manager) this.manager.trackMap(p);
this.quiet--;
if (!this.isEdge(p,ev)) return true;
// start capturing mouse events and set mouse/key handlers
var target=p; // if 'capture' not supported, track in panel only
if (document.body.setCapture) // IE
{ document.body.setCapture(); var target=document.body; }
if (window.captureEvents) // moz
{ window.captureEvents(Event.MouseMove|Event.MouseUp,true); var target=window; }
if (target.onmousemove!=undefined) target.saved_mousemove=target.onmousemove;
target.onmousemove=this.dragmove;
if (target.onmouseup!=undefined) target.saved_mouseup=target.onmouseup;
target.onmouseup=this.dragstop;
if (target.onkeydown!=undefined) target.saved_keydown=target.onkeydown;
target.onkeydown=this.dragkey;
// calculate and save drag data in target element
var x=findMouseX(ev); var left=findPosX(p); var width =p.offsetWidth;
var y=findMouseY(ev); var top =findPosY(p); var height=p.offsetHeight;
var sizing=ev.shiftKey;
var edgeW=this.getPanelEdgeWidth(p); var edgeH=this.getPanelEdgeHeight(p);
var isT=(y-top<edgeH); var isL=(x-left<edgeW);
var isB=(top+height-y<edgeH); var isR=(left+width-x<edgeW);
var d=new Object();
d.panel=p; d.left=left; d.top=top;
d.width=this.getPanelWidth(p); d.height=this.getPanelHeight(p);
d.sizing=sizing; d.edgeW=edgeW; d.edgeH=edgeH;
d.isT=isT; d.isL=isL; d.isB=isB; d.isR=isR; d.offset=this.getPanelOffset(p);
d.saved={ x:p.style.left, y:p.style.top, w:p.style.width, h:p.style.height,
z:p.style.zIndex, pos:p.style.position, classname:p.className };
target.data=d;
this.addGhost(p); // keep document from shrinking during move/size
return this.processed(ev);
},
// MOUSEMOVE (during drag)=move/size panel
dragmove: function(ev){ var ev=ev||window.event; var cmm=config.macros.moveablePanel;
var d=this.data; var p=d.panel;
if (!p) { this.onmousemove=this.saved_mousemove?this.saved_mousemove:null; return; }
cmm.quiet++; // save all notifications until the end...
// ensure panel is undocked and scrolled into view, THEN get starting mouse and scroll positions
if (!hasClass(p,'undocked'))
{ cmm.undockPanel(p,true); if (this.manager) this.manager.trackMap(p); }
if (d.x===undefined) // first move event only
{ cmm.scrollToPanel(p); d.x=findMouseX(ev); d.y=findMouseY(ev); }
// get current mouse pos
var newX=findMouseX(ev); var newY=findMouseY(ev);
// calculate new TLWH (start with current panel pos/size)
var startX=d.x; var startY=d.y; var offsetX=d.offset.x; var offsetY=d.offset.y;
var L=d.left; var T=d.top; var W=d.width; var H=d.height;
var newL=L; var newT=T; var newW=p.fixedwidth||W; var newH=p.fixedheight||H;
if (d.sizing) { // resize panel
var minW=d.edgeW*2; var minH=d.edgeH*2; // stay bigger than edge areas
if (hasClass(p,'folded')) this.fold(p.foldButton,ev); // un-fold first!
if (d.isT) newH=H-newY+startY+1;
if (d.isB) newH=H+newY-startY+1;
if (d.isL) newW=W-newX+startX+1;
if (d.isR) newW=W+newX-startX+1;
if (d.isT) newT=T-offsetY+newY-startY+1; else newT=T-offsetY;
if (d.isL) newL=L-offsetX+newX-startX+1; else newL=L-offsetX;
if ((d.isL||d.isR)&&!p.fixedwidth) newW=(newW>minW?newW:minW);
if ((d.isT||d.isB)&&!p.fixedheight) newH=(newH>minH?newH:minH);
} else { // move panel
newL=L-offsetX+newX-startX+1;
newT=T-offsetY+newY-startY+1;
}
if (hasClass(p,'hover')) { // hover=stay on first screen
var ww=findWindowWidth(); var wh=findWindowHeight();
newL+=offsetX; newT+=offsetY; // hover=no relative offset (window-relative)
// WFFL lower right is off... a bit too far (perhaps scrollwidth?)
if (newL+newW>ww) newL=ww-newW; if (newT+newH>wh) newT=wh-newH; // limit lower right
if (newL<0) newL=0; if (newT<0) newT=0; // limit upper left
} else { // normal floating panel=limit upper left (stay on page)
if (newL+offsetX<0) newL=0-offsetX; if (newT+offsetY<0) newT=0-offsetY;
}
// move the panel and scroll into view as needed
p.style.left=newL.toString()+'px';
p.style.top=newT.toString()+'px';
if (d.sizing) p.style.width=newW.toString()+'px';
if (d.sizing) p.style.height=newH.toString()+'px';
cmm.scrollToPanel(p);
// report new position and notify panel manager... done!
cmm.quiet--; cmm.showPanelStatus(p,true); cmm.notify(p);
return cmm.processed(ev);
},
dragkey: function(ev){ var ev=ev||window.event;
var d=this.data; var p=d.panel;
if (ev.keyCode==27) { // ESC=CANCEL... restore panel to previous pos/size
p.style.left =d.saved.x; p.style.top =d.saved.y;
p.style.width=d.saved.w; p.style.height=d.saved.h;
p.style.zIndex=d.saved.z;
p.style.position=d.saved.pos;
p.className=d.saved.classname;
return this.onmouseup(ev);
}
if (this.saved_keydown) return this.saved_keydown(ev);
},
// MOUSEUP: END MOVE/SIZE, SHIFT-CLICK=SEND TO BACK
dragstop: function(ev){ var ev=ev||window.event; var cmm=config.macros.moveablePanel;
var newX=findMouseX(ev); var newY=findMouseY(ev);
if (this.releaseCapture) this.releaseCapture(); // IE
if (this.releaseEvents) this.releaseEvents(Event.MouseMove|Event.MouseUp); // moz
this.onmousemove=this.saved_mousemove?this.saved_mousemove:null;
this.onmouseup=this.saved_mouseup?this.saved_mouseup:null;
this.onkeydown=this.saved_keydown?this.saved_keydown:null;
var d=this.data; var p=d.panel;
if (ev.shiftKey && d.x==newX && d.y==newY && cmm.isEdge(p,ev))
cmm.sendPanelToBack(p); // SHIFT-CLICK *EDGE*
cmm.togglePanelButtons(p,true);
cmm.quiet++; if (cmm.manager) cmm.manager.trackMap(p); cmm.quiet--;
cmm.clearGhost(); // allow document to adjust extents (if needed)
cmm.showPanelStatus(p,false); cmm.timedMessage(cmm.formatPanelStatus(p),cmm.msgDuration);
return cmm.processed(ev);
},
//}}}
// // CSS definitions
//{{{
css: '/*{{{*/\n'
+'.moveablePanelMenu\n'
+'\t{ display:none; position:absolute; right:.5em; top:-1em; }\n'
+'.undocked .selected.moveablePanelMenu\n'
+'\t{ display:inline; }\n'
+'.floatingPanel .selected .moveablePanelMenu\n'
+'\t{ display:inline; }\n'
+'.hover\n'
+'\t{ position:fixed !important; }\n'
+'.folded\n'
+'\t{ height:1.5em !important; overflow:hidden !important; }\n'
+'.tiddler .folded\n'
+'\t{ height:2em !important; }\n'
+'.folded .moveablePanelMenu\n'
+'\t{ top:.5em; } /* buttons fit in folded panel */\n'
+'.tiddler .moveablePanelMenu\n'
+'\t{ top:.2em; } /* buttons fit in tiddler title */\n'
+'.undocked .toolbar\n'
+'\t{ padding-right:7.5em; } /* make room for buttons next to toolbar */\n'
+'.floatingPanel .moveablePanelMenu\n'
+'\t{ right:1em;top:1em; } /* buttons fit in floating panel */\n'
+'.moveablePanelButton\n {'
+'\tbackground:#ccc !important; color:#000 !important;\n'
+'\tborder:1px solid #666; padding:0 .25em; margin:0px 1px;\n'
+'}\n'
+'.moveablePanelButton:hover\n'
+'\t{ background:#fff !important; color:#000 !important; }\n'
+'.popup\n'
+'\t{ z-index:9999999 !important; } /* popups MUST always be on top! */\n'
+'.moveablePanelGhost\n'
+'\t{ position:absolute; border:1px dotted #999; }\n'
+'/*}}}*/'
});
//}}}
// // load time initialization
//{{{
// defaults for options
if (config.options.txtMoveablePanelMapName===undefined)
config.options.txtMoveablePanelMapName='DefaultMap';
if (config.options.chkMoveablePanelShowStatus===undefined)
config.options.chkMoveablePanelShowStatus=true;
if (config.options.chkMoveablePanelShowManager===undefined)
config.options.chkMoveablePanelShowManager=true;
// set up shadow stylesheet, then load styles (might be customized)
config.shadowTiddlers.MoveablePanelStyles=config.macros.moveablePanel.css;
var css=store.getRecursiveTiddlerText('MoveablePanelStyles',config.macros.moveablePanel.css,10);
setStylesheet(css,'moveablePanelStyles');
//}}}
// // hijacks
//{{{
// adjust popup placement to account for the current horizontal scrollbar
// offset (if any), so that popups will appear in the correct location, even
// when their 'root' element is scrolled far from the page origin.
var fn=Popup.place; fn=fn.toString(); if (fn.indexOf('findScrollX')==-1) { // only once
fn=fn.replace(/winWidth\s*-\s*scrollWidth\s*-\s*1/,
'findScrollX() + winWidth - scrollWidth - 1');
fn=fn.replace(/winWidth\s*-\s*popupWidth\s*-\s*scrollWidth\s*-\s*1/,
'findScrollX() + winWidth - popupWidth - scrollWidth - 1');
eval('Popup.place='+fn);
}
//}}}
//{{{
// window.scrollTo() is used throughout the core (and plugins) to scroll to a *vertical*
// position as computed by ensureVisible(), in order to bring a tiddler into view.
// Unfortunately, the *horizontal* scroll position is almost always hard-coded to 0
// (i.e. a return to the left edge of the page). Normally, this is not a problem,
// since a page is rarely scrolled horizontally. However, when there are moveable
// panels, they can appear far from the left edge, so always scrolling to the left
// edge is very disruptive. In addition, unwanted scrolling can occur as a side
// effect when displaying or refreshing a tiddler (e.g., switching between
// view/edit templates). These hijacks adds control flags ('noScrollX' and 'noscrollY')
// that can be used to temporarily disable scrolling within the document.
if (window.scrollTo_moveablePanel==undefined) { // only once
window.scrollTo_moveablePanel=window.scrollTo;
window.scrollTo=function(x,y) {
var cmm=config.macros.moveablePanel;
if (cmm.noScrollX&&cmm.noScrollY) return;
x=cmm.noScrollX?findScrollX():x;
y=cmm.noScrollY?findScrollY():y;
window.scrollTo_moveablePanel(x,y);
}
}
// ensureVisible() is used to calculate the y-offset of a tiddler, just before scrolling
// This tweak sets up an ASYNC timer to invoke the 'bring to front/scroll into view'
// function for 'tiddler' and 'popup' classes. This allows the function
// to be triggered *after* core scrolling occurs, so the fixups are not
// stomped on by the core's normal scroll handling
if (window.ensureVisible_moveablePanel==undefined) { // only once
window.ensureVisible_moveablePanel=window.ensureVisible;
window.ensureVisible=function(e) {
var ny=ensureVisible_moveablePanel.apply(this,arguments); // get core value
// fixup height to account for horizontal scrollbar (if present)
var atBottom=findPosY(e)+e.offsetHeight>=findScrollY()+findWindowHeight();
var hasHScroll=document.documentElement.scrollWidth>findWindowWidth();
var hScrollSize=findWindowWidth()-document.body.offsetWidth;
if (atBottom && hasHScroll) ny+=hScrollSize;
// defer scrolling for tiddlers and popups (except during startup)
if (!startingUp && (hasClass(e,'tiddler')||hasClass(e,'popup'))) {
var cmm=config.macros.moveablePanel;
cmm.noScrollX++; if (hasClass(e,'tiddler')) cmm.noScrollY++;
var delay=config.options.chkAnimate?config.animDuration+50:50;
cmm.ensurePanelVisible(e,delay); // ASYNC SCROLL
}
return ny;
}
}
// story.refreshTiddler()
if (Story.prototype.refreshTiddler_moveablePanel==undefined) { // only once
Story.prototype.refreshTiddler_moveablePanel=Story.prototype.refreshTiddler;
Story.prototype.refreshTiddler=function() {
var cmm=config.macros.moveablePanel;
cmm.noScrollX++; cmm.noScrollY++; // DON'T SCROLL AT ALL
var r=this.refreshTiddler_moveablePanel.apply(this,arguments);
cmm.noScrollX--; cmm.noScrollY--;
return r;
}
}
// story.displayTiddler()
if (Story.prototype.displayTiddler_moveablePanel==undefined) { // only once
Story.prototype.displayTiddler_moveablePanel=Story.prototype.displayTiddler;
Story.prototype.displayTiddler=function(srcElement,tiddler) {
var cmm=config.macros.moveablePanel;
//WFFL cmm.noScrollX++; cmm.noScrollY++;
var r=this.displayTiddler_moveablePanel.apply(this,arguments);
var title=(tiddler instanceof Tiddler)?tiddler.title:tiddler;
var panel=cmm.findPanel(title); // if moveable... unfold panel (but not during startup)
if (panel&&hasClass(panel,'folded')&&!startingUp) cmm.foldPanel(panel);
var delay=config.options.chkAnimate?config.animDuration+50:50;
cmm.ensurePanelVisible(this.getTiddler(title),delay); // ASYNC SCROLL
return r;
}
}
//}}}
//{{{
// Zoomer() displays an animated bounding box when showing a tiddler. But this box 'zooms' to the tiddler's 'anchor point', not the current panel position, which can cause a 'scroll blink'. This hijack redirects the zoomer's target directly to the undocked panel (if any)
if (window.Zoomer_moveablePanel==undefined) { // only once
window.Zoomer_moveablePanel=window.Zoomer;
window.Zoomer=function(text,startElement,targetElement,unused) {
if (hasClass(targetElement,'tiddler')) {
var tid=targetElement.getAttribute('tiddler');
arguments[2]=config.macros.moveablePanel.findPanel(tid)||targetElement;
}
return window.Zoomer_moveablePanel.apply(this,arguments);
}
}
//}}}
/***
|Name|MoveablePanelPluginInfo|
|Source|http://www.TiddlyTools.com/#MoveablePanelPlugin|
|Documentation|http://www.TiddlyTools.com/#MoveablePanelPluginInfo|
|Version|3.0.3|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Description|documentation for MoveablePanelPlugin|
Adds move/resize mouse handling plus fold/unfold, hover/scroll, and close/dock buttons to any rendered tiddler content, page element, or [[floating slider panel|NestedSlidersPlugin]].
!!!!!Usage
<<<
Please see [[MoveablePanelPackage]] for a general overview of features as well as information about other plugins and tiddlers associated with installation and use of moveable panels.
{{{
<<moveablePanel>>
<<moveablePanel undocked fold hover noclose nodock manager name:... width:... height:...>>
<<moveablePanel move label:... prompt:... name:... top:... left:...>>
<<moveablePanel jump label:... prompt:... name:... >>
<<moveablePanel jump label:... prompt:... top:... left:... >>
<<moveablePanel dock label:... prompt:... name:... >>
<<moveablePanel dock label:... prompt:... all>>
}}}
Without any parameters, the {{{<<moveablePanel>>}}} simply adds the 'moveable panel' mouse handling and button commands to a containing element that has been marked with a CSS class of 'moveablePanel' (e.g., """{{moveablePanel{...}}}""") or 'floatingPanel' (created by [[NestedSlidersPlugin]]) . If no containing 'moveablePanel' or 'floatingPanel' element is located, the panel handlers are added directly to the element in which the macro is contained.
__Optional macro parameters are:__
*''undocked''<br>by default, a moveable panel is rendered inline ('docked'), and only floats in front of other content ('undocked') after the user has moved it from it's 'anchor point'. The ''undocked'' keyword indicates that the panel should be be immediately 'undocked' and brought to the front of the 'stack' of undocked panels as soon as it is rendered.
*''fold''<br>adds the fold/unfold (-/+) button
*''hover''<br>adds the hover/scroll (^/=) button
*''noclose''<br>supresses the close (X) button
*''nodock''<br>supresses the dock (√) button
*''manager''<br>forces the Panel Manger button to always appear in the panel, regardless of the option setting (see below)
*''name:...''<br>specifies a unique identifier for the panel, to be used by the ''menu'', ''move'', ''jump'', or ''dock'' functions described below, as well as by the (optional) [[PanelManagerPlugin]] to create //panel maps// that track and record the size and position of named panels, so that they can remain where you put them, even in between browser sessions.
*''width:...''<br>specifies a fixed-width for the panel (using CSS dimensions). This prevents horizontal resizing.
*''height:...''<br>specifies a fixed-height for the panel (using CSS dimensions). This prevents vertical resizing.
In addition to adding panel handlers to a containing element, the macro can also be used to invoke several panel-specific actions, either immediately, or by clicking on an embedded command link:
*''dock''<br>returns a named panel to it's original anchor point.
*''jump''<br>scrolls the window to view a named panel or go to the specified (top,left) location on the page. To dock all panels at once, the ''all'' keyword can be used instead of specifying a ''name:...'' parameter.
*''move''<br>moves the named panel to the specified (top,left) location on the page.
Note: when using ''dock'', ''jump'', or ''move'', if the ''label:...'' parameter is omitted, the action is performed immediately upon rendering the macro. Otherwise, a command link is created using the specified ''label:...'' and (optional) ''prompt:...'' values.
__Mouse handling:__
When the mouse is just inside the edges of a moveable panel, the cursor will change to 'crossed-arrows'. Grab (click-hold) the panel anywhere in the edge area and then drag the mouse to reposition it. To resize the panel, hold the ''shift'' key before grabbing the panel: the cursor will change to a 'double-arrow' resizing symbol. Drag a side edge of the panel to stretch horizontally or vertically, or drag a corner of the panel to stretch in both dimensions at once. Double-clicking the edge of a panel resets it to its original 'docked' size and location. Clicking (anywhere) in a moveable panel brings it to the top of the 'zIndex' stack (if overlapping with other panels). Shift-click (along an edge) sends the panel to the back.
__Panel buttons:__
When the mouse is anywhere over a panel (not just near the edge), a special 'panel menu' appears in the ''upper right corner'' of the panel, with the following command buttons:
* −/+ (fold/unfold): ''fold'' temporarily reduces the panel height to just one line. ''unfold'' restores the panel height.
*^/= (hover/scroll): ''hover'' causes the panel to remain in view (i.e., 'fixed position') even when scrolling the rest of the page content. ''scroll'' allows the panel to revert to scrolling with the page content (the usual behavior)
*X (close): ''close'' hides a panel from the page display. If you have moved/resized a panel, closing it restores its default position and size.
*√ (dock): When a moveable panel has actually been moved from its default position, the ''close'' command is replaced with ''dock'', which restores the tiddler to its default //non-floating// location on the page.
*≡ (manager): If [[PanelManagerPlugin]] is installed, this button provides instant access to the entire Panel Manager popup menu and interactive, graphical panel map viewer.
__Adding panel handlers to all tiddlers__
You can apply {{{<<moveablePanel ...>>}}} to //all// tiddlers by customizing the [[ViewTemplate]] definition to wrap the entire tiddler layout within a span that invokes the macro. To uniquely name each moveable tiddler panel (i.e., so its position/size will be remembered by the Panel Manager), you can use a 'computed parameter' to dynamically assign the tiddler's title as the value of the 'name:...' parameter, like this:
{{{
<div class='moveablePanel'>
... rest of tiddler layout template (i.e., everything from the normal ViewTemplate)
<div macro='moveablePanel name:{{tiddler?tiddler.title:""}} height:auto'></div>
</div>
}}}
//Note: reference to 'tiddler.title' in this way requires installation of TiddlyTools'// [[CoreTweaks##444]] or use of TW2.5 (not yet available)
<<<
!!!!!Configuration
<<<
<<option chkMoveablePanelShowManager>> automatically add<<moveablePanel menu label:[[Panel Manager Popup Menu]]>>in undocked panels
{{{<<option chkMoveablePanelShowManager>>}}}
<<option chkMoveablePanelShowStatus>> show position/size while moving/resizing a panel
{{{<<option chkMoveablePanelShowStatus>>}}}
<<<
!!!!!Revisions
<<<
2010.12.24 3.0.4 fixed findMouseX/findMouseY for webkit browsers
2008.12.24 3.0.3 added ESC key handling to cancel panel move/size (restores previous panel state)
2008.12.20 3.0.2 addGhost()/clearGhost(): shows panel outline during move/size (prevents document from shrinking until move/size is done)
2008.12.15 3.0.1 handling for 'hovered' elements: adjust for fixed vs. absolute (no relative offsets, no scroll offsets), translate movement to top-left screen, restrict movement within screen bounds
2008.12.10 3.0.0 total rewrite: extensive code refactoring and improved event handling for cross-browser compatibility, manage zIndex 'stacking' of panels, added shadow tiddler for customizable CSS, named panels, macro commands for embedding jump, dock, or move command links, complete I18N/L10N-readiness, {{{ensureVisible()}}} 'fixups' for horizontal scrolling, and hooks for optional [[PanelManagerPlugin]] (panel map 'memory' and interactive graphical viewers)
2008.11.17 2.6.0 added optional 'height:...' and 'width:...' macro params for fixed size dimensions (use 'height:auto' for moveable tiddlers). Added CSS for moveablePanelMenu and moveablePanelButton styles (for easier customization)
2008.11.16 2.5.2 small fixes to mouseover/isEdge() handling. some code cleanup as well
2008.11.15 2.5.1 changed stored panel data format to be compatible with Project Cecily map format (space-separated, strip decimals and 'px'). Also, moved slider-specific adjustPanel() logic into [[NestedSlidersPlugin]].
2008.11.12 2.5.0 more major code changes (lots of event handling fixes and code refactoring)
2008.11.09 2.4.0 major re-write to fix mouse event handling issues and isEdge() logic for nested moveable panels
2008.11.06 2.3.0 added CLICK/SHIFT-CLICK for 'move to top / return to stack' panel zIndex handling
2008.11.03 2.2.0 automatically store/recall position/size of named panels using a cookie and/or tiddler
2008.09.11 2.1.2 corrected caching of transient attribute (use =='true' to convert string to boolean)
2008.01.08 [*.*.*] plugin size reduction: documentation moved to ...Info tiddler
2007.12.30 2.1.0 added 'noedges' option for alternative 'grab handles' (top=move, bottom-right=resize)
2007.12.17 2.0.0 code reduction and feature cleanup: when the macro is not in a floating panel, it will make it's containing element moveable. Removed 'maximize' functionality (which was badly broken), and replaced it with 'double-click=DOCK' (resets size/position without hiding panel). Use hasClass() test function to allow additional classes to be used with moveable floating panels (to apply extra custom CSS styles).
2007.06.10 1.3.7 in handler(), mouse event handlers now use apply() to correctly invoke any previous mouse handler functions. Also, clear the existing 'snap panel back to button location' mouseover/out event handlers for floating panels (defined by NestedSlidersPlugin). Extends fix from v1.3.5.
2007.06.08 1.3.6 in getPanel(), remove unneeded check for 'moveable' tag. Also, added support for 'noclose' macro param, and updated documentation accordingly.
2007.06.02 1.3.5 in handler(), remove onmouseover handler from NestedSlider button elements, to prevent automatic 'snap to original location' behavior. This allows *moveable* floating panels to maintain their placement when they have been manually re-positioned. This change is made for compatibility with [[NestedSlidersPlugin]] use of onmouseover (see entry for version 2.0.4)
2006.10.17 1.3.4 when moving panel, adjust position for relative containing DIV
2006.05.25 1.3.3 in closePanel(), use p.button.onclick() so that normal processing (updating slider button tooltip, access key, etc.) is performed
2006.05.11 1.3.2 doc update
2006.05.11 1.3.1 re-define all functions within moveablePanel object (eliminate global window.* function definitions (and some 'leaky closures' in IE)
2006.05.11 1.3.0 converted from inline javascript to true plugin
2006.05.09 1.2.3 in closePanel(), set focus to sliderpanel button (if any)
2006.05.02 1.2.2 in MoveOrSizePanel(), calculate adjustments for top and left when inside nested floating panels
2006.04.06 1.2.1 in getPanel(), allow redefinition or bypass of 'moveable' tag (changed from hard-coded 'tearoff')
2006.03.29 1.2.0 in getPanel(), require 'tearoff' tag to enable floating tiddlers
2006.03.13 1.1.0 added handling for floating tiddlers and conditional menu display
2006.03.06 1.0.2 set move or resize cursor during mousetracking
2006.03.05 1.0.1 use 'window' vs 'document.body' so mousetracking in FF doesn't drop the panel when moving too quickly
2006.03.04 1.0.0 Initial public release
<<<
|''Name''|MoveableTheme|
|''Source''||
|''Checkout''| <html><A HREF="javascript:void(0)"onclick="window.open('#txtTheme:MoveableTheme','linkname','height=800, width=1000,scrollbars=no')" accesskey="u">Popout</a></html> |
|''Version:''|1.0|
|''Author:''|MƄns MƄrtensson|
|''Date:''|Dec 17, 2011|
|''License:''|[[BSD License]]|
|''Comments:''|Please make comments at http://groups.google.nl/group/TiddlyWiki|
|''~CoreVersion:''|2.6.5|
|''Type''|CSS|
|''Description''|a ''~TiddlyWiki'' theme: MoveableThemeInfo|
|''PageTemplate:''|##PageTemplate|
|''ViewTemplate:''|##ViewTemplate|
|''EditTemplate:''|##EditTemplate|
|''StyleSheet:''|##StyleSheet|
|PageTemplateReadOnly|##PageTemplateReadOnly|
|ViewTemplateReadOnly|##ViewTemplateReadOnly|
/%
!basket
[img(180%,130%)[flowerbasket.gif]]
!end %/
!SiteSubtitle
<<tiddler [[MoveableTheme##lys]] with:{{store.getTiddlerText("SiteSubtitle")}} 2 7>>
! /%
!lys
<html><style type="text/css">.html-marquee {height:1$3px;width:50%;background-color:ffff33;font-family:Cursive;font-size:$3pt;color:33cc33;border-width:1pt;border-style:dotted;border-color:ff0000;}
</style>
<marquee class="html-marquee" direction="left" behavior="scroll" scrollamount="$2" >$1...</marquee></html>
! %/
!SiteTitle
<<tiddler MoveableTheme##title with:{{store.getTiddlerText("SiteTitle")}}>>
!title
@@display:none;$1@@[<img(3.2em,auto)[$1|knitting.png][$1]]
!StyleSheet
[[MoveableTiddlerStyles]] /* styles for moveable tiddlers */
[[StyleSheetShortcuts]]
/*{{{*/
#basket
{ width:auto;padding:1em; margin:0; -moz-border-radius:1em; -webkit-border-radius:1em; }
.undocked .searchResults
{ margin-left:1em; width:auto; text-align:left;background-image: url('[[WoodshopBackgroundMedium]]');border:1px solid; padding:1em; -moz-border-radius:1em; -webkit-border-radius:1em; }
.button, .tiddler .button, #sidebarTabs .button
{ margin:0px; padding: 0px .3em; border:1px solid transparent;
-moz-border-radius:3px; -webkit-border-radius:3px; }
.button:hover
{ border:1px solid #999; }
/* GENERAL STYLE TWEAKS */
body { background:#ffe; }
.headerForeground, .headerShadow
{ padding:.5em; }
.headerShadow
{ color:[[ColorPalette::Background]]; }
.headerShadow a
{ color:[[ColorPalette::PrimaryPale]]; }
.headerForeground
{ display:none; }
.undocked .headerShadow
{ color:black; }
.undocked .headerShadow a
{ color:green; }
.undocked .headerForeground
{ display:block; }
#messageArea
{ -moz-border-radius:1em; -webkit-border-radius:1em; }
.popup
{ -moz-border-radius:.5em; -webkit-border-radius:.5em; }
.popup li a
{ padding:2px; }
#mainMenu
{ margin-left:1em; width:auto; text-align:center; background:#fff;
border:1px solid; padding:1em; -moz-border-radius:1em; -webkit-border-radius:1em; }
#sidebarOptions
{ padding-left:1em; margin-left:-1em; border-left:1px solid transparent; }
#sidebarOptions:hover
{ border-left:1px dotted; }
.editor textarea
{ font-family:monospace; line-height:110%; }
.tagged, .tagging
{ -moz-border-radius:.5em; -webkit-border-radius:.5em; }
.selected .tagged, .selected .tagging
{ border:1px solid; }
.tagging
{ margin-left:1em; }
body
{ background-image: url('[[cloth052.jpg]]'); background-color:#db7; }
.undocked #sidebarOptions
{ background-image: url('[[TexturesCrumpled]]'); background-color:#edb; }
.undocked #sidebarTabs
{ background-image: url('[[WoodshopBackgroundMedium]]'); background-color:#edb; }
#mainMenu
{ background-image: url('[[WoodshopBackgroundMedium]]'); background-color:#edb; }
.tiddler .folded .title
{ background-image: url('[[WoodshopBackgroundMedium]]'); }
/*}}}*/
!PageTemplateReadOnly
<!--{{{-->
<div macro='moveablePanel name:header'>
<div class='header' macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryMid]]'>
<div class='headerShadow'>
<span class='siteTitle' refresh='content' tiddler='MoveableTheme##SiteTitle'></span>
<span class='siteSubtitle' refresh='content' tiddler='MoveableTheme##SiteSubtitle'></span>
</div>
<div class='headerForeground'>
<span class='siteTitle' refresh='content' tiddler='MoveableTheme##SiteTitle'></span>
<span class='siteSubtitle' refresh='content' tiddler='MoveableTheme##SiteSubtitle'></span>
</div>
</div>
</div><div macro='moveablePanel name:basket'><div id="basket" refresh='content' force='true' tiddler='MoveableTheme##basket'></div></div>
<div id='mainMenu' class='moveablePanel'>
<div refresh='content' tiddler='MainMenu'></div>
<div macro='moveablePanel name:mainmenu width:auto height:auto'></div>
</div>
<div id='sidebar'>
<span style='position:relative'>
<div macro='moveablePanel name:options width:16em height:auto'>
<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>
</div>
<div macro='moveablePanel name:tabs width:16em height:auto'>
<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>
</div>
</span>
</div>
<div id='displayArea'>
<div id='messageArea'></div>
<div id='searchPanel' class='searchPanel smallform' style='display:none;margin:1em;clear:both' macro='moveablePanel name:searchresults undocked width:auto height:auto'></div>
<div id='tiddlerDisplay'></div>
</div>
<!--}}}-->
!PageTemplate
<!--{{{-->
<div macro='moveablePanel name:header'>
<div class='header' macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryMid]]'>
<div class='headerShadow'>
<span class='siteTitle' refresh='content' tiddler='MoveableTheme##SiteTitle'></span>
<span class='siteSubtitle' refresh='content' tiddler='MoveableTheme##SiteSubtitle'></span>
</div>
<div class='headerForeground'>
<span class='siteTitle' refresh='content' tiddler='MoveableTheme##SiteTitle'></span>
<span class='siteSubtitle' refresh='content' tiddler='MoveableTheme##SiteSubtitle'></span>
</div>
</div>
</div><div macro='moveablePanel name:basket'><div id="basket" refresh='content' force='true' tiddler='MoveableTheme##basket'></div></div>
<div id='mainMenu' class='moveablePanel'>
<div refresh='content' tiddler='MainMenu'></div>
<div macro='moveablePanel name:mainmenu width:auto height:auto'></div>
</div>
<div id='sidebar'>
<span style='position:relative'>
<div macro='moveablePanel name:options width:16em height:auto'>
<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>
</div>
<div macro='moveablePanel name:tabs width:16em height:auto'>
<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>
</div>
</span>
</div>
<div id='displayArea'>
<div id='messageArea'></div>
<div id='searchPanel' class='searchPanel smallform' style='display:none;margin:1em;clear:both' macro='moveablePanel name:searchresults undocked width:auto height:auto'></div>
<div id='tiddlerDisplay'></div>
</div>
<!--}}}-->
!EditTemplate
<!--{{{-->
<div class='moveablePanel'>
<div class='toolbar' macro='toolbar [[ToolbarCommands::EditToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='viewer'>
<div class='editor' macro='edit title'></div>
<div macro='annotations'></div>
<div class='editor' macro='edit text'></div>
<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser'></span></div>
</div>
<div macro='resizeEditor'></div>
<div macro='moveablePanel name:{{story.findContainingTiddler(place).getAttribute("tiddler")}} undocked fold hover height:auto'></div>
</div>
<!--}}}-->
!ViewTemplate
<!--{{{-->
<div class='moveablePanel'>
<div class='toolbar' macro='toolbar [[ToolbarCommands::ViewToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='subtitle'><span macro='view modifier link'></span>, <span macro='view modified date'></span> (<span macro='message views.wikified.createdPrompt'></span> <span macro='view created date'></span>)</div>
<div class='tagged' macro='tags'></div>
<div class='tagging' macro='tagging'></div>
<div class='viewer'>
<div class='content' macro='view text wikified'></div>
</div>
<div class='tagClear'></div>
<div macro='moveablePanel name:{{story.findContainingTiddler(place).getAttribute("tiddler")}} undocked fold hover height:auto'></div>
</div>
<!--}}}-->
!ViewTemplateReadOnly
<!--{{{-->
<div class='moveablePanel'>
<div class='toolbar' macro='toolbar [[ToolbarCommands::ViewToolbarReadOnly]]'></div>
<div class='title' macro='view title'></div>
<div class='subtitle'><span macro='view modifier link'></span>, <span macro='view modified date'></span> (<span macro='message views.wikified.createdPrompt'></span> <span macro='view created date'></span>)</div>
<div class='tagged' macro='tags'></div>
<div class='tagging' macro='tagging'></div>
<div class='viewer'>
<div class='content' macro='view text wikified'></div>
</div>
<div class='tagClear'></div>
<div macro='moveablePanel name:{{story.findContainingTiddler(place).getAttribute("tiddler")}} undocked fold noclose nodock height:auto'></div>
</div>
<!--}}}-->
/***
This stylesheet contains CSS definitions for extra styling of tiddlers (and other standard page content) for use with MoveablePanelPlugin
***/
/*{{{*/
/* UNDOCKED STYLES */
.tiddler
{ margin:0 !important; padding:0 !important; overflow:visible !important;
}
.undocked .header {
border:1px solid; -moz-border-radius:.5em; -webkit-border-radius:.5em;
}
.undocked #sidebarOptions {
width:auto; border:1px solid; padding:1em; margin:0; background:#fff;
-moz-border-radius:1em; -webkit-border-radius:1em;
}
.undocked #sidebarTabs {
width:auto; border:1px solid; padding:1.0em; background:#fff;
-moz-border-radius:1em; -webkit-border-radius:1em;
}
.undocked #sidebarTabs .tabContents
{ width:17em; max-height:30em; overflow:auto; }
.undocked #sidebarTabs .tabContents .tabContents
{ width:16em; max-height:24em; overflow:auto; }
/* TIDDLER 'TITLEBAR' */
.title {
font-size:120%;
line-height:150%;
background-color:#ace;
color:[[ColorPalette::Background]];
border:1px solid [[ColorPalette::Foreground]]; border-bottom:0;
-moz-border-radius:1em 1em 0 0;
-webkit-border-bottom-left-radius:0;
-webkit-border-bottom-right-radius:0;
-webkit-border-top-left-radius: .7em;
-webkit-border-top-right-radius: .7em;
padding-left:.5em;
}
.selected .title {
background-color:#def;
color:[[ColorPalette::Foreground]];
}
.subtitle { display:none; }
/* TIDDLER TOOLBAR */
.tiddler .folded
{ height:2em !important; }
.tiddler .folded .title
{ -moz-border-radius:1em; -webkit-border-radius:1em; border:1px solid #000; }
.tiddler .moveablePanelMenu
{ top:.4em !important } /* shift buttons to fit in titlebar */
.undocked .toolbar
{ padding-right:8em !important; } /* make room for buttons next to toolbar */
.toolbar
{ float:right; visibility:hidden; margin-top:.5em; margin-right:.5em; }
.toolbar .button
{ padding:0px .5em; }
.selected .toolbar
{ visibility:visible; }
.selected .toolbar .button {
background:#fff; color:black; border:1px solid black; margin:0 1px;
-moz-border-radius:.5em; -webkit-border-radius:.5em; }
.selected .toolbar .button:hover
{ background:#ace; }
/* TIDDLER BODY */
.viewer {
border:1px solid; padding:1em; background:#fff;
-moz-border-radius:0 0 1em 1em;
-webkit-border-bottom-left-radius:1em;
-webkit-border-bottom-right-radius:1em;
-webkit-border-top-left-radius:0;
-webkit-border-top-right-radius:0;
}
.viewer .content
{ max-height:35em; overflow:auto; } /* limit tiddler height */
/* ADJUST 'TAGGED' DISPLAY FOR UNDOCKED TIDDLERS */
.undocked .tagged
{ position:absolute; right:2.5em; }
.selected .undocked .tagged
{ opacity:0.1 !important; filter:'alpha(opacity:10)' !important; }
.selected .undocked .tagged:hover
{ opacity:1 !important; filter:'alpha(opacity:100)' !important; }
/* DOTTED FOCUS AROUND CURRENT TIDDLER */
.moveablePanel
{ margin:1px; }
.selected .moveablePanel
{ margin:0px; border:1px dotted;
-moz-border-radius:1.1em; -webkit-border-radius:1.1em; }
/* ELIMINATE SCROLLBARS (and TAGS) IN PanelViewer */
#tiddlerPanelViewer .viewer .content
{ max-height:999999em; }
#tiddlerPanelViewer .panelManagerMapViewer
{ margin-right:1em; }
#tiddlerPanelViewer .tagged
{ display:none; }
/*}}}*/
<!--{{{-->
<!--
|Name|MoveableViewTemplate|
|Source|http://www.TiddlyTools.com/#MoveableViewTemplate|
|Version||
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|template|
|Requires|MoveablePanelPlugin, ViewTemplate, TaggedTemplateTweak|
|Description|add moveablePanel macro to tiddlers tagged with 'moveable'|
-->
<div class='moveablePanel'>
[[ViewTemplate]]
<div macro='moveablePanel name:{{tiddler?tiddler.title:""}} height:auto'></div>
</div>
<!--}}}-->
<!--{{{-->
<div class='header' macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryMid]]'>
<div class='headerShadow'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
<div class='headerForeground'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
</div>
<div id='mainMenu' refresh='content' tiddler='MainMenu'></div>
<div id='sidebar'>
<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>
<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>
</div>
<div id='displayArea'>
<div id='messageArea'></div>
<div id='searchPanel' class='searchPanel smallform' style='display:none;margin:1em;clear:both' macro='moveablePanel name:searchresults undocked width:auto height:auto'></div>
<div id='tiddlerDisplay'></div>
</div>
<!--}}}-->
/***
|Name|[[PanelManagerPlugin]]|
|Source|http://www.TiddlyTools.com/#PanelManagerPlugin|
|Documentation|http://www.TiddlyTools.com/#PanelManagerPlugin|
|Version|1.0.2|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Requires|MoveablePanelPlugin|
|Description|Add-on for [[MoveablePanelPlugin]]: Panel Manager Menu, Control Panel, and Map Viewer |
Track position/size of moveable panels using named //panel maps//. Interactive graphical map viewer provides "bird's eye" view of entire document for quick navigation between panels and management of panel layouts.
!!!!!Documentation
<<<
see [[PanelManagerPluginInfo]] (pending)
{{{
<<moveablePanel menu label:... prompt:...>>
<<moveablePanel menu label:... prompt:... name:...>>
<<moveablePanel maps label:... prompt:...>>
<<moveablePanel load label:... prompt:... name:...>>
<<moveablePanel viewer size:... >>
<<moveablePanel table>>
<<moveablePanel commands>>
}}}
*''menu''<br>instead of adding the mouse handling to the containing panel, the macro will render just the Panel Manager menu button. This allows you to embed the button anywhere in your document (e.g., in the main menu or sidebar) to provide a fixed location for always accessing the current panel layout. When ''menu'' is specified, you can use ''label:...'' and ''prompt:...'' to override the default button text (≡) and tooltip to suit your purposes. If you provide a ''name:...'' parameter along with ''menu'', then only the section of the Panel Manager menu that applies to that named panel will be included in the resulting menu (to control a single, specific panel).
*''maps''<br>embeds a popup list of all panel maps stored in the document, permitting you to quickly switch between panel maps just by selecting a map from the popup list.
*''load''<br>embeds a command link that loads the panel map specified by the ''name:...'' parameter.
*''viewer''<br>embeds a graphical, interactive panel map viewer and page navigator in your tiddler content. You can specify the maximum width and height of the embedded viewer using the ''size:...'' parameter with CSS units of measure (e.g., px, em, cm, in, %). If the size is not specified, the default is for the viewer to fit the element in which it rendered (i.e., using the 'auto' or '100%' CSS value). The ''viewer'' display is updated //live// as panels are docked/undocked, moved, size, folded, etc.
*''table''<br>embeds a panel map data table viewer in your tiddler content. This table shows the x, y, w, h, and z, values associated with each panel stored in the current map. As with the ''viewer'', the ''table'' data is automatically updated when panels are changed.
*''commands''<br>embeds the panel map management commands (i.e., ''new'', ''load'', ''edit'', ''save'', and ''view table...'').
// more documentation pending... //
<<<
!!!!!Open issues
<<<
Known problems:
* IE: Popups appear as a vertical line when X > window width (i.e., the core assumes left side of page)... maybe a CSS clipping issue?
* IE: 'zoomed in' mapsize calculation is way off. These equations need to be re-examined for all browsers.
Additional features (for later):
* Track hover/docked states (in addition to x,y,w,h,z,folded)
* Drag outline in map to scroll page
* Option to normalize z-range when saving maps
<<<
!!!!!Configuration
<<<
<<option chkPanelManagerUseCookies>> remember panel maps between sessions (enables cookies)
<<option chkMoveablePanelShowStatus>> show position/size while moving/resizing a panel
<<option chkMoveablePanelShowManager>> add Panel Manager button to all undocked panels
<<option chkPanelManagerAutoMap>> automatically show map viewer as soon as popup menu is opened
<<option chkPanelManagerMapFullPage>> show full page (zoom out) in map viewer (no scrollbars)
Popup map viewer display size (maximum width and height): {{fourchar{<<option txtPanelManagerPopupMapSize>>}}}
^^//(use CSS dimensions, leave blank or use 'auto' to fit to container)//^^
<<<
!!!!!Examples
<<<
popup menu:
>{{{<<moveablePanel menu label:panels>>}}}
><<moveablePanel menu label:panels>>
map viewer control panel
>{{{<<moveablePanel commands>>}}}
><<moveablePanel commands>>
map viewer display
>{{{<<moveablePanel viewer size:400px>>}}}
>{{groupbox floatleft center{<<moveablePanel viewer size:400px>>}}}{{clear block{}}}
<<<
!!!!!Revisions
<<<
2010.12.24 1.0.2 fixed findMouseX/findMouseY for webkit browsers
2008.12.15 1.0.1 handling for 'hovered' elements: adjust for fixed vs. absolute (no relative offsets, no scroll offsets), translate movements to top-left screen, restrict movements within screen bounds
2008.11.26 1.0.0 initial release - use with [[MoveablePanelPlugin]] v3.0.0 or above
|please see [[MoveablePanelPluginInfo]] for additional information|
<<<
!!!!!Code
***/
//{{{
version.extensions.PanelManagerPlugin= {major: 1, minor: 0, revision: 2, date: new Date(2010,12,24)};
//}}}
// // defaults for options
//{{{
if (config.options.txtMoveablePanelMapName===undefined)
config.options.txtMoveablePanelMapName='DefaultMap';
if (config.options.chkMoveablePanelShowStatus===undefined)
config.options.chkMoveablePanelShowStatus=true;
if (config.options.chkMoveablePanelShowManager===undefined)
config.options.chkMoveablePanelShowManager=true;
if (config.options.chkPanelManagerAutoMap===undefined)
config.options.chkPanelManagerAutoMap=true;
if (config.options.chkPanelManagerMapFullPage===undefined)
config.options.chkPanelManagerMapFullPage=true;
if (config.options.txtPanelManagerPopupMapSize===undefined)
config.options.txtPanelManagerPopupMapSize='auto';
if (config.options.chkPanelManagerUseCookies===undefined)
config.options.chkPanelManagerUseCookies=true;
//}}}
// // shadow tiddlers (for displaying interfaces inside sliders, tabs, etc)
//{{{
config.shadowTiddlers.PanelViewer='<<moveablePanel viewer>>';
config.shadowTiddlers.PanelTable='<<moveablePanel table>>';
config.shadowTiddlers.PanelCommands='<<moveablePanel commands>>';
//}}}
// // translate
//{{{
// TRANSLATORS: copy this section to PanelManagerPluginLingoXX
if (config.macros.moveablePanel===undefined) config.macros.moveablePanel={};
if (config.macros.moveablePanel.manager===undefined) config.macros.moveablePanel.manager={};
merge(config.macros.moveablePanel.manager,{
buttonLabel: '\u2261', // equiv
buttonTip: 'Panel Manager',
panelCmd: "panel: '%0'\xa0",
jumpToPanelCmd: 'jump to panel',
jumpToPanelTip: "bring '%0' into view",
frontCmd: 'bring to front',
frontTip: "bring '%0' to front of stack",
backCmd: 'send to back',
backTip: "send '%0' to back of stack",
stackCmd: 'return to stack',
stackTip: "return '%0' to it's default stack order (zIndex)",
moveCmd: 'move panel',
moveTip: "move '%0' to another location on the page",
foldCmd: 'fold panel',
foldTip: "reduce the height of '%0'",
unfoldCmd: 'unfold panel',
unfoldTip: "restore the height of '%0'",
hoverCmd: 'hover panel',
hoverTip: "keep '%0' in view when scrolling",
scrollCmd: 'scroll panel',
scrollTip: "allow '%0' to move with page",
dockCmd: 'dock panel',
dockTip: "attach '%0' to it's default anchor point",
undockCmd: 'undock panel',
undockTip: "detach '%0' from it's default anchor point",
closeCmd: 'close panel',
closeTip: "hide/close '%0'",
openCmd: 'open panel',
openTip: "show/open '%0'",
resetCmd: 'reset panel',
resetTip: "return '%0' to it's starting size/position for this session",
tiddlerCmd: "tiddler: '%0'",
tiddlerDirtyMsg:"'%0' is currently being edited. Unsaved changes will be discarded.",
selectPanelCmd: 'panels...',
selectPanelTip: 'select and navigate to other panels',
selectPanelMsg: 'select a panel:',
selectMapCmd: 'maps...',
selectMapTip: 'Select a stored panel layout',
selectMapMsg: 'select a map:',
viewMapCmd: "map: '%0'\xa0",
viewMapTip: 'view, load, edit and save panel layouts',
viewMapHeader: "__//current map:// %0 %1__\n",
viewMapEmpty: '| there are currently no //undocked// panels |>|>|>|>|>|',
viewMapUnsaved: '(unsaved)',
newMapCmd: 'new',
newMapTip: "Dock all panels and start a new map",
newMapPrompt: 'Create a new panel map:',
newMapName: 'NewMap',
newMapErr: "A panel map named '%0' already exists. Unsaved changes in '%0' will be discarded.",
loadMapCmd: 'load',
loadThisMapTip: "Apply the panel layout from '%0'",
switchMapMsg: "Now using panel map: '%0'",
editMapCmd: "edit",
editMapTip: 'Edit the stored panel layout',
saveMapCmd: 'save',
saveMapTip: 'Save the current panel layout',
saveMapPrompt: 'Save the current panel map to a tiddler:',
saveMapMsg: "Panel layout saved to '%0'",
unsavedMapErr: "Unsaved changes to the current panel map, '%0', will be discarded.",
optionsCmd: 'options...',
optionsTip: 'set MoveablePanel options',
useCookiesCmd: 'remember panel maps between sessions\xa0',
useCookiesTip: 'remember panel maps between sessions (uses cookies)',
showManagerCmd: 'add PanelManager button to all panels\xa0',
showManagerTip: 'add PanelManager button to all panels',
autoMapCmd: 'show map viewer when popup menu is opened\xa0',
autoMapTip: 'show map viewer when popup menu is opened',
showStatusCmd: 'show panel info while moving/sizing\xa0',
showStatusTip: 'show panel info while moving/sizing',
mapFullPageCmd: 'zoom out (fullpage)',
mapFullPageTip: 'view the entire panel map scaled to fit\xa0',
mapScrollPageCmd:'zoom in (scroll)',
mapScrollPageTip:'view a portion of the panel map with scrolling',
mapSizeCmd: 'viewer size:\xa0',
mapSizeTip: 'set the map viewer display (use CSS measurements: px, em, in, cm, %)',
dockAllCmd: 'dock all panels',
dockAllTip: 'Return all panels to their default anchor points',
resetAllCmd: 'reset all panels',
resetAllTip: 'Reset all panels to their starting size/position for this session',
noPid: 'unnamed panel',
noPanels: '\xa0no active panels\xa0',
notAPanel: "\xa0has not been displayed yet\xa0",
noMaps: '\xa0no saved maps\xa0',
thisPanel: 'this panel',
notMoveableMsg: "'%0' is not a moveable panel",
viewerMapStatsMsg:
"| document size: |''%0 x %1'' |\n"
+"| window size: |''%2 x %3'' |\n"
+"| window view: |''(%4-%5) x (%6-%7)'' |\n",
viewerTableCmd: 'show table...',
viewerTableTip: 'show/hide current map data table',
viewerBackgroundTip:'click for display options...',
refreshMapCmd: 'refresh viewer',
refreshMapTip: 'redraw map viewer display image',
viewerMapTip: 'click to scroll...',
XYJumpCmd: 'scroll window to:',
XYJumpTip: 'scroll to %0(%1,%2)',
XYMoveCmd: "move '%0' to:",
XYMoveTip: 'move panel to %0(%1,%2)',
jumpHereCmd: 'scroll here (%0,%1)\xa0',
moveHereCmd: 'move here (%0,%1)\xa0',
compassJumpCmd: 'or, scroll to:',
compassMoveCmd: 'or, move to:',
centerJumpCmd: 'center on panel',
centerJumpTip: 'view panel in center of window ',
centerMoveCmd: 'center in view',
centerMoveTip: 'center of current window view ',
compassTL: '\u25E4', compassT: '\u25B2', compassTR: '\u25E5',
compassL: '\u25C4', compassC: '\u25CA', compassR: '\u25BA',
compassBL: '\u25E3', compassB: '\u25BC', compassBR: '\u25E2',
compassTLTip: 'top left corner of page ',
compassTTip: 'top edge of page ',
compassTRTip: 'top right corner of page ',
compassLTip: 'left edge of page ',
compassCTip: 'center of page ',
compassRTip: 'right edge of page ',
compassBLTip: 'bottom left corner of page ',
compassBTip: 'bottom edge of page ',
compassBRTip: 'bottom right corner of page ',
mapTags: ['panelmap'], // default tags - 1st tag used to find panelmaps - can be customized
mapTag: 'panelmap', // fallback default - DO NOT CHANGE
mapHeader: '| %0!panelname| !x | !y | !w | !h | !z | !fold | !hover |h', // CHANGE HEADINGS ONLY
mapFormat: '| %0| %1| %2| %3| %4| %5| %6 | %7 |', // DO NOT CHANGE
checkmark: '\u221A', // DO NOT CHANGE
// DO NOT TRANSLATE PARAMETERS (BREAKS PORTABILITY OF CONTENT ACROSS DOCUMENTS)
nameParam: 'name',
menuParam: 'menu',
mapsParam: 'maps',
labelParam: 'label',
promptParam: 'prompt',
commandsParam: 'commands',
viewerParam: 'viewer',
tableParam: 'table',
sizeParam: 'size',
loadParam: 'load'
});
//}}}
// // general utilities (global)
//{{{
// if removeCookie() function is not defined by TW core, define it here (for <TW2.5)
if (window.removeCookie===undefined) {
window.removeCookie=function(name) {
document.cookie = name+'=; expires=Thu, 01-Jan-1970 00:00:01 UTC; path=/;';
}
}
if (window.copyObject===undefined) {
window.copyObject=function(src) {
for (var i in src) this[i]=typeof src[i]!='object'?src[i]:new copyObject(src[i]);
}
}
if (window.compareObjects===undefined) {
window.compareObjects=function(a,b) {
if (a===b) return true;
if (a==undefined||b==undefined) return false;
for (var i in a) if (typeof a[i]!='object'?a[i]!==b[i]:!compareObjects(a[i],b[i])) return false;
return true;
}
}
if (window.isEmptyObject===undefined) {
window.isEmptyObject=function(src) { for (var i in src) return false; return true; }
}
// cross-browser metrics
window.findMouseX=function(ev) { if (!ev) return 0; var x=0;
if (config.browser.isIE) return ev.clientX+findScrollX();// IE
if (config.browser.isSafari) return ev.pageX+findScrollX(); // Webkit
else return ev.pageX; // Firefox/other
}
window.findMouseY=function(ev){ if (!ev) return 0; var y=0;
if (config.browser.isIE) return ev.clientY+findScrollY();// IE
if (config.browser.isSafari) return ev.pageY+findScrollY(); // Webkit
else return ev.pageY; // Firefox/other
}
// NOTE: WEBKIT uses document.width/height, MOZ uses the 'documentElement.scrollWidth/Height'
window.findDocumentWidth=function()
{ var dw=document.documentElement.scrollWidth; if (document.width>dw) dw=document.width; return dw; }
window.findDocumentHeight=function()
{ var dh=document.documentElement.scrollHeight; if (document.height>dh) dh=document.height; return dh; }
// abbreviations for adding menu elements
window.addLI=function(place)
{return createTiddlyElement(place,'li');};
window.addBR=function(place)
{return createTiddlyElement(place,'br');};
window.addHR=function(place)
{return createTiddlyElement(createTiddlyElement(place,'li',null,'listBreak'),'div');};
window.addSEP=function(place)
{return createTiddlyText(place,'\xa0|\xa0');};
window.addTXT=function(place,txt)
{return createTiddlyText(addLI(place),txt)};
window.addBTN=function(place,label,tip,fn)
{return createTiddlyButton(place,label,tip,fn,'button')};
window.addCMD=function(place,label,tip,fn)
{return createTiddlyButton(addLI(place),label,tip,fn,'button')};
window.addPOP=function(place,className)
{return Popup.create(place,null,'popup '+className)};
window.addCHK=function(place,label,tip,opt,hidechk) { // option checkbox AND text toggle config.options[chk...]
if (!hidechk) config.macros.option.genericCreate(place,'chk',opt,null,'no');
var b=addBTN(place,label,tip,function(ev){
var ev=ev||window.event; var cmm=config.macros.moveablePanel;
config.options[this.opt]=!config.options[this.opt];
config.macros.option.propagateOption(this.opt,'checked',config.options[this.opt],'input');
saveOptionCookie(this.opt); cmm.manager.notify('option:'+this.opt);
Popup.remove(Popup.find(this)); return cmm.processed(ev);
}); b.opt=opt; b.innerHTML=label;
};
// open popup at current mouse position
Popup.showHere=function(place,ev) {
var x=findMouseX(ev)-findPosX(place);
var y=findMouseY(ev)-findPosY(place);
Popup.show('top','left',{x:x,y:y});
}
//}}}
// // macro
//{{{
if (config.macros.moveablePanel===undefined) config.macros.moveablePanel={};
if (config.macros.moveablePanel.manager===undefined) config.macros.moveablePanel.manager={};
merge(config.macros.moveablePanel.manager,{
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
var showmenu =params.contains(this.menuParam);
var showcommands=params.contains(this.commandsParam);
var showtable =params.contains(this.tableParam);
var showviewer =params.contains(this.viewerParam);
var showmaps =params.contains(this.mapsParam);
params=paramString.parseParams('anon',null,true,false,false);
var load =getParam(params,this.loadParam,null);
var name =getParam(params,this.nameParam,null);
var label =getParam(params,this.labelParam,null);
var prompt =getParam(params,this.promptParam,null);
var size =getParam(params,this.sizeParam,null);
if (load) addBTN(place,label||load,prompt||this.loadThisMapTip.format([load]),function(ev){
config.macros.moveablePanel.manager.loadMap(this.map,ev)}).map=load;
if (showmenu) this.menu(place,name,label||this.buttonLabel,prompt||this.buttonTip);
if (showcommands) this.viewer_commands(createTiddlyElement(place,'div'));
if (showtable) this.viewer_table(createTiddlyElement(place,'div'));
if (showviewer) this.viewer_map(createTiddlyElement(place,'div'),false,size);
if (showmaps) this.menu_loadMap(place,label||this.selectMapCmd,prompt||this.selectMapTip,'bottom','left');
return load||showmenu||showcommands||showtable||showviewer||showmaps; // handled==TRUE
},
//}}}
// // notifications
//{{{
notify: function(p) { // p=panel that was changed (or a text message if refresh/reload event)
if (config.macros.moveablePanel.quiet) return;
// for now, just a general refresh of all currently display viewers
this.refreshAllViewers(p);
},
//}}}
// // panel maps
//{{{
map: undefined,
startingMap: undefined,
trackMap: function(p) {
if (!p||!p.pid||!p.pid.length) return;
this.readMap(config.options.txtMoveablePanelMapName);
var re=/(\.[0-9]*px)|px/g; // removes decimals and 'px' from CSS
if (!hasClass(p,'undocked'))
delete this.map[p.pid];
else this.map[p.pid]={ pid:p.pid,
x:p.style.left.replace(re,''), y:p.style.top.replace(re,''),
w:p.style.width.replace(re,''), h:p.style.height.replace(re,''),
z:p.style.zIndex, folded:hasClass(p,'folded'), hover:hasClass(p,'hover') };
this.setMapCookie(config.options.txtMoveablePanelMapName);
this.notify(p);
},
applyMap: function(p) {
var cmm=config.macros.moveablePanel;
if (!p||!p.pid||!p.pid.length) return;
this.readMap(config.options.txtMoveablePanelMapName);
var d=this.map[p.pid]; if (!d) return; // panel is not mapped... do nothing
if (!cmm.isStackable(p)) p.style.position='absolute';
addClass(p,'undocked');
if (d.folded) addClass(p,'folded'); else removeClass(p,'folded');
if (d.hover) addClass(p,'hover'); else removeClass(p,'hover');
function addPX(v) { return v&&v.length?v+(!isNaN(v)?'px':''):''; }
p.style.left =addPX(d.x); p.style.top =addPX(d.y);
p.style.width =addPX(d.w); p.style.height=addPX(d.h);
p.style.zIndex=d.z&&d.z.length?d.z:'';
this.notify(p);
},
formatMap: function(includeHeading) {
var cmm=config.macros.moveablePanel;
function pad(t,maxlen) {
var spaces=' '; // 50 spaces
return t.toString().length>=maxlen?'':spaces.substr(0,maxlen-t.toString().length);
}
var panels=cmm.getAllPanels(true); // sorted by zIndex
var maxlen=0; for (var i=0; i<panels.length; i++)
if (panels[i].pid && panels[i].pid.length>maxlen) maxlen=panels[i].pid.length;
var panelHeader=this.mapHeader.split('|')[1].trim().format(['']);
if (maxlen<panelHeader.length) maxlen=panelHeader.length;
var out=[];
if (includeHeading) out.push(this.mapHeader.format([pad(panelHeader,maxlen)]));
for (var i=0; i<panels.length; i++) {
var pid=panels[i].pid; var d=this.map[pid]; if (!d) continue;
out.push(this.mapFormat.format([pad(pid,maxlen)+pid,
pad(d.x,5)+d.x, pad(d.y,5)+d.y, pad(d.w,5)+d.w, pad(d.h,5)+d.h,
pad(d.z,5)+d.z, d.folded?this.checkmark:' ', d.hover?this.checkmark:' ' ]));
}
return out.join('\n');
},
setMapCookie: function(map) {
if (!config.options.chkPanelManagerUseCookies) return;
var opt='txt'+map;
config.options[opt]=this.formatMap();
if (config.options[opt].length) saveOptionCookie(opt); else removeCookie(opt);
},
readMap: function(map,force) { // get map from tiddler+cookie (cookie takes precedence)
if (this.map && !force) return; // CACHED or LOAD ON DEMAND
delete this.map; this.map=new Object();
var t=store.getTiddlerText(map);
if (config.options.chkPanelManagerUseCookies) var c=config.options['txt'+map];
var m=(t||'')+(t&&c?'\n':'')+(c||'');
if (!m||!m.length) return false; // NO MAP
var items=m.split('\n');
for (var i=0; i<items.length; i++) {
// skip non-data table rows (|h, |c, or |k syntax)
if (items[i].substr(items[i].length-1,1)!='|') continue;
var d=items[i].split('|');
for (var j=0;j<d.length;j++) d[j]=d[j]?d[j].trim():'';
if (d[1]&&d[1].length) {
var m=this.map[d[1]]=new Object();
m.pid=d[1]; m.x=d[2]; m.y=d[3]; m.w=d[4]; m.h=d[5]; m.z=d[6];
m.folded=(d[7]&&d[7].length>0); m.hover=(d[8]&&d[8].length>0);
}
}
if (!force) this.startingMap=new copyObject(this.map); // DEEP COPY TO CACHE
},
writeMap: function(map) {
this.readMap(map);
var t=store.getTiddler(map);
var who=t&&config.options.chkForceMinorUpdate?t.modifier:config.options.txtUserName;
var when=t&&config.options.chkForceMinorUpdate?t.modified:new Date();
var tags=t?t.tags:this.mapTags; tags.pushUnique(this.mapTags[0]||this.mapTag);
var fields=t?t.fields:{};
store.saveTiddler(map,map,this.formatMap(true),who,when,tags,fields);
story.refreshTiddler(map,null,true);
},
newMap: function(ev) { // clear map and docked all panels
var cmm=config.macros.moveablePanel;
var map=config.options.txtMoveablePanelMapName;
var newname=prompt(this.newMapPrompt,this.newMapName);
while (newname && newname.trim().length && newname!=map && newname!=this.newMapName
&& (config.options['txt'+newname]||store.tiddlerExists(newname)) ) {
if (confirm(this.newMapErr.format([newname]))) break; // CANCELLED
newname=prompt(this.newMapPrompt,newname);
}
if (!newname || !newname.trim().length) return true; // CANCELLED
if (this.isMapChanged(map)&&!confirm(this.unsavedMapErr.format([map]))) return true;
delete this.map; this.map=new Object();
config.options['txt'+newname]=''; removeCookie('txt'+newname); // flush new map cookie (if any)
var panels=cmm.getAllPanels();
cmm.quiet++; for (var i=0; i<panels.length; i++) cmm.restorePanel(panels[i]); cmm.quiet--;
config.options.txtMoveablePanelMapName=newname;
saveOptionCookie('txtMoveablePanelMapName');
this.notify('new map');
return cmm.processed(ev);
},
loadMap: function(map,ev) { // *adds* entries to existing map data
var cmm=config.macros.moveablePanel;
var currmap=config.options.txtMoveablePanelMapName;
if (this.isMapChanged(currmap)&&!confirm(this.unsavedMapErr.format([currmap]))) return true;
config.options['txt'+map]=''; removeCookie('txt'+map);
this.readMap(map,true); // FORCE RELOAD
cmm.quiet++;
var panels=cmm.getAllPanels();
for (var i=0; i<panels.length; i++) {
if (hasClass(panels[i],'undocked')) cmm.restorePanel(panels[i]);
this.applyMap(panels[i]);
}
cmm.quiet--;
config.options.txtMoveablePanelMapName=map;
saveOptionCookie('txtMoveablePanelMapName')
this.setMapCookie(map);
this.notify('load map');
return cmm.processed(ev);
},
saveMap: function(map,ev) {
var cmm=config.macros.moveablePanel;
var map=prompt(this.saveMapPrompt,map);
while (map && map.trim().length && store.tiddlerExists(map)) {
var msg=story.isDirty(map)?this.tiddlerDirtyMsg:config.messages.overwriteWarning;
if (confirm(msg.format([map]))) break; // CANCELLED
map=prompt(this.saveMapPrompt,map);
}
if (!map || !map.trim().length) return true; // CANCELLED
if (story.isDirty(map)) { story.closeTiddler(map); story.displayTiddler(null,map); }
this.writeMap(map);
displayMessage(this.saveMapMsg.format([map]));
config.options.txtMoveablePanelMapName=map; saveOptionCookie('txtMoveablePanelMapName');
return cmm.processed(ev);
},
isPanelMapped: function(pid) { // is panel ID in the map?
return this.map && this.map[pid];
},
isPanelChanged: function(p) { // compare current and starting map values
var now=this.map?this.map[p.pid]:undefined;
var then=this.startingMap?this.startingMap[p.pid]:undefined;
if (!now&&!then) return false;
if (!now&&then || now&&!then) return true;
return (now.x!=then.x || now.y!=then.y || now.w!=then.w || now.h!=then.h || now.z!=then.z);
},
resetPanel: function(p) { // restore panel from starting map (if any)
var cmm=config.macros.moveablePanel;
if (!this.startingMap || !this.startingMap[p.pid]) { cmm.dockPanel(p); return; }
cmm.quiet++;
if (hasClass(p,'folded')) cmm.foldPanel(p); // un-fold
if (hasClass(p,'hover')) cmm.hoverPanel(p); // un-hover
this.map[p.pid]=new copyObject(this.startingMap[p.pid]);
this.setMapCookie(config.options.txtMoveablePanelMapName);
cmm.quiet--;
this.applyMap(p);
},
isMapChanged: function(map) { // compare with saved map or starting map
var currMap=this.formatMap(true);
var savedMap=store.getTiddlerText(map);
if (isEmptyObject(this.map)&&(!savedMap||(map==this.newMapName))) return false;
return savedMap?currMap!=savedMap:!compareObjects(this.map,this.startingMap);
},
//}}}
// // menu button and popup
//{{{
menu: function(place,name,label,prompt) {
if (name) { // show only the submenu for the named panel
var b=addBTN(place,label,prompt,function(ev){
var ev=ev||window.event; var cmm=config.macros.moveablePanel;
var popup=addPOP(this,'panelManagerPopup'); if (!popup) return false;
var docX=findMouseX(ev)+findScrollX(); var docY=findMouseY(ev)+findScrollY();
cmm.manager.menu_panel(popup,cmm.findPanel(this.pid),this.pid,Popup.find(this)+1,docX,docY);
Popup.show(); return cmm.processed(ev);
}); b.innerHTML=label; b.pid=name;
} else { // show entire manager menu
var b=addBTN(place,label,prompt,function(ev){
return config.macros.moveablePanel.manager.popup(this,ev,null,true);
}); b.innerHTML=label;
}
},
popup: function(place,ev,pid,nopanel) {
var ev=ev||window.event; var cmm=config.macros.moveablePanel; var mgr=cmm.manager;
var popup=addPOP(place,'sticky panelManagerPopup'); if (!popup) return cmm.processed(ev);
popup.onclick=function(ev) { var ev=ev||window.event; var cmm=config.macros.moveablePanel;
var lvl=Popup.find(this); if (lvl<Popup.stack.length-1) // toggle child popups
{ Popup.remove(lvl+1); return cmm.processed(ev); }
}
var panel=cmm.findPanel(pid)||cmm.getPanel(place);
var showPanelMenu=hasClass(panel,'moveablePanel')&&!nopanel;
mgr.menu_map(popup,config.options.chkPanelManagerAutoMap);
if (showPanelMenu) { // FOR THIS PANEL
var b=addCMD(popup,mgr.panelCmd.format([pid]),cmm.getPanelTooltip(panel),function(ev){
var ev=ev||window.event; var cmm=config.macros.moveablePanel;
var popup=addPOP(this,'panelManagerPopup'); if (!popup) return false;
var docX=findMouseX(ev)+findScrollX(); var docY=findMouseY(ev)+findScrollY();
cmm.manager.menu_panel(popup,panel,this.panel.pid,Popup.find(this)+1,docX,docY);
Popup.show('top','right'); return cmm.processed(ev);
}); b.panel=panel;
}
addHR(popup);
mgr.menu_forAll(popup);
addHR(popup);
mgr.menu_selectMap(popup);
mgr.menu_selectPanel(popup);
mgr.menu_options(popup);
addHR(popup);
addTXT(popup,mgr.XYJumpCmd);
mgr.menu_compass(popup,showPanelMenu?panel:null,findMouseX(ev),findMouseY(ev)); // scroll
Popup.showHere(place,ev)
return cmm.processed(ev);
},
//}}}
// // manager menu
//{{{
menu_panel: function(place,p,pid,remove,x,y) {
var cmm=config.macros.moveablePanel;
// commands FOR ONE PANEL
// p=panel, pid=requested panel ID, remove=popup level to close afterwards
if (!p){addTXT(place,this.panelCmd.format([pid]));addTXT(place,this.notAPanel.format([pid]));return;}
function cmd(place,label,tip,callback,p,arg) { // buttons invoke 'callback(p,arg)'
var b=addCMD(place,label,tip,function(ev){
var ev=ev||window.event; var cmm=config.macros.moveablePanel;
this.callback.apply(cmm,[this.panel,this.arg]);
cmm.manager.trackMap(this.panel);
cmm.manager.refreshAllViewers();
Popup.remove(this.remove);
return cmm.processed(ev);
}); b.panel=p; b.callback=callback; b.arg=arg; b.remove=remove;
}
var pid=p.pid||this.thisPanel;
var u=hasClass(p,'undocked');
var f=hasClass(p,'floatingPanel');
var folded=hasClass(p,'folded');
var hover=hasClass(p,'hover');
var v=p.style.display!='none';
var here=story.findContainingTiddler(p);
var t=here&&cmm.findPanel(here.getAttribute('tiddler'));
cmd(place,this.jumpToPanelCmd,this.jumpToPanelTip.format([pid]),cmm.ensurePanelVisible, p);
if (u) cmd(place,this.frontCmd,this.frontTip.format([pid]),cmm.bringPanelToFront, p);
if (u) cmd(place,this.backCmd, this.backTip.format( [pid]),cmm.sendPanelToBack, p);
if (u) cmd(place,this.stackCmd,this.stackTip.format([pid]),cmm.returnPanelToStack,p);
if (p.showfold && (u||f)) {
if (!folded) cmd(place,this.foldCmd, this.foldTip.format( [pid]),cmm.foldPanel, p);
if ( folded) cmd(place,this.unfoldCmd,this.unfoldTip.format([pid]),cmm.foldPanel, p);
}
if (p.showhover && (u||f)) {
if (!hover) cmd(place,this.hoverCmd, this.hoverTip.format( [pid]),cmm.hoverPanel,p);
if ( hover) cmd(place,this.scrollCmd,this.scrollTip.format([pid]),cmm.hoverPanel,p);
}
if (cmm.manager.isPanelChanged(p))
cmd(place,this.resetCmd,this.resetTip.format([pid]),cmm.resetPanel,p);
if (t) cmd(place,this.closeCmd,this.closeTip.format([pid]),cmm.closePanel,p);
if (f&&v) cmd(place,this.closeCmd,this.closeTip.format([pid]),cmm.closePanel,p);
if (f&&!v) cmd(place,this.openCmd, this.openTip.format( [pid]),cmm.closePanel,p);
if (u) cmd(place,this.dockCmd, this.dockTip.format( [pid]),cmm.dockPanel, p);
if (!u) cmd(place,this.undockCmd,this.undockTip.format([pid]),cmm.undockPanel,p,true);
if (u||f) { // move panel
addHR(place); addTXT(place,this.XYMoveCmd.format([pid]));
this.menu_compass(place,p,x,y,true); // move
}
},
menu_compass: function(place,p,x,y,move) { // scroll page or move panel using 'compass' buttons
function cmd(place,label,tip,isTD,p,x,y,move) {
var b=createTiddlyButton(isTD?createTiddlyElement(place,'TD'):addLI(place),label,tip,function(ev){
var ev=ev||window.event; var cmm=config.macros.moveablePanel;
if (this.move && this.p) cmm.movePanel(this.p,this.x,this.y,true,true);
else window.scrollTo(this.x,this.y);
cmm.manager.refreshAllViewers(); Popup.remove(Popup.find(this)); return cmm.processed(ev);
},isTD?'panelManagerPopupCompassButton':'button'); b.p=p; b.x=x; b.y=y; b.move=move;
}
var ww=findWindowWidth(); var dw=findDocumentWidth(); var sx=findScrollX();
var wh=findWindowHeight(); var dh=findDocumentHeight(); var sy=findScrollY();
var cx=Math.floor(dw/2); var cy=Math.floor(dh/2);
var nx=sx; var ny=sy; // assume scrolling
move=move&&p; // only if a valid panel
var tip=move?this.XYMoveTip:this.XYJumpTip;
if (p) { // if panel, calc window center position for center on panel / center in view
var px=p.offsetLeft; var py=p.offsetTop; var pw=p.offsetWidth; var ph=p.offsetHeight;
if (move) { // adjust document width/centering to account for panel width/height
dw-=pw+2; cx-=pw/2; var nx=px;
dh-=ph+2; cy-=ph/2; var ny=py;
var wcx=Math.floor(sx+ww/2-pw/2);
var wcy=Math.floor(sy+wh/2-ph/2);
} else {
var offset=config.macros.moveablePanel.getPanelOffset(p); // adjust for relative elements
var wcx=Math.max(Math.floor(px+offset.x-ww/2+pw/2),0);
var wcy=Math.max(Math.floor(py+offset.y-wh/2+ph/2),0);
}
}
var indent='\xa0\xa0';
// PANEL
if (p) {
var label=move?this.centerMoveCmd:this.centerJumpCmd;
var prompt=tip.format([move?this.centerMoveTip:this.centerJumpTip,wcx,wcy]);
cmd(place,indent+label,prompt,false,p,wcx,wcy,move);
}
// HERE
var label=move?this.moveHereCmd:this.jumpHereCmd;
cmd(place,indent+label.format([x,y]),tip.format(['',x,y]),false,p,x,y,move);
addTXT(place,indent+(move?this.compassMoveCmd:this.compassJumpCmd));
// COMPASS
var tbl=createTiddlyElement(place,'table',null,'panelManagerPopupCompass');
var tbody=createTiddlyElement(tbl,'tbody');
var tr=createTiddlyElement(tbody,'tr');
cmd(tr,this.compassTL,tip.format([this.compassTLTip, 0,0]),true,p, 0,0,move);
cmd(tr,this.compassT, tip.format([this.compassTTip ,nx,0]),true,p,nx,0,move);
cmd(tr,this.compassTR,tip.format([this.compassTRTip,dw,0]),true,p,dw,0,move);
var tr=createTiddlyElement(tbody,'tr');
cmd(tr,this.compassL, tip.format([this.compassLTip, 0,ny]),true,p, 0,ny,move);
cmd(tr,this.compassC, tip.format([this.compassCTip,cx,cy]),true,p,cx,cy,move);
cmd(tr,this.compassR, tip.format([this.compassRTip,dw,ny]),true,p,dw,ny,move);
var tr=createTiddlyElement(tbody,'tr');
cmd(tr,this.compassBL,tip.format([this.compassBLTip, 0,dh]),true,p, 0,dh,move);
cmd(tr,this.compassB, tip.format([this.compassBTip ,nx,dh]),true,p,nx,dh,move);
cmd(tr,this.compassBR,tip.format([this.compassBRTip,dw,dh]),true,p,dw,dh,move);
},
menu_map: function(place,autoclick) {
var map=config.options.txtMoveablePanelMapName;
var b=addCMD(place,this.viewMapCmd.format([map]),this.viewMapTip,function(ev){
var ev=ev||window.event; var cmm=config.macros.moveablePanel;
var popup=addPOP(this,'sticky panelManagerMapPopup'); if (!popup) return false;
cmm.manager.viewer_commands(popup);
addHR(popup);
cmm.manager.viewer_map(popup);
popup.onclick=function(ev) {
var ev=ev||window.event; var cmm=config.macros.moveablePanel;
var lvl=Popup.find(this); if (lvl<Popup.stack.length-1) // toggle child popup
{ Popup.remove(lvl+1); return cmm.processed(ev); }
var popup=addPOP(this,'sticky panelManagerPopup'); if(!popup)return false;
cmm.manager.menu_mapBackground(popup);
Popup.showHere(this,ev); return cmm.processed(ev);
}
popup.title=cmm.manager.viewerBackgroundTip;
Popup.show('top','right');
return cmm.processed(ev);
});
// autoclick on initial mouseover
if (autoclick) b.onmouseover=function(ev) { this.onmouseover=null; return this.onclick.apply(this,arguments); };
},
menu_forAll: function(place) {
var cmm=config.macros.moveablePanel;
// commands FOR ALL PANELS
function cmd(label,tip,callback) {
var b=addCMD(place,label,tip,function(ev){
var ev=ev||window.event; var cmm=config.macros.moveablePanel;
if (!confirm(this.title+'?')) return false;
var panels=cmm.forAllPanels(this.callback);
cmm.manager.refreshAllViewers();
Popup.remove(Popup.find(this)); return cmm.processed(ev);
}); b.callback=callback;
};
cmd(this.resetAllCmd,this.resetAllTip,cmm.resetPanel);
cmd(this.dockAllCmd,this.dockAllTip,cmm.dockPanel);
},
menu_selectPanel: function(place){
// LIST OF PANELS with PANEL SUBMENUS
addCMD(place,this.selectPanelCmd,this.selectPanelTip,function(ev){
var ev=ev||window.event; var cmm=config.macros.moveablePanel;
var popup=addPOP(this,'panelManagerPopup'); if (!popup) return false;
var panels=cmm.getAllPanels();
addTXT(popup,panels.length?cmm.manager.selectPanelMsg:cmm.manager.noPanels);
for (var i=0; i<panels.length; i++) { var p=panels[i];
var b=addCMD(popup,p.pid||cmm.manager.noPid,cmm.getPanelTooltip(p),function(ev){
var ev=ev||window.event; var cmm=config.macros.moveablePanel;
var popup=addPOP(this,'panelManagerPopup');
if(!popup)return false;
var docX=findMouseX(ev)+findScrollX(); var docY=findMouseY(ev)+findScrollY();
cmm.manager.menu_panel(popup,this.p,
this.p.pid||cmm.manager.thisPanel,Popup.find(this)+1,docX,docY);
Popup.show('top','right'); return cmm.processed(ev);
}); b.p=p; b.onmouseover=b.onclick; // ALWAYS autoclick on mouseover
}
Popup.show('top','right'); return cmm.processed(ev);
});
},
menu_selectMap: function(place){
// same as LOAD COMMAND IN VIEWER (with different label/tip and popup alignment)
this.menu_loadMap(addLI(place),this.selectMapCmd,this.selectMapTip,'top','right');
},
menu_options: function(place) {
var on='<input type="checkbox" checked>'; var off='<input type="checkbox">';
addCMD(place,this.optionsCmd,this.optionsTip,function(ev){
var ev=ev||window.event; var cmm=config.macros.moveablePanel; var mgr=cmm.manager;
var popup=addPOP(this,'sticky panelManagerPopup'); if (!popup) return false;
addCHK(popup,mgr.useCookiesCmd,mgr.useCookiesTip,'chkPanelManagerUseCookies');
addBR(popup);
addCHK(popup,mgr.showManagerCmd,mgr.showManagerTip,'chkMoveablePanelShowManager');
addBR(popup);
addCHK(popup,mgr.autoMapCmd,mgr.autoMapTip,'chkPanelManagerAutoMap');
addBR(popup);
addCHK(popup,mgr.showStatusCmd,mgr.showStatusTip,'chkMoveablePanelShowStatus');
Popup.show('top','right'); return cmm.processed(ev);
});
},
//}}}
// // panel map viewers
//{{{
// MAP MANAGEMENT COMMANDS
viewer_commands: function(place,refresh) {
if (refresh) removeChildren(place);
else place=createTiddlyElement(place,'div',null,'panelManagerMapCommands');
var map=config.options.txtMoveablePanelMapName;
var unsaved=this.isMapChanged(map)?this.viewMapUnsaved:'';
wikify(this.viewMapHeader.format([map,unsaved]),place);
this.command_newMap(place);
addSEP(place); this.menu_loadMap(place,this.loadMapCmd,this.selectMapTip);
addSEP(place); this.command_editMap(place);
addSEP(place); this.command_saveMap(place);
addSEP(place); this.command_viewerTable(place);
},
//}}}
//{{{
// TABLE VIEW - ALL MAP ENTRIES
viewer_table: function(place,refresh) {
var cmm=config.macros.moveablePanel;
if (refresh) removeChildren(place);
else place=createTiddlyElement(place,"div",null,"panelManagerMapTable");
place.onclick=function(ev){ var cmm=config.macros.moveablePanel;
var lvl=Popup.find(this); if (lvl!=-1) Popup.remove(lvl+1);
cmm.manager.refreshAllViewers(); return cmm.processed(ev); }
var link='[[%0]]'; var cmd='<<moveablePanel %2 %3:[[%0]] %4:[[%0]] %5:[[%1]]>>';
cmd=cmd.format(['%0','%1',this.menuParam,this.nameParam,this.labelParam,this.promptParam]);
var sortByZ=function(a,b){ var v1=parseInt(a.z); var v2=parseInt(b.z); return(v1==v2)?0:(v1>v2?1:-1); }
var map=[]; for (var pid in this.map) map.push(this.map[pid]); map=map.sort(sortByZ);
var rows=[]; for (var i=0; i<map.length; i++) { var m=map[i];
var isPanel=cmm.findPanel(m.pid);
var isTiddler=store.tiddlerExists(m.pid)||store.isShadowTiddler(m.pid);
var fmt=isPanel?cmd:(isTiddler?link:cmd);
var lbl=fmt.format([m.pid,this.panelCmd.format([m.pid])]);
rows.push(this.mapFormat.format([lbl,m.x,m.y,m.w,m.h,m.z,
m.folded?this.checkmark:' ', m.hover?this.checkmark:' ']));
}
var table=this.mapHeader.format([''])+'\n'+rows.join('\n')+(!rows.length?this.viewMapEmpty:'');
wikify(table,place);
},
//}}}
//{{{
// GRAPHICAL VIEWER - ACTIVE PANELS AND TIDDLERS
mapXtoDocX: function(e,ev,scale,scroller) { // convert mouse click in map panel to equivalent document location
var mouseX=findMouseX(ev);
var mapX=findPosX(e.parentNode)-scroller.scrollLeft;
var docX=Math.floor((mouseX-mapX)/scale)-Math.floor((mouseX-mapX)*scale);
return docX;
},
mapYtoDocY: function(e,ev,scale,scroller) { // convert mouse click in map panel to equivalent document location
var mouseY=findMouseY(ev);
var mapY=findPosY(e.parentNode)-scroller.scrollTop;
var docY=Math.floor((mouseY-mapY)/scale)-Math.floor((mouseY-mapY)*scale);
return docY;
},
viewer_map: function(place,refresh,mapSize){
var cmm=config.macros.moveablePanel;
if (!refresh) {
place=createTiddlyElement(place,'div',null,'panelManagerMapViewer');
place.mapSize=mapSize; // save for use with refresh
} else {
var mapSize=place.mapSize; // refresh... use saved map size
removeChildren(place); // NOTE: ASSUMES CONTAINER HAS NO OTHER CONTENT
}
// METRICS
var dw=findDocumentWidth(); var ww=findWindowWidth(); if (dw<ww) dw=ww; var sx=findScrollX();
var dh=findDocumentHeight(); var wh=findWindowHeight(); if (dh<wh) dh=wh; var sy=findScrollY();
// SET MAP MAXSIZE
var wrapper=createTiddlyElement(place,'div');
if (Popup.find(place)!=-1) mapSize=config.options.txtPanelManagerPopupMapSize; // IF POPUP
wrapper.style.width=mapSize||''; mapSize=wrapper.offsetWidth; // APPLY CSS THEN GET PIXELS
// SET SCROLLING/SCALING
var scroll=!config.options.chkPanelManagerMapFullPage;
// default to fit entire page in viewer
if (dw>dh) { var w=mapSize; var h=dh/dw*mapSize; var scale=w/dw; }
else { var h=mapSize; var w=dw/dh*mapSize; var scale=h/dh; }
if (scroll) { // set smaller dimension to fixed value, scroll the other
wrapper.style.width=mapSize+'px'; wrapper.style.height=wh/ww*mapSize+'px';
wrapper.style.overflow='auto'; // make it's contents scrollable
var scrollsize=findWindowWidth()-document.body.offsetWidth+2;
if (dw<=ww&&dh<=wh) { // smaller than window... enlarge to fit width
w=mapSize; h=dh/dw*w; scale=w/dw;
wrapper.style.overflow='visible'; // no scrollbars
} else if (dw>dh) { // wide... add hScroll
h=wh/ww*mapSize; w=dw/dh*h; scale=h/dh;
wrapper.style.height=h+scrollsize+'px';
} else { // tall... add vScroll
w=mapSize-scrollsize; h=dh/dw*w; scale=w/dw;
}
}
// CREATE DOCUMENT BACKGROUND
var doc=createTiddlyElement(wrapper,'div',null,'map');
doc.style.width=w+'px'; doc.style.height=h+'px';
doc.onclick=function(ev){ // BACKGROUND POPUP: SCROLL+OPTIONS
var ev=ev||window.event; var cmm=config.macros.moveablePanel;
var lvl=Popup.find(this); if (lvl<Popup.stack.length-1) // toggle child popup
{ Popup.remove(lvl+1); return cmm.processed(ev); }
var popup=addPOP(this,'sticky panelManagerPopup'); if(!popup)return false;
var dx=cmm.manager.mapXtoDocX(this,ev,scale,this.parentNode);
var dy=cmm.manager.mapYtoDocY(this,ev,scale,this.parentNode);
addTXT(popup,cmm.manager.XYJumpCmd); cmm.manager.menu_compass(popup,null,dx,dy);
addHR(popup); cmm.manager.menu_mapBackground(popup);
Popup.showHere(this,ev); return cmm.processed(ev);
};
doc.scale=scale; doc.title=this.viewerMapTip; doc.style.cursor='crosshair';
// SHOW VIEWPORT (CURRENT WINDOW POS)
var currview=createTiddlyElement(doc,'div');
var s=currview.style; s.border='1px dotted'; s.position='absolute';
s.left=sx*scale+'px'; s.top=sy*scale+'px'; s.width=(ww-2)*scale+'px'; s.height=(wh-2)*scale+'px';
// GET ALL PANELS AND FIND BASELINE Z FOR RENDERING MAP ON TOP OF POPUPS/PANELS
var panels=cmm.getAllPanels(); var allPids=[]; var minZ=0; var viewerZ=0;
for (var i=0; i<panels.length; i++) { var p=panels[i]; allPids.push(p.pid);
if (p.style.zIndex<minZ) minZ=p.style.zIndex;
}
if (Popup.find(place)!=-1) viewerZ=Popup.stack[Popup.find(place)].popup.style.zIndex;
else if (cmm.getPanel(place)) viewerZ=cmm.getPanel(place).style.zIndex;
var baseZ=viewerZ-minZ+1;
// DRAW PANEL BOXES
for (var i=0; i<panels.length; i++) {
var p=panels[i];
var d=cmm.manager.viewer_mapbox_draw(doc,p,scale,baseZ);
d.title=cmm.getPanelTooltip(p);
}
// DRAW TIDDLER BOXES
story.forEachTiddler(function(t,e){
if (allPids.contains(t)) return; // TIDDLER IS ALSO MOVEABLE PANEL... SKIP IT
var d=cmm.manager.viewer_mapbox_draw(doc,e,scale,baseZ);
d.tid=t; var tiddler=store.getTiddler(t);
d.title=tiddler?tiddler.getSubtitle():config.macros.moveablePanel.manager.tiddlerCmd.format([t]);
});
// SHOW DOC/WINDOW SIZE/VIEWPORT
var span=createTiddlyElement(place,'span',null,'panelManagerMapStats');
var msg=this.viewerMapStatsMsg.format([dw,dh,ww,wh,sx,sx+ww,sy,sy+wh]);
wikify(msg,span);
// SET MAP SCROLLPOS TO MATCH PAGE SCROLLPOS
// NOTE: must be done *after* all content has been rendered or scrollbar will jump to zero
if (scroll) { wrapper.scrollTop=sy*scale; wrapper.scrollLeft=sx*scale; }
},
// draw one map box with borders, mouseover shading and drag handling for moving
viewer_mapbox_draw: function(doc,p,scale,baseZ) {
var x=findPosX(p); var w=p.offsetWidth; var y=findPosY(p); var h=p.offsetHeight;
if (hasClass(p,'hover')) { x+=findScrollX(); y+=findScrollY(); } // hover=always in view
var db=createTiddlyElement(doc,'div',null,'panelManagerViewerMapBox');
db.panel=p; db.scale=scale; var s=db.style;
s.border="1px solid"; s.position='absolute'; s.cursor='crosshair'; s.zIndex=baseZ+p.style.zIndex;
s.top=y*scale+'px'; s.left=x*scale+'px'; s.width=w*scale+'px'; s.height=h*scale+'px';
s.background='#eee'; s.opacity='0.6'; s.filter='alpha(opacity:60)';
db.onmouseover=function(ev)
{ var s=this.style; s.background='#999';s.opacity='1';s.filter='alpha(opacity:100)'; }
db.onmouseout=function(ev)
{ var s=this.style; s.background='#eee';s.opacity='0.5';s.filter='alpha(opacity:50)'; }
db.onmousedown=this.viewer_mapbox_dragstart;
db.onclick=this.viewer_mapbox_popup;
return db;
},
viewer_mapbox_dragstart: function(ev) { var ev=ev||window.event; var cmm=config.macros.moveablePanel;
// capture mouse events and set drag handlers on target (body, window, or this panel)
var target=this; // fallback to this panel if 'capture' not supported
if (document.body.setCapture) // IE
{ document.body.setCapture(); var target=document.body; }
if (window.captureEvents) // moz
{ window.captureEvents(Event.MouseMove|Event.MouseUp,true); var target=window; }
// save drag data in target element
if (!target.dragData) target.dragData=new Object();
var d=target.dragData;
d.box=this; d.scale=this.scale; d.map=this.parentNode; d.scroller=this.parentNode.parentNode;
d.startX=findMouseX(ev); d.startScrollX=d.scroller.scrollLeft; d.grabX=findMouseX(ev)-findPosX(this);
d.startY=findMouseY(ev); d.startScrollY=d.scroller.scrollTop; d.grabY=findMouseY(ev)-findPosY(this);
d.offset=cmm.getPanelOffset(d.box.panel);
d.dragging=true; this.style.cursor='move';
d.savedonmousemove=target.onmousemove;
target.onmousemove=cmm.manager.viewer_mapbox_dragmove;
d.savedonmouseup=target.onmouseup;
target.onmouseup=cmm.manager.viewer_mapbox_dragstop;
cmm.addGhost(d.box.panel); // keep document from shrinking during move/size
cmm.noScrollX++; cmm.noScrollY++; // prevent document from scrolling during move/size
return cmm.processed(ev);
},
viewer_mapbox_dragmove: function(ev) { var ev=ev||window.event; var cmm=config.macros.moveablePanel;
var d=this.dragData; if (!d || !d.dragging) return; // NOT DRAGGING
if (!hasClass(d.box.panel,'moveablePanel')) { // NOT MOVEABLE
clearMessage();
displayMessage(cmm.manager.notMoveableMsg.format([d.box.panel.pid||d.box.tid]));
return this.onmouseup(ev);
}
cmm.quiet++; cmm.undockPanel(d.box.panel,true); cmm.quiet--; // GET READY TO MOVE
var mouseX=!config.browser.isIE?ev.pageX:ev.clientX;
var mouseY=!config.browser.isIE?ev.pageY:ev.clientY;
var mapX=findPosX(d.map)+d.startScrollX; var mapW=d.map.offsetWidth;
var mapY=findPosY(d.map)+d.startScrollY; var mapH=d.map.offsetHeight;
var scrollX=d.scroller.scrollLeft; var scrollW=d.scroller.offsetWidth;
var scrollY=d.scroller.scrollTop; var scrollH=d.scroller.offsetHeight;
var boxW=d.box.offsetWidth; var boxH=d.box.offsetHeight;
var boxX=findMouseX(ev)-mapX-d.grabX+scrollX;
var boxY=findMouseY(ev)-mapY-d.grabY+scrollY;
if (boxX<0) boxX=0; if (boxY<0) boxY=0; // limit upper left=stay on page
if (hasClass(d.box.panel,'hover')) { // hover=limit bottom right (stay in screen)
if (boxX+boxW>scrollW) boxX=scrollW-boxW; if (boxY+boxH>scrollH) boxY=scrollH-boxH;
if (boxX<scrollX) boxX=scrollX; if (boxY<scrollY) boxY=scrollY;
}
var docX=Math.floor(boxX/d.scale)-d.offset.x;
var docY=Math.floor(boxY/d.scale)-d.offset.y;
if (hasClass(d.box.panel,'hover')) { // window-relative placement
var ww=findWindowWidth(); var sx=findScrollX();
var wh=findWindowHeight(); var sy=findScrollY();
docX-=sx-d.offset.x; docY-=sy-d.offset.y;
if (docX+d.box.panel.offsetWidth >ww) docX=ww-d.box.panel.offsetWidth;
if (docY+d.box.panel.offsetHeight>wh) docY=wh-d.box.panel.offsetHeight;
if (docX<0) docX=0; if (docY<0) docY=0;
}
// update box AND panel positions
d.box.style.left=boxX+'px'; d.box.panel.style.left=docX+'px';
d.box.style.top =boxY+'px'; d.box.panel.style.top =docY+'px';
// resize map/scroll viewer as needed
if (boxX<scrollX) d.scroller.scrollLeft=boxX;
if (boxX+boxW>scrollX+scrollW || boxX+boxW>d.map.offsetWidth) {
d.map.style.width=Math.max(boxX+boxW,mapW)+'px';
d.scroller.scrollLeft=boxX+boxW-scrollW;
}
if (boxY<scrollY) d.scroller.scrollTop=boxY;
if (boxY+boxH>scrollY+scrollH || boxY+boxH>d.map.offsetHeight) {
d.map.style.height=Math.max(boxY+boxH,mapH)+'px';
d.scroller.scrollTop=boxY+boxH-scrollH;
}
cmm.showPanelStatus(d.box.panel,true);
return cmm.processed(ev);
},
viewer_mapbox_dragstop: function(ev) { var ev=ev||window.event; var cmm=config.macros.moveablePanel;
var d=this.dragData; if (!d || !d.dragging) return; // NOT DRAGGING
if (this.releaseCapture) this.releaseCapture(); // IE
if (this.releaseEvents) this.releaseEvents(Event.MouseMove|Event.MouseUp); // moz
this.onmousemove=d.savedonmousemove; this.onmouseup=d.savedonmouseup;
cmm.noScrollX--; cmm.noScrollY--; // allow document to scroll
cmm.clearGhost(); // allow document to adjust extents (if needed)
var moved=findMouseX(ev)!=d.startX || findMouseY(ev)!=d.startY;
if (moved) { cmm.manager.trackMap(d.box.panel); cmm.manager.refreshAllViewers(); }
d.dragging=false; d.box.style.cursor='pointer';
cmm.showPanelStatus(d.box.panel,false);
cmm.timedMessage(cmm.formatPanelStatus(d.box.panel),cmm.msgDuration);
// HACK: ignore next click to prevent webkit from closing popup after dragging
d.box.ignoreClick=moved&&config.browser.isSafari;
return cmm.processed(ev);
},
viewer_mapbox_popup: function(ev) {
var ev=ev||window.event; var cmm=config.macros.moveablePanel; var mgr=cmm.manager;
if (this.ignoreClick) { this.ignoreClick=false; return cmm.processed(ev); } // HACK
var lvl=Popup.find(this); if (lvl<Popup.stack.length-1) // toggle child popup
{ Popup.remove(lvl+1); return cmm.processed(ev); }
var popup=addPOP(this,'sticky panelManagerPopup'); if (!popup) return false;
var dx=cmm.manager.mapXtoDocX(this,ev,this.scale,this.parentNode.parentNode);
var dy=cmm.manager.mapYtoDocY(this,ev,this.scale,this.parentNode.parentNode);
if (this.tid) cmm.manager.menu_mapTiddler(popup,this.tid,this.panel,dx,dy);
else cmm.manager.menu_mapPanel(popup,this.panel,dx,dy);
Popup.showHere(this,ev); return cmm.processed(ev);
},
//}}}
//{{{
refreshAllViewers: function(){
var elems=document.getElementsByTagName("DIV");
for (var i=0; i<elems.length; i++) {
if (hasClass(elems[i],'panelManagerMapViewer')) this.viewer_map(elems[i],true);
if (hasClass(elems[i],'panelManagerMapTable')) this.viewer_table(elems[i],true);
if (hasClass(elems[i],'panelManagerMapCommands')) this.viewer_commands(elems[i],true);
}
},
//}}}
// // map viewer commands
//{{{
menu_mapBackground: function(place) {
var centered=createTiddlyElement(place,'div'); centered.style.textAlign='center';
if (Popup.find(place)>0) { // POPUP VIEWER PERMITS RESIZING
addBTN(centered,'\xa0'+this.mapSizeCmd,this.refreshMapTip,function(ev){
var ev=ev||window.event; var cmm=config.macros.moveablePanel;
cmm.manager.refreshAllViewers();
Popup.remove(Popup.find(this)); return cmm.processed(ev);
});
wikify('{{panelManagerMapPopupEdit{<<option txtPanelManagerPopupMapSize>>}}}\xa0',centered);
}
var opt='chkPanelManagerMapFullPage'; // toggle label...
var label=config.options[opt]?this.mapScrollPageCmd:this.mapFullPageCmd;
var tip=config.options[opt]?this.mapScrollPageTip:this.mapFullPageTip;
addCHK(addLI(centered),label,tip,opt,true);
addHR(centered); addCMD(centered,this.refreshMapCmd,this.refreshMapTip,function(ev){
var ev=ev||window.event; var cmm=config.macros.moveablePanel;
cmm.manager.refreshAllViewers();
Popup.remove(Popup.find(this)); return cmm.processed(ev);
});
},
menu_mapPanel: function(place,panel,docX,docY) {
var cmm=config.macros.moveablePanel;
var b=addCMD(place,this.panelCmd.format([panel.pid]),cmm.getPanelTooltip(panel),function(ev){
var ev=ev||window.event; var cmm=config.macros.moveablePanel;
var popup=addPOP(this,'panelManagerPopup'); if (!popup) return false;
cmm.manager.menu_panel(popup,panel,this.panel.pid||this.thisPanel,Popup.find(this)+1,docX,docY);
Popup.show('top','right'); return cmm.processed(ev);
}); b.panel=panel;
// autoclick on initial mouseover
b.onmouseover=function(ev) { this.onmouseover=null; return this.onclick.apply(this,arguments); };
addHR(place); addTXT(place,this.XYJumpCmd); this.menu_compass(place,panel,docX,docY);
addHR(place); this.menu_mapBackground(place);
},
menu_mapTiddler: function(place,tid,tiddlerElem,docX,docY) {
var cmm=config.macros.moveablePanel;
var b=addCMD(place,this.tiddlerCmd.format([tid]),'',function(ev){
var ev=ev||window.event; var cmm=config.macros.moveablePanel; var mgr=cmm.manager;
var popup=addPOP(this,'panelManagerPopup'); if (!popup) return false;
var b=addCMD(popup,mgr.jumpToPanelCmd,mgr.jumpToPanelTip.format([tid]),function(ev){
var ev=ev||window.event; var cmm=config.macros.moveablePanel;
cmm.scrollToPanel(this.tiddlerElem,true); cmm.manager.refreshAllViewers();
Popup.remove(Popup.find(this)); return cmm.processed(ev);
}); b.tid=this.tid; b.tiddlerElem=this.tiddlerElem;
var b=addCMD(popup,mgr.closeCmd,mgr.closeTip.format([tid]),function(ev){
var ev=ev||window.event; var cmm=config.macros.moveablePanel;
var OK=!story.isDirty(this.tid)||confirm(cmm.manager.tiddlerDirtyMsg.format([this.tid]));
if (OK) { story.closeTiddler(this.tid); cmm.manager.refreshAllViewers(); }
Popup.remove(Popup.find(this)); return cmm.processed(ev);
}); b.tid=this.tid;
Popup.show('top','right'); return cmm.processed(ev);
}); b.tid=tid; b.tiddlerElem=tiddlerElem;
// autoclick on initial mouseover
b.onmouseover=function(ev) { this.onmouseover=null; return this.onclick.apply(this,arguments); };
addHR(place); addTXT(place,this.XYJumpCmd); this.menu_compass(place,tiddlerElem,docX,docY);
addHR(place); this.menu_mapBackground(place);
},
command_newMap: function(place){
addBTN(place,this.newMapCmd,this.newMapTip,function(ev){
var ev=ev||window.event; var cmm=config.macros.moveablePanel;
if (!cmm.manager.newMap(ev)) cmm.manager.refreshAllViewers();
return cmm.processed(ev);
});
},
menu_loadMap: function(place,label,tip,valign,halign){
addBTN(place,label,tip,function(ev){
var ev=ev||window.event; var cmm=config.macros.moveablePanel;
var popup=addPOP(this,'panelManagerPopup'); if (!popup) return false;
var tids=store.getTaggedTiddlers(cmm.manager.mapTags[0]||cmm.manager.mapTag);
addTXT(popup,tids.length?cmm.manager.selectMapMsg:cmm.manager.noMaps);
for (var t=0;t<tids.length;t++) { var title=tids[t].title;
var b=addCMD(popup,title,cmm.manager.loadThisMapTip.format([title]),function(ev){
var ev=ev||window.event; var cmm=config.macros.moveablePanel;
if (!cmm.manager.loadMap(this.map,ev)) {
cmm.manager.refreshAllViewers();
displayMessage(cmm.manager.switchMapMsg.format([this.map]));
}
Popup.remove(Popup.find(this)); return cmm.processed(ev);
}); b.map=title;
}
if (valign||halign) Popup.show(valign,halign); else Popup.showHere(this,ev);
return cmm.processed(ev);
});
},
command_editMap: function(place){
var map=config.options.txtMoveablePanelMapName;
addBTN(place,this.editMapCmd.format([map]),this.editMapTip,function(ev){
var ev=ev||window.event; var cmm=config.macros.moveablePanel;
if (!store.tiddlerExists(this.map)&&cmm.manager.saveMap(this.map,ev)) return cmm.processed(ev);
cmm.manager.refreshAllViewers();
story.displayTiddler(null,this.map,DEFAULT_EDIT_TEMPLATE);
return cmm.processed(ev);
}).map=map;
},
command_saveMap: function(place){
addBTN(place,this.saveMapCmd,this.saveMapTip,function(ev){
var ev=ev||window.event; var cmm=config.macros.moveablePanel;
if (!cmm.manager.saveMap(this.map,ev)) cmm.manager.refreshAllViewers();
return cmm.processed(ev);
}).map=config.options.txtMoveablePanelMapName;
},
command_viewerTable: function(place){
addBTN(place,this.viewerTableCmd,this.viewerTableTip,function(ev){
var ev=ev||window.event; var cmm=config.macros.moveablePanel;
var popup=addPOP(this.parentNode,'panelManagerPopup'); if (!popup) return false;
cmm.manager.viewer_table(popup);
Popup.showHere(place,ev); return cmm.processed(ev);
});
},
//}}}
// // CSS definitions
//{{{
css: '/*{{{*/\n'
+'.panelManagerPopup\n'
+'\t{ white-space:nowrap; }\n'
+'.panelManagerPopup input\n'
+'\t{ text-align:center; font-size:90%; }\n'
+'.panelManagerPopupCompass {\n'
+'\tbackground:#999; margin:1em;\n'
+'\t-moz-border-radius:.5em; -webkit-border-radius:.5em;\n'
+'}\n'
+'.panelManagerPopupCompass td {\n'
+'\tfont-size:2em; width:1.5em; height:1.5em; text-align:center; vertical-align;center;\n'
+'\tbackground:#eee !important; color:#000 !important;\n'
+'\tborder:1px solid #666; padding:0; margin:0;\n'
+'\t-moz-border-radius:2px; -webkit-border-radius:2px;\n'
+'}\n'
+'.panelManagerPopupCompass td:hover\n'
+'\t{ background:#fff !important; color:#000 !important; }\n'
+'.panelManagerPopupCompassButton:hover\n'
+'\t{ background:transparent !important; color:#000; }\n'
+'.panelManagerMapPopup\n'
+'\t{ text-align:center; white-space:nowrap; }\n'
+'.panelManagerMapPopupEdit input\n'
+'\t{ width:5em; margin-top:.2em; }\n'
+'.panelManagerMapViewer .map {\n'
+'\tposition:relative; overflow:hidden;\n'
+'\tcolor:#000; background-color:#fff;\n'
+'\tmargin:0; border:1px solid;\n'
+'\t-moz-border-radius:3px; -webkit-border-radius:3px;\n'
+'}\n'
+'.panelManagerViewerMapBox\n'
+'\t{ border:1px solid; -moz-border-radius:2px; -webkit-border-radius:2px; }\n'
+'.panelManagerMapStats\n'
+'\t{ font-size:80%; }\n'
+'.panelManagerMapStats .twtable, .panelManagerMapStats .twtable tr, .panelManagerMapStats .twtable td\n'
+'\t{ padding:0; margin:0; border:0; }\n'
+'.panelManagerMapStats .twtable\n'
+'\t{ width:100%; }\n'
+'.panelManagerMapStats .twtable td\n'
+'\t{ width:50%; }\n'
+'/*}}}*/'
});
//}}}
// // CSS initialization (during startup)
//{{{
// set up shadow stylesheet, then load styles so customized CSS (if any) will be applied
config.shadowTiddlers.PanelManagerStyles=config.macros.moveablePanel.manager.css;
var css=store.getRecursiveTiddlerText('PanelManagerStyles',config.macros.moveablePanel.manager.css,10);
setStylesheet(css,'panelManagerStyles');
//}}}
// // hijack: sticky popups (allows interaction inside popup)
// // COPIED FROM [[StickyPopupPlugin]] TO ELIMINATE PLUGIN DEPENDENCY
//{{{
if (config.options.chkStickyPopups==undefined) config.options.chkStickyPopups=false;
try{removeEvent(document,"click",Popup.onDocumentClick);}catch(e){};
try{removeEvent(document,"click",Popup.stickyPopup_onDocumentClick);}catch(e){};
Popup.stickyPopup_onDocumentClick = function(ev)
{
// if click is in a sticky popup, ignore it so popup will remain visible
var e = ev ? ev : window.event; var target = resolveTarget(e);
var p=target; while (p) {
if (hasClass(p,"popup") && (hasClass(p,"sticky")||config.options.chkStickyPopups)) break;
else p=p.parentNode;
}
// if not a sticky popup... use normal handling
if (!p) {
// HACK: if flag is set, ignore this click (and clear the flag)
if (Popup.ignoreClick) Popup.ignoreClick=false;
else Popup.onDocumentClick(ev);
}
return true;
};
try{addEvent(document,"click",Popup.stickyPopup_onDocumentClick);}catch(e){};
//}}}
// // hijack: page background popup menu (ALT-CLICK)
//{{{
if (!document.getElementById('panelManagerPopupRoot')) { // only once
var root=createTiddlyElement(document.body,'span','panelManagerPopupRoot');
var s=root.style; s.width=0; s.height=0; s.top=0; s.left=0;
s.display='inline'; s.overflow='visible'; s.position='absolute';
document.onmousedown_panelmanager=document.onmousedown;
document.onmousedown=function(ev) {
var ev=ev||window.event; var target=resolveTarget(ev); var cmm=config.macros.moveablePanel;
if (!ev||!ev.altKey) { // if not ALT-CLICK... handle event normally
if (document.onmousedown_panelmanager==undefined) return;
return document.onmousedown_panelmanager.apply(target,arguments);
}
var root=document.getElementById('panelManagerPopupRoot');
var mX=findMouseX(ev); var mY=findMouseY(ev);
root.style.left=mX+'px'; root.style.top =mY+'px';
var p=cmm.getPanel(target); var t=story.findContainingTiddler(target);
var id=p?p.pid:(t?t.getAttribute('tiddler'):'')
// HACK: ignore next click on doc background (prevents IE from closing popup)
Popup.ignoreClick=config.browser.isIE;
cmm.manager.popup(root,ev,id);
return cmm.processed(ev);
}
}
//}}}
// // hijack: refresh map viewers when window is scrolled
//{{{
if (window.onscroll_panelManager_init===undefined) { // only once
window.onscroll_panelManager_init=true;
window.onscroll_panelManager=window.onscroll;
window.onscroll=function() {
config.macros.moveablePanel.manager.notify('refresh');
if (window.onscroll_panelManager)
return window.onscroll_panelManager.apply(this,arguments);
}
}
//}}}
// // hijacks: refresh map viewers when tiddlers or nested sliders are opened/closed
//{{{
if (Story.prototype.displayTiddler_panelManager===undefined) { // only once
Story.prototype.displayTiddler_panelManager=Story.prototype.displayTiddler;
Story.prototype.displayTiddler=function() {
var r=this.displayTiddler_panelManager.apply(this,arguments);
config.macros.moveablePanel.manager.notify('refresh');
return r;
}
Story.prototype.closeTiddler_panelManager=Story.prototype.closeTiddler;
Story.prototype.closeTiddler=function() {
var r=this.closeTiddler_panelManager.apply(this,arguments);
// NOTE: ASYNC wait for core animation to finish, then update viewers
var delay=config.options.chkAnimate?config.animDuration+100:0;
setTimeout("config.macros.moveablePanel.manager.notify('refresh')",delay);
return r;
}
}
if (window.onClickNestedSlider && (window.onClickNestedSlider_panelManager===undefined)) { // only once
window.onClickNestedSlider_panelManager=window.onClickNestedSlider;
window.onClickNestedSlider=function() {
var r=window.onClickNestedSlider_panelManager.apply(window,arguments);
// NOTE: ASYNC wait for core animation to finish, then update viewers
var delay=config.options.chkAnimate?config.animDuration+100:0;
setTimeout("config.macros.moveablePanel.manager.notify('refresh')",delay);
return r;
}
}
//}}}
/***
|''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"
});
*/
//}}}
| !panelname| !x | !y | !w | !h | !z | !fold | !hover |h
| SampleMap| 350| 200| 550| auto| | | |
| mainmenu| 0| 30| 80| 115| 2| | |
| accessories| 15| 160| 80| 125| 3| | |
| powertools| 50| 352| 80| 125| 4| | ā |
/***
|ModName|SearchOptionsPlugin_da|
|BasedOn|SearchOptionsPlugin|
|Source|http://klasser.tiddlyspace.com/#SearchOptionsPlugin_da|
|OrigSource|http://www.TiddlyTools.com/#SearchOptionsPlugin|
|Documentation|http://www.TiddlyTools.com/#SearchOptionsPluginInfo|
|Version|3.0.7|
|Author|Eric Shulman|
|Translator|MƄns MƄrtensson|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Description|extend core search function with additional user-configurable options|
Adds extra options to core search function including selecting which data items to search, enabling/disabling incremental key-by-key searches, and generating a ''list of matching tiddlers'' instead of immediately displaying all matches. This plugin also adds syntax for rendering 'search links' within tiddler content to embed one-click searches using pre-defined 'hard-coded' search terms.
!!!!!Documentation
>see [[SearchOptionsPluginInfo]]
!!!!!Configuration
<<<
Search in:
<<option chkSearchTitles>> titles <<option chkSearchText>> text <<option chkSearchTags>> tags <<option chkSearchFields>> fields <<option chkSearchShadows>> shadows
<<option chkSearchHighlight>> Highlight matching text in displayed tiddlers
<<option chkSearchList>> Show list of matches
<<option chkSearchListTiddler>> Write list to [[SearchResults]] tiddler
<<option chkSearchTitlesFirst>> Show title matches first
<<option chkSearchByDate>> Sort matching tiddlers by modification date (most recent first)
<<option chkSearchResultsOptions>> Include {{{options...}}} slider in "search again" form
<<option chkIncrementalSearch>> Incremental key-by-key search: {{twochar{<<option txtIncrementalSearchMin>>}}} or more characters, {{threechar{<<option txtIncrementalSearchDelay>>}}} msec delay
<<option chkSearchOpenTiddlers>> Search only in tiddlers that are currently displayed
<<option chkSearchExcludeTags>> Exclude tiddlers tagged with: <<option txtSearchExcludeTags>>
<<<
!!!!!Revisions
<<<
2010.05.03 3.0.8 added chkSearchResultsOptions to allow/omit the "options..." slider from the "search again" form
|please see [[SearchOptionsPluginInfo]] for additional revision details|
2005.10.18 1.0.0 Initial Release
<<<
!!!!!Code
***/
//{{{
version.extensions.SearchOptionsPlugin= {major: 3, minor: 0, revision: 8, date: new Date(2010,5,3)};
var defaults={
chkSearchTitles: true,
chkSearchText: true,
chkSearchTags: true,
chkSearchFields: true,
chkSearchTitlesFirst: true,
chkSearchList: true,
chkSearchHighlight: true,
chkSearchListTiddler: false,
chkSearchByDate: false,
chkIncrementalSearch: true,
chkSearchShadows: true,
chkSearchOpenTiddlers: false,
chkSearchResultsOptions:true,
chkSearchExcludeTags: true,
txtSearchExcludeTags: 'excludeSearch',
txtIncrementalSearchDelay: 500,
txtIncrementalSearchMin: 3
}; for (var id in defaults) if (config.options[id]===undefined)
config.options[id]=defaults[id];
if (config.macros.search.reportTitle==undefined)
config.macros.search.reportTitle="SearchResults"; // note: not a cookie!
config.macros.search.label+="\xa0"; // a little bit of space just because it looks better
//}}}
// // searchLink: {{{[search[text to find]] OR [search[text to display|text to find]]}}}
//{{{
config.formatters.push( {
name: "searchLink",
match: "\\[search\\[",
lookaheadRegExp: /\[search\[(.*?)(?:\|(.*?))?\]\]/mg,
prompt: "sĆøg efter: '%0'",
handler: function(w)
{
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
var label=lookaheadMatch[1];
var text=lookaheadMatch[2]||label;
var prompt=this.prompt.format([text]);
var btn=createTiddlyButton(w.output,label,prompt,
function(){story.search(this.getAttribute("searchText"))},"searchLink");
btn.setAttribute("searchText",text);
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
}
});
//}}}
// // incremental search uses option settings instead of hard-coded delay and minimum input values
//{{{
var fn=config.macros.search.onKeyPress;
fn=fn.toString().replace(/500/g, "config.options.txtIncrementalSearchDelay||500");
fn=fn.toString().replace(/> 2/g, ">=(config.options.txtIncrementalSearchMin||3)");
eval("config.macros.search.onKeyPress="+fn);
//}}}
// // REPLACE story.search() for option to "show search results in a list"
//{{{
Story.prototype.search = function(text,useCaseSensitive,useRegExp)
{
var co=config.options; // abbrev
var re=new RegExp(useRegExp ? text : text.escapeRegExp(),useCaseSensitive ? "mg" : "img");
if (config.options.chkSearchHighlight) highlightHack=re;
var matches = store.search(re,co.chkSearchByDate?"modified":"title","");
if (co.chkSearchByDate) matches=matches.reverse(); // most recent first
var q = useRegExp ? "/" : "'";
clearMessage();
if (!matches.length) {
if (co.chkSearchListTiddler) discardSearchResults();
displayMessage(config.macros.search.failureMsg.format([q+text+q]));
} else {
if (co.chkSearchList||co.chkSearchListTiddler)
reportSearchResults(text,matches);
else {
var titles = []; for(var t=0; t<matches.length; t++) titles.push(matches[t].title);
this.closeAllTiddlers(); story.displayTiddlers(null,titles);
displayMessage(config.macros.search.successMsg.format([matches.length, q+text+q]));
}
}
highlightHack = null;
}
//}}}
// // REPLACE store.search() for enhanced searching/sorting options
//{{{
TiddlyWiki.prototype.search = function(searchRegExp,sortField,excludeTag,match)
{
var co=config.options; // abbrev
var tids = this.reverseLookup("tags",excludeTag,!!match,sortField);
var opened=[]; story.forEachTiddler(function(tid,elem){opened.push(tid);});
// eliminate tiddlers tagged with excluded tags
if (co.chkSearchExcludeTags&&co.txtSearchExcludeTags.length) {
var ex=co.txtSearchExcludeTags.readBracketedList();
var temp=[]; for(var t=tids.length-1; t>=0; t--)
if (!tids[t].tags.containsAny(ex)) temp.push(tids[t]);
tids=temp;
}
// scan for matching titles first...
var results = [];
if (co.chkSearchTitles) {
for(var t=0; t<tids.length; t++) {
if (co.chkSearchOpenTiddlers && !opened.contains(tids[t].title)) continue;
if(tids[t].title.search(searchRegExp)!=-1) results.push(tids[t]);
}
if (co.chkSearchShadows)
for (var t in config.shadowTiddlers) {
if (co.chkSearchOpenTiddlers && !opened.contains(t)) continue;
if ((t.search(searchRegExp)!=-1) && !store.tiddlerExists(t))
results.push((new Tiddler()).assign(t,config.shadowTiddlers[t]));
}
}
// then scan for matching text, tags, or field data
for(var t=0; t<tids.length; t++) {
if (co.chkSearchOpenTiddlers && !opened.contains(tids[t].title)) continue;
if (co.chkSearchText && tids[t].text.search(searchRegExp)!=-1)
results.pushUnique(tids[t]);
if (co.chkSearchTags && tids[t].tags.join(" ").search(searchRegExp)!=-1)
results.pushUnique(tids[t]);
if (co.chkSearchFields && store.forEachField!=undefined)
store.forEachField(tids[t],
function(tid,field,val) {
if (val.search(searchRegExp)!=-1) results.pushUnique(tids[t]);
},
true); // extended fields only
}
// then check for matching text in shadows
if (co.chkSearchShadows)
for (var t in config.shadowTiddlers) {
if (co.chkSearchOpenTiddlers && !opened.contains(t)) continue;
if ((config.shadowTiddlers[t].search(searchRegExp)!=-1) && !store.tiddlerExists(t))
results.pushUnique((new Tiddler()).assign(t,config.shadowTiddlers[t]));
}
// if not 'titles first', or sorting by modification date,
// re-sort results to so titles, text, tag and field matches are mixed together
if(!sortField) sortField = "title";
var bySortField=function(a,b){
if(a[sortField]==b[sortField])return(0);else return(a[sortField]<b[sortField])?-1:+1;
}
if (!co.chkSearchTitlesFirst || co.chkSearchByDate) results.sort(bySortField);
return results;
}
//}}}
// // HIJACK core {{{<<search>>}}} macro to add "report" and "simple inline" output
//{{{
config.macros.search.SOP_handler=config.macros.search.handler;
config.macros.search.handler = function(place,macroName,params)
{
// if "report", use SearchOptionsPlugin report generator for inline output
if (params[1]&¶ms[1].substr(0,6)=="report") {
var keyword=params[0];
var options=params[1].split("=")[1]; // split "report=option+option+..."
var heading=params[2]?params[2].unescapeLineBreaks():"";
var matches=store.search(new RegExp(keyword.escapeRegExp(),"img"),"title","excludeSearch");
if (matches.length) wikify(heading+window.formatSearchResults(keyword,matches,options),place);
} else if (params[1]) {
var keyword=params[0];
var heading=params[1]?params[1].unescapeLineBreaks():"";
var seperator=params[2]?params[2].unescapeLineBreaks():", ";
var matches=store.search(new RegExp(keyword.escapeRegExp(),"img"),"title","excludeSearch");
if (matches.length) {
var out=[];
for (var m=0; m<matches.length; m++) out.push("[["+matches[m].title+"]]");
wikify(heading+out.join(seperator),place);
}
} else
config.macros.search.SOP_handler.apply(this,arguments);
};
//}}}
// // SearchResults panel handling
//{{{
setStylesheet(".searchResults { padding:1em 1em 0 1em; }","searchResults"); // matches std tiddler padding
config.macros.search.createPanel=function(text,matches,body) {
function getByClass(e,c) { var d=e.getElementsByTagName("div");
for (var i=0;i<d.length;i++) if (hasClass(d[i],c)) return d[i]; }
var panel=createTiddlyElement(null,"div","searchPanel","searchPanel");
this.renderPanel(panel,text,matches,body);
var oldpanel=document.getElementById("searchPanel");
if (!oldpanel) { // insert new panel just above tiddlers
var da=document.getElementById("displayArea");
da.insertBefore(panel,da.firstChild);
} else { // if panel exists
var oldwrap=getByClass(oldpanel,"searchResults");
var newwrap=getByClass(panel,"searchResults");
// if no prior content, just insert new content
if (!oldwrap) oldpanel.insertBefore(newwrap,null);
else { // swap search results content but leave containing panel intact
oldwrap.style.display='block'; // unfold wrapper if needed
var i=oldwrap.getElementsByTagName("input")[0]; // get input field
if (i) { var pos=this.getCursorPos(i); i.onblur=null; } // get cursor pos, ignore blur
oldpanel.replaceChild(newwrap,oldwrap);
panel=oldpanel; // use existing panel
}
}
this.showPanel(true,pos);
return panel;
}
config.macros.search.renderPanel=function(panel,text,matches,body) {
var wrap=createTiddlyElement(panel,"div",null,"searchResults");
wrap.onmouseover = function(e){ addClass(this,"selected"); }
wrap.onmouseout = function(e){ removeClass(this,"selected"); }
// create toolbar: "Ƅben alle", "fold/foldud", "luk"
var tb=createTiddlyElement(wrap,"div",null,"toolbar");
var b=createTiddlyButton(tb, "Ƅben alle", "Ƅben alle matchende tiddlere", function() {
story.displayTiddlers(null,this.getAttribute("list").readBracketedList()); return false; },"button");
var list=""; for(var t=0;t<matches.length;t++) list+='[['+matches[t].title+']] ';
b.setAttribute("list",list);
var b=createTiddlyButton(tb, "fold", "visning af sĆøgeresultater til/fra", function() {
config.macros.search.foldPanel(this); return false; },"button");
var b=createTiddlyButton(tb, "luk", "fortryd sĆøgeresultater", function() {
config.macros.search.showPanel(false); return false; },"button");
createTiddlyText(createTiddlyElement(wrap,"div",null,"title"),"SĆøg efter: "+text); // title
wikify(body,createTiddlyElement(wrap,"div",null,"viewer")); // report
return panel;
}
config.macros.search.showPanel=function(show,pos) {
var panel=document.getElementById("searchPanel");
var i=panel.getElementsByTagName("input")[0];
i.onfocus=show?function(){config.macros.search.stayFocused(true);}:null;
i.onblur=show?function(){config.macros.search.stayFocused(false);}:null;
if (show && panel.style.display=="block") { // if shown, grab focus, restore cursor
if (i&&this.stayFocused()) { i.focus(); this.setCursorPos(i,pos); }
return;
}
if(!config.options.chkAnimate) {
panel.style.display=show?"block":"none";
if (!show) { removeChildren(panel); config.macros.search.stayFocused(false); }
} else {
var s=new Slider(panel,show,false,show?"none":"children");
s.callback=function(e,p){e.style.overflow="visible";}
anim.startAnimating(s);
}
return panel;
}
config.macros.search.foldPanel=function(button) {
var d=document.getElementById("searchPanel").getElementsByTagName("div");
for (var i=0;i<d.length;i++) if (hasClass(d[i],"viewer")) var v=d[i]; if (!v) return;
var show=v.style.display=="none";
if(!config.options.chkAnimate)
v.style.display=show?"block":"none";
else {
var s=new Slider(v,show,false,"none");
s.callback=function(e,p){e.style.overflow="visible";}
anim.startAnimating(s);
}
button.innerHTML=show?"fold":"foldud";
return false;
}
config.macros.search.stayFocused=function(keep) { // TRUE/FALSE=set value, no args=get value
if (keep===undefined) return this.keepReportInFocus;
this.keepReportInFocus=keep;
return keep
}
config.macros.search.getCursorPos=function(i) {
var s=0; var e=0; if (!i) return { start:s, end:e };
try {
if (i.setSelectionRange) // FF
{ s=i.selectionStart; e=i.selectionEnd; }
if (document.selection && document.selection.createRange) { // IE
var r=document.selection.createRange().duplicate();
var len=r.text.length; s=0-r.moveStart('character',-100000); e=s+len;
}
}catch(e){};
return { start:s, end:e };
}
config.macros.search.setCursorPos=function(i,pos) {
if (!i||!pos) return; var s=pos.start; var e=pos.end;
if (i.setSelectionRange) //FF
i.setSelectionRange(s,e);
if (i.createTextRange) // IE
{ var r=i.createTextRange(); r.collapse(true); r.moveStart("character",s); r.select(); }
}
//}}}
// // SearchResults report generation
// note: these functions are defined globally, so they can be more easily redefined to customize report formats//
//{{{
if (!window.reportSearchResults) window.reportSearchResults=function(text,matches)
{
var cms=config.macros.search; // abbrev
var body=window.formatSearchResults(text,matches);
if (!config.options.chkSearchListTiddler) // show #searchResults panel
window.scrollTo(0,ensureVisible(cms.createPanel(text,matches,body)));
else { // write [[SearchResults]] tiddler
var title=cms.reportTitle;
var who=config.options.txtUserName;
var when=new Date();
var tags="excludeLists excludeSearch temporary";
var tid=store.getTiddler(title); if (!tid) tid=new Tiddler();
tid.set(title,body,who,when,tags);
store.addTiddler(tid);
story.closeTiddler(title);
story.displayTiddler(null,title);
}
}
if (!window.formatSearchResults) window.formatSearchResults=function(text,matches,opt)
{
var body='';
var title=config.macros.search.reportTitle
var q = config.options.chkRegExpSearch ? "/" : "'";
if (!opt) var opt="all";
var parts=opt.split("+");
for (var i=0; i<parts.length; i++) { var p=parts[i].toLowerCase();
if (p=="again"||p=="all") body+=window.formatSearchResults_again(text,matches);
if (p=="summary"||p=="all") body+=window.formatSearchResults_summary(text,matches);
if (p=="list"||p=="all") body+=window.formatSearchResults_list(text,matches);
if (p=="buttons"||p=="all") body+=window.formatSearchResults_buttons(text,matches);
}
return body;
}
if (!window.formatSearchResults_again) window.formatSearchResults_again=function(text,matches)
{
var title=config.macros.search.reportTitle
var body='';
// search again
body+='{{span{<<search "'+text.replace(/"/g,'"')+'">> /%\n';
body+='%/<html><input type="button" value="sĆøg igen"';
body+=' onclick="var t=this.parentNode.parentNode.getElementsByTagName(\'input\')[0];';
body+=' config.macros.search.doSearch(t); return false;">';
if (!config.options.chkSearchResultsOptions) { // omit "muligheder..."
body+='</html>}}}\n\n';
return body;
}
body+=' <a href="javascript:;" onclick="';
body+=' var e=this.parentNode.nextSibling;';
body+=' var show=e.style.display!=\'block\';';
body+=' if(!config.options.chkAnimate) e.style.display=show?\'block\':\'none\';';
body+=' else anim.startAnimating(new Slider(e,show,false,\'none\'));';
body+=' return false;">muligheder...</a>';
body+='</html>@@display:none;border-left:1px dotted;margin-left:1em;padding:0;padding-left:.5em;font-size:90%;/%\n';
body+=' %/<<option chkSearchTitles>>titler /%\n';
body+=' %/<<option chkSearchText>>tekst /%\n';
body+=' %/<<option chkSearchTags>>tags /%\n';
body+=' %/<<option chkSearchFields>>felter /%\n';
body+=' %/<<option chkSearchShadows>>skygger\n';
body+=' <<option chkCaseSensitiveSearch>>store-smƄ bogstaver /%\n';
body+=' %/<<option chkRegExpSearch>>tekst mĆønstre /%\n';
body+=' %/<<option chkSearchByDate>>sorteret efter dato\n';
body+=' <<option chkSearchHighlight>> markƩr matchende tekst i de viste tiddlere\n';
body+=' <<option chkIncrementalSearch>>tegn efter tegn sĆøgning: /%\n';
body+=' %/{{twochar{<<option txtIncrementalSearchMin>>}}} eller flere tegn, /%\n';
body+=' %/{{threechar{<<option txtIncrementalSearchDelay>>}}} msek forsinkelse\n';
body+=' <<option chkSearchOpenTiddlers>> søg kun i allerede Äbne tiddlere\n';
body+=' <<option chkSearchExcludeTags>>udelad tiddlere der er tagget med:\n';
body+=' {{editor{<<option txtSearchExcludeTags>>}}}/%\n';
body+='%/@@}}}\n\n';
return body;
}
if (!window.formatSearchResults_summary) window.formatSearchResults_summary=function(text,matches)
{
// summary: nn tiddlers found matching '...', options used
var body='';
var co=config.options; // abbrev
var title=config.macros.search.reportTitle
var q = co.chkRegExpSearch ? "/" : "'";
body+="''"+config.macros.search.successMsg.format([matches.length,q+"{{{"+text+"}}}"+q])+"''\n";
var opts=[];
if (co.chkSearchTitles) opts.push("titler");
if (co.chkSearchText) opts.push("tekst");
if (co.chkSearchTags) opts.push("tags");
if (co.chkSearchFields) opts.push("felter");
if (co.chkSearchShadows) opts.push("skygger");
if (co.chkSearchOpenTiddlers) body+="^^//search limited to displayed tiddlers only//^^\n";
body+="~~ sĆøgte i "+opts.join(" + ")+"~~\n";
body+=(co.chkCaseSensitiveSearch||co.chkRegExpSearch?"^^ og brugte ":"")
+(co.chkCaseSensitiveSearch?"case-sensitive ":"")
+(co.chkRegExpSearch?"pattern ":"")
+(co.chkCaseSensitiveSearch||co.chkRegExpSearch?"matching^^\n":"");
return body;
}
if (!window.formatSearchResults_list) window.formatSearchResults_list=function(text,matches)
{
// bullet list of links to matching tiddlers
var body='';
var co=config.options; // abbrev
var pattern=co.chkRegExpSearch?text:text.escapeRegExp();
var sensitive=co.chkCaseSensitiveSearch?"mg":"img";
var link='{{tiddlyLinkExisting{<html><nowiki><a href="javascript:;" onclick="'
+'if(config.options.chkSearchHighlight)'
+' highlightHack=new RegExp(\x27'+pattern+'\x27.escapeRegExp(),\x27'+sensitive+'\x27);'
+'story.displayTiddler(null,\x27%0\x27);'
+'highlightHack = null; return false;'
+'" title="%2">%1</a></html>}}}';
for(var t=0;t<matches.length;t++) {
body+="* ";
if (co.chkSearchByDate)
body+=matches[t].modified.formatString('YYYY.0MM.0DD 0hh:0mm')+" ";
var title=matches[t].title;
var fixup=title.replace(/'/g,"\\x27").replace(/"/g,"\\x22");
var tid=store.getTiddler(title);
var tip=tid?tid.getSubtitle():''; tip=tip.replace(/"/g,""");
body+=link.format([fixup,title,tip])+'\n';
}
return body;
}
if (!window.formatSearchResults_buttons) window.formatSearchResults_buttons=function(text,matches)
{
// embed buttons only if writing SearchResults to tiddler
if (!config.options.chkSearchListTiddler) return "";
// "open all" button
var title=config.macros.search.reportTitle;
var body="";
body+="@@diplay:block;<html><input type=\"button\" href=\"javascript:;\" "
+"onclick=\"story.displayTiddlers(null,[";
for(var t=0;t<matches.length;t++)
body+="'"+matches[t].title.replace(/\'/mg,"\\'")+"'"+((t<matches.length-1)?", ":"");
body+="],1);\" accesskey=\"O\" value=\"Ƅben alle matchende tiddlere\"></html> ";
// "discard SearchResults" button
body+="<html><input type=\"button\" href=\"javascript:;\" "
+"onclick=\"discardSearchResults()\" value=\"kassƩr "+title+"\"></html>";
body+="@@\n";
return body;
}
if (!window.discardSearchResults) window.discardSearchResults=function()
{
// remove the tiddler
story.closeTiddler(config.macros.search.reportTitle);
store.deleteTiddler(config.macros.search.reportTitle);
store.notify(config.macros.search.reportTitle,true);
}
//}}}
/*{{{*/
[[StyleSheetShortcuts]]
.undocked .searchResults
{ margin-left:1em; width:auto; text-align:left; background:#fff;
border:1px solid; padding:1em; -moz-border-radius:1em; -webkit-border-radius:1em; }
.button, .tiddler .button, #sidebarTabs .button
{ margin:0px; padding: 0px .3em; border:1px solid transparent;
-moz-border-radius:3px; -webkit-border-radius:3px; }
.button:hover
{ border:1px solid #999; }
/*}}}*/
/***
|Name|StyleSheetShortcuts|
|Source|http://www.TiddlyTools.com/#StyleSheetShortcuts|
|Version||
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|CSS|
|Description|'convenience' classes for common formatting, alignment, boxes, tables, etc.|
These 'style tweaks' can be easily included in other stylesheet tiddler so they can share a baseline look-and-feel that can then be customized to create a wide variety of 'flavors'.
***/
/*{{{*/
/* text alignments */
.left
{ display:block;text-align:left; }
.center
{ display:block;text-align:center; }
.center table
{ margin:auto !important; }
.right
{ display:block;text-align:right; }
.justify
{ display:block;text-align:justify; }
.indent
{ display:block;margin:0;padding:0;border:0;margin-left:2em; }
.floatleft
{ float:left; }
.floatright
{ float:right; }
.valignTop, .valignTop table, .valignTop tbody, .valignTop th, .valignTop tr, .valignTop td
{ vertical-align:top; }
.valignBottom, .valignBottom table, .valignBottom tbody, .valignBottom th, .valignBottom tr, .valignBottom td
{ vertical-align:bottom; }
.clear
{ clear:both; }
.wrap
{ white-space:normal; }
.nowrap
{ white-space:nowrap; }
.hidden
{ display:none; }
.show
{ display:inline !important; }
.span
{ display:span; }
.block
{ display:block; }
.relative
{ position:relative; }
.absolute
{ position:absolute; }
/* font sizes */
.big
{ font-size:14pt;line-height:120% }
.medium
{ font-size:12pt;line-height:120% }
.normal
{ font-size:9pt;line-height:120% }
.small
{ font-size:8pt;line-height:120% }
.fine
{ font-size:7pt;line-height:120% }
.tiny
{ font-size:6pt;line-height:120% }
.larger
{ font-size:120%; }
.smaller
{ font-size:80%; }
/* font styles */
.bold
{ font-weight:bold; }
.italic
{ font-style:italic; }
.underline
{ text-decoration:underline; }
/* plain list items (no bullets or indent) */
.nobullets li { list-style-type: none; margin-left:-2em; }
/* vertical tabsets - courtesy of Tobias Beer */
.vTabs .tabset {float:left;display:block;padding:0px;margin-top:.5em;min-width:20%;}
.vTabs .tabset .tab {display:block;text-align:right;padding:2px 3px 2px 7px; margin:0 1px 1px 0;}
.vTabs .tabContents {margin-left:20%;max-width:80%;padding:5px;}
.vTabs .tabContents .tabContents {border:none; background:transparent;}
/* multi-column tiddler content (not supported in Internet Explorer) */
.twocolumns { display:block;
-moz-column-count:2; -moz-column-gap:1em; -moz-column-width:50%; /* FireFox */
-webkit-column-count:2; -webkit-column-gap:1em; -webkit-column-width:50%; /* Safari */
column-count:2; column-gap:1em; column-width:50%; /* Opera */
}
.threecolumns { display:block;
-moz-column-count:3; -moz-column-gap:1em; -moz-column-width:33%; /* FireFox */
-webkit-column-count:3; -webkit-column-gap:1em; -webkit-column-width:33%; /* Safari */
column-count:3; column-gap:1em; column-width:33%; /* Opera */
}
.fourcolumns { display:block;
-moz-column-count:4; -moz-column-gap:1em; -moz-column-width:25%; /* FireFox */
-webkit-column-count:4; -webkit-column-gap:1em; -webkit-column-width:25%; /* Safari */
column-count:4; column-gap:1em; column-width:25%; /* Opera */
}
/* page breaks */
.breakbefore { page-break-before:always; }
.breakafter { page-break-before:always; }
/* show/hide browser-specific content for InternetExplorer vs. non-IE ("moz") browsers */
*[class="ieOnly"]
{ display:none; } /* hide in moz (uses CSS selector) */
* html .mozOnly, *:first-child+html .mozOnly
{ display: none; } /* hide in IE (uses IE6/IE7 CSS hacks) */
/* borderless tables */
.borderless, .borderless table, .borderless td, .borderless tr, .borderless th, .borderless tbody
{ border:0 !important; margin:0 !important; padding:0 !important; }
.widetable, .widetable table
{ width:100%; }
/* thumbnail images (fixed-sized scaled images) */
.thumbnail img { height:5em !important; }
/* stretchable images (auto-size to fit tiddler) */
.stretch img { width:95%; }
/* grouped content */
.outline
{ display:block; padding:1em; -moz-border-radius:1em;-webkit-border-radius:1em; border:1px solid; }
.menubox
{ display:block; padding:1em; -moz-border-radius:1em;-webkit-border-radius:1em; border:1px solid; background:#fff; color:#000; }
.menubox .button, .menubox .tiddlyLinkExisting, .menubox .tiddlyLinkNonExisting
{ color:#009 !important; }
.groupbox
{ display:block; padding:1em; -moz-border-radius:1em;-webkit-border-radius:1em; border:1px solid; background:#ffe; color:#000; }
.groupbox a, .groupbox .button, .groupbox .tiddlyLinkExisting, .groupbox .tiddlyLinkNonExisting
{ color:#009 !important; }
.groupbox code
{ color:#333 !important; }
.borderleft
{ margin:0;padding:0;border:0;margin-left:1em; border-left:1px dotted; padding-left:.5em; }
.borderright
{ margin:0;padding:0;border:0;margin-right:1em; border-right:1px dotted; padding-right:.5em; }
.borderbottom
{ margin:0;padding:1px 0;border:0;border-bottom:1px dotted; margin-bottom:1px; padding-bottom:1px; }
.bordertop
{ margin:0;padding:0;border:0;border-top:1px dotted; margin-top:1px; padding-top:1px; }
/* scrolled content */
.scrollbars { overflow:auto; }
.height10em { height:10em; }
.height15em { height:15em; }
.height20em { height:20em; }
.height25em { height:25em; }
.height30em { height:30em; }
.height35em { height:35em; }
.height40em { height:40em; }
/* compact form */
.smallform
{ white-space:nowrap; }
.smallform input, .smallform textarea, .smallform button, .smallform checkbox, .smallform radio, .smallform select
{ font-size:8pt; }
/* stretchable edit fields and textareas (auto-size to fit tiddler) */
.stretch input { width:99%; }
.stretch textarea { width:99%; }
/* compact input fields (limited to a few characters for entering percentages and other small values) */
.onechar input { width:1em; }
.twochar input { width:2em; }
.threechar input { width:3em; }
.fourchar input { width:4em; }
.fivechar input { width:5em; }
/* text colors */
.white { color:#fff !important }
.gray { color:#999 !important }
.black { color:#000 !important }
.red { color:#f66 !important }
.green { color:#0c0 !important }
.blue { color:#99f !important }
/* rollover highlighting */
.mouseover
{color:[[ColorPalette::TertiaryLight]] !important;}
.mouseover a
{color:[[ColorPalette::TertiaryLight]] !important;}
.selected .mouseover
{color:[[ColorPalette::Foreground]] !important;}
.selected .mouseover .button, .selected .mouseover a
{color:[[ColorPalette::PrimaryDark]] !important;}
/* rollover zoom text */
.zoomover
{ font-size:80% !important; }
.selected .zoomover
{ font-size:100% !important; }
/* [[ColorPalette]] text colors */
.Background { color:[[ColorPalette::Background]]; }
.Foreground { color:[[ColorPalette::Foreground]]; }
.PrimaryPale { color:[[ColorPalette::PrimaryPale]]; }
.PrimaryLight { color:[[ColorPalette::PrimaryLight]]; }
.PrimaryMid { color:[[ColorPalette::PrimaryMid]]; }
.PrimaryDark { color:[[ColorPalette::PrimaryDark]]; }
.SecondaryPale { color:[[ColorPalette::SecondaryPale]]; }
.SecondaryLight { color:[[ColorPalette::SecondaryLight]];}
.SecondaryMid { color:[[ColorPalette::SecondaryMid]]; }
.SecondaryDark { color:[[ColorPalette::SecondaryDark]]; }
.TertiaryPale { color:[[ColorPalette::TertiaryPale]]; }
.TertiaryLight { color:[[ColorPalette::TertiaryLight]]; }
.TertiaryMid { color:[[ColorPalette::TertiaryMid]]; }
.TertiaryDark { color:[[ColorPalette::TertiaryDark]]; }
.Error { color:[[ColorPalette::Error]]; }
/* [[ColorPalette]] background colors */
.BGBackground { background-color:[[ColorPalette::Background]]; }
.BGForeground { background-color:[[ColorPalette::Foreground]]; }
.BGPrimaryPale { background-color:[[ColorPalette::PrimaryPale]]; }
.BGPrimaryLight { background-color:[[ColorPalette::PrimaryLight]]; }
.BGPrimaryMid { background-color:[[ColorPalette::PrimaryMid]]; }
.BGPrimaryDark { background-color:[[ColorPalette::PrimaryDark]]; }
.BGSecondaryPale { background-color:[[ColorPalette::SecondaryPale]]; }
.BGSecondaryLight { background-color:[[ColorPalette::SecondaryLight]]; }
.BGSecondaryMid { background-color:[[ColorPalette::SecondaryMid]]; }
.BGSecondaryDark { background-color:[[ColorPalette::SecondaryDark]]; }
.BGTertiaryPale { background-color:[[ColorPalette::TertiaryPale]]; }
.BGTertiaryLight { background-color:[[ColorPalette::TertiaryLight]]; }
.BGTertiaryMid { background-color:[[ColorPalette::TertiaryMid]]; }
.BGTertiaryDark { background-color:[[ColorPalette::TertiaryDark]]; }
.BGError { background-color:[[ColorPalette::Error]]; }
/*}}}*/
/***
|Name|TaggedTemplateTweak|
|Source|http://www.TiddlyTools.com/#TaggedTemplateTweak|
|Documentation|http://www.TiddlyTools.com/#TaggedTemplateTweakInfo|
|Version|1.6.1|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Description|use alternative ViewTemplate/EditTemplate for specific tiddlers|
This plugin extends the core function, story.chooseTemplateForTiddler(), so that any given tiddler can be viewed and/or edited using alternatives to the standard tiddler templates.
!!!!!Documentation
>see [[TaggedTemplateTweakInfo]]
!!!!!Revisions
<<<
2009.09.02 [1.6.1] apply field-based template (if any) *before* tag-based template
| please see [[TaggedTemplateTweakInfo]] for previous revision details |
2007.06.11 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.TaggedTemplateTweak= {major: 1, minor: 6, revision: 1, date: new Date(2009,9,2)};
if (!config.options.txtTemplateTweakFieldname)
config.options.txtTemplateTweakFieldname='template';
Story.prototype.taggedTemplate_chooseTemplateForTiddler = Story.prototype.chooseTemplateForTiddler
Story.prototype.chooseTemplateForTiddler = function(title,template)
{
// get core template and split into theme and template name
var coreTemplate=this.taggedTemplate_chooseTemplateForTiddler.apply(this,arguments);
var theme=""; var template=coreTemplate;
var parts=template.split(config.textPrimitives.sectionSeparator);
if (parts[1]) { theme=parts[0]; template=parts[1]; }
else theme=config.options.txtTheme||""; // if theme is not specified
theme+=config.textPrimitives.sectionSeparator;
// look for template using title as prefix
if (!store.getTaggedTiddlers(title).length) { // if tiddler is not a tag
if (store.getTiddlerText(theme+title+template))
{ return theme+title+template; } // theme##TitleTemplate
if (store.getTiddlerText(title+template))
{ return title+template; } // TitleTemplate
}
// look for templates using custom field value as prefix
var v=store.getValue(title,config.options.txtTemplateTweakFieldname);
if (store.getTiddlerText(theme+v+template))
{ return theme+v+template; } // theme##valueTemplate
if (store.getTiddlerText(v+template))
{ return v+template; } // valueTemplate
// look for template using tags as prefix
var tiddler=store.getTiddler(title);
if (!tiddler) return coreTemplate; // tiddler doesn't exist... use core result
for (i=0; i<tiddler.tags.length; i++) {
var t=tiddler.tags[i]+template; // add tag prefix to template
var c=t.substr(0,1).toUpperCase()+t.substr(1); // capitalized for WikiWord title
if (store.getTiddlerText(theme+t)) { return theme+t; } // theme##tagTemplate
if (store.getTiddlerText(theme+c)) { return theme+c; } // theme##TagTemplate
if (store.getTiddlerText(t)) { return t; } // tagTemplate
if (store.getTiddlerText(c)) { return c; } // TagTemplate
}
// no match... use core result
return coreTemplate;
}
//}}}
/***
|Name|TaggedTemplateTweakInfo|
|Source|http://www.TiddlyTools.com/#TaggedTemplateTweak|
|Documentation|http://www.TiddlyTools.com/#TaggedTemplateTweakInfo|
|Version|1.6.1|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|documentation|
|Description|Documentation for TaggedTemplateTweak|
This plugin extends the core function, story.chooseTemplateForTiddler(), so that any given tiddler can be viewed and/or edited using alternatives to the standard tiddler templates. To select alternative templates, a 'template prefix' is determined by using the tiddler's title or matching a tag value or using a value stored in a custom tiddler field.
!!!!!Usage
<<<
*The plugin first attempts to use the tiddler's //title// as a prefix added to the standard TiddlyWiki template titles, [[ViewTemplate]] and [[EditTemplate]] (i.e., ''TiddlerNameViewTemplate'' and ''TiddlerNameEditTemplate''). This allows you to associate a custom template with a specific tiddler, without needing to add any special tags or custom field values to that individual tiddler.
*You can also define a tiddler's template prefix by using a //custom tiddler field// named 'template'. If no corresponding template was found using the tiddler's title, then the tiddler's 'template' field value, if present, will be used as a prefix (e.g., if template='SomeThing', then [[SomeThingViewTemplate]] will be applied).
*If no template is found using the either the title or 'template' field, then each of the tiddler's tags is tried as a template prefix, until a corresponding template, if any, is found. For example, any tiddlers that are tagged with ''<<tag media>>'' could find alternative templates named [[mediaViewTemplate]] and [[mediaEditTemplate]].
*If you using a systemTheme, the plugin will also tries adding the currently selected theme name (specified by {{{config.options.txtTheme}}}) to the template name (e.g. ''[[SomeTheme##MediaViewTemplate]]'') so that the alternative template definitions can be contained as //sections// within a single systemTheme tiddler.
*Lastly, if no alternative template is found at all, the standard [[ViewTemplate]] or [[EditTemplate]] definition as determined by the TiddlyWiki core handler is used.
Notes:
*You can redefine the //name// of the custom field used to store the template prefix. For example, to use the name of a TiddlyWeb server-side 'bag' as a prefix (so that tiddlers from separate bags can have different appearances), add the following to a tiddler tagged with<<tag systemConfig>>:{{block{
{{{
config.options.txtTemplateTweakFieldname='server.bag'; // use TiddlyWeb bag name as prefix
}}}
}}}
*To permit use of templates that have proper WikiWord tiddler titles (e.g., [[MediaViewTemplate]] and [[MediaEditTemplate]]), the plugin also attempts to use a capitalized form of the tag value (e.g., ''Media'') as a prefix. //This capitalization is for comparison purposes only and will not alter the actual tag values that are stored in the tiddler.//
<<<
!!!!!Examples
<<<
|Sample tiddler| tag | view template | edit template |
|[[MediaSample - QuickTime]]| <<tag media>> | [[MediaViewTemplate]] | [[MediaEditTemplate]] |
|[[MediaSample - Windows]]| <<tag media>> | [[MediaViewTemplate]] | [[MediaEditTemplate]] |
|[[CDSample]]| <<tag CD>> | [[CDViewTemplate]] | [[CDEditTemplate]] |
|<<newTiddler label:"create new task..." title:SampleTask tag:task text:"Type some text and then press DONE to view the task controls">> | <<tag task>> | [[TaskViewTemplate]] | [[EditTemplate]] |
//(note: if these samples are not present in your document, please visit// http://www.TiddlyTools.com/ //to view these sample tiddlers on-line)//
<<<
!!!!!Revisions
<<<
2009.09.02 1.6.1 apply field-based template (if any) *before* tag-based template
2009.07.31 1.6.0 added support for using custom field value as prefix
2009.05.04 1.5.2 check for tiddler exist *after* title-as-prefix (allows shadow tiddlers to use custom templates)
2009.01.06 1.5.1 reversed logic so that title-as-prefix takes precedence over tag-matched prefix
2008.12.18 1.5.0 added handling for using tiddler //title// as prefix (e.g., {{{SomeTiddlerViewTemplate}}})
2008.08.29 1.4.1 corrected handling for tiddlers with no matching tagged template when non-default theme is in effect (e.g., use "MyTheme##ViewTemplate").
2008.05.15 1.4.0 support use of *shadow* tagged templates (e.g., [[DiscussionViewTemplate]] created by [[DiscussionPlugin]])
2008.05.10 1.3.0 corrected handling for determining core template when using theme with sections
2008.05.01 1.2.5 added support for tagged templates stored as sections in a theme
2008.04.01 1.2.0 added support for using systemTheme section-based template definitions (requested by Phil Hawksworth)
2008.01.22 [*.*.*] plugin size reduction - documentation moved to [[TaggedTemplateTweakInfo]]
2007.06.23 1.1.0 re-written to use automatic 'tag prefix' search instead of hard coded check for each tag. Allows new custom tags to be used without requiring code changes to this plugin.
2007.06.11 1.0.0 initial release
<<<
/***
|Name|TextAreaPlugin|
|Source|http://www.TiddlyTools.com/#TextAreaPlugin|
|Documentation|http://www.TiddlyTools.com/#TextAreaPluginInfo|
|Version|2.3.0|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Description|Adds Find/Again keyboard search, autosize, and 'stretch bar' resize for textarea controls|
!!!!!Documentation
>see [[TextAreaPluginInfo]]
!!!!!Configuration
<<<
<<option chkTextAreaExtensions>> use control-f (find), control-g (find again) inside text area
<<option chkDisableAutoSelect>> place cursor at start of textarea instead of pre-selecting content
<<option chkResizeEditor>> modify shadow EditTemplate to add resizeable text area (and autosize command)
<<<
!!!!!Revisions
<<<
2011.10.28 2.3.0 added resizeHere macro to add stretch bar to current container (e.g., sidebar panels)
|please see [[TextAreaPluginInfo]] for additional revision details|
2006.01.22 1.0.0 Moved from temporary "System Tweaks" tiddler into 'real' TextAreaPlugin tiddler.
<<<
!!!!!Code
***/
//{{{
version.extensions.TextAreaPlugin= {major: 2, minor: 3, revision: 0, date: new Date(2011,10,28)};
if (config.options.chkTextAreaExtensions===undefined) config.options.chkTextAreaExtensions=true;
if (config.options.chkDisableAutoSelect===undefined) config.options.chkDisableAutoSelect=true;
if (config.options.chkResizeEditor===undefined) config.options.chkResizeEditor=true;
// automatically tweak shadow EditTemplate to add "autosizeEditor" toolbar command
if (config.options.chkResizeEditor)
config.shadowTiddlers.EditTemplate=config.shadowTiddlers.EditTemplate.replace(/deleteTiddler/,"deleteTiddler autosizeEditor");
// automatically tweak shadow EditTemplate to add "resizeEditor" macro
if (config.options.chkResizeEditor)
config.shadowTiddlers.EditTemplate+="<span macro='resizeEditor'></span>";
// Put focus in a specified tiddler field
Story.prototype.TextAreaExtensions_focusTiddler=Story.prototype.focusTiddler;
Story.prototype.focusTiddler = function(title,field)
{
this.TextAreaExtensions_focusTiddler.apply(this,arguments); // first call core
var e = this.getTiddlerField(title,field);
if (e && config.options.chkDisableAutoSelect) {
if (e.setSelectionRange) // FF
e.setSelectionRange(0,0);
else if (e.createTextRange) // IE
{ var r=e.createTextRange(); r.collapse(true); r.select(); }
}
if (e && config.options.chkTextAreaExtensions) addKeyDownHandlers(e);
}
//}}}
//{{{
function addKeyDownHandlers(e)
{
// exit if not textarea or element doesn't allow selections
if (e.tagName.toLowerCase()!="textarea"||!e.setSelectionRange||e.initialized) return;
// utility function: exits keydown handler and prevents browser from processing the keystroke
var processed=function(ev) {
ev.cancelBubble=true; // IE4+
try{event.keyCode=0;}catch(e){}; // IE5
if (window.event) ev.returnValue=false; // IE6
if (ev.preventDefault) ev.preventDefault(); // moz/opera/konqueror
if (ev.stopPropagation) ev.stopPropagation(); // all
return false;
}
// capture keydown in edit field
e.saved_onkeydown=e.onkeydown; // save current keydown handler (if any)
e.onkeydown=function(ev) { if (!ev) var ev=window.event;
var key=ev.keyCode;
if (!key) {
var char=event.which?event.which:event.charCode;
if (char==102) key=70;
if (char==103) key=71;
}
// process CTRL-F (find matching text) or CTRL-G (find next match)
if (ev.ctrlKey && (key==70||key==71)) {
// prompt for text to find
var defFind=e.findText?e.findText:e.value.substring(e.selectionStart,e.selectionEnd);
if (key==70||!e.findText||!e.findText.length) // ctrl-f or no saved search text
{ var f=prompt("find:", defFind); e.focus(); if (f) e.findText=f; }
if (!e.findText||!e.findText.length) return processed(ev); // if no search text, exit
// do case-insensitive match with 'wraparound'... if not found, alert and exit
var newstart=e.value.toLowerCase().indexOf(e.findText.toLowerCase(),e.selectionStart+1);
if (newstart==-1) newstart=e.value.toLowerCase().indexOf(e.findText.toLowerCase());
if (newstart==-1) { alert("'"+e.findText+"' not found"); e.focus(); return processed(ev); }
// set new selection, scroll it into view, and report line position in status bar
e.setSelectionRange(newstart,newstart+e.findText.length);
var linecount=e.value.split('\n').length;
var thisline=e.value.substr(0,e.selectionStart).split('\n').length;
e.scrollTop=Math.floor((thisline-1-e.rows/2)*e.scrollHeight/linecount);
window.status="line: "+thisline+"/"+linecount;
return processed(ev);
}
if (e.saved_onkeydown) // call previous keydown handler (if any)
e.saved_onkeydown(ev);
}
e.initialized=true;
}
//}}}
// // 'autosize' toolbar command
//{{{
config.commands.autosizeEditor = {
text: 'autosize',
tooltip: 'automatically adjust the editor height to fit the contents',
text_alt: '\u221Aautosize',
hideReadOnly: false,
handler: function(event,src,title) {
var here=story.findContainingTiddler(src); if (!here) return;
var ta=here.getElementsByTagName('textarea'); if (!ta) return;
for (i=0;i<ta.length;i++) {
// only autosize textareas actually used to edit tiddler fields
if (ta[i].getAttribute("edit")==undefined) continue;
ta[i].button=src;
if (!ta[i].maxed)
config.commands.autosizeEditor.on(ta[i]);
else
config.commands.autosizeEditor.off(ta[i],true);
}
return false;
},
on: function(e) {
if (e.maxed) return; // already autosizing!
if (e.savedheight==undefined)
e.savedheight=e.style.height;
if (e.savedkeyup==undefined) {
e.savedkeyup=e.onkeyup;
e.onkeyup=function(ev) {
if (!ev) var ev=window.event; var e=resolveTarget(ev);
e.style.height=e.scrollHeight+'px';
if (e.savedkeyup) e.savedkeyup();
}
}
// IE reports error: "not implemented" for onkeypress
if (!config.browser.isIE && e.savedkeypress==undefined) {
e.savedkeypress=e.onkeypress;
e.onkeypress=function(ev) {
if (!ev) var ev=window.event; var e=resolveTarget(ev);
if (ev.keyCode==33) { // PGUP
if (window.scrollByPages) window.scrollByPages(-1);
return false;
}
if (ev.keyCode==34) { // PGDN
if (window.scrollByPages) window.scrollByPages(1);
return false;
}
if (e.savedkeypress) e.savedkeypress();
}
}
e.style.height=e.scrollHeight+'px';
if (e.button) e.button.innerHTML=config.commands.autosizeEditor.text_alt;
e.maxed=true;
},
off: function(e,resetHeight) {
if (resetHeight) e.style.height=e.savedheight;
e.onkeyup=e.savedkeyup;
// IE reports error: "not implemented" for onkeypress
if (!config.browser.isIE) e.onkeypress=e.savedkeypress;
if (e.button) e.button.innerHTML=config.commands.autosizeEditor.text;
e.maxed=false;
}
};
config.macros.autosizeEditor={
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
var here=story.findContainingTiddler(place); if (!here) return;
var ta=here.getElementsByTagName('textarea'); if (!ta) return;
for (i=0;i<ta.length;i++) {
// only autosize textareas actually used to edit tiddler fields
if (ta[i].getAttribute("edit")==undefined) continue;
config.commands.autosizeEditor.on(ta[i]);
}
return false;
}
}
//}}}
// // grab-and-stretch handle
//{{{
config.macros.resizeEditor = { // add stretch bar to editor textarea
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
var here=story.findContainingTiddler(place); if (!here) return;
var ta=here.getElementsByTagName('textarea');
if (ta) for (i=0;i<ta.length;i++) {
// only resize tiddler editor textareas
if (ta[i].getAttribute("edit")==undefined) continue;
new window.TextAreaResizer(ta[i]);
}
}
}
config.macros.resizeTiddler = { // add stretch bar to tiddler viewer element
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
var here=story.findContainingTiddler(place); if (!here) return;
var elems=here.getElementsByTagName('div');
if (elems) for (i=0;i<elems.length;i++) if (hasClass(elems[i],'viewer')) break;
if (i<elems.length) new window.TextAreaResizer(elems[i]);
}
}
config.macros.resizeFrame = { // add stretch bar to iframes
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
var here=story.findContainingTiddler(place); if (!here) return;
var fr=here.getElementsByTagName('iframe');
if (fr) for (i=0;i<fr.length;i++) new window.TextAreaResizer(fr[i]);
}
}
config.macros.resizeListbox = { // add stretch bar to listbox controls
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
var here=story.findContainingTiddler(place); if (!here) here=place;
var fr=here.getElementsByTagName('select');
if (fr) for (i=0;i<fr.length;i++) new window.TextAreaResizer(fr[i]);
}
}
config.macros.resizeHere = { // add stretch bar to containing element
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
new window.TextAreaResizer(place);
}
}
// TextAreaResizer script by Jason Johnston (jj@lojjic.net)
// Created August 2003. Use freely, but give me credit.
// adds a handle below textareas that the user can drag with the mouse to resize the textarea.
// MODIFIED by ELS for use with TW
window.TextAreaResizer = function(elt) {
this.element = elt;
this.create();
}
window.TextAreaResizer.prototype = {
create : function() {
var elt = this.element;
var thisRef = this;
var h = this.handle = document.createElement("div");
h.style.height = "3px"; // was 4px... looked too fat!
h.style.overflow = "hidden"; // ELS: force IE to trim height to < 1em
var adjust=elt.nodeName=='textarea'?4:0; // 4 pixels for textarea border edge
// h.style.width=(elt.offsetWidth-adjust)+"px";
h.style.width="auto";
h.style.backgroundColor = "#999"; // ELS: standard mid-tone (dark) gray
h.style.cursor = "s-resize";
h.title = "Drag to resize text box";
h.onmousedown=function(evt){thisRef.dragStart(evt)};
elt.parentNode.insertBefore(h, elt.nextSibling);
},
dragStart : function(evt) {
if (!evt) var evt=window.event;
this.dragStop(evt); // ELS: stop any current drag processing first
var thisRef = this;
this.dragStartY = evt.clientY;
this.dragStartH = this.element.offsetHeight;
document.savedmousemove=document.onmousemove;
document.onmousemove=this.dragMoveHdlr=function(evt){thisRef.dragMove(evt)};
document.savedmouseup=document.onmouseup;
document.onmouseup=this.dragStopHdlr=function(evt){thisRef.dragStop(evt)};
},
dragMove : function(evt) {
if (!evt) var evt=window.event;
// ELS: make sure height is at least 10px
var h=this.dragStartH+evt.clientY-this.dragStartY;
if (h<10) h=10; this.element.style.height=h+"px";
// ELS: match handle to textarea width (which may have changed due to document scrollbars)
// var adjust=this.element.nodeName.toLowerCase()=='textarea'?4:0; // 4 pixels for textarea
// this.handle.style.width=(this.element.offsetWidth-adjust)+"px";
// ELS: when manually resizing, disable autoresizing (without restoring saved height)
if (this.element.maxed!=undefined && this.element.maxed)
config.commands.autosizeEditor.off(this.element,false);
},
dragStop : function(evt) {
if (!evt) var evt=window.event;
document.onmousemove=(document.savedmousemove!=undefined)?document.savedmousemove:null;
document.onmousemove=(document.savedmouseup!=undefined)?document.savedmouseup:null;
},
destroy : function() {
var elt = this.element;
elt.parentNode.removeChild(this.handle);
elt.style.height = "";
}
};
//}}}
!usage
{{{[img[TexturesCrumpled]]}}}
[img[TexturesCrumpled]]
!notes
!type
image/jpg
!file
./images/crumpled.jpg
!url
!data
data:image/jpeg;base64,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
/%
!info
|Name|ToggleFullScreen|
|Source|http://www.TiddlyTools.com/#ToggleFullScreen|
|Version|2.1.0|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|transclusion|
|Description|Create a link that shows/hides sidebars and page headers|
Usage
<<<
{{{
<<tiddler ToggleFullScreen>>
<<tiddler ToggleFullScreen with: label altlabel>>
}}}
embeds a command link into content, where:
*''label'' (optional, default={{{fullscreen}}})<br>command text
*''altlabel'' (optional, default={{{restore}}})<br>alternative command text shown when full screen is enabled
You can also enable/disable full screen immediately (without clicking a command link) by embedding the one of the following directly in your content:
{{{
<<tiddler ToggleFullScreen##ON>>
<<tiddler ToggleFullScreen##OFF>>
}}}
<<<
Example
<<<
{{{<<tiddler ToggleFullScreen with: fullscreen restore>>}}}
<<tiddler ToggleFullScreen##show with: fullscreen restore>>
<<<
Revisions
<<<
2011.05.13 2.1.0 refactored code and restored "##ON" and "#OFF" usage
2010.xx.xx 2.0.1 converted to transclusion
2008.10.13 1.1.3 re-written to support bookmarklet usage
2008.01.20 1.0.0 created (inline script)
<<<
!end
!code
<<tiddler {{
window.setFullScreen = function(fs) {
var co=config.options; var cm=config.macros;
cm.option.propagateOption('chkFullScreen','checked',fs,'input');
var showmm=!fs && co.chkShowLeftSidebar!==false;
var showsb=!fs && co.chkShowRightSidebar!==false;
var showcrumbs=!fs && co.chkShowBreadcrumbs!==false
&& cm.breadcrumbs && cm.breadcrumbs.crumbs.length;
var showstorymenu=!fs;
var da=document.getElementById('displayArea');
var cw=document.getElementById('contentWrapper');
var mm=document.getElementById('mainMenu');
var sb=document.getElementById('sidebar');
var sm=document.getElementById('storyMenu');
var bc=document.getElementById('breadCrumbs');
if (cw){ // toggle page header
var elems=cw.getElementsByTagName('*');
for (var i=0; i<elems.length; i++) if (hasClass(elems[i],'header'))
{ elems[i].style.display=fs?'none':'block'; break; }
}
if (mm) { // toggle MainMenu
mm.style.display=showmm?'block':'none';
da.style.marginLeft=showmm?(co.txtDisplayAreaLeftMargin||''):'1em';
}
if (sb) { // toggle sidebar
sb.style.display=showsb?'block':'none';
da.style.marginRight=showsb?(co.txtDisplayAreaRightMargin||''):'1em';
}
if (sm) sm.style.display=showstorymenu?'block':'none'; // toggle StoryMenu
if (bc) bc.style.display=showcrumbs?'block':'none'; // toggle BreadCrumbsPlugin
var b=document.getElementById('restoreFromFullscreenButton'); if (b) removeNode(b);
if (fs) {
setStylesheet(store.getTiddlerText('ToggleFullScreen##styles'),'fullScreenStyles');
var b=createTiddlyElement(null,'span','restoreFromFullscreenButton','selected');
b.innerHTML='◊';
b.title='RESTORE: redisplay page header, menu and sidebar';
b.onclick=function(ev){return window.setFullScreen(false);};
document.body.insertBefore(b,null);
}
return false;
};
'';}}>>
!end
!styles
#restoreFromFullscreenButton {
position:fixed; top:.3em; right:.3em; z-index:10001;
cursor:pointer; font-size:8pt; color:ButtonText !important;
border:2px outset ButtonFace; padding:0px 3px;
background-color:ButtonFace; -moz-appearance:button;
}
!end
!ON
<<tiddler ToggleFullScreen##code>><<tiddler {{window.setFullScreen(true);'';}}>>
!end
!OFF
<<tiddler ToggleFullScreen##code>><<tiddler {{window.setFullScreen(false);'';}}>>
!end
!show
<<tiddler ToggleFullScreen##code>><html><nowiki>
<a href='javascript:;' title="FULLSCREEN: toggle sidebars and page header"
onmouseover="
this.href='javascript:void(eval(decodeURIComponent(%22(function(){try{('
+encodeURIComponent(encodeURIComponent(this.onclick))
+')()}catch(e){alert(e.description?e.description:e.toString())}})()%22)))';"
onclick="
window.setFullScreen(!config.options.chkFullScreen); // toggle setting
this.innerHTML=!config.options.chkFullScreen?'$1':'$2'; // set command text
return false;
">$1</a></html>
!end
%/<<tiddler {{var src='ToggleFullScreen'; src+(tiddler&&tiddler.title==src?'##info':'##show');}}
with: {{'$'+'1'!='$1'?'$1':'fullscreen'}}
{{'$'+'2'!='$2'?'$2':'restore'}}>>
|~ViewToolbar|closeTiddler closeOthers +editTiddler > fields syncing permalink references jump|
|~ViewToolbarReadOnly||
|~EditToolbar|+saveTiddler -cancelTiddler deleteTiddler|
/***
Description: Contains the stuff you need to use Tiddlyspot
Note, you also need UploadPlugin, PasswordOptionPlugin and LoadRemoteFileThroughProxy
from http://tiddlywiki.bidix.info for a complete working Tiddlyspot site.
***/
//{{{
// edit this if you are migrating sites or retrofitting an existing TW
config.tiddlyspotSiteId = 'moveabletheme-da';
// make it so you can by default see edit controls via http
config.options.chkHttpReadOnly = false;
window.readOnly = false; // make sure of it (for tw 2.2)
window.showBackstage = true; // show backstage too
// disable autosave in d3
if (window.location.protocol != "file:")
config.options.chkGTDLazyAutoSave = false;
// tweak shadow tiddlers to add upload button, password entry box etc
with (config.shadowTiddlers) {
SiteUrl = 'http://'+config.tiddlyspotSiteId+'.tiddlyspot.com';
SideBarOptions = SideBarOptions.replace(/(<<saveChanges>>)/,"$1<<tiddler TspotSidebar>>");
OptionsPanel = OptionsPanel.replace(/^/,"<<tiddler TspotOptions>>");
DefaultTiddlers = DefaultTiddlers.replace(/^/,"[[WelcomeToTiddlyspot]] ");
MainMenu = MainMenu.replace(/^/,"[[WelcomeToTiddlyspot]] ");
}
// create some shadow tiddler content
merge(config.shadowTiddlers,{
'TspotOptions':[
"tiddlyspot password:",
"<<option pasUploadPassword>>",
""
].join("\n"),
'TspotControls':[
"| tiddlyspot password:|<<option pasUploadPassword>>|",
"| site management:|<<upload http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/store.cgi index.html . . " + config.tiddlyspotSiteId + ">>//(requires tiddlyspot password)//<br>[[control panel|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/controlpanel]], [[download (go offline)|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/download]]|",
"| links:|[[tiddlyspot.com|http://tiddlyspot.com/]], [[FAQs|http://faq.tiddlyspot.com/]], [[blog|http://tiddlyspot.blogspot.com/]], email [[support|mailto:support@tiddlyspot.com]] & [[feedback|mailto:feedback@tiddlyspot.com]], [[donate|http://tiddlyspot.com/?page=donate]]|"
].join("\n"),
'WelcomeToTiddlyspot':[
"This document is a ~TiddlyWiki from tiddlyspot.com. A ~TiddlyWiki is an electronic notebook that is great for managing todo lists, personal information, and all sorts of things.",
"",
"@@font-weight:bold;font-size:1.3em;color:#444; //What now?// @@ Before you can save any changes, you need to enter your password in the form below. Then configure privacy and other site settings at your [[control panel|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/controlpanel]] (your control panel username is //" + config.tiddlyspotSiteId + "//).",
"<<tiddler TspotControls>>",
"See also GettingStarted.",
"",
"@@font-weight:bold;font-size:1.3em;color:#444; //Working online// @@ You can edit this ~TiddlyWiki right now, and save your changes using the \"save to web\" button in the column on the right.",
"",
"@@font-weight:bold;font-size:1.3em;color:#444; //Working offline// @@ A fully functioning copy of this ~TiddlyWiki can be saved onto your hard drive or USB stick. You can make changes and save them locally without being connected to the Internet. When you're ready to sync up again, just click \"upload\" and your ~TiddlyWiki will be saved back to tiddlyspot.com.",
"",
"@@font-weight:bold;font-size:1.3em;color:#444; //Help!// @@ Find out more about ~TiddlyWiki at [[TiddlyWiki.com|http://tiddlywiki.com]]. Also visit [[TiddlyWiki.org|http://tiddlywiki.org]] for documentation on learning and using ~TiddlyWiki. New users are especially welcome on the [[TiddlyWiki mailing list|http://groups.google.com/group/TiddlyWiki]], which is an excellent place to ask questions and get help. If you have a tiddlyspot related problem email [[tiddlyspot support|mailto:support@tiddlyspot.com]].",
"",
"@@font-weight:bold;font-size:1.3em;color:#444; //Enjoy :)// @@ We hope you like using your tiddlyspot.com site. Please email [[feedback@tiddlyspot.com|mailto:feedback@tiddlyspot.com]] with any comments or suggestions."
].join("\n"),
'TspotSidebar':[
"<<upload http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/store.cgi index.html . . " + config.tiddlyspotSiteId + ">><html><a href='http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/download' class='button'>download</a></html>"
].join("\n")
});
//}}}
| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |
| 18/12/2011 00:29:59 | YourName | [[/|http://moveabletheme-da.tiddlyspot.com/#txtTheme:MoveableTheme]] | [[store.cgi|http://moveabletheme-da.tiddlyspot.com/store.cgi]] | . | [[index.html | http://moveabletheme-da.tiddlyspot.com/index.html]] | . |
| 18/12/2011 00:46:11 | YourName | [[/|http://moveabletheme-da.tiddlyspot.com/]] | [[store.cgi|http://moveabletheme-da.tiddlyspot.com/store.cgi]] | . | [[index.html | http://moveabletheme-da.tiddlyspot.com/index.html]] | . |
| 18/12/2011 04:06:38 | DitNavn | [[moveabletheme-da%20(1).html|file:///C:/Documents%20and%20Settings/mama/Skrivebord/empty/moveabletheme-da%20(1).html]] | [[store.cgi|http://moveabletheme-da.tiddlyspot.com/store.cgi]] | . | [[index.html | http://moveabletheme-da.tiddlyspot.com/index.html]] | . |
| 18/12/2011 04:12:05 | YourName | [[/|http://moveabletheme-da.tiddlyspot.com/]] | [[store.cgi|http://moveabletheme-da.tiddlyspot.com/store.cgi]] | . | [[index.html | http://moveabletheme-da.tiddlyspot.com/index.html]] | . |
| 18/12/2011 04:23:36 | YourName | [[/|http://moveabletheme-da.tiddlyspot.com/]] | [[store.cgi|http://moveabletheme-da.tiddlyspot.com/store.cgi]] | . | [[index.html | http://moveabletheme-da.tiddlyspot.com/index.html]] | . |
| 18/12/2011 04:26:01 | YourName | [[/|http://moveabletheme-da.tiddlyspot.com/]] | [[store.cgi|http://moveabletheme-da.tiddlyspot.com/store.cgi]] | . | [[index.html | http://moveabletheme-da.tiddlyspot.com/index.html]] | . |
| 18/12/2011 04:28:05 | YourName | [[/|http://moveabletheme-da.tiddlyspot.com/]] | [[store.cgi|http://moveabletheme-da.tiddlyspot.com/store.cgi]] | . | [[index.html | http://moveabletheme-da.tiddlyspot.com/index.html]] | . |
| 18/12/2011 05:11:36 | YourName | [[/|http://moveabletheme-da.tiddlyspot.com/]] | [[store.cgi|http://moveabletheme-da.tiddlyspot.com/store.cgi]] | . | [[index.html | http://moveabletheme-da.tiddlyspot.com/index.html]] | . | ok |
| 18/12/2011 05:14:02 | YourName | [[/|http://moveabletheme-da.tiddlyspot.com/]] | [[store.cgi|http://moveabletheme-da.tiddlyspot.com/store.cgi]] | . | [[index.html | http://moveabletheme-da.tiddlyspot.com/index.html]] | . |
| 22/12/2011 14:03:05 | DitNavn | [[/|http://moveabletheme-da.tiddlyspot.com/#txtTheme:MoveableTheme]] | [[store.cgi|http://moveabletheme-da.tiddlyspot.com/store.cgi]] | . | [[index.html | http://moveabletheme-da.tiddlyspot.com/index.html]] | . |
/***
|''Name:''|UploadPlugin|
|''Description:''|Save to web a TiddlyWiki|
|''Version:''|4.1.3|
|''Date:''|Feb 24, 2008|
|''Source:''|http://tiddlywiki.bidix.info/#UploadPlugin|
|''Documentation:''|http://tiddlywiki.bidix.info/#UploadPluginDoc|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0|
|''Requires:''|PasswordOptionPlugin|
***/
//{{{
version.extensions.UploadPlugin = {
major: 4, minor: 1, revision: 3,
date: new Date("Feb 24, 2008"),
source: 'http://tiddlywiki.bidix.info/#UploadPlugin',
author: 'BidiX (BidiX (at) bidix (dot) info',
coreVersion: '2.2.0'
};
//
// Environment
//
if (!window.bidix) window.bidix = {}; // bidix namespace
bidix.debugMode = false; // true to activate both in Plugin and UploadService
//
// Upload Macro
//
config.macros.upload = {
// default values
defaultBackupDir: '', //no backup
defaultStoreScript: "store.php",
defaultToFilename: "index.html",
defaultUploadDir: ".",
authenticateUser: true // UploadService Authenticate User
};
config.macros.upload.label = {
promptOption: "Save and Upload this TiddlyWiki with UploadOptions",
promptParamMacro: "Save and Upload this TiddlyWiki in %0",
saveLabel: "save to web",
saveToDisk: "save to disk",
uploadLabel: "upload"
};
config.macros.upload.messages = {
noStoreUrl: "No store URL in parmeters or options",
usernameOrPasswordMissing: "Username or password missing"
};
config.macros.upload.handler = function(place,macroName,params) {
if (readOnly)
return;
var label;
if (document.location.toString().substr(0,4) == "http")
label = this.label.saveLabel;
else
label = this.label.uploadLabel;
var prompt;
if (params[0]) {
prompt = this.label.promptParamMacro.toString().format([this.destFile(params[0],
(params[1] ? params[1]:bidix.basename(window.location.toString())), params[3])]);
} else {
prompt = this.label.promptOption;
}
createTiddlyButton(place, label, prompt, function() {config.macros.upload.action(params);}, null, null, this.accessKey);
};
config.macros.upload.action = function(params)
{
// for missing macro parameter set value from options
if (!params) params = {};
var storeUrl = params[0] ? params[0] : config.options.txtUploadStoreUrl;
var toFilename = params[1] ? params[1] : config.options.txtUploadFilename;
var backupDir = params[2] ? params[2] : config.options.txtUploadBackupDir;
var uploadDir = params[3] ? params[3] : config.options.txtUploadDir;
var username = params[4] ? params[4] : config.options.txtUploadUserName;
var password = config.options.pasUploadPassword; // for security reason no password as macro parameter
// for still missing parameter set default value
if ((!storeUrl) && (document.location.toString().substr(0,4) == "http"))
storeUrl = bidix.dirname(document.location.toString())+'/'+config.macros.upload.defaultStoreScript;
if (storeUrl.substr(0,4) != "http")
storeUrl = bidix.dirname(document.location.toString()) +'/'+ storeUrl;
if (!toFilename)
toFilename = bidix.basename(window.location.toString());
if (!toFilename)
toFilename = config.macros.upload.defaultToFilename;
if (!uploadDir)
uploadDir = config.macros.upload.defaultUploadDir;
if (!backupDir)
backupDir = config.macros.upload.defaultBackupDir;
// report error if still missing
if (!storeUrl) {
alert(config.macros.upload.messages.noStoreUrl);
clearMessage();
return false;
}
if (config.macros.upload.authenticateUser && (!username || !password)) {
alert(config.macros.upload.messages.usernameOrPasswordMissing);
clearMessage();
return false;
}
bidix.upload.uploadChanges(false,null,storeUrl, toFilename, uploadDir, backupDir, username, password);
return false;
};
config.macros.upload.destFile = function(storeUrl, toFilename, uploadDir)
{
if (!storeUrl)
return null;
var dest = bidix.dirname(storeUrl);
if (uploadDir && uploadDir != '.')
dest = dest + '/' + uploadDir;
dest = dest + '/' + toFilename;
return dest;
};
//
// uploadOptions Macro
//
config.macros.uploadOptions = {
handler: function(place,macroName,params) {
var wizard = new Wizard();
wizard.createWizard(place,this.wizardTitle);
wizard.addStep(this.step1Title,this.step1Html);
var markList = wizard.getElement("markList");
var listWrapper = document.createElement("div");
markList.parentNode.insertBefore(listWrapper,markList);
wizard.setValue("listWrapper",listWrapper);
this.refreshOptions(listWrapper,false);
var uploadCaption;
if (document.location.toString().substr(0,4) == "http")
uploadCaption = config.macros.upload.label.saveLabel;
else
uploadCaption = config.macros.upload.label.uploadLabel;
wizard.setButtons([
{caption: uploadCaption, tooltip: config.macros.upload.label.promptOption,
onClick: config.macros.upload.action},
{caption: this.cancelButton, tooltip: this.cancelButtonPrompt, onClick: this.onCancel}
]);
},
options: [
"txtUploadUserName",
"pasUploadPassword",
"txtUploadStoreUrl",
"txtUploadDir",
"txtUploadFilename",
"txtUploadBackupDir",
"chkUploadLog",
"txtUploadLogMaxLine"
],
refreshOptions: function(listWrapper) {
var opts = [];
for(i=0; i<this.options.length; i++) {
var opt = {};
opts.push();
opt.option = "";
n = this.options[i];
opt.name = n;
opt.lowlight = !config.optionsDesc[n];
opt.description = opt.lowlight ? this.unknownDescription : config.optionsDesc[n];
opts.push(opt);
}
var listview = ListView.create(listWrapper,opts,this.listViewTemplate);
for(n=0; n<opts.length; n++) {
var type = opts[n].name.substr(0,3);
var h = config.macros.option.types[type];
if (h && h.create) {
h.create(opts[n].colElements['option'],type,opts[n].name,opts[n].name,"no");
}
}
},
onCancel: function(e)
{
backstage.switchTab(null);
return false;
},
wizardTitle: "Upload with options",
step1Title: "These options are saved in cookies in your browser",
step1Html: "<input type='hidden' name='markList'></input><br>",
cancelButton: "Cancel",
cancelButtonPrompt: "Cancel prompt",
listViewTemplate: {
columns: [
{name: 'Description', field: 'description', title: "Description", type: 'WikiText'},
{name: 'Option', field: 'option', title: "Option", type: 'String'},
{name: 'Name', field: 'name', title: "Name", type: 'String'}
],
rowClasses: [
{className: 'lowlight', field: 'lowlight'}
]}
};
//
// upload functions
//
if (!bidix.upload) bidix.upload = {};
if (!bidix.upload.messages) bidix.upload.messages = {
//from saving
invalidFileError: "The original file '%0' does not appear to be a valid TiddlyWiki",
backupSaved: "Backup saved",
backupFailed: "Failed to upload backup file",
rssSaved: "RSS feed uploaded",
rssFailed: "Failed to upload RSS feed file",
emptySaved: "Empty template uploaded",
emptyFailed: "Failed to upload empty template file",
mainSaved: "Main TiddlyWiki file uploaded",
mainFailed: "Failed to upload main TiddlyWiki file. Your changes have not been saved",
//specific upload
loadOriginalHttpPostError: "Can't get original file",
aboutToSaveOnHttpPost: 'About to upload on %0 ...',
storePhpNotFound: "The store script '%0' was not found."
};
bidix.upload.uploadChanges = function(onlyIfDirty,tiddlers,storeUrl,toFilename,uploadDir,backupDir,username,password)
{
var callback = function(status,uploadParams,original,url,xhr) {
if (!status) {
displayMessage(bidix.upload.messages.loadOriginalHttpPostError);
return;
}
if (bidix.debugMode)
alert(original.substr(0,500)+"\n...");
// Locate the storeArea div's
var posDiv = locateStoreArea(original);
if((posDiv[0] == -1) || (posDiv[1] == -1)) {
alert(config.messages.invalidFileError.format([localPath]));
return;
}
bidix.upload.uploadRss(uploadParams,original,posDiv);
};
if(onlyIfDirty && !store.isDirty())
return;
clearMessage();
// save on localdisk ?
if (document.location.toString().substr(0,4) == "file") {
var path = document.location.toString();
var localPath = getLocalPath(path);
saveChanges();
}
// get original
var uploadParams = new Array(storeUrl,toFilename,uploadDir,backupDir,username,password);
var originalPath = document.location.toString();
// If url is a directory : add index.html
if (originalPath.charAt(originalPath.length-1) == "/")
originalPath = originalPath + "index.html";
var dest = config.macros.upload.destFile(storeUrl,toFilename,uploadDir);
var log = new bidix.UploadLog();
log.startUpload(storeUrl, dest, uploadDir, backupDir);
displayMessage(bidix.upload.messages.aboutToSaveOnHttpPost.format([dest]));
if (bidix.debugMode)
alert("about to execute Http - GET on "+originalPath);
var r = doHttp("GET",originalPath,null,null,username,password,callback,uploadParams,null);
if (typeof r == "string")
displayMessage(r);
return r;
};
bidix.upload.uploadRss = function(uploadParams,original,posDiv)
{
var callback = function(status,params,responseText,url,xhr) {
if(status) {
var destfile = responseText.substring(responseText.indexOf("destfile:")+9,responseText.indexOf("\n", responseText.indexOf("destfile:")));
displayMessage(bidix.upload.messages.rssSaved,bidix.dirname(url)+'/'+destfile);
bidix.upload.uploadMain(params[0],params[1],params[2]);
} else {
displayMessage(bidix.upload.messages.rssFailed);
}
};
// do uploadRss
if(config.options.chkGenerateAnRssFeed) {
var rssPath = uploadParams[1].substr(0,uploadParams[1].lastIndexOf(".")) + ".xml";
var rssUploadParams = new Array(uploadParams[0],rssPath,uploadParams[2],'',uploadParams[4],uploadParams[5]);
var rssString = generateRss();
// no UnicodeToUTF8 conversion needed when location is "file" !!!
if (document.location.toString().substr(0,4) != "file")
rssString = convertUnicodeToUTF8(rssString);
bidix.upload.httpUpload(rssUploadParams,rssString,callback,Array(uploadParams,original,posDiv));
} else {
bidix.upload.uploadMain(uploadParams,original,posDiv);
}
};
bidix.upload.uploadMain = function(uploadParams,original,posDiv)
{
var callback = function(status,params,responseText,url,xhr) {
var log = new bidix.UploadLog();
if(status) {
// if backupDir specified
if ((params[3]) && (responseText.indexOf("backupfile:") > -1)) {
var backupfile = responseText.substring(responseText.indexOf("backupfile:")+11,responseText.indexOf("\n", responseText.indexOf("backupfile:")));
displayMessage(bidix.upload.messages.backupSaved,bidix.dirname(url)+'/'+backupfile);
}
var destfile = responseText.substring(responseText.indexOf("destfile:")+9,responseText.indexOf("\n", responseText.indexOf("destfile:")));
displayMessage(bidix.upload.messages.mainSaved,bidix.dirname(url)+'/'+destfile);
store.setDirty(false);
log.endUpload("ok");
} else {
alert(bidix.upload.messages.mainFailed);
displayMessage(bidix.upload.messages.mainFailed);
log.endUpload("failed");
}
};
// do uploadMain
var revised = bidix.upload.updateOriginal(original,posDiv);
bidix.upload.httpUpload(uploadParams,revised,callback,uploadParams);
};
bidix.upload.httpUpload = function(uploadParams,data,callback,params)
{
var localCallback = function(status,params,responseText,url,xhr) {
url = (url.indexOf("nocache=") < 0 ? url : url.substring(0,url.indexOf("nocache=")-1));
if (xhr.status == 404)
alert(bidix.upload.messages.storePhpNotFound.format([url]));
if ((bidix.debugMode) || (responseText.indexOf("Debug mode") >= 0 )) {
alert(responseText);
if (responseText.indexOf("Debug mode") >= 0 )
responseText = responseText.substring(responseText.indexOf("\n\n")+2);
} else if (responseText.charAt(0) != '0')
alert(responseText);
if (responseText.charAt(0) != '0')
status = null;
callback(status,params,responseText,url,xhr);
};
// do httpUpload
var boundary = "---------------------------"+"AaB03x";
var uploadFormName = "UploadPlugin";
// compose headers data
var sheader = "";
sheader += "--" + boundary + "\r\nContent-disposition: form-data; name=\"";
sheader += uploadFormName +"\"\r\n\r\n";
sheader += "backupDir="+uploadParams[3] +
";user=" + uploadParams[4] +
";password=" + uploadParams[5] +
";uploaddir=" + uploadParams[2];
if (bidix.debugMode)
sheader += ";debug=1";
sheader += ";;\r\n";
sheader += "\r\n" + "--" + boundary + "\r\n";
sheader += "Content-disposition: form-data; name=\"userfile\"; filename=\""+uploadParams[1]+"\"\r\n";
sheader += "Content-Type: text/html;charset=UTF-8" + "\r\n";
sheader += "Content-Length: " + data.length + "\r\n\r\n";
// compose trailer data
var strailer = new String();
strailer = "\r\n--" + boundary + "--\r\n";
data = sheader + data + strailer;
if (bidix.debugMode) alert("about to execute Http - POST on "+uploadParams[0]+"\n with \n"+data.substr(0,500)+ " ... ");
var r = doHttp("POST",uploadParams[0],data,"multipart/form-data; ;charset=UTF-8; boundary="+boundary,uploadParams[4],uploadParams[5],localCallback,params,null);
if (typeof r == "string")
displayMessage(r);
return r;
};
// same as Saving's updateOriginal but without convertUnicodeToUTF8 calls
bidix.upload.updateOriginal = function(original, posDiv)
{
if (!posDiv)
posDiv = locateStoreArea(original);
if((posDiv[0] == -1) || (posDiv[1] == -1)) {
alert(config.messages.invalidFileError.format([localPath]));
return;
}
var revised = original.substr(0,posDiv[0] + startSaveArea.length) + "\n" +
store.allTiddlersAsHtml() + "\n" +
original.substr(posDiv[1]);
var newSiteTitle = getPageTitle().htmlEncode();
revised = revised.replaceChunk("<title"+">","</title"+">"," " + newSiteTitle + " ");
revised = updateMarkupBlock(revised,"PRE-HEAD","MarkupPreHead");
revised = updateMarkupBlock(revised,"POST-HEAD","MarkupPostHead");
revised = updateMarkupBlock(revised,"PRE-BODY","MarkupPreBody");
revised = updateMarkupBlock(revised,"POST-SCRIPT","MarkupPostBody");
return revised;
};
//
// UploadLog
//
// config.options.chkUploadLog :
// false : no logging
// true : logging
// config.options.txtUploadLogMaxLine :
// -1 : no limit
// 0 : no Log lines but UploadLog is still in place
// n : the last n lines are only kept
// NaN : no limit (-1)
bidix.UploadLog = function() {
if (!config.options.chkUploadLog)
return; // this.tiddler = null
this.tiddler = store.getTiddler("UploadLog");
if (!this.tiddler) {
this.tiddler = new Tiddler();
this.tiddler.title = "UploadLog";
this.tiddler.text = "| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |";
this.tiddler.created = new Date();
this.tiddler.modifier = config.options.txtUserName;
this.tiddler.modified = new Date();
store.addTiddler(this.tiddler);
}
return this;
};
bidix.UploadLog.prototype.addText = function(text) {
if (!this.tiddler)
return;
// retrieve maxLine when we need it
var maxLine = parseInt(config.options.txtUploadLogMaxLine,10);
if (isNaN(maxLine))
maxLine = -1;
// add text
if (maxLine != 0)
this.tiddler.text = this.tiddler.text + text;
// Trunck to maxLine
if (maxLine >= 0) {
var textArray = this.tiddler.text.split('\n');
if (textArray.length > maxLine + 1)
textArray.splice(1,textArray.length-1-maxLine);
this.tiddler.text = textArray.join('\n');
}
// update tiddler fields
this.tiddler.modifier = config.options.txtUserName;
this.tiddler.modified = new Date();
store.addTiddler(this.tiddler);
// refresh and notifiy for immediate update
story.refreshTiddler(this.tiddler.title);
store.notify(this.tiddler.title, true);
};
bidix.UploadLog.prototype.startUpload = function(storeUrl, toFilename, uploadDir, backupDir) {
if (!this.tiddler)
return;
var now = new Date();
var text = "\n| ";
var filename = bidix.basename(document.location.toString());
if (!filename) filename = '/';
text += now.formatString("0DD/0MM/YYYY 0hh:0mm:0ss") +" | ";
text += config.options.txtUserName + " | ";
text += "[["+filename+"|"+location + "]] |";
text += " [[" + bidix.basename(storeUrl) + "|" + storeUrl + "]] | ";
text += uploadDir + " | ";
text += "[[" + bidix.basename(toFilename) + " | " +toFilename + "]] | ";
text += backupDir + " |";
this.addText(text);
};
bidix.UploadLog.prototype.endUpload = function(status) {
if (!this.tiddler)
return;
this.addText(" "+status+" |");
};
//
// Utilities
//
bidix.checkPlugin = function(plugin, major, minor, revision) {
var ext = version.extensions[plugin];
if (!
(ext &&
((ext.major > major) ||
((ext.major == major) && (ext.minor > minor)) ||
((ext.major == major) && (ext.minor == minor) && (ext.revision >= revision))))) {
// write error in PluginManager
if (pluginInfo)
pluginInfo.log.push("Requires " + plugin + " " + major + "." + minor + "." + revision);
eval(plugin); // generate an error : "Error: ReferenceError: xxxx is not defined"
}
};
bidix.dirname = function(filePath) {
if (!filePath)
return;
var lastpos;
if ((lastpos = filePath.lastIndexOf("/")) != -1) {
return filePath.substring(0, lastpos);
} else {
return filePath.substring(0, filePath.lastIndexOf("\\"));
}
};
bidix.basename = function(filePath) {
if (!filePath)
return;
var lastpos;
if ((lastpos = filePath.lastIndexOf("#")) != -1)
filePath = filePath.substring(0, lastpos);
if ((lastpos = filePath.lastIndexOf("/")) != -1) {
return filePath.substring(lastpos + 1);
} else
return filePath.substring(filePath.lastIndexOf("\\")+1);
};
bidix.initOption = function(name,value) {
if (!config.options[name])
config.options[name] = value;
};
//
// Initializations
//
// require PasswordOptionPlugin 1.0.1 or better
bidix.checkPlugin("PasswordOptionPlugin", 1, 0, 1);
// styleSheet
setStylesheet('.txtUploadStoreUrl, .txtUploadBackupDir, .txtUploadDir {width: 22em;}',"uploadPluginStyles");
//optionsDesc
merge(config.optionsDesc,{
txtUploadStoreUrl: "Url of the UploadService script (default: store.php)",
txtUploadFilename: "Filename of the uploaded file (default: in index.html)",
txtUploadDir: "Relative Directory where to store the file (default: . (downloadService directory))",
txtUploadBackupDir: "Relative Directory where to backup the file. If empty no backup. (default: ''(empty))",
txtUploadUserName: "Upload Username",
pasUploadPassword: "Upload Password",
chkUploadLog: "do Logging in UploadLog (default: true)",
txtUploadLogMaxLine: "Maximum of lines in UploadLog (default: 10)"
});
// Options Initializations
bidix.initOption('txtUploadStoreUrl','');
bidix.initOption('txtUploadFilename','');
bidix.initOption('txtUploadDir','');
bidix.initOption('txtUploadBackupDir','');
bidix.initOption('txtUploadUserName','');
bidix.initOption('pasUploadPassword','');
bidix.initOption('chkUploadLog',true);
bidix.initOption('txtUploadLogMaxLine','10');
// Backstage
merge(config.tasks,{
uploadOptions: {text: "upload", tooltip: "Change UploadOptions and Upload", content: '<<uploadOptions>>'}
});
config.backstageTasks.push("uploadOptions");
//}}}
!usage
{{{[img[WoodshopBackgroundMedium]]}}}
[img[WoodshopBackgroundMedium]]
!notes
!type
image/jpg
!file
./images/wood.jpg
!url
!data
data:image/jpeg;base64,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
!usage
{{{[img[cloth052.jpg]]}}}
[img[cloth052.jpg]]
!notes
http://www.grsites.com/archive/textures/category/26/texture/48/?bare=
!type
image/jpeg
!file
./cloth052.jpg
!url
!data
data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wgARCAEYASwDASIAAhEBAxEB/8QAGwAAAgMBAQEAAAAAAAAAAAAABQYDBAcCAAH/xAAZAQADAQEBAAAAAAAAAAAAAAAAAQIDBAX/2gAMAwEAAhADEAAAAX3hRJ8+7F5JnLb+Q1MTHCElTKWUogNhkXKrTN9A0k2vlImBunzeyGg8LC2PRuk6iLQuEUuDHOinAO/A4Npx+BaKbX2uSiYul+g01fVeIGvpSvE5fWJfH2WZdAOGGGy6Tm63oetXg9e0IzXNiUWvZgtgfy9ytmXu+2HOrhX3NigxSlzPWxGZmKuFPR9dzY0BkYuzWA+wuL5cSua+ksza3Y5nolJWdLM8Sv60ikqoov6ri61wHnWZGAnOkMgL4/TaZ91AAmulU6tWZoTzOEl7UbEVht+ahZZrcvQUA+xUJjIJftOtObVbSFKJU21DTVSa/wA3DuGCmldXnTZZeVnKgOglTrMJNTrUyENHWJvGw6MvVvmG6AvrotKWIfiYakQsUgzJ0KVNxFJ+RozJcrJUL5j5Atykwr0dAK8Rr6cc5MeBU6IADwKqlVnA6YwGpO1TiPTyKm8Cm+NhWG+PGegHSZ9NWzxZWzFaSonjobHmml1x88W/lYUu5pE6mdaMgT0rHP2yu2v3WmF16DplySerOlCxWkrOSPmwiGbiYelkB5ivMgn6lqKNiXkQ0NdziOx2WxNhdPEF6BacyfLwF5WW7XnrbJGIIYa4oMwh9zzmevTczmOMVuD9RaxNy1GI6tWKQrfPfC3sMyXbfOXUzUBQ2e+SCVnSRRnoJDLrhOu8BY65L6uy31aiA0pUWyd9sVV2ar9tUb8qfyFDO5ZDOA3rag68adSw2VdO6SW3J/wW8Kn80QgZZUQ0u888qk1LtLFo9ggd5Rc0RWVjugvw0+yyESh9C5EE9brgVrWsdZzB76zthWbB611WGd102ydRHxcOumu8KdohlXK0CfNuS4WdtiH2uJEtuE5Hy1F1pz+p9ps2duY8QWmuziSNYzrbDwGb3HXmN11Vb1JdALknQXQyFEv6Z9U7cTqOSb6B2FFjrkkmPAzW5Xr/AEC0DLLFgjaqwl6HPFNfmTS1bDmeHqlU0k8YvR0tY8K8x0J9oiYKB3RApxpTTiWkVyuMcM94/K3upqNaY16dlAT3Zn0Kfm1beQ2Wh9qeIzthMP6vTrKz1FE4ng6utVCNLlVrNXMOpNgM4VrZLN1Hw8K9Iz4aUk6pnwl+XqZblHcQ4vmpE/n0vuv3WFUCqquunVVtI6a9z3I3Wn+ROZpqPSd7ofdWuoK+mVZ58I71z47RXxTUVb6lULDcHnOi2tNCzFWDOQT3qNND+LwGcXWNKck+PsvLzmlAK6100GJJNIEw4LehYXEaqRnnAZO1ltyz6lqWZXH9LMJdYledKZj8pryoBqd2+P5JpyZqt7VBO2Me2ZWKzKE96qqOadLA100ecVT61ULr59vL8O1zS6oYAF8nKVSROpQ6RZ3JMN6YchdCbJIiwbW2C8oyLRCtkiepZDOLXKbQjsgNhep7nugsdPlfb68evh96aWsx/rPxPLVHT0Ke0N4g0VKtYH1x260JloN2U+qxxgaPeZmn4oqD/XFSCxrKPpczbjuR1y17EkbUS+YTI6WCNT4nq7pzxLrt9jDpkZnDlL84sTTKVZvciT5jrAhG0AUJrUDo9JVItd2NBtwsmqsCzdW+YOAsFRmlJIsGnApaH6DrSSmzZC1y9E6UeTnbZc0MttoQXXQVF3oo6F3sf6fQVLJUtpxrFrVvjwxXlprrcJ9LtwIMO39PnycFpicugDIauDHj9bq3y5XQ0lVWwD4b7GCLX9CIzsVsKySg/WCvPVSlL6SYYlZ2DzjD5mGqukHOXcTNEj1sU88hvmx62+l3fOHJeMP1Nz8vLK8sYu6DnhoSOJXKZam2GxZrxqGYAUvK3LZMedcVCFU0ucMtMsOeDZR4z477tMTWozgm45qNoDh+iqRQ48PPKYdey4CXS55XCSOOFZg87NXiV6wYrFUWOYeTImmyY1eweWhlGRcpoa1OxdEuxSdUrjpn1ZGg30XtwVXPDVd35cJMKWFexLOgbIUqtaPWHNeCIyKQFfsjUbDUJAnNQ4J02b3lz+++816T3g+ce8z5V95P3fvJzQe8Ljn3h+494XXveH1H7wpe/eH9l94UMfvDsd+85nj95nfHvIj694Oa3vI//8QAKhAAAgICAwACAgICAwADAAAAAgMBBAAFERITFCIVIQYjFjEQMkEkM0L/2gAIAQEAAQUCHjnmIyY+wxzn76yPGSHOdSgZEwiOfWA+0RwueeeIlgxnSOp8c8BBrgMiBjDiIDgZkRiC6z0mI6h279J5GIhZduOrBIFz3iPr1kZj9z/+T4HA/wBK4mG7tS3xtkfAr71bLFrcIRYVsq80Y3lKZtbWuhk7Wp8WtvE+1zdBXuarcLswf8gV22G1BNaluifbu7xybP5lv4qvvbRu2u3fX2GouvtIs7q2DW7ZoaqlvXst2t5YVbXtj/Fhvg9L22Go2lt0PV/kATjdwqKNDcV2NduaoOLa1V1q23qWLFvcoS89soNfR3iHvt7pSn0b8Wk66sFlgC8l2dc2vVoa0rET8oEMT5U3Gdh1YX2Bu6a1XzXa2zb2J6/YVnKol8JjGWMaPW7qtRL6n+OvzYaQXDFFFVspkcpV0SK9H7xsNJ7ZV0JA69WdUnzGK1OJv2wq3hyrpHzrypbAguaq1SiP7GrYxqrCzrXtZQZfsLrWiHY0WVLVOtFrFsYoRtOHESRupjxVieZ2oWPhGRkX15q9vWqdmUff1axg5ctWWHzPUe8zpzprkCUaWMT6bSUfJjvnM86oqkVAICiw6txbiv2GWYJmB6S1aaCiPzfLhXvZtSyfP/jUfIO0qDGXSPXfA0XqsMTEWHRhGYE0iFQubye0f8i3se2vh2EYxgt6kG4uCu9u3ZN0yqS0uYJ/Xzf49mSSXMBK7bAxK3tZU1Ngl26FqvlZ7K8osMEjJklShrGN9wlhNEqlnzavaW1OvbpxLs7Bto5MYk2cQm0S2bDaN+RZunYQD2ybSlZgD2C1KzPafECsUcGMHMK4ItTQolSdq6DGbOprwrHk94z9zCVnLqi48Gcjmyn3s9ZjO0Z/H/WbAMkcu+x1LRf2fWclZTn8eZJJ6x4fyZU+nBRE9uR75rl1Db+MoNJmvoeW0rpRcjuUxzmmlAslNdpJjgKm3PwPa3Cy7aF69eEMlLYhk7NFfWa/css5c2g2kP6wvI45pWus0N0ZOt7yVvVsItVQmWv2sAF7XXXitjhmfluALbja54B+K0TQ+Sjeny7cxOt/Jstsc30H9ZH6wTRXsa3bk8k7/szfvTNioIugT4JuxMS1W3d6/mbkEbsKFtXS1r/kbOu8thGrd+FBDTZt1EjYVqMlp11iKdpS8NjrNaVhfxpERr1xBiYmVVXzliqydJXq2lCEgGekZ6LysBmSqNmbO3rNPYqRPPivqaEw3W6wnmyuwJbQ8tZqqXtsjU1Fm5U41OqqNbev696bY03N0cUzrtNgQXrzgt5KCXOUrMKQvZVylWyRzwHBpWwwjqogBedAlqxlebZk2GyhWdIEe+d+cJhSNYpLDMM7DIgxnf05mTzmCLxHBUmM1LmtVCglcwMgIQLPAGz1HzvWU1cnY15wdgo8uHBPIwwHzEdIiT+MKZ46D6ROrhEmsg8on9iUQP8A7xy39CvavE86TMgxMRygiz6lixiDE1zj5E4EIwcPriGVYwvvlf6M1rhZAjEifPlExBjP77DIbn4pSXpyEfuJX6PFHaFROS6OY7HlXWeymafiaWshUw39dp7OYArnYgWfk1+znQ6rMzyyT5JkTlPgjjXjK72uOBhTgLqUYQt606dhrY1sddhX8IIw7dynI5kdAU/IbfBQ/kVyutcW5sFnfqFtQ2hLUT6xp1wu5XalxMgc9YwVliFMdldYiv8AXc46pK4kSm+qT2pTKBbGc9hWwwyBq3VsoMEvjtAFWFqj5ZRhbG3wtvoXrxhFMwi65UzeeeBb/cQLjio7E69UE+zGf7n0kcqH3f8AIhMlfr+SGw0+OCmIle3rdjODI/Jk54AUD9Q+uCY875lhavT9ga+zp5xR4Xn3LK75rjOytzg3rMBElGR17QPbK+te2JqWowdbYdB12Kz68RPXKj3V5+fZ7TsbJYXHeOM7BAFPae8dSNeU3PF6Z4iCiRmRjJUBN8+mfsotWlqS/YNYfzbawv7Jzwj/AKh05+uBxi5GDZKYqxIzkwfFNajKrRpGlerqhP4+r2BYAPnXyBV2ZTrtydejzjV1BberUAiYZ3LKBK9bXlH/ABHXPp0+vKnEhs7WwZTauRlDZLMonucEyM/NLKdjbB+SS86wUkP616K3xWa+nE3aaUzHcQTLTKmmslT9cu0DNN4sqac+1aOgcmOfuckpWLLtccVYWw1dpjsURPaMv0flYeqZGL0YjhLQvLqQApJszC5JiNfU4XTpqDaqELghznIjgkmCnagEBvQgY/Q1oMSLXgxXmzklygzszx2IwYHEBWYQiuxOVtcbGApQDyMnA8DEq6crHJMM3FtfQ2fulYFbar1NETX1/r7fWT4gcDqYbaip4zVsLk0WWRZX0Z1gGe5jL3QzCruAa1MnzsFRXyPqU9+YXHACHB2yEIfGGxr8n6SoYA0Wq4lVZ9enfAn6zEjgx2mSMctX0JGzuHMJ22d4ylhrOAGUpJkrssovPaunKW47kh62YuJIeZ4L6ZI9mR/WGxsIA2sBi2QK8gSx1lnA2epNZ7F0XOEPEiNDHinmVckCuGRGo8LzNfIySYmgFTupkdh6wqSVAx1E54KTJi034sk+IiJ+0ZV5XQuurk2o9E5tYcFjK4nOaI7IwETOSY9ZkBzkPSZEc2viarPiE05pezC1xZtgoTnjOdIHK40fIvgCXoqBHykyMhmSjiSKMgiwmTlWo2xNW2iqH5tI4na0zgW9yiR5+srYIyJa9Mnf14xVZ7xnyIjFMI819dr3Rrk4NdScXEQyOOxSPk+6Cxbu6gmjbV2Bt0TbI+6ylk8QRRnMxMs4xf8A9cGqMli+WCY4WF/ZELGDMmGZVrER5nkz0Mi5If8AYzmp+QdWJKM4iR/chI8ncqg6td1bRyUvxdSy4tbrBU0VxE8cAUT7B9ZfDZR/Iib87mP+JP6dZkBS4ysKauCk2LhYxjCmZHPFs5Opohn8gqUUAIxE9R509B9h1ggSVp1Xwtxyef7wSkCXtSXk7iyM63aOO1LFeZmHpJxAlAzniHYVjA9gEhKM9A6722NdH5m3GDt2+d+3Ls4/f/kQRTSJQRD63ps6LLNRi5GeI4qAmbA63XyidPSiZMpG4sW5Ooq+hapIxs226eETJLnFyEl405xwa5eWfj9/riZ8809uXlYvV68WN1+qO1ljRP8Aff7dv6tjbCukNy2Gq3Cjyw9cpt3CcUiMSXXE/BgBRrub4IBczgzOVLNlOJplYAtPWxFCujJmRE5KSlkGMh94GMbEGO11LTsNo2lyFKwZPQ6nJNkj79pooZJTrq0l+PqCO2BCEdmZBFM0W1QixcY0/kWOfdvEXVGl0h37szXnHyGU605OtozN+mQoMPIoZzgNkhLXWoX8V84vVWmZq6fx6v8AsyEOhx5ib4ggYfWnfYBCQzBf9Thcu8hmDSIZt9fYuyzW21FOss8dYqttXnGMNGYUDGMRq5etVCywn6h1cSH9yss6cZVry83aa2kKmtbYyzV88iSHEWepOty0FUWsEtdbGamltnKgPy+OMGIL8/8AYcxLbVv46G2GsMzKSEIjKTAgzvDGFegJqW12CiOIIP358z58C4DgP5Ah3yiLrnIc9y5G03hGwsqizYe059oyTzsc5MmMq2N1avlP9GvNkdsEhiFrY4taDviSv+wFcwQfWB4IusLsbKJwLwiVqyLEN6smQXGR1HJ/WcsxcH21k1oJXn5xAhP1IwgOjJgc3d1aG3GgzKIVWuu63Wor9JjGTGBE4tsAsDXwDQGbHJnH+44nNfXQyxsddrqqVSr0rXoVFdiir8R2CB4kg69RGXEqAtQmSj2jCksnqOSOdCnEL5aGrgh/Grma9YK0deVl+5jj05Hy+sj/ACesn2kvriyjBruLB11w8fXcjO0wXb9EeDyWBrbZAVO4GSMLyJnILiErFlimlSagyMO/8KA6jHYjjiWa1M5OsAsuVPjhCyzjJsIiNQapJm+QGXb6qhV9yox/yBObHexXfr97LA/yX97DcrXWs26u0t2R6NOcoSj5TLGvqmLq009tc+Q8/wDcccFxEqKQnU3V2FWblFLd58D4hF+iyopPxqe9QEbTeDWmjvpeX+RzljdqBFXdpbMbxZZe2aaeLvIvIOwoT9kTh+hOp2WqgQaNeSfsth2kGQn62Ie9wD+nVTGvIsdLarqVyRPmYYzGrlFmuDdjZJ7fh36p1nz2mOeYn7FPY8YltWFrPYMc9p1Trn4fdho+V4WqMorTBNN1eUMJZnjIYaf2ogR6UZsWbELa+m77yK2FAIXCs19RL7Io/wDi/HCtNuZJ5FGciM6elLMZC2BWoors2/yyOYXkD+wX7tpUawrXq9cg97KX2OFBnmE5ELHFKTJwNO5r6usp1i2VFQYf2HhcZVhvrTFrKQ0atc7CRtrsCdcx8xwpiR1Et8QqKUW1pAcRAAJVIKWs6s1Ow8nxtrU2b+4cb682LIVhM3PIhPW3mpNO3eTbm98LZbB9gzajqyQCFP6u/LXIL885cN2h2LJt8mAcyD3dCF5KQjfGtDtzaInX7Dki1PBEsCh/XK+8YpdvbyevHbWDV7kUgLZrVlsZgX7KibuGHQDbumoVjuVYGPW/X62cNQ9vv2+0ZomB8VPj2uop+DITJ8FGSBZokUsnW0ujqFJpWVeTpg8KGSOkGp6DXonD61Mh+NSKw4KAUzH+3+yZntmnoVWVmUahs+FTWq0tMO6lEdc0q6RvSFYK8yMHfMDs8HkAwh0dSi9lSnThNbZquVbD1ydgWKivA/DVtHgF/a2VV6Wza+qTYI3dgClw7K+0Oth7awGsTvXNdsra2NCGRRWRy2tclL6u5V8It7WJaN2htzYbWXYxnZKJYbiIlWam0+PQDeuZav7eym0qV2clpZZ5AtBZCHfm7k5t9nZVaqO+dcMzibcEg/48+p3L+Ql3nV3ZJmgaFTV6yydp+pvixmsd+F1Orf8APdq7Qtp6dnw9ZqG/LOo4Cp6yWq+HcYFnVWlvq6gviFXs8Xq81rFKn6zwxgbOl5hs6gV2orlaiQIYZTYC9TQl9hurtrluqsqVT17rNkqprzX6wm0dZqXzZLU2ltqak51Wv1l35ez1lib6dPa/Gp1NtrrWjelqdXcIewePIzHcIaEh1FgQPcPQCDzMV9eY7kK5wYWIgUFnX+yI4mRjzlIkYqgI8QiDGZkg7xCxE/jhIwP2iOJEYlZf9O4EcAmTD/p/XOD5gXYOPQeBJfp3CB5DrJB6mcQX/8QAJxEAAgEEAgEFAQEBAQEAAAAAAAECAxESIRMxQQQQIlFhFDIwQoH/2gAIAQMBAT8BW9GEhRZgxwZi2zFmLMDjMTBmDFFmDsYSMHcwftH06j5H8bkIqauSoX8l8dFKLkcKJ3i9FG8ns44knJMpLPs4bdFT4uxFcjFQt5Kvw0QWch+mUvIqzlo67Mmlc58hpCyfQq3gimfoptiTTLuLuKo5uxd/+iOtn9HgbfkV29D9QzgXgd8rsvfQvjsk2ynktI4fLRtFOG7yMYkoWEnKxxOPRK7d2Rk0WM2UoybxOCI20OjF7K8VB6Mi56bciwtm7lxX9kipplzJlGlGUSMFDZtjeh1537G5VCFK72fzwFHiP247+GRvezHY+T6ZsbxRwqbyZKhCxxsjUlDRRrScvky4rs/mdimmtDIofZZfRzRWiVdeD+hka8bCqRn7R2SRsqQc2SoOI2yDV+iLuON/IoNdsuvsqyxemf0SsN3IRyOMasRk49D9RJlBru5pnHL7IqxJ2diVvoccTKZGX4ScbD96dJNbFFQXxHGyuTpxl2VIY9e9L/WzJDn+GUvKFBE6jj2Zsu30L47kJRZUgkte3YpTjLvQ6v6Jzf8Asv7RhGx8Y7GpeDK2jkfbIzk0ZvyLAloyyWLOLHRyYa7O1cVNscGhUoraONsULMlLAi+SV2cSe2SqXEtfIbj4OSSJ+mcfZVPsU4ss35MRK7Mf32/+DMC36OFza8nJFEp3Ipt2F6RvslDLR/NFFWKjLRcuRXxuO6G3YgshU/0emNuwl5K2kX9qEIyeyPple4kTqWRKpUXkalLZxysccjqImSmPRkxuyuRl+GRUV1o45DpsTlDop1Z32KSHSaVxyT0RofZKEYbORWIU1JXHRsrnIiNJtXOB/ZOOGyMlJ2OAqx4xTVziTJ0sUKSejhkQlyHEiVdwdiD5B0bnNh8bEanIOmn4HUcND9RoT5TBDrYaMubwKkkSqunpkJupo4kOs4Owvj0zkd+y99svj0ckrkvl2f56HKSJNvs19GUkhSkNZEW49HI/I97YpYuyM39js9v/AIXMmXMmX/4f/8QAIREAAwADAAMBAQADAAAAAAAAAAEREBIhAiAxMEEyUXH/2gAIAQIBAT8B94TEJ+D8ylN4UbNilLimwmWGxSm+eExzF4fC48mfCDxB4pUcxwcZwSQ3hM4Kf0TQ5jg2i58cQf4ImH6JHw2On31npWbEo8336Q7l+sH4j9F01w3hD6aj9ILxKRZQsNjKITy8LpCiRD4f8J6cIc/npqcxBpHw2ZNheMNjWj4UpSlF40+I2ND/ABNsXHSlQ6/hr/spFSIUWH4v+Hjz6VFeGbYomQgikQyn04in0hBsuISnwuEMrF0g6V+lJSENimxtjY2xsbFuNhMZsbFNj5n4UnqsQ+F9IcOY4cOHDhEaoiOHCJnM8/Ofl//EADUQAAEDAwIFAwIFBAMAAwAAAAEAAhEDEiExQQQTIlFhMnGRI4EUM0JSoRAkYnKSscGC4fD/2gAIAQEABj8CdlRzN03q8J2VtrCmJT8L+Fc4glZOUbHG2OyMHKFxj7IQfJTrjndanVNiZTslaOhGdUPVrlNyj1FGD/C6XeUJ99EbHH4R6j5TW4zutek6f09KbEdkSfherdNl8Im6UerdVGcqS2Wr8U4GyY03VOk2gRdDVUpcpzi3ByvxBbazG26YDdKqNIdcMao1ZMTH3WWO95lco0CajPOE4OEOY2bfCLWUnOzqqT+UXc0S1MoNptHMPqlVKbGU4b06r8SW07jUsA+yptcKXbRPpUXttA1RdULGkOhVGgsAmNFQ4hpYXvkEFUqdQU7XEMxsqtINpQCWyncZYyWutLZQvofBTWmm52/2VR2W2Nud4CeDRuZ3lMrmm62pNv2QY4OBOAJVuTrMFNqOm1xIHum02zJ9IPdFnKPmMIcU2mbXOtjym0zRLHOwPdPpGnMSCuYxm8Ks+s5+GEjyV+GAfEyQqFWnTfzBlx1XGPrNr85jOkRq5fhqgqNa11xaQqPEfUFe/QhVqtZ0O1iF+GpS6TdHlU3Mp1Htt6iO65vGU60H1kiEbKFZsgjp7dlXrVGVGOZFnTqmU3F77QIHYJ34eQyekgqs97mX1WwCckIfVp2TGipclzKdgs9OqcanEsdUZ4Q5dTfsqlOrVAvG7UHs4pvLLo0VLkGkxzQGHp1RqVnU3dJEWp1AOuaP2lU6gaeYHdWdtlSp13vLbYnXbCqNZR4gB2HQ06Ku6pRfzccsTqmcPya5DSbZb8qnxAa7ABd/i5PL35yZ8qlwtSeUHz6UeSagDHSxyq1OKZWDHNJDo3TKLadYsunIwuZRa8NGQuIfWNQGwlp7lWtqVB7FHre27WFIME7kqkKtdklOIc3KLm2uN0khS8OWUHcO8h/ZUg6k24+rOitjBT6jbPSYzunNqOkeDhfl691D9PCdZXeDYdcLoql3mUJqGQJ9SL6NW6dV6gupwXLbVJ3IlMIqEiJ1VYHiD6DPVopoOe4+WqXMlS0OafdOZUcwgtjJzKOmOyDm0w45nKLfTS791rPlYHwqbWjAMmU+S2NghdUY2DqnnmtLY0lQx9RqxcrHU3NPlNcG+pNl56fOiik8gWWZVCnzHX5vysjC6hHumltzZ0hU6THt+nOdSU38M9xMAkkbq2oXGo6pr4hYc5Bw0OBhPqREBTOUaI0mZTxh97bZcgymxxdtCD3Nflw0OydLHljU42jqbbDkHh0lu04RfOuqsHYlRbCtcYIVNzi4i4XJ9jjy3OmFT5FXaXyNCn1ajoDoENOFDm5QNpzog8Oj2KrHh6hsLY/hUhLpAgqXG/yTKthXt4erHhOc6hMCEGGjjQYRiAOyw1WuA+6ZUqsDnF5zCe91PIaU2TYBoQiae53WyG6GJzoqI5IVWyj3KJFLlHtC6pXSACmuYz6W5VrrdY1VXltFx0UEQf1ArAha47Itbw0AD1d1PJHqn+EC1keVlQpxCsruODgd0+5gJtTGmlInCrimG2g9ONFLWqMBA1mXEmAU76EuLYOEAKJx2VfmufzIkYxK6n4mdFTwLyM4VRtWo0NaycoOcBAVN9OiBzJtAXEHlACnSvjuuVU4cDJOCmupGGuMZXqJQ1hVa9v5bdNlSp1RO2FUphk2iCfK4gVRRaabJE7pmdT2VSlTdIarGvFo3IX1asn3XRVkdii+o6Xe2FRrNdkuIMJwqGmLWSLwj9JuRiChXtyTb7FPpPA6m/Cb3asErDlNl7m65XERRawtpmp8bJgq0hCfSZTAeNSN1WucxpayR5XMd1K2iQGiNGp/4lx9JOG7p3Kd0k/rCi3CgN8rh6z2yy+TjsVWI4Z4aXYhuqd/ak13PHvams5LpnSFXFCny6ZFsDAIVeoKLuaHgsPhM4fkvlzpwqjGMeGT0qq99N8BvT5UVnlv+KaZFwRmpLijaA4ATK4eKbQ9jiSFVDm7QQoLHM+ykNPwoILfsnGlTLZaRKpXM6XP1JVZ1KkLdV9R0eEGvqXNUtqW9oVXmBxAb0kItex7SNlw/EcqpfebpG2yZdRdySZcqrWMcyZHbC4R7aHXLr3R8Kk48OXU2u65CqBvDusnogbJtP8ADltUVZGMwi2r+nRQ1uVJDh7IyV3KAdViPCyXBAfymvaR4RLoJyNEWCICDgRhS4tkaJwBaYEr+4pcqP8AHVYn5V1sDbyouK/UB7qWV3XLLQSoFzI1Utp/KMPLG+Fh7jGi/UCFE+NV1MjwsHPlFr6IphoxjVEvc03eEGFwgygQW51TnPDTIjRWSLdF1QSe26dLiEQHlv2Re7q8rpOFi5egn7ropF1SFirldEPKnisu/aqZsIEftToD8DssiEz6XdSaemJRFm2VY0ytD8oioyRuppt1+Vhjo/p+72WaGVimR2UyD47LpBXU1w90RZ1x9lLGoHPypb1YT4ZrplfleIR6YnROgHTULIdnwiKzLTGDanNYLmdyFmp0qHg1WnXwvo0yQtD8qJJPaFLGOym84gE9gnNbV8oPfUuI2QF4z4TiHiES6rbvlN6nR3DcLFTXOdlUtrAXN+FGDG/daY8KHMgIMbTDkOlkz+5ONJo8CVaWR4K6lKH08blNlomc51TiKTHD3V0ZUhkELIHynVOYG9MWpw5jcJoa97jrjKg1YcMwRBXQ/wCUOtq5bnDuiebLdVeaklEAdPhZaQtZ9ws0jhBpa+EwNan20/KmG6ymh5pT7p7WvpEa4Ka8PY5naVaGK4kQukNjsU4uoWv/AMUAJAKLy1xYPGqNlOmTuShD4hYcUX8wk+VkFawFbSe8gahddT/tHFN098q2gyJ7bI7P7IOrtdCDeHosYG7ryjIDoXQA13dxRuqMJjugS6iczqhby4907oB3Q6Izlcym0yNgjNNxKxSlEu38IYHwhBTgbk0UmP5e5XUVAk4QPWQBoro6VLMDbupyvpnqWXD2hWSNFc5uu6yC4lRJCusLQ3Q9100y4Igh2Eea00/CMslYzOyfbEdldcEBUIIXSSZUEn7oBoN/8KyHXeES684Uh38JvJBLuwU1GuBLcrV0SunKN0CFaDA9kbrVfUfPgKaH02jRFzqgdshTf9MbrTCGZUh0D/tdPSApcy4LmGkdYkd1grpAQHEPNIeE403OeNNE3lhS5on4RtcYAwhgaqGmJ7L6uXfyoDYE/tWAZKNtdweNowoa35WceFY4OdKczlZ7KNPCwbSd9UR9lrK5jCWvH8poAt7FQa0hBlQWVO69TSAotaU7oeJQBw1Wse9rfeFIulROSqTKjrnlklYdHVqppV2P8dlsUGvNnkZVnPuzJBCAFOlTn9ShlS4KXm5vYKwN0xlD0wienSE4ktEboN54XRVa65HSCIUdK6rdESAQ7ujLgm1S8PO7Tog2GUvZOrUK5dcZiFBa2FaS3PdD64fJRcrmPuYWjZZLi3wh1uEeYTXtJu8phLfhRynqTU6u0L9Np21TarWWSJOVZ0hfXYfHZD6pJHbAXU90dplNfE7FMqUW4ImFlhAG0oGsYG0INbOPKe00/MwiQ1wXp/hNFp0TuwC5LMu910uTamw1ypYZxotE1xacgLoDgN4WWZAlDoIyuY0mQMK2PaCvR91yg2X4WHEWqHvd/wAkLncydMZCDzjtKN0eIXLpMDTHqXW6J1IRh8/ZS6rj2UhRzHENwsXA90L6od2VrmwfGAg6Q7CN9F3sm2U8WougSUBbEoEFvbKcbh2wjLmota+XAoRt2XLaSxc1rmPbuFmnCApUw33Qsqg943VwuCAq7KaNQGSpe4ZGyDZZrEqcFaaK0NmAgKlHqLVa2nH+Tipmfur8NH8poq1C+Ngobc1AvcXbL12lfm/wmkl5RZSfAnVE8wRKbzHdO9qinJfEi4lEmpm2E0NeWppPEh57INnbELFQkTC38L0fKMM2To4a6NrkS/h6lMdhopLn/KH6sqa9NsF2k7K4NgKk1rG3jco3MAk4KILz4hdHMJ8IMfwhE/qKc40okd1Fibc1wlCCRKqO5h84Q5z2s7FdPE3ey+o4jZUrzcxrUPwjn3H4WajUPqAkH5Ti4vkoi5/2U3fCzYB37K1zpneVkgrfxlSZ1UDRYta39xKYx3FNlrd1Zzpb4ahy6pkbQhc8jQ4T4cj1nKALpkraIypp1Q2Mkq4m8d5lbr6Yn3TWPrxbsTKeQROoEaIEYXr0KIDygRUIzKHNfDSNVNOq6f8AVPu4lonGUK9Cu1/TooiCgj2XVr5U3K6o5v8Ai1ASBPZaj4UOaoGCgD22WHIXHwFdyyh0KMo+6yJWNfC4dznRuRCfLmd0YLMmdE0OsyibQrHM3nVXUy5/hyh1N4+y/LIHchMc+97m58J0MHyh6cLNkBWhzV0PZMyi1+WgYwj0/wBMTqpDVa2mULxbsoqHQK4EoaQApDZWya4tL/dSyWv0hp/pJQf6WN/UQpqVGaZTIr0S4YMIvZaW+FJXqJQ6yPZNtuMbEo2VA0f6ptKq7odqULfsU6J7a7L9WqENcnYcph2qGoTpuz52TO07ovpfmLFW2f8AFQdSdRhA3vBHdZK9Uq0JralSm0nVO5dahkYgr6T2yNBGqLKrSHdoRTG1bgwmEIpT5zKi5w+6DelHmUmVGHZE8lo8JttGmJyhRFYM/wBSiXEuPeVkIBxgeAiHOtB+U0BziZzhfQvt8hetyxaf9lyvw9Gdbuy/NYSNUTT6p0CayuIJTIf8p31G9l+Y05hXuJJhdTejwUKbnCU6tSFKu0Zhfl0m+wRNxWpIWS+6cyFeyofCbaYM/ZYC0whbWc0HaVzq4pvnIyoNJgwmlvDNv2ch6cLRqDekSpdluye5oTALvGU+pTeBLsBymy4BQ1uymqzGyLi5Rkpr6dSiD+0lfWjHZAC3WNFDOIcwn0sboowVkIcyhc7udFIcaYGgBRLauusqOc//AJKOJo8wj5R5bS0diVgfdfVrupNO7SmklpP7iESY+yHJfRY06kojDo3aVrCbS9XZX2K2wkoSWt7yrXEnqzGkLQ6K0DMprnESFm1RfCZTcL/KqOuc0jH3TYfouokwU8B0e4Tbbey6ajAB+lFtoP8AquoNHkq6pDnA6KXOtB2Ry75XMcC/3XMbFLG5VjWgwfVKL6tSl8qC2UOsBSQHK2WNP+SBFlQe6cS5rY2Rpil99UGVHO8ZX03OCFCsJ7P/APVcwtIUWaoVLmM7INqFrtpTTcNIWZMpsP7qHPOcIFjC7MK4v+yknVSCYTQKEuB1Lk5vSU2FJcAWnREdJCatm+yOGuiMlBzWsU8ubN41QDp8ytE3rd7IsaXlCyqR7hXV3XnbKBjVZcukz9lDwVYawt7epXXPPdXFztVLjJ2KwgGsc4GNlSlgFw0IQFrMqZjwtAMoQiXvAnsiwRExKu/7GimxtQXZzoulpaD5XWXEqC7VYcVAj5X1II7pkSXRJXphCe26BiRuoLChcHWxlWt9Z1lFxYJlAVTa3dGs2sQTpDlqLVh+FgIMNIGAvyB90foK8MAXqtK6XZ8rl8VUtuGy6KnX/svThAQA2YTTTDs6IEglOtYfCjCE9lUlmF9HSNDopws4+6y5YcsYQZYHT3V7uk/tCAIjH7kbbTvlE3Rumh1TacLD3IzUkkprS/Vc/ndbv06oGddkRKtqXOYg2kOb53X5JX1cFR/UeVeKchGaBwrnEufHTGgUlxnytSuXUqWifVCpsZUJDdDKBv8AOqfFQ4Xrcm/UnEotwfdF0z90BluNij0NcB+r+mihF5c42icFFopVdd+ypfQcXOaH6qoTSktyYys04z7oUxRkgByrOLA0MF2qF1ERMph5RdzG3NQHKqUqhENtRZ67TCB5eqb+Kb0eE1r+g9gEK34lobP6sZTqcsLAcW7qHLRaIP7JorV6VN86Tqn06lU3T2TXinl35ZAQlsoN5cJ3FVnvLGmIaqVMcMQ1jYlMaKfW4B2VUbyw023DOqINDeVQqGnHMEj5ThyjgTOqI5MiZwf/ABUDynW1W3Y7KoA2s0gSsun7rA/hYaFVDCIqNsK53MMSqPPLs4x2Tmi7sm5gzoVc4uc6M+ytTaxDxL4g9oTWNvcdBlc3hb4aMOKdUdMkzpqm09bcNCtv07KvUqVstpF5x2TeHltocXJrXlp6Qekr0EwhbsulhctFw9a6n1i4ALjKznhrm0zV0TKLn9NP0plWZB18KXnXdVOFYHWPMuG6oVAHyfzJ2TGy45jVOY4P6SQCd0XMB+FTa5/Sz0zsnwTBxKq1xfLXD4VHh3vIswDGyq9cuILDKdGYQFrVENPuo/CMMtOmyFP8M0/pjZHkUGNwubWYLjtGi6zr4XRUtJ8o1apaTtK/D1GB57H/APeEDRpMZIglPby4pzEhQfV7q5uPsgCOa7dObyLA4feE2oaDnEnAOidR5IBbiUGAQpyPsiudZd3ndM5vDYm0QMhVeWx2e+4Rczh7cyVAd07DsurH8K7hxKPPY1p9MJtRnDsCuxaRglct9WB4wChBVrhcPZOpOY00wPlNqM4Vkn1FVajuFa+1sBQ2jTb3U6/dOYWG4bgoNsNvcFMucRTDu226cKLnhm2E4XYYyVy2N6kWOZnyjmKaY17rWl2pan02w8M0PdHqcQcwsi5AupwDpK5lGkWHy5HqEERCZey4T1YWGDrdiEWOpZGqDtJVhbK54pw0mNN1yxTbddPhEtxiNFbUzhW8m33KHMpwYnIRdRJ8wnMebic3KjXZUF5dBYqjSYdHThXPALk6qGGwapxp4taXIkPdkZTbHuFW7qxsqpq3GpsAiSyPAKvY2BPdV3uYLmsz1aL+3Lo8orMSiGUvT6sZKY91MNfmZCr1H0mnp1CPKaWD3X7l6USGfUGs6px/CA9XZUr6LfHZOa1wi4xCjVRgoc1gNSelVnGkxzt1T+mwZ9kLqFM/ZEOYw0we+6PKGNpU6qZT3cQGvIePhU7uHa77bKo3kBoOvsv7dptWmSup32Qa6j1WnXKdTtbBxCLadKBqOnCc6myzvjC2IWvuntqgvdbuUOUy5vcOVYVqeWN6vZHkBwZ7qjb6qjL9VW4h1rzSjfui2k5jBOwXBua/Lm3u+VxQr2OsbcNpUtGPdUyNHCQqhqVLQ0SU7kNaLhGU2vDCTU5Yzr5VKmGM6ulO5dMMdOcr8Rd+u1MY7f8AhB9Oix9p76p9V4i0x7pl1EzELlBpbOhVSkyiC2dSi8N3iGlU2Th5gFPa/NpjVOfQpNABg+6o0y1gkhrs6KrShm7I1TuoMcGyMrVWu1idU7pbIYXXEo9YHVOAm8upgsa6NdQhRe1kvJyE4tIt3ymb3sD9e6cbTzA3M9keVTFuyLeTZnUaQm2gXfq9lTdVoWUwRLT2VQmj0kzgptCnRp8y+4k6wmO4rhwabRo5VAKJiVXNSiDUcOnq0TRxlBxpNYYyi19Is/2wqzzSfdb09pQo8mpYCYBQspmDpCr1K1KXOb0CVyuXUidIxKbbeDaCSe6c4h4DWz7rlODyVw34enVywXyP1KjUosqxyxd/sq19/S2WoshwnZcPUpMqmWycaOTncRScQQcnuiwUyfYqm8UjfqYT3cVRq7yd5VtkR3XFczhn3wDSKu4qjLSz9TkWimT2gyuID+HHNcRYTsqL30Ba0gm/snv4ej6ziFUa6m0VLw5v/qDXUbI76OCJpNkHYKTwzdcKTPygPKEA/KP0rvdYH2Xp0X5YKmNf8lLWxHlOdUpXnRYNg+UGtnHmUJMQjEHypneShcBjOU61rfhAgN1nRZA8INdCNrW5zojhszOiYiBBRlwHhTmF6oPaZlZo3E41RaBhNlsezlFm/wAJ3RC0hH6f/wBI4LfugQIQ9+6gPt/+S//EACUQAQACAgIBAwUBAQAAAAAAAAEAESExQVFhcYGRobHB0fDh8f/aAAgBAQABPyEos9ntC7RxBPmUU717IXNvAnUW8BVmWOyjCmo9GHFXWZpsW6dwXzfxc0q+hG5UeCzKiyNJzC6EVbpLltdNw6tiNOpstXDxLSaVa6hcMnbxNpRJVSqpwzfUVxpb2THHopOpdNhfWp0QJXKoE7e2czcivQzHAjFj2lO3e3MvY0uEd1wAOf8AstMBQm4oDa0viAsVaRqob1qyk548faJ8BgbLxCKrMlwXRxQsjpdkvvmEVG6ekVroWxyv+zjqoJmJBgi+ws14mZr8Xm4sS1gpnDNcCxHVPWd1ihexGTCpvAtfudyiNw249ZVhIQIWdxoi6QrzCV9fhr0me2M7Xn/Ih3W2uVynIUvhHIRFi7smKSCHcvoQHkRqQcErWIVPZgm24+8Ly+Zr2fMyg6l5kGO/KFSGWonC0uPcweIcTIBRxdfaYoL3q1wZUFxV/wAyiasKBT89ziq83huADggekazoIlhmvuRT3g3BYCQznhFDFsqmOV0N3WyUKdac8OZyoK4zqOfq74Rxi/SZCkKx/g1GomcT/r+8s1sVsYNRSiasVvUHmdYoVTdw6hTBf+Y+PubbdY/EXWiN32IXGq1mTmJ15LtH/YxCbrJ6xMust27u+5QDC3Z+sMURp9dl9IAG+w2SpJTllAc4ZszvcueowvX1ht2JFSnMPX21YtKH2jWUXS0+amRgmumH7QfP8YC2lQQUAHowFPOQrsfH3mH+7QC9pUuZwYPTiZwC07/lxxCm5ZzuBBFcW4M08/5LGDdemIxeFyxvPvDVYc10gXz3Fv5DdzKRG7qmE0WtG4kXjuHFdF+MN0/WPvIRJQgoxzVcS4FfeYD0D1AegAKxGImjQpLHIcPtzB0HBf8AriNy6KoMYS4dCAI1rhc3eCNPmHa8b8tQqUmOi81Fut6Xn19Z2YM6uOFUeSemq6j+JRhhedysmqH6k8x0wC0OOGUnDThHEAGD6HmGeksu97gPNYNceJe/HVD6uoR9TLMKDb0iNpo7OKIeD3E1A3I2XmaEWBV71Kgi8grLEFb9IqFuBTBjOVc3w/dmfIWC7l1xLalKbZ1bnm4lQcpHOD4+0yVZbjMRq0e6L5mSrJa4LJsZzF4qoBVMx7f4UxbSJTW9OYkS3gsZvTHEOYTe9xbKYzIlH1lLeoQO4qXF0OZe76geUaecVOOtS0tcgqr5jyU2NEMpi74RE2PYYlJ6LDFrFU0Sha4nVw526hYXiHKcXnNR7KEVT29phE84RvYcR3Du6pU6xC8ka8IGve4lMUVe9+upZrYzYR0sjqXIFyEJn73TMRYu140xsMtPjqIrq5bx8zoOqu04DPBVaK+ssJsW3iPlof68+0o3dwQcW4eoTOY5ahOLitd5hVrdOqrMCqygDQ5Zgdm3BxuCSyT6yk80czJJndzZ/fSF4bQa5Zakmb+Y5UmrBYJU8SsVU/mIKV1QVv8AWNZo5Lr3TEioslcauVFOdrbG9XpUBq9xTyweG5Tym+L8t3j6wpod8uzCaO2O+pkA1wJLbyK57hJ8U/xFguCSNJMKGo7cnluFcysB1Gv91LltWNER59o+XQ0z0RBpshj2lo7ARxi9xhFTNmlFSrmCqaeKhZjlFaJNQUULNWRQQ0BojUAQF6srKS/gBGnWvLtr+5msdJgbg7F1dF/1zq92SQ2vw6wxVVjLCa5LoAiMP7BhNfSVEysGzi4NQsJogcRTGmGCXjTdCU6qZB5qHkajUZbaphNJ+bgsTzFtrCldqpTtjsWNbIuNSGF5dRbvbqHhzlQLVs1dIKMfy53Ahbf0nYU8ZYSxtP8AnEddc+ByEWWNsfCAZQxpAN/5L6KrlvzKzTcMD7pHUiRh7xXBdoVDVH1/iHsvLdJ4gHLV6tepb20rt8cEAHEZIs0h9nvEZOwAH3ghjDWRuv8AkVLa7t759Yc0hrOT+oo0wuy38QoHnUJZEVrPIysh0Fwl87hTKAthdB5hk5hpx5ghZcnrHFq4X5VMkI1YXq+ZvHmj6TRtUIlKy/u4mX+SuCsDLKT3WvxErUGTtLLLD9xthr3gctqrDLGphI3Oan7g+isafPzMJHLF49ZUWV4/4hJQfOJiqvdDX1uUUhUBSy412dwdvC0O68X6w+El3D/rZcCOgxAxKwCWkO3My9LSQ6lADjVUDIXtfs5iXdjcKSsduX4gKLPeeIqw+oQxeCtt1cxnKVcy4Wiw1cWsbl5+8R3bFuPkKC1VxavIdtMRMo4LpLlGYXlUeLAZDKZfKGPwlSqGh+YwZWqupcCdXMFWPKRpPY0lIJHW0FJhKPJ7y/aC7bW+I99GmnHszIBtfMov0GGrH0/EZ04rxoge1ewdb1Ch292a+s8CwYp7d+lyirqGRzLToLjt6x+dBGOKA6XjvE6uCk8/edjFsrflnApz1NQ9bvGenrFvtEKgaFrBkoI2t/aVYUl9zesUzA+ZDdttzDdGxfiD9MpuKu3XtcCL4RLVKUvod5euoKqaFxdS9SqdNrj/ADSzrBKNWgDD/CYIW7qmHGr4Sx8t1kzHOHTK3NECLRXokwxPBldzhpbONQ7AS+Coh2Sjr/sGtb2SnTHoBKlJSq7/AFAWhLAwpoqLX1zBlpvoRuFrIx97dzBQZPaXAUvae8FZjChYUUbKFGz4RNqHE40i3WvNjP6n0TU90Dao9Y6oK6isIt9WNiB/yJ3UVUm+MXmY0WRSaO7HC9wF9OBxgc4V50fEKslsFRz1yDmItBOrMurKLLvcuDJvDn7xFENmtlOpr8sQzpwrhzL2ti6/qjvDAEMkwxAb3X0ghVl659ISzqlxjTLco9u5cDj4bYUXugHEFzrd1iosZquaU5nAUbw1UTCeC+JcW85wIjAD+DLpMtWT6RVUV0urgt+aAxnwR1GJFyEo0fbbEz3inPWI6BCqSCIurb6StSsspb+kvRfkdR81+73cMth3HFwqFp0BDAqzeWFpWm8aEuIVsGxdRNlSdivSKv0sNU9YmcjOX3mDGhuFaniavdyoGyVSqNYA3NCMRlqGkuMsUqLO1XDOIJFl9qw9wB5+gK8ExqL7cavMXTnbtURgo3ngTe+uD2mUuvtCckXfrOmv7MLWoHT+YEb46rh85ipD2si7LPjLcvXb2t9z3G1Rr61Hd66XODxUbrt0/KaQ7A7r9y+sWbwr6QVZ0rn0hIFnBTFjMYcfGNIA5WCSPC8XELHrv8zG+4XumZAXccqgxUsWr5uJqkvNXPRBOLm569yfuYtF5ZmVZba+GOH9x2VS73pnFIW18kqDhTmn5h5b/Xg1XiL8WksboLepvQ60kVLBxRA6M0Q3FK6NyhMU9zDlQMjNkypHCr/cvsXFftKlmug4gtIxQ7yVDNZXVUL7uJTu+RK7u3/kZZChyuXrElS19ajLvDbe/ETtelv1mIBW4P2lwhm+8X9peivRSIodSb9I0RhY6G3txATQM3gR/eLSzyyzH28mTcUsP9r4jtD2pQSp4OJTWVQDm/eJamdZZE7qcUbPGNqr0haBcGaFbjdzhA+Ko+5LOEoCoLjhSc8S3Boqxv3hJqv4wcngvZD/AHO4FNVtx5lCqjKP5l/UAv8AVzfElFJUZCvz1de8didBiKmyBtXrPWWUESWedSjAcI0gDP4wV/5FpGSeCMGLuzMoGhnkfWDUjRoEeRUop23Mh0zBeZjBgsy6Ep4L3DXfCHIlVL1CpFrqxxNgLAQckGqR1/Mp7l618x/1nN6S+NdE5jOdvJlfSlGcx2McpPfnrVeZl6bvOpmqYAMWTLKgba9pUQvQ3espAeE/SOzUKRZcdVDVl5V/2MypNGuuYBy2yijKG2ktuecmsDD3uX1ekFy+NH0i6XmSz6JQ1Ol8f30iPXmXzmCJgDQf39mXsnTbcE/Ca1JeQBdlrI9rdVW5gi7dbblhcBaYDAS5YYmfBtrQ73Cx0OXcuQKYUs/rlxlm0OSMa3dt7mCECtvc1bhRCRfnuZFjAsju1dYgkTMXjxLns6VXxN143FNgiXPPUNEyhPHmFjubdl/swoIh/VxA2ovnTuUox8Fymr82tX34gwEHiW1fUoKheH/qNo/DZl1Y6zdQJqIH2lcRxvyeY0Kox0YlhvkFeDwvLn5jbS4eT/YDUYUxUbiAQ9Jxh5sBaaoqlyE0kEodArOosm5ehig06RdEHFpxKShnQkoKNN9xcilzfA8Sw6WDlZpoU1tmNjkHerj0rD4RygPAgN6hXrHRx5XzGqcTfU8AMb5jRDbLBf6gJtmjTH1g8zfLwo0kGjb8y1Ru9Szf8qSpoU9CYR+MJbUXBLctpQz72kDI7YHIX5ggytwd+kZhhoH+Tgg1xVjOJuGl0puypd0DNUN0NeHmNdKsAxg3sdZlfyqcjLzgqq6esQhVrlLbRORHjrEdPh9YfExqv1Er0Zb8ziMFzj1iXQRzZBGmtedHiWWRQ1fJKcRQGeZgx3SeYViBH5xBCYWYei8cBL4QQvrjcCVMlMf5MSkRu934lhqlubp754lnZyYYE3j+j9R1yXHEAGo1DeEJwKv3jqJHqt35lFyAg2P14mME5KlF3wnSCoEvull5FUMur5WhKsbibahfSBq1qoQoxCqxK66BMn8FubpgZwtd3E4lCrlTaNac1LW54oX/AJMghUaXtLCZIW3cRBLeioHDzV+pZx9gIMyWrI1VL3RFJwteZfEGhu2A2aMJfpWGbEE6KcSsQ8lXl1MtyOGMxKrWOZXMtsHmVFnptUxTb0xEKUsLnhd+PSXAnk8e5LKqOMj7E2qvVTZo5sR4oND1QAspe3Et0ujoqarzCn2mTKesvgA5pwmP3NyRtcqJXDGaI6lQ+hKb7lviOCbQfymbZLKKow241U1MpfpGLQ4rVUdpDmjOJt/DAQcUrMyIIAvHsnmEZtZKPaPfmZbOma3GKrdriYMsVD6SyyXfCxzLKUTwzIGUlNasqz4zKp+e3O6lo9cYlyIXhmHEVg7qZEq7zTNSqfrNbQ4Qga6Htcyh9/VzKHoc5V75l0byJuqlIHTbRB93gZ8BEQdptj4gWvgGZt1HQiqoLuzXcdrqwJAXljUfU0k9pbcbxRv5h6FLAriOx86JaQcckIRpwt4mPxeb4uPDRaYvEFjavPEwMNp3xDvAMAUpojZuKUArHv1BSl6Jr/JaGNt1PSUphDYyTK2ybpbxXUK5PWY4qJeJTXU0DFYrEpbsqfB4hMM7ZFETDs8kUnIhxcEObRVY9Y5puiEIC7NwobgWZhN1QnmXwBo84hAg8Zqczf6orS76uepmG1eCX+IbuNnbUtjiEZ0uaqlPDZG427sXHmGNFe6Hc/snqeJaIoUGD6xRmDY/35geAClDbYpocHcHtzI9Iko4Gm+I4tsVYY+0qT22nHxCDEvdiJDDZBCHbo1NVdNK0uxxSXVZsIaje9q6yoa2C61mo9bgtfSr2PeV3psyuXVs4PmeVaKxEfa3MXcHmXC7Na8zFoxgvmNUbbPe/MpBeGVcy1XWRderLj4hGFkI2zxDBeyrniZ0MNfhu2Ozzm99InMvTU91Gtc5QGNL2lZSi7S9sIjhef8AJaypvsHdQhnXCDR4bLmHqZwqWIig390UryqtYhga3jpKl3HSz5ln+cgV9YIgboPCXCi0a1xKCd5sXK+/0VG5S0qtl8EwtHUHBaBXqeI7yf1RCqyUkgg5dy+MSowVRtw1EQBZEu40EPbcGMc96vUy5iFBszz/AJLJAH1lmJWQDRmMrHFj+uZFGPBcvVjQeJfVNLXuY8XdIOwvYkBRtW9XnL3L1MWpQHb+omdd8mJGjqlzICyhdfkaCMZKco+5E7FV8TjlctkiaZBw6iRWdCE+ZU46OMsJyfq/qlYmnxEY1bnNv+sNnVKin+dQUrauy4ODfDRNgNlzDV4b9sQPA24z4i05i71MGelGcSnDRp6TOhXnmouKXoDV+8yyuWGZy64L1KDuNCZdS7xmPy1zW4C47ES8BXFVcPaVjDC9ZQ+6Daro7LicSHU37iw+aLRBrDb+594IiqPGj9zHCU4DKby6Kyy5hrvz3mP3qZF6/R4mYY6O5ZVqntOZa44SrM1in4h7ruFPSZ2qBV9ZmJ7o6xEriVWOSYUB5xEMgrslwwYZdSufeIvfX0xNI2yDiWcHQTbi5QAK4zFiaHDqWRRQBuagyag5vkCunzGlHMGf4jlcpblAR+0F7YuDNQco3q3CU1ugM+0pSmwubzxLM8zq9xj3rXlCiVOGpfANl2O5mNHNzczHP4Mx3Vo5s7neGF1DcxlZnqI+Ud5jXN2KW5k5DtxiYGdbph1dF0dJWYt5XEdUSaGtS5s4FJUKkdqhBOoLC9SoK7BlCDFtycR16qszFeqq9Z5lquooe/aLfNTT5qZv4Z7hQ7pt5mBfDneYgLqCch8zHS/ekiqzF0hFEUXiVPbnJHNv7o2W0o9EBd5Zg7greJ2uATtFWfaBBzOR3NwcKjMLJzFvNSqysMofaI+6FoswV4re3nxELzNoYqXlN8dXLTdtU5viotTq4NDyQ81a8sfatm6npBOZWl17zNjvvE07nA8yzDhuPbLk4mb1wfl7ivFPCLdgviFA0/3QNKWtrvbFhhQFwuNZiZGB+0oExN2uIljUxNwgdS7GbnNc3Vg+IvwBvaRs6Bk5jtWXlPeFMPzpg4YdOyG8XRfxlwzqqLJikykAVSjz1KWwSzper5jfVA0u1e2PrCdWFdFIP5jPwpwHweYqkvezSYgZ3uDV18yhgVzdQSm654gcR57uomweg1MvWCpuuLmSRcotyP8AJWTOPg7l8S/zALCL9YeJrmoxMbExeDKB0jutFg2nkluHN7KUUAPExdBRl1BmKMKz5l7sWwviXWtBhTkjMERcV6PMCQKzW51Mk4lV4KUsZlyZaUfaEC69M9V/MSh2CMH+fuNYAlwVfesRCdTH4EU2ae+O1UTNPUFLy3YfuVc5qGc+YBKOHVSJYKrHaPEs5IGSnchV0DE3IjejiYSrwqhh/eIxKWjKiAzYGhRjPtFBLcYQMS5KELsNxvtKOT47V1HYZx5tiwPJ7iOu95LAxFm3iLIl4YQRR0XiW+M2ap5j1YQbaxFVrKK1e4art4G0bSFoNOv+w2sAE+XpGiTQadNcRfLrlbFzHVIqpcvY8qQ2QtOot1Kpr7kRqQHK0Lf2gywZSzDfcrAEi+RxFeJz08TNlPL+JiV3hYJuLK0l+FhilplrT8Qtwu/mdluGMKtt5cIPqVDFZg01UZfLKwaDVZzn6p6hI5zcpGor2EPT7MAW4Yz/ABlVT2KAnBlYFPUhOKFpt6t14jmF5KNVj9yxs71zA2AGS9PefaOOc3eBCm+kr7zCQY5BcvXEbdttDwkuBUbtYnCaYUHkU1XpGklXCV8IYgB7/dM5GYoV9sQBtl3TZ7R3GBbWnuX7ufMLGNaHgFAypX3ueKQvM7hDqqaptxK8MoKsv+ZyOD6bvePEXHqukWsG8sANLSFkzZS63+YdiDPNO0yFwJzplyy53dvtA9ldWfeeQE9M01C63mVeQ6gvP9xBU+njxz7szlJB4v0mlF6XFEBuqrIdvPoL6TAh1SYshg8OBjIvNgFV0QWkfgbhIa+yHlc8al+/DFeENLb5oRoS6y0eZisdqauFJVXsuA6pQ8Mr4j7MyxrdxjAe5AGH0c4/H7loFtSpdcS33E2/1TC0NlqVevcAmv7iDNIACyaELHra94H+BUofjxCR8M4v9U4ihT/qKuUI23zLu2fGJUKem5VdvAcRdMuC3PMpagspbX/Iu5dKOb4ics9X3lYVre6qa2WeA/MQXIeg9NVNwq/or7eIMs0kKp6QbbAHAvEyBdPFTsAuoS7eZaL8eYovoCrRzLTEY1t4joM5fzlJXvTxxzUHD5+SNnktsYKCreNSt6kl4o4/uoFUtI7H5EMmKSlFPxHG9rhPlzOAqfEHbc+GKl3Xk6KkE4lomDLnYVmC+F0Clj0id/Ali4ZpLds4qDyVBcoGvVYpTtOmuXAcrwmVH8TI2L1bavmPAN2m5Urcmy7VxK1eksVmPKOWIbB272grHf1TnbBySXNFs4cxTWECvPnqM1oX2u8+8wQrCXzUNhtAh2iEHFs+yEe0kYtPU2EZGHcxxmmqlqcgahpP3KRhCrAYc/SVtAPI6i9Bt+iUr9vbFEMQsssmpjwCrctZ97+kxlO1B/vzFaw2zBmZ8FwXAqzrBccZeJPyQxIIroWQbORQHFxCUuBp6+YR2giuHCbw+7ikxUX2S2I72kukbMlaPDUtJu2Xh7S4wtJ8vMvgH6EBmzhCbKxiAgm1gBV4gq9a4ubkNDkaxGRjb4PzE26scLn/AMgZm0DB3NI+yZvnzGVEQrI3uCY48v8A6VMZhwBXMt3Nekt1cLyxo3a+e4N9rLGIGBsWs54uV8DQA1ZwEOeGujsmtoAnJX6h4U20zO4QUEzcPUa4Byqb/wCTQN8Lo9ZTqwUipX39pxjEqzAOPlcHELOWu0JZAhVEG+Zi24LDbUv6WIYVj4hFaZscV/KlytXPIT3LSE6iIHLKxr2hesW0vPzqWI9tuTzKZY1hF1xqZfwbXcKb7dt+0aBfJS+YFYmC+5Z7VY29KmAGgGtioIBuNlB8RHYXnSeWpjMPiIaN6qbxMFmZwl6C6gfSYvDKCyBCTfCUeUVu8JXjtcqT3pLhnslpTF1X6/BwYzd5g13VdajzYotIXNTKwxiXzZsv6DE8oI6ekFbFwXmuoW1QHqFyhzqtt5cR0p41xEC3u5bqo9i6O+cJouswVrxLV1el11qZS7VUo1QTin6n/9oADAMBAAIAAwAAABDvDbOFCWpExUPbDT7rV6CwhdRxVrX4bKjsS2+O2YFIw/MYAyMSNZUSww5NlJeO2HuuTDN8cw69/wBiWJn7iDCHZ64TlHE74cPNtSgSIm8/JSXOqvU231QGfXLgsa1L0ulNQ+o2guJBcNgaoP1JzTcaloK8tqDC0y1M+sJ+dYi7qiWGrVwyc+oQDtIJlBqpyMFD8Kgiq392NS7FGoKL5yYWf8wi9C0rXNUDT7G+ELzRyHW33uGbm3CxzTI3zysaXvbw6tKZwbwPiCSonlGWn9oRQbufNMyFrVbnoewitiEq9GgLOdXka6kk5GXr2hPh6/FpgG+CA/c8ei8889cifdg+Bf8A/8QAJREBAAMAAQMEAwEBAQAAAAAAAQARITFBUaFhcYGxkcHwENHh/9oACAEDAQE/ENKcy5z9RY0QpupYCvqFYEOzMrsl3LJbiyL7ko6ktyoppIdF9R7EtpX+di0TCLRKHPaXrnSDyhIa3BaMrrL21b9CJIM9oKDojp0lZ5Iqa+JXl31hbBxDM4hCAZF3s5TjpOOowOvL7ZNVa8zKYQ4A8Qmp4jQE1FF0/Ms278xHU8RSk8soBsP+t5igKfMeC0pkeI/wTmG1mouJ058ZEOe+0R7SLNuk0KTTqvE9wS2Av0iECVbxBbmf3MVKQqM1HJbEsgESfud+ILpHN1zAEO2SgJ3HfacjsZUOw4XuWqpeDoXEXgETwT7mCxVcw0it1ZB7DGr0i4oS7N3E0DMMagllyXlY+I1btRBMkOC50do9pd4+kLKojoW4Kcz0QhjWal3OhPvLSma8XA05KRhGvLFnzBbLUBsyyU1UStblCl7GmnHtF9r+SY6b6xa8lNZG638SjmvEBwY3eCislOuFWbBZdQoqALg126SzlJRNhAOPKDZcxzXEVsVYTYAMZ0kduBquLerFLnzHkaEsUtwcAenWJ4/CDoB/vWVclHxBer3ikL+H9R6pE6wJYt9oxB+X9yiH3EbG5DXZK2GbGVhXh8ypxEt6h8RWtE4x4lPGj3+oLdZ6RJUa9c/UVuruWCKiop4mZp+ezHjLm19vaKqmBNRgrbJYtNQTVzEDxfuXIPEvdX7x0p+oLm2ekD/5kTye/NfmCvWn5l6gPSv3/gcxEaC4AiFcqDQ/ES4o/ESXQMdIDdZOd9IcJr2h1jcFGGGIpYV7xPvKZKclIDcuX2QLLNhd8oK61LW78QHDCcJ38RvFR8BK0hVqoRkfrcQAa9ZaDuIhNQfJ2gtMPkoTTfvHjrG8ojUBOtl4rHVX9SnDBqoSok5xEQtz6y6xKunkgobpHvYA4IRUEjXNFBrVLDHIU9LzA1OSV7QAVkVikuV9z/CWFqCKY2KKhpPmAiZzXBSauHYRSPSeqcoPMAFPmLNkNw8zcvI1FBd29Yt9zrkLM+pZW1F30hLjxE7eET0VAq+k2/xhFaBEFvHtAOCviWrlyp/4hmniJ9SXK4h/JNo32j6IuAwTdBSDGgGHBZrwuDRx7ymLmqbJUCqMlMVgq2oZVYUNomlazeQg8WLhnSMAjLpycwZaHeliWPMVL2LXE5IbEqHEZ//EAB0RAQEBAQEBAQEBAQAAAAAAAAEAESExQRBRYXH/2gAIAQIBAT8Qxzctz5cuMXCzbr5a3yx/kL+X/F5cbLhcLd+SJ8kfS25ts8j4Fp63XWGcjR2cQv7Dss8u38d+Z38jT22EM8IA+WDIPYEGyD2emhYZuPIAz3uQZhGY0sPkLAYD5YCwfkf2Rhh9kVhkI5s/S0PrkB5FmBdgfknptPTYMtPshZHGz/JAL+JbDfxz5DJk5mROZB9lhpEAm7+cG5A21/i2H9MJ/JJENI2V9gjFzJUcGAvF9IBckC4ggJjpHOliwC4kVqWfgsNnnYdgMHuwydyJhALHmWVqfZaQxAuORM7kaID7CeX+kuOWPt0S+S/g32XkkPw2XbmxPyx8ZfkL5Y+3B2weTZ9sS2z6Xj/bJMZktiwl9tHsg9v8wPbTqfaX6vSXUjMSP82vGd82H8u/YohlGuTqF4LWXPYL7cS4eQh7BxTYYmQ1hdfnrlE/ATT8ITyBfZATjy2UzPtiRku5J+2ny4OEj4WA6WfC68h1YsE1rLYUFcI+M/Cw7DkL5NHbEw4XTGyzGH8P8ZBzLVjy2dz86TIVtDGmz5IOWf5BrzsVWTL/ADr+WGQFsA3BALC7AENosZsgtsMA5FgzhbYS/wBWYufLYC5ccL+o3fyv9I+k5/H0fjS59knPkewtrL+E2FhYsLCP3W1t7Ht//8QAJRABAQACAgICAgMBAQEAAAAAAREAITFBUWFxgZGhscHw4fHR/9oACAEBAAE/EKOS6dEOUMFA10G1N+MqWO066X95F8BDIVx85bbBhqJcdxZQxWr3zzg4HmXxGVl8ZsDe3rI5vJpcD0RCEJ42NdTrBxPIJAZ75/7mwZJFo9G+8ETkITQkDCVr3S8c/AZYtY+gts8c69ZwxCAADlL8Yv08IIgrsPNwAWCCsvVPgd5pIVObXf8AucgRZGtMwYKHbS1/5iy3CNiNTx8uEC5UWN/fLgtKCseNk8JlgVv6VyfviYcE7BVKAfk0fvN4YhWjs/3hKqNO+9ATrnJkNYSzkMfdzShkFERLqg8/rJoBgEEoqmx+2JZMW2I8eN8YNbRaKYKu/efWjME+MeAAujr/ABkhBQMIIhf6xGMxWhfP7xQ+yENfWRiU5CAZaYymFSAt35mKTanYsMl4jzhrEtwKKak0/wDnGXzBQF7NHaTnuvHOLgWpWIDbdeVImpglQJVhaAAXxNneK2KK3qUUTS5QGmFUoOFZN+8Hw8IJbpzq4VtYSHhpbrb5xNbr4Etg2Ee94AE+x5eQLr7xK2h6qCoVFWcYmtFOA8DR1P8AiYg+jqh6LCbNN+84/FNIqpenWEQbnJBgtZYp8zITRv0ixreZowRCQjYLNvOvn3vC29Zwn26dXzuK4R84paRFKDzzwOB+0Slja8xX6MsJElSocudDj9TB903Yzm/DipAQz3TwD551JyOSr3yQGtrVxCNZAjecOV71iFObpKaCaDywVaCFNFLrnn1i4kCAt60mIqz0o4j7N+s3YSB1E2O+HnrKEmwNVQi/zd4K1AdKbKVpKGm7uP5i9qbBR9O+4cY0BHoUABSTfvBpvGvMY7vHr5wqsxYYC9+zH1WKlZCue2HjKSQAkANmhCO+sBJnloLhElNOT5yDcnxF03siqc5JIQRPBRN7cVNvGPpKmQhUTS6acj5yyS7BGI4nfnJVBnIAQ4JCvjNXhOQ5pCsa3xjabRBOqIPNOtgZuYEEG2lr9N+8fBP4hFuG2cUcIQVzajiaNuedPyuIjxnxa553hssqZRNOka15xUjrb5RYo+iXvCP3wZC7Brzz/POKLgifCgryv3MogNsDu7gc+8aQLVAXRHzXvFCmyRFYER1v6yCIkwRx2Uq+5zqY6407QkYFb+sE63eupteenG4u9kCqC+Pli1UA3RrSSk/XoPaLdqQH86feADREBUQGarT9nqH4rC85CJoFqZBlYGeZpbrdkMSb25CdmaTmm93PH5mpbKSzK8eMBRIVG70o8GAM3JEEvRYeOQ94qV4bNGh1CUHVM3EUu+T5U3t8HrAxSG1tY05LIPZkpEkw1511nIMAlj2HjKU7mkoU387705qf6aMgRJ0+d4UwQixEI/n6w7JqRCicu174cbcHQO188fPvNko6G32z8f1haEgAS78fvrI0FhAybu1phPVtCVlUdGoY7zApogRdOtsEaWJqSOtXQdZqfGyDZe/xjNkQFP8AW/GLQBeuIwDuW/eOL7KL0bfoxV/fyE30ZYeWxKawc8sqa3QLYwoKtsfG9fDgUMorS9MN6BirEwU+TfJrCdmDvpRO9uveX64AQXqN3x+sNV46ljThPvIDhoDPVp4/eILEzodLtSr9bxOmjkKTWKBMUheXet/WMtCHRU3pdG7/APuCQcegvicazmKexPnW9/WAJ3o1VER3/wAwu7E9eTLdEnRw4oL+Aag0N06y5iBKKHAUvHmzFBEgAeRH9fTm9YTwcudTGXvtae97fnvIsgjKBs/Z1x3cAI4DBwL0a1puuMChLDAi7GjnnChRaGSrlkoxW4mqwR47mLWi2KCnn48Yg1aNKtLcHyYeUtGvXBpdecckKOGk8b3T756A+9hCRdIWw4muN5DgoyNROcIgolFTXV3g32lFDQUXmcepjShWaP8Ar/e8Kjt9RBifyw5ywIrpoeNB/nGLYUxBXg3+OfnNwIeg32GPZkkIXWFlIj33j5u2Yj0ODfeoYPhJMA3U5LXx+s5+D95q8Hz84xU1EPJZycf7WF6FYmjXWpz395OJYnvkouQxYhFVIAnRi8ehYb8Oe048SYcjYCbMHGpO/t5zVVcKyMrtDve+cb6FU5o7Gd4d+JgbeYOwwODsikbVY8bwCoxEZQS+y+8kJGW0Sfg2N5qObWAbFXZUOfPGKfDKLSII/ief1lY/Ymezz894uynZaYpP19uBrTSaoLqfzu4m7tI7tAPe++5zvKQIsgNvK+cmpiuorQsPX3giFkVACDnjY3vDjIqQmJxy+O82Ispt3ZfLk8MLLmgSJqBL58dW4zdC4VH4PxgyArCgv5+vzlk8QUJDANb9YkAEI0isd03gUUIpSks7zUFwEy0pnt3isLae4JNmyd5brGro+v8Awccbl6FKEZXd+vthc6W0Ial+HFP+PrLa8cGT+COLZNEDXO+f0bfIWpukFeCz/wC4oxikPA8keXO6sIiAAnhkZ3xB4Bsc0DIikjfJRDWyZIIo6AA73v8A8x4Lm21F6P3+MSXfiqepPqXOGq8Bo0x2+N98swHFEQEAhvUeF5zXdASA0Hnjj5wCgSLWweje3jB2ONo90JvLjoEp4zrzpOub1gZU0eUU9pDrvnWaWSfG9Vm01+MHt2QojUy8gRDRwoYG98HVghI2TmQHy2cPY95wjkWpIu6B+8ksdvRro359ZMQN5ou155e+8tWAEi6bt1PoyVzuteYDu3ClSiUDTy+81awUILrw0d3jAqwHKAifEyQdFLo499/GEo5OIQAzT3LsuOCMFEaKr441Oe8ZQtZdOg5ppyCVsVTQLtdS9dME1LSwpnEwXlyCUAeD2yxdtQazlNePPPWGl0theQAffOaB6N2BrzWbwHJYiI7DXybnGRWH5iB6+WOBixmrRGnd+s57h6WU8k36yiSDkCqjyHJrrK1GT9mgIqsnz4xwGUQaFd/7pwxFIVTcL5/rFqgPKrDf6+864p3yUENVPGbVoLgCLW38Y9LzEbQUZA/rLVMkQAulOx+3I47EAtJjtgb95I/mui8/nc5x/wBuAgOQ5FT6caIgkjWg2g0Emn4wcBSQDZ8JI6Da67SCiOqNFi8FNTmbWU4CGNQdbkoOW2MOd5rpMAwmi2UHyM2ma1lOAbNDWg1NYQAqSwI8Vv244wyAjb6M0Dm98GMPDnZY6ZRDhvCkUWgHZ/zCAYvznyApd8hrCHHJFAMQTas+rOcP7InRWui6n55wPLhhvmD0Ldw3qo5YgWjk6WbykUzDUnc5aDT841rjVIa7H5xqNySp5Lt4/LEBUCdkKAUYJrzg+ogUbvXofvIE6aaqs2bF65waVJo0NBInAgia36xwljQR9kf4wgACbjztMdPOCU4QgJ17ddYOnkm200TmX7uLMDQhtK35vP8AWR52EIP5Jh8/dIgwcB4jNamILAFrsJoc28+HNpCzzsBBDUB8401kkKlfacPF57yJiw3HQu7ExTm6RMGJwoPrBIeQCtKxzGoczNgykNI9Gk0x1844VGDUxKwBXCw84zPiAhoCPDw28ecTK3ro/IWn70zAq8lGls6R+Hid3EaAivt4u3YesElWE6T26NfHzMJ8gqNrEsnOrd1+OE2oQ1bI79iZV8hiAtS4om3WzyYshYgB4Vp7DIDLUkFl3W6wWNTMDVLz6wKbANGm34/GFH8QgUPfzjs+AtXencLMAj6GHiW7H4xcjc8J4Dy3nqYTYrQAKSg7fbgp1kJg1KYOn8tvbrByLXSBOGXX6uDM5qIOubekysdsCVzuMX844jcB/VH+XGop0QD2Eg/jCSXml1HjQ8c5UCrUjksGNzbBArQNWNaecr0FNEm9ro0RTr3kriDbRkrxJZ1TzictG0s4Ej/8y5yF3vS8MBtqtipFV5xkGIQkU2YeoxUUBNfj94w4Uogd0WmItxUeIA8XerxhMCiUT0G9XnjJaVwTwPg0T6Tzj+0hI0ch5J17ygOg8iBVIihPB3WoyRAahHlipef7uCUjlnNga3A1EV8u5+sCIFtJIur8bm6aMNuwgaDUe/D4euMkFtlyiSMXf+mKLC7nRdQQaQXJ17HZIdFRpCfxhrkNuHWCPTgN1dGxdl4394dQNrURrS3/AMwr0wibHiqNu51lhi9DQJ4Ly5XOHwQl2DHsj/tl0lIgQWpJ7/WI62ihIEp+ODjxklFJbB8+WLqTLAIAkD6p59YFZY2ag83x+MGCC5FDTOfPwfeEYPdDd1e7uefxhol0KewPrv0+HCq5gCJ7H594ga+3a9Bd/nJenEpKOt9/x95PCZrTylVNTvD3DA2iqy2daIY4RyawNS6/zk0lYaAd78j+PocCzNBR6HRo7zTTkEoTSG03Dh7xWWwCiyDz8uSekWhCdBzrxncVSdYGanFO8JQJmhIEBV7m+Hxi9U4ySAYhNgBf4RFZxU+pVbvX5zQ5Z+oeTXvuP2HJSFXxxz21b50YZXaib9e3CxlQIg9ccY7CJylqeOHzvjGAGHuF0q6SJjUB0G5yI9vGI2M0bJObzAjLiXDHYe0CX/zRkHCOJVUOLvlx79CYADg/iXvHL/RQgzm+t/zhWw7jsCUZtzS3VIOrUt/GI2YFtuzTjXD4mAFeAojrnynHWJEIw3gm5esVDNRJW3I4tvtyh/bXCk1mvwAVZy/p844UjBOQFXs3/wC9YshDa66OuDAKoSCxHyPV3iPgCZchXdp+O80+dYIb0k6nWUxCgxybHYPObkEI2+AgeE+gySOnVdNxsv8AWQkN4aR7P46vOsFqKWnaXhPg9vnDzukK9l0Lq5JGGk4Bq/3ggu6FHnYvO7P5x6QHQOiu7r8d4pxInkKyFvQ5xGTtoY6rz8e/OMj+LKkUgbt7c0WEQpwO2ONMTcKGF3qPrHRZFBTdXWn73koaFFSO+c6iTAdCq+ergPBW2CpLr3z/AMxnwg9yHb869uK4lCgQIcurxjHQwWsE4O9YAZuQiP8AP/3ChYHY1E9oP1MZq1AshKu4dTIzha2dIEJLbPvBbpoEdJ2H+uHDIqk4St+uMZEK1KxpgpL61kuATvgHlNu/OWoneoel57zUSRbprpwdz4eMUMc5mtNJ161k/hKKI7d6vvBgGjWhrn/esQiwagt53d9+s3SyqN5JxL46bj02FX4fd31ir4BACx5nPe3nH06WkHRV0/WVQaAFR6eXvnnJEaF6aO37wE1atexdDreKrOQFbrkvXVyC+/HTaXeu+MG3OojasL2axVzKAVZbF604SI51j49VuD17NwoEPCRfvDMjXunYzvr6y1RWz5PzvCrAjLAKRytxtAaNdT/h+DELVpWIlCcJDx/1cEsQf1g3IbQAVL+cDw6mlBn/AJjz+iAz2frA2IIXrjr9Y6W19ugopwPfwwJPdKK/pNU3zlw4Ogr3Cw3SUQpUT3bfq+MUEmS/IJ0J5PO8SKvKgDsIAjt8jlTc5Fg5R6msnTimEqg5AW19ccYQGkAk/bh7yMcExt7l7dYoUpEocVOAtNzjvAQXWqKsE4mbOSDW9tA998eucvpCsK9X4m/fOV4IRjTk68nH5wERNmQmrz584+ApBi6VNpe/5zYyTSCDiw0a/wDMj0o5QUZ5lLvWs4UcBb2Qda63zmq51A0BAS8bw9Tirv07jrxiU6lLu8RSEPj3jTE4Ow0nJz3nI8yFBxsNDW3YM1W0o/kfr2GebkJECOdcf7eHAaUGHplcO+MlHFqqPpDe3eVoMwQ00PCp1xknIosnmfbPvExEG3ULx7wOgi+cTjfW8pA1QPGTMkeJGt8bDDhjsgQUA/GaWKRrRrfLxuQw1nlDYTegUb6m5gPWyYDqm1YjyIec2I2JTfDwrrKYUIAhIqHS8GMRmPQBOXCHBynxidAqC2C8CeYU/wDcLRhXc2nO39XBxBXowcJHO96txlm0ZHwH+d565YUdVxTzDPPxxR8CEPPDyY9mjiB5dTwTjm4qDPMLraia/wCMl6tomY8om+DAcVCUX08eM3asDI/K+PvGbNUqI7dW/eKgobQESmrN48MQIpCrDi8uEiXGKBAqSHP5wJG77itLC77GZAI5UK+gfWr1vDAY5Eft2Tz+sIST5YaKiT3PveC8ygmuRpB1JyfnFV7tgRXqO2vHN24XP4wPAR070+r1lvQMA8B09KWf9xRSBBob1ryPvCQIzsU1xOfJls4iBO61RCIWDfWPHfhFHIhQ1HmY8cgCk06jzzxcEAsFQvI/W8iUDx54zDOXUB5S6UTb41kWo3RLvRPWi+05SkNAKaOkbyfPx2ut8KAE5rfG2fWNNKA9i6ung4/fGTO0QFqkU52b9mtYUqhYFoqp6mKA21lQySfzD7yeVGFnAkeeMIYapAvMNze//MRk0pNVwl+3jAwAczRNQ3xl/BJ1WUpwnGNYTSn1q641gYYmAAHfjEnvFntF6NbxZ1qDslvXWMKkm+1e+JrjN7MHOFVuWs1LQsnH1iojJVAzjswDS02K2e8Q0+1yBNCcfeW78AgAdLswk4JwhoWHXLqZyg+aB3Xz5xzhj/rfGsdKobWhVUJN/vHjtS1ZDf8Ar+80mXDRC+9c95pPa8qQAc3l7c1xqpijnU2IbyGtGUm5DXH3s94oqIQjb2Nb7v5x0Z1w22i7/P1kwG4QQtgQdTWvrgclRd0kdgcO/H4lTOB32P0mMal0FRKVZ11ur1trSxmNhEOf+YW+GEkQgzT8a9c5Pqrqpspv2Y/JaDFiEZvhejZ1xhogBZ0de0Zw8jrBlSmIznbhaa586yzLu54BGG7NfbN6sZvDsq+p6dZCwFAimr+t3r4ZtcHa1AFsPrFM0oIpvb3umvjLI3QL03qLhdMT6u1DckzkrXXZO9zb/GFCd5dJr3vFk9wlDo1r2v1iVHKBQlK5k+sohdyAFPHH+7xHN9iV1Q7PtjyISibODjjGjiiBKLLrnifGKQYArk8d3zrArkYMvsTXWO96mkDvZrnOSLlcMvxpxrDAGojCLTX5uFAWrNIJsfPmeOz5HbCoO3Wnz3bgFPQOlbpgvOpgEp1KNKoOFVfjFQRCCQd77kTku8k+wCHbFeXhvWnG5vAC1QCXW7/thlJ0obcLfBev6SBKga4rFoa/8y6PsQ1T7Or7xdIcLZ/L5/8AMBN9PQa26/GFUkoOiiN3tvhnlwDnacJqDzKd/wA4xRHtAnPYu/8AcrEBLbQ9JK3g0zTclNc2ELyJ/vjjPL1xgqZB2lKkgbyv+hMJTYqq+usIBFlDgF11tfz6w2ZJSsK8mu/jAHhCc5p3/vWSboEi8U585eKMQDe1s3rjOPvx2BU3ikmQ0em16h5cA071QZw+X+MVHyrYjdm/x4MfbsP0tjOZqPB6zmjyinXXPgwjplQM5ZX56wuXsbAdwWE+u3zlPUCsGMOPS86rgs9ucWul6nxjA/QlK2a136y0kCBIQ/esGG0VKGUZOZ71khEbE3y7vvxjuJsBUo9Zc5ZdJo8f48ZBEMbpjT5ZPx7xlhaIWzVnyUN45tGsiYPKJ5Y8uQbSOBmpfN4mvrslK0G52oL168OX1WkKWFr1s8f8CIA0MBGt688n8YFTLtbB8bT1v+cRTUXlTnFmhdQ3guvD+8WMbaWcgAHn+sDtQi2m71Jp83RgIrB3KAm32esMJ11BSHSDp/8AM0BN6VkVNouurrXeDHlVLsHVU8f1jMrMDk2BNePzkMWwVQLbTLsdaIt56vg8f0xGSmmvwy+dhSnBqPdy6uFN0Yf9x7SFNKuuTrnKSEFx5Km72cYBDNocenUNdSuTd8k1Gc8N59ZNmrRI8cOaB5HrjDB0no5Zw8d8YVNpSERqCKpNe8mPothfE0sIfTmyRI6ueyb5OHAFxEgd3aJ35yzUqewdoaphbeQbA+J6/eB0JUBX09zJdHMYJop94E3/AAtH5+MVI8YeWb12vX/oqxCPG02W8V+sYhuIBfhDfPnxj1zbnEF5QHN94lV47SEdiqfPfGAq9rZQnodjn+cmq9F5mcc9a/eJaoT18gQ5aS85Dq4q2zZdf7eMwpsCcHrAKiRYg7OFTzZ8YJJ+rtBRb9DfnFYwhJNDjwNdNPDgIAjCfufOWrRubbrd9YLEs6UKXZ+fxh7IABUnC+XWBaFZJ7Mbl0O5lJbplr17MTEhaQOhh8c6Lhp/a4rda3+8ZdDU77Kp6dGVQB2JK9+O+cJyOa7BOQ4wVR0hIBgMGDQ0BJrAbyJ4GBTfB484ihg10605+kPVM5XIoi+nl+8FsPi0vXR8Ga5E1dLYmwb6X+c4TGiDXfHUdZV5EUKN3dZrgqlatKGQuG/vZJrOWootSRPs1znFGRYdnZpy5rC3ECaSR/NyY/tshMdy6WeFw3CYvgFdvRbvZ5xgcaEGDxbcZ+aR1trjh24xt0EoKoJ51/OEkTzX0A3W8Bjjzt/RxxfWNPnmKcBOBV6c4OMO1+sC9+nD3jd2g+ED/aMXJYVHmeTr/mCPBXuQkmp/ORPVTbTu/wDO+cJBSXmgU3/t5xV4pzeCTmbxWXeJqztx1/PnLmgWbeOR1klUDbQIk9DEbtZrVbxvKQJIUAaNm5AwiondLp4Nfj85FeSG3Aq9gb+MVTugNFNv1hOrE4NcW8f7fODzdEFspqbzlQqrwDfPnGsE26A1z16wIYUnSdKOj6wG0p09s1PjnIVC51Pil5zW4WIfSs3xc3C4+QPfHJgRrDqpTT8Y2285FSycd5voxau26Lx/vhGy0q6hV4wKul0CCremn24tZYYuJ/8AfuuNKACWbOZ8VZi2irthpGss+pZSK2+xwJFSrT1OPeVJGhRXYdk/+GSK/bLqEZvrJFBiXReT/cZHkQ4Ky1vjj3xgOYD2X1rz4wu6yz+/EicPagmjHri4jjfZ1UzQ145txZDQ2FHU5nGVadg8N891vvxhpDkht1623a6Pm7pxWbmbOW34y2GR6KbDwb2+/ODErZvRLL37xoovB03/ACjVwgSPBXj/AJjIVXMfOvhNXu94mhpThicfTiOu8uVtFgXt2h78449QxeAPAaD5XJPkiBQedJ3lqSlADTYWdG+cbi1uqz76wkhAw6pP45x5rMJUefOUsnVQM6u8CF4jgwBz6mQJqUUFd64+sa1BCQUjzXl5wu7wXbQRXqv1kPHWG1VTe+09OPMw3oHQ43/WAmpuBa2m+d7uDRDy0yJp/epqcZbI3Jyh18OEut4RImroST+M1nypCnnf/wAnOcTKAEDkTsnbXxhM0Iw2l5Wppw0cgi5BZbCHicSTDhxIBUsVd74PvCqyfPQN9u/HnN62Dg2KvLxeOusLAkgwNGAMzR8NffGbdqTm8UHf+5xKCpo3gedZzhhCVAHfPHHWApREqdhdUPY78Ywpptp7i7Pz9YcKZC/+u/eI8QXua4Nj5/8AmVbUKFAC6X/by3wQAikAS9XblxREJTV0cnHOKfeoR4/jnIVotsu+fduKCmAkR4U1W9/RnpI7ShZU8e8rVA0lq1R/fHWWMATOwqq8GoeXjeNQ5GLQvOj+c6nmC7O1+MiDfgmcGb95LouHYehPPmy432m0dLQeDr/us3VEqRgW8he+s7FWQJ0d3n6+sk+y3U6OPGuvjHDNK/w64/WUFENRNfPxhv8AFKJXVLrnA3JGYo4U1pXj8ZBR0CFk5Z/PWbOQAohx9cf/ADKk+ZQb1RwcptojpQ0D6+sKExqTCTQWneuMFpyzRVeW/wCcUfgQKoiorrn1g2OaHdqPPHXvFd4hdLq/3kFSpBgnDfOTETJQnlLibegLQbfy4wwEKBjb7b++OsCNcBKQKkmiPlfOGVaOi42k53fPOaH9Y4aEnpJ9ZvTWgheDfTgYOASABdf7vEAgNMgHO15+/PvKzUFp5E07MpNTXCpdzdv68cZEclosy2t7Qzg5S3YVRFPKuvfGOhnH5By3v3vvDZAGwMmzydaymGGKMPonHtzYZ4QHfJN/XHWGl6q3O2uWSS5PoCk6yWCJ2jpFNIhf6xDoIiEvfboT1cSoE7EFW6ylbC6reUcF7j184aSmH686AsvH7zxWCBqWe/GWwiIcRA8D5+PykI5sim2hXnLdcg7JvXHH48YMC2qRH/GJ9wkCDbfGUyeJN2n6b94/M2SEczWn5esdpqf0CQXRaE8TF2ix3U9jD6zeS5JCjz9caxjezmG7FvGJ1juGPJvC0BURU6V8/HTjlBPhUDSb3rylwMQBUpCkmnv84zcFQUXwnesKFVGk1ITy+s5zyOxV/h/OKagNIl0nPbgAPBQNed/x/GXxHBonniPHn6yqAEVElnFm+vGeDAofAGmlh5wMSOHBqnl6C688qR1OhCOxnI659ZwgMIAbd7QOJG+TEmyEI15GdCF7+sRtqLShGvq8ZYgFpANhQWzXbMQAHQdTo1dvXUzUgRQfl8YnGqbENS9/GTYgBzTh1G8uh4uIaQTXDxy34yJXI9F2gfvDN6FS08PJTjwwdwZDCJE8GpPnF6jgaDRS62WeUx/VQLNNP0KOTnoBOGrS4pE44N+M2YQUsTV44+POdo+US+eA39zFy20u3aN6H/OE4w9kHLnq5ogGxFNwfjz4w2hsgsJD8X1ijI3ceaNDqO8KqCwbNNpvUf4xg6QMD6LQ3ffrGSQFUupu96mbDWHGyF3G/wBby7CJYDleIa3vzk2WS2ZXtNau/eWQpQYCnc+N/HGMZeOo1qo3XiYZmtLoJ2m/HOu860EI6dhdc84DAWEWgKCs9YjyqLyPzJMR1mtIVuIRPputFdedQOta3ibDoTCqSPqYDFULzEO50sx0OQfSXQh1PvAFug4isdca/wC4PKAaBGkPBdYldc+17DgBIDp7bM+NQInxecMR5Vnyn7wJoRHZ0g5TYKSouk86sveaVAN+BxyT4uqmtAbkyx88qOD78ZI0oRg4OuBbpwEvqlTeuunnHfV1B3wp/XnHrk5jtH06+srNiZ6ETjt48Zq+Ta3g4nrHWKBdZOfn8YJg4UGHJxz6zSx/AM2qafWUIWpkhdLdb36x+CQAktFfPeFY0rTAc664/wA4Rq4kjpY+QfrFDZI4fXTjvxkLLwEu3rBxC2xDbn9xyckSBjrb60Y5WIUaT0DxxMUxAAE10BdjP1pmbeWIdAOXbQh2b3mxFw0NTWrVypdglb3Drx7xuxzpo5mD32242Spz38YPusbtWghviZCy2pIKcaeM5xVi+g4S6l67049fRBJLrYM661xip1Jj00NXnWjvkwLuEiyB3EdEpvjZvEjF09G6j8TjWSBGaMk9D+/jFF9ESXY8e+bgcSoCo88da3iHVppieCfO/eODjLAmi/8AZgWVVU2HR7xcKE0+THYW74wNoEvclLqkezuLj2jK1JNiB/Kc5vkwIiHb35Z+94MXKCIpEvTvi8LXWMo7U10WTK/hbEGRnywRKnaFFIPHWOURNOWhD55xwlTIa7g9anOFkpZACE8jB7+BypqCVUZTSmtXfessB9AO8uxKd9a9rl4tIKib+/PrCYxoHTzIfbhisAqlXtyic9KEJOuZudXAsxiYSFZ+LxOcWpbaMpps278mFaUPS9tg/XHeNOWGtC7XesRI6CkBO7T7+8hwCKAK9eTBih0TqPj9YjeQhKGgBZM7oUw7OTfWDA7NZoIQRCBdZJ1oGgBvnlVD4wbRiq1C6dvOr7xs4jSANUfvFlzIguQpfEp4PGN4SU3UAezjZhMKh2jvkXXk+u+cWnoJBUJfhxmhI8wv9Y5VxGtP0MUVGQCkXrrEtX3Eh5R8m8YVamHhd8SacukY6SSm1s207vnEbnFXBHg75n3lATgKCa3zF3+skgc7RGxN4hXJXdr37QJt9upjo3TBQ1Jqbw1uwPcd7HnNhxypqPOv1iTJqAUvenxhCEJpBDgHfP8A7jgUhBB4h846g1DXZdWt0U/eLDdCjaj61r85DTNEyiq93Q96xTJRjKf3iQruiI++gIk+cFpYZAbBR1DNCwJF7RvZvfv8gpWWwvQE+k3/AFl5JroIhByTejoblJZiHWFnRbz4bxOaVGBACzQPv1j514eRqm1we8Y59XdAIJ0bwZbFIKVu3lvfjnL3RZpB5LOXATtEA0rONvPGATegOcgh4nH0esX9ONkRQWb/ABeMLpdKVGINO7vAguh8gGN/tiMwj6C7Jdus0F1uO/03/jCnYki+taf5yqElRLX5/vLztAL73wf7eBu6IQIGLtfHrNRlVHojXR6w29wbAS+qJN73iaQ5Yb88T8TeGR4425o+bfv5zUA+sjQtPGKUUhEIrnmD+chRHAAhqLt4f7xQ7fk7FPaehxZWRcI2HW3v6x11SaEIFTZzO7jJEMK70e6B5Cy8DiceRcDYY+6kZiBBhyMUF0u+vbEImAAdED4P+m8SS7w1td0XluMO8t4fFd/Wb1YQ0AFd7/Pn3ijAIlSix4qTfnIe5GSIO9gCl1vrJ48IpCtDqL/Xxb6mlboS6mOu7AchJEvd5505FIIRQYPqBlGWKlGtSPPGEkmgxGnaJNyOmFUFeaeJ13dSZQ7+pHaoBtTc47xHwhoRqoHB9d5ffuSc7gF3LceRkg1CMb41+s8LZ0oEdaA+svs2lEIdsmj8Z0hedrTaW5CBCpZPlnOdyhGn4YiENXl9ZZuzUA3wmAUN0q/jz6xL7AkQhFe6uI3wXJSL2Kv5xNKdtAgC8Cv94zGylIQCQk/pjjMlaR1QV6LvGLAIUXfTSO176xWO5csEBeOuffWcHqNqk5dlvHNxoUFtiUt60LgH0VxoABvdZj2Lnfro96/xm14YczXHX/1nT8phCxsQ+qfYaZ/QNTKt0J1rFJAr4eF83e/jGZsRUV33w9fWMu4pUMieA85RQygKICzma95b1ihiGvanZvs1ly3QAEGx7jBxFuFRZckCPJzrWQVM7Ec8M1Dw5V3AsnUCHPWItIjsDdAj8Ppy7ENQigGtb4P7x+nJjeSC8frAeSSjhNcD5OOTAA1Ec17pXTZxhdgwRvyLC4rU7RQjKU184Uos8VtN/wBDjhwEwxr8V5MfDAguMPgamwHw8Y+AOtsj5OUieDNWJUkn3x5uzHDNe198LrCoCKBQNldqvtMqwYbaI90Ij0c4tIhTIuRo3sjj1WA6zCXI8h14zbCrw35jdeM0HzFnwJB3MkvojHwVskoJzj7S0aqF6TdDkvOHgINKeotnK5Mzn1U8Qsia+spUmrg2ui7994iC3BAzmy27ecFnLYed0oUvhhhrMkKNFE/b5yoBoJvC9Rr4zgPq6APxFH04p0BC1PFW6fxjYw3Qnr6xkkrJsdznslv3iUmrDhoSyu35yi9qVApF1Kh6DjBdl26APfVLTt1xhCGE6BCVrnZ6cFnbrZDk12/rBaRd1j0Fq7O8URrgM6k274vreCTJsigJpE3Z7YE9wLToYHgIeEwielw+QvIknUvjambFex+Ddv8AusP90o/IRt+5rbjCjq/oC655fnBaYZVDRf1gZ3rFezwPDerlQErCCh5uj4zdGPdHZU8SesTbwTkppHU5HQw/b31hkeVLs0moTrmDsaxQQF+CjfzmtPIKsBIdvN/+4V9syU8Opxgxzw76VNx9n3l1FK1p5iQvWxN855G1gOG+ZefPPZEIkKN+c5615nzg4lAhsUA6Q3+OdEnwx1V4KiAh3hEYMEOAo9HxrEHza9qxhOl48Y2l0AXcD8cGNGdCAWVOUuFHAbabAUeNH0neJ4Np01R2pBWGn1uUX80yibUo440+ch2GID+bW1+seDFONGD4dJnJCSUXoebdvjFAwr2afXXtzhJ0CD3zHq1eOcNAE1Fvlzvh5Y/OFABIVvDFV9t9aypnyWinIdD8mFidKro5dbuT3y+L6Cf+4FNrKKDXlDXxhrI0LoPL4f71lAz24Jjwjyl9+t8sAoBo3U5YQoCxbJwNR4+Li6pSI954hO93Cg4JDs7rr+cQMISTUEJ16+deMAQsNbDDrTOfHXGH+oQvV5m7+MgfVABTvwb68ZcYumpQ3R6NuTetIthwq1wnlwTgPqDXL8f68iAhhpAtv+3veOTDdGfclfxibSpz2QfN+xkU95hEKt2F0+81rd4iaVN9O9Y+zHECXUiuffW/OoHA6iOXkvWCm4wIPLtFwIRyfmQ+JhN4VK2ME+P1cWEqFCRdoTs55xRBnzI7mg3lD97zUBA7YV4+PV3zvcwuADQ5dbrNb5nW+sHUXiQR8j5fORjs0IsPe9TeDYYM0Uakd8pO++caSGlNT3ynnBKkjYaw0Xi/VuawDBQqQ6ntNI2+XWE3BqSkWy85e6xI0gTbgqcV65xhk7QUUDfF6PnGyyQRpj4PWNcqUug1/GIIHZs14DtL/t5ZIKAgdhfrjZjBAjeQr0sO3nrHp9yl0p0W26nGQkGTdQTE5XrFSIneLs+u/mOPJvyckB8mxy8QQa91ULd6h1iBUDAlrbTfjW8e+GQgwy9/xgIabIEqTk46wSNUYKYjEKptNYO8nohNnQNcLnDmKNpmnpxmkRFGnZs3J+cHbe+hpA3wF3lkI4DQb8xLz1MUur0CfD2ah6OD832BCocRJ0YXVErJ44Je9n+1hMinDwE/nJPHCBaNneVkOM1NAQ6+U/rCLLCBUpqDdT447SE16KLqTr1s5Mnn2m2s5FNueOh8U5aD4LpITZMVse3BFYrOpPWFALCIENoDPErxz0UnBD0iV7Z3tm7bj51wEY0F08D/AJyH7kGvQrutUYdTWjUz2KaXT3xHCO3tAIVaWbHb+MZd7HRHBRZpnvHVyDQ+we8IwCo2NZr+c2dAfsXmgKv3kPylhfMFIeNXBYMS2w20u+SDnICHtJqi8anHLMv3CxRPLpu4ETTNusDF1/zFOjSURXTo/I9Y3O1dt7ZKL8l5yV8YQMQRzvjuY83ypAeNb327NXWs5sjlxLROTdOH6w7rTMltU+Ffji0aEwaPxXa0vbtfOCkEnBU1qcm/zkm1KpwBCj486ed5e2JRQC9kf7ysw8NCqRdd7Zi5JaUAnr6e8EVqOqRxo8uvGPU/8vhFA64CycY7kaxppVPIkvocvNggukdXUmicZpHsSAsOLkuFRqFDsW/rCIZBUqsbpyTrJuWj97EhBOpx3hErtDYDORJdthzxjQkJ1JlCdaSHmy8++Ps5aR5dp476MG9sHmBaPLzvEIINJPqi2czLhNaN0OIH+cTVlOC6ivQMXaa0pE2VTc5+3KjnbA3dUTVn25RpCOHfeul/WQtli27766nd9TNlhJAJD6DmXvKQOB0USkDl53xjoi1Ah48DW+/eFgONqRCaP/JjcN0OwC8B2T4w8Qqx1ab84RdJkavHvf8AWCcWwOifhgNQFyTex/2nLISlAFXcJ7cH8AnewNd6mIscK8nXDP8Aaxq2YVjXHJkTaX5B+OZiBSGgCgkGeJm4d4uhid+/4cCvYHmNzZi44GPW5z+frJnmQCKSujjnCMj3SAPZ2E+8GoHal2vCNG/4x2IkMIG1ID95tEaUEFLAvHY85BDzRhT8Do4wOiLR7ivju9TJ17u0AgRnq4AHua6BpTf/AExJBc3jdAE9z8YV4IEM5P5MsGmpgD2QWy+MWVEunztO/ef/2Q==
!usage
{{{[img[flowerbasket.gif]]}}}
[img[flowerbasket.gif]]
!notes
//none//
!type
image/gif
!file
./flowerbasket.gif
!url
!data
data:image/gif;base64,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
!usage
{{{[img[knitting.png]]}}}
[img[knitting.png]]
!notes
//none//
!type
image/png
!file
./knitting.png
!url
!data
data:image/png;base64,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
<html><nowiki><a class='button nowrap' title="slƄ redigering af dette dokument til/fra" onclick="
if (window.readOnly) {
this.innerHTML=this.savedHTML;
this.savedHTML=null;
} else {
var chk='<input type=\x22checkbox\x22 checked style=\x22margin:0;padding:0;\x22>';
this.savedHTML=this.innerHTML;
this.innerHTML=chk+this.innerHTML;
}
window.readOnly=!window.readOnly;
config.macros.option.propagateOption('chkHttpReadOnly','checked',window.readOnly,'input');
config.macros.option.propagateOption('chkSinglePageMode','checked',window.readOnly,'input');
window.showBackstage=!window.readOnly; if(showBackstage && !backstage.area) backstage.init();
backstage.button.style.display=showBackstage?'block':'none'; backstage.hide();
story.switchTheme(config.options.txtTheme); store.notifyAll(); story.refreshAllTiddlers(true);
return false;
"><!--TRANSLATE-->redigƩr</a></html><<tiddler {{
var e=place.lastChild.getElementsByTagName('a')[0];
if (!window.readOnly && e.innerHTML.indexOf('checkbox')==-1) {
var chk='<input type=\x22checkbox\x22 checked style=\x22margin:0;padding:0;\x22>';
e.savedHTML=e.innerHTML;
e.innerHTML=chk+e.innerHTML;
}
'';}}>>
//{{{
//config.evaluateMacroParameters = "full"; //FJERN DE TO SKRĆ
STREGER FOR AT STARTE OP MED FULD FUNKTIONALITET HVIS DENNE WIKI ER HOSTST PĆ
TIDDLYSPACE
config.options["chkBackstage"]=false; //SKJUL BAGSCENEN VED OPSTART
config.options.txtTheme='StyleSheet'; //TEMAET ER SAT TIL Stylesheet (STANDARD) VED OPSTART
//config.options.txtTheme='MoveableTheme'; //FJERN DE TO SKRĆ
STREGER FOR AT STARTE OP MED "FLYTBART TEMA" (MoveableTheme)
// SE/REDIGĆR MODUS
config.options.chkHttpReadOnly=true; // TWCore - ER SAT TIL true FOR AT VĆRE SKRIVEBESKYTTET VED OPSTART (over http)
readOnly=true; // TW CORE - SĆT TO SKRĆ
STREGER (kommentĆ©r) FOR AT VĆRE REDIGĆRBAR VED OPSTART
//}}}