<!--{{{-->
<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml'/>
<!--}}}-->
Background: #fff
Foreground: #000
PrimaryPale: #8cf
PrimaryLight: #18f
PrimaryMid: #04b
PrimaryDark: #014
SecondaryPale: #ffc
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #841
TertiaryPale: #eee
TertiaryLight: #ccc
TertiaryMid: #999
TertiaryDark: #666
Error: #f88
/*{{{*/
body {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}

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

h1,h2,h3,h4,h5,h6 {color:[[ColorPalette::SecondaryDark]]; background:transparent;}
h1 {border-bottom:2px solid [[ColorPalette::TertiaryLight]];}
h2,h3 {border-bottom:1px solid [[ColorPalette::TertiaryLight]];}

.button {color:[[ColorPalette::PrimaryDark]]; border:1px solid [[ColorPalette::Background]];}
.button:hover {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::SecondaryLight]]; border-color:[[ColorPalette::SecondaryMid]];}
.button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::SecondaryDark]];}

.header {background:[[ColorPalette::PrimaryMid]];}
.headerShadow {color:[[ColorPalette::Foreground]];}
.headerShadow a {font-weight:normal; color:[[ColorPalette::Foreground]];}
.headerForeground {color:[[ColorPalette::Background]];}
.headerForeground a {font-weight:normal; color:[[ColorPalette::PrimaryPale]];}

.tabSelected{color:[[ColorPalette::PrimaryDark]];
	background:[[ColorPalette::TertiaryPale]];
	border-left:1px solid [[ColorPalette::TertiaryLight]];
	border-top:1px solid [[ColorPalette::TertiaryLight]];
	border-right:1px solid [[ColorPalette::TertiaryLight]];
}
.tabUnselected {color:[[ColorPalette::Background]]; background:[[ColorPalette::TertiaryMid]];}
.tabContents {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::TertiaryPale]]; border:1px solid [[ColorPalette::TertiaryLight]];}
.tabContents .button {border:0;}

#sidebar {}
#sidebarOptions input {border:1px solid [[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel {background:[[ColorPalette::PrimaryPale]];}
#sidebarOptions .sliderPanel a {border:none;color:[[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel a:hover {color:[[ColorPalette::Background]]; background:[[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel a:active {color:[[ColorPalette::PrimaryMid]]; background:[[ColorPalette::Background]];}

.wizard {background:[[ColorPalette::PrimaryPale]]; border:1px solid [[ColorPalette::PrimaryMid]];}
.wizard h1 {color:[[ColorPalette::PrimaryDark]]; border:none;}
.wizard h2 {color:[[ColorPalette::Foreground]]; border:none;}
.wizardStep {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];
	border:1px solid [[ColorPalette::PrimaryMid]];}
.wizardStep.wizardStepDone {background:[[ColorPalette::TertiaryLight]];}
.wizardFooter {background:[[ColorPalette::PrimaryPale]];}
.wizardFooter .status {background:[[ColorPalette::PrimaryDark]]; color:[[ColorPalette::Background]];}
.wizard .button {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryLight]]; border: 1px solid;
	border-color:[[ColorPalette::SecondaryPale]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryPale]];}
.wizard .button:hover {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Background]];}
.wizard .button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::Foreground]]; border: 1px solid;
	border-color:[[ColorPalette::PrimaryDark]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryDark]];}

#messageArea {border:1px solid [[ColorPalette::SecondaryMid]]; background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]];}
#messageArea .button {color:[[ColorPalette::PrimaryMid]]; background:[[ColorPalette::SecondaryPale]]; border:none;}

.popupTiddler {background:[[ColorPalette::TertiaryPale]]; border:2px solid [[ColorPalette::TertiaryMid]];}

.popup {background:[[ColorPalette::TertiaryPale]]; color:[[ColorPalette::TertiaryDark]]; border-left:1px solid [[ColorPalette::TertiaryMid]]; border-top:1px solid [[ColorPalette::TertiaryMid]]; border-right:2px solid [[ColorPalette::TertiaryDark]]; border-bottom:2px solid [[ColorPalette::TertiaryDark]];}
.popup hr {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::PrimaryDark]]; border-bottom:1px;}
.popup li.disabled {color:[[ColorPalette::TertiaryMid]];}
.popup li a, .popup li a:visited {color:[[ColorPalette::Foreground]]; border: none;}
.popup li a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border: none;}
.popup li a:active {background:[[ColorPalette::SecondaryPale]]; color:[[ColorPalette::Foreground]]; border: none;}
.popupHighlight {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
.listBreak div {border-bottom:1px solid [[ColorPalette::TertiaryDark]];}

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

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

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

.toolbar {color:[[ColorPalette::PrimaryMid]];}
.toolbar a {color:[[ColorPalette::TertiaryLight]];}
.selected .toolbar a {color:[[ColorPalette::TertiaryMid]];}
.selected .toolbar a:hover {color:[[ColorPalette::Foreground]];}

.tagging, .tagged {border:1px solid [[ColorPalette::TertiaryPale]]; background-color:[[ColorPalette::TertiaryPale]];}
.selected .tagging, .selected .tagged {background-color:[[ColorPalette::TertiaryLight]]; border:1px solid [[ColorPalette::TertiaryMid]];}
.tagging .listTitle, .tagged .listTitle {color:[[ColorPalette::PrimaryDark]];}
.tagging .button, .tagged .button {border:none;}

.footer {color:[[ColorPalette::TertiaryLight]];}
.selected .footer {color:[[ColorPalette::TertiaryMid]];}

.sparkline {background:[[ColorPalette::PrimaryPale]]; border:0;}
.sparktick {background:[[ColorPalette::PrimaryDark]];}

.error, .errorButton {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Error]];}
.warning {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryPale]];}
.lowlight {background:[[ColorPalette::TertiaryLight]];}

.zoomer {background:none; color:[[ColorPalette::TertiaryMid]]; border:3px solid [[ColorPalette::TertiaryMid]];}

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

.annotation {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border:2px solid [[ColorPalette::SecondaryMid]];}

.viewer .listTitle {list-style-type:none; margin-left:-2em;}
.viewer .button {border:1px solid [[ColorPalette::SecondaryMid]];}
.viewer blockquote {border-left:3px solid [[ColorPalette::TertiaryDark]];}

.viewer table, table.twtable {border:2px solid [[ColorPalette::TertiaryDark]];}
.viewer th, .viewer thead td, .twtable th, .twtable thead td {background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::Background]];}
.viewer td, .viewer tr, .twtable td, .twtable tr {border:1px solid [[ColorPalette::TertiaryDark]];}

.viewer pre {border:1px solid [[ColorPalette::SecondaryLight]]; background:[[ColorPalette::SecondaryPale]];}
.viewer code {color:[[ColorPalette::SecondaryDark]];}
.viewer hr {border:0; border-top:dashed 1px [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::TertiaryDark]];}

.highlight, .marked {background:[[ColorPalette::SecondaryLight]];}

.editor input {border:1px solid [[ColorPalette::PrimaryMid]];}
.editor textarea {border:1px solid [[ColorPalette::PrimaryMid]]; width:100%;}
.editorFooter {color:[[ColorPalette::TertiaryMid]];}

#backstageArea {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::TertiaryMid]];}
#backstageArea a {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
#backstageArea a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; }
#backstageArea a.backstageSelTab {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
#backstageButton a {background:none; color:[[ColorPalette::Background]]; border:none;}
#backstageButton a:hover {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
#backstagePanel {background:[[ColorPalette::Background]]; border-color: [[ColorPalette::Background]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]];}
.backstagePanelFooter .button {border:none; color:[[ColorPalette::Background]];}
.backstagePanelFooter .button:hover {color:[[ColorPalette::Foreground]];}
#backstageCloak {background:[[ColorPalette::Foreground]]; opacity:0.6; filter:'alpha(opacity:60)';}
/*}}}*/
/*{{{*/
* html .tiddler {height:1%;}

body {font-size:.75em; font-family:arial,helvetica; margin:0; padding:0;}

h1,h2,h3,h4,h5,h6 {font-weight:bold; text-decoration:none;}
h1,h2,h3 {padding-bottom:1px; margin-top:1.2em;margin-bottom:0.3em;}
h4,h5,h6 {margin-top:1em;}
h1 {font-size:1.35em;}
h2 {font-size:1.25em;}
h3 {font-size:1.1em;}
h4 {font-size:1em;}
h5 {font-size:.9em;}

hr {height:1px;}

a {text-decoration:none;}

dt {font-weight:bold;}

ol {list-style-type:decimal;}
ol ol {list-style-type:lower-alpha;}
ol ol ol {list-style-type:lower-roman;}
ol ol ol ol {list-style-type:decimal;}
ol ol ol ol ol {list-style-type:lower-alpha;}
ol ol ol ol ol ol {list-style-type:lower-roman;}
ol ol ol ol ol ol ol {list-style-type:decimal;}

.txtOptionInput {width:11em;}

#contentWrapper .chkOptionInput {border:0;}

.externalLink {text-decoration:underline;}

.indent {margin-left:3em;}
.outdent {margin-left:3em; text-indent:-3em;}
code.escaped {white-space:nowrap;}

.tiddlyLinkExisting {font-weight:bold;}
.tiddlyLinkNonExisting {font-style:italic;}

/* the 'a' is required for IE, otherwise it renders the whole tiddler in bold */
a.tiddlyLinkNonExisting.shadow {font-weight:bold;}

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

.header {position:relative;}
.header a:hover {background:transparent;}
.headerShadow {position:relative; padding:4.5em 0em 1em 1em; left:-1px; top:-1px;}
.headerForeground {position:absolute; padding:4.5em 0em 1em 1em; left:0px; top:0px;}

.siteTitle {font-size:3em;}
.siteSubtitle {font-size:1.2em;}

#mainMenu {position:absolute; left:0; width:10em; text-align:right; line-height:1.6em; padding:1.5em 0.5em 0.5em 0.5em; font-size:1.1em;}

#sidebar {position:absolute; right:3px; width:16em; font-size:.9em;}
#sidebarOptions {padding-top:0.3em;}
#sidebarOptions a {margin:0em 0.2em; padding:0.2em 0.3em; display:block;}
#sidebarOptions input {margin:0.4em 0.5em;}
#sidebarOptions .sliderPanel {margin-left:1em; padding:0.5em; font-size:.85em;}
#sidebarOptions .sliderPanel a {font-weight:bold; display:inline; padding:0;}
#sidebarOptions .sliderPanel input {margin:0 0 .3em 0;}
#sidebarTabs .tabContents {width:15em; overflow:hidden;}

.wizard {padding:0.1em 1em 0em 2em;}
.wizard h1 {font-size:2em; font-weight:bold; background:none; padding:0em 0em 0em 0em; margin:0.4em 0em 0.2em 0em;}
.wizard h2 {font-size:1.2em; font-weight:bold; background:none; padding:0em 0em 0em 0em; margin:0.4em 0em 0.2em 0em;}
.wizardStep {padding:1em 1em 1em 1em;}
.wizard .button {margin:0.5em 0em 0em 0em; font-size:1.2em;}
.wizardFooter {padding:0.8em 0.4em 0.8em 0em;}
.wizardFooter .status {padding:0em 0.4em 0em 0.4em; margin-left:1em;}
.wizard .button {padding:0.1em 0.2em 0.1em 0.2em;}

#messageArea {position:fixed; top:2em; right:0em; margin:0.5em; padding:0.5em; z-index:2000; _position:absolute;}
.messageToolbar {display:block; text-align:right; padding:0.2em 0.2em 0.2em 0.2em;}
#messageArea a {text-decoration:underline;}

.tiddlerPopupButton {padding:0.2em 0.2em 0.2em 0.2em;}
.popupTiddler {position: absolute; z-index:300; padding:1em 1em 1em 1em; margin:0;}

.popup {position:absolute; z-index:300; font-size:.9em; padding:0; list-style:none; margin:0;}
.popup .popupMessage {padding:0.4em;}
.popup hr {display:block; height:1px; width:auto; padding:0; margin:0.2em 0em;}
.popup li.disabled {padding:0.4em;}
.popup li a {display:block; padding:0.4em; font-weight:normal; cursor:pointer;}
.listBreak {font-size:1px; line-height:1px;}
.listBreak div {margin:2px 0;}

.tabset {padding:1em 0em 0em 0.5em;}
.tab {margin:0em 0em 0em 0.25em; padding:2px;}
.tabContents {padding:0.5em;}
.tabContents ul, .tabContents ol {margin:0; padding:0;}
.txtMainTab .tabContents li {list-style:none;}
.tabContents li.listLink { margin-left:.75em;}

#contentWrapper {display:block;}
#splashScreen {display:none;}

#displayArea {margin:1em 17em 0em 14em;}

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

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

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

.title {font-size:1.6em; font-weight:bold;}

.missing .subtitle {display:none;}
.subtitle {font-size:1.1em;}

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

.tagging {margin:0.5em 0.5em 0.5em 0; float:left; display:none;}
.isTag .tagging {display:block;}
.tagged {margin:0.5em; float:right;}
.tagging, .tagged {font-size:0.9em; padding:0.25em;}
.tagging ul, .tagged ul {list-style:none; margin:0.25em; padding:0;}
.tagClear {clear:both;}

.footer {font-size:.9em;}
.footer li {display:inline;}

.annotation {padding:0.5em; margin:0.5em;}

* html .viewer pre {width:99%; padding:0 0 1em 0;}
.viewer {line-height:1.4em; padding-top:0.5em;}
.viewer .button {margin:0em 0.25em; padding:0em 0.25em;}
.viewer blockquote {line-height:1.5em; padding-left:0.8em;margin-left:2.5em;}
.viewer ul, .viewer ol {margin-left:0.5em; padding-left:1.5em;}

.viewer table, table.twtable {border-collapse:collapse; margin:0.8em 1.0em;}
.viewer th, .viewer td, .viewer tr,.viewer caption,.twtable th, .twtable td, .twtable tr,.twtable caption {padding:3px;}
table.listView {font-size:0.85em; margin:0.8em 1.0em;}
table.listView th, table.listView td, table.listView tr {padding:0px 3px 0px 3px;}

.viewer pre {padding:0.5em; margin-left:0.5em; font-size:1.2em; line-height:1.4em; overflow:auto;}
.viewer code {font-size:1.2em; line-height:1.4em;}

.editor {font-size:1.1em;}
.editor input, .editor textarea {display:block; width:100%; font:inherit;}
.editorFooter {padding:0.25em 0em; font-size:.9em;}
.editorFooter .button {padding-top:0px; padding-bottom:0px;}

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

.sparkline {line-height:1em;}
.sparktick {outline:0;}

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

* html #backstage {width:99%;}
* html #backstageArea {width:99%;}
#backstageArea {display:none; position:relative; overflow: hidden; z-index:150; padding:0.3em 0.5em 0.3em 0.5em;}
#backstageToolbar {position:relative;}
#backstageArea a {font-weight:bold; margin-left:0.5em; padding:0.3em 0.5em 0.3em 0.5em;}
#backstageButton {display:none; position:absolute; z-index:175; top:0em; right:0em;}
#backstageButton a {padding:0.1em 0.4em 0.1em 0.4em; margin:0.1em 0.1em 0.1em 0.1em;}
#backstage {position:relative; width:100%; z-index:50;}
#backstagePanel {display:none; z-index:100; position:absolute; margin:0em 3em 0em 3em; padding:1em 1em 1em 1em;}
.backstagePanelFooter {padding-top:0.2em; float:right;}
.backstagePanelFooter a {padding:0.2em 0.4em 0.2em 0.4em;}
#backstageCloak {display:none; z-index:20; position:absolute; width:100%; height:100px;}

.whenBackstage {display:none;}
.backstageVisible .whenBackstage {display:block;}
/*}}}*/
/***
StyleSheet for use when a translation requires any css style changes.
This StyleSheet can be used directly by languages such as Chinese, Japanese and Korean which need larger font sizes.
***/
/*{{{*/
body {font-size:0.8em;}
#sidebarOptions {font-size:1.05em;}
#sidebarOptions a {font-style:normal;}
#sidebarOptions .sliderPanel {font-size:0.95em;}
.subtitle {font-size:0.8em;}
.viewer table.listView {font-size:0.95em;}
/*}}}*/
/*{{{*/
@media print {
#mainMenu, #sidebar, #messageArea, .toolbar, #backstageButton, #backstageArea {display: none ! important;}
#displayArea {margin: 1em 1em 0em 1em;}
/* Fixes a feature in Firefox 1.5.0.2 where print preview displays the noscript content */
noscript {display:none;}
}
/*}}}*/
<!--{{{-->
<div class='header' macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryMid]]'>
<div class='headerShadow'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
<div class='headerForeground'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
</div>
<div id='mainMenu' refresh='content' tiddler='MainMenu'></div>
<div id='sidebar'>
<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>
<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>
</div>
<div id='displayArea'>
<div id='messageArea'></div>
<div id='tiddlerDisplay'></div>
</div>
<!--}}}-->
<!--{{{-->
<div class='toolbar' macro='toolbar closeTiddler closeOthers +editTiddler > fields syncing permalink references jump'></div>
<div class='title' macro='view title'></div>
<div class='subtitle'><span macro='view modifier link'></span>, <span macro='view modified date'></span> (<span macro='message views.wikified.createdPrompt'></span> <span macro='view created date'></span>)</div>
<div class='tagging' macro='tagging'></div>
<div class='tagged' macro='tags'></div>
<div class='viewer' macro='view text wikified'></div>
<div class='tagClear'></div>
<!--}}}-->
<!--{{{-->
<div class='toolbar' macro='toolbar +saveTiddler -cancelTiddler deleteTiddler'></div>
<div class='title' macro='view title'></div>
<div class='editor' macro='edit title'></div>
<div macro='annotations'></div>
<div class='editor' macro='edit text'></div>
<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser'></span></div>
<!--}}}-->
To get started with this blank TiddlyWiki, you'll need to modify the following tiddlers:
* SiteTitle & SiteSubtitle: The title and subtitle of the site, as shown above (after saving, they will also appear in the browser title bar)
* MainMenu: The menu (usually on the left)
* DefaultTiddlers: Contains the names of the tiddlers that you want to appear when the TiddlyWiki is opened
You'll also need to enter your username for signing your edits: <<option txtUserName>>
These InterfaceOptions for customising TiddlyWiki are saved in your browser

Your username for signing your edits. Write it as a WikiWord (eg JoeBloggs)

<<option txtUserName>>
<<option chkSaveBackups>> SaveBackups
<<option chkAutoSave>> AutoSave
<<option chkRegExpSearch>> RegExpSearch
<<option chkCaseSensitiveSearch>> CaseSensitiveSearch
<<option chkAnimate>> EnableAnimations

----
Also see AdvancedOptions
<<importTiddlers>>
* 2pm: Shangshang TiddlyWikiRSS
* 3:30: Guangchen on Ruby on Foot
* 7:30: Choir get-together: Duchess Crest condo, multipurpose function room, Ducess Avenue. Bring laptop and speakers.
Meet Michael on TiddlyCal (time to be confirmed via email)
!! Coordinates
<html>
<PRE>
Phone:+65 6516-6632
Fax:  +65 6779-4580
Email: Put my last name in front of @comp.nus.edu.sg
http://www.comp.nus.edu.sg/~henz

<EM>Postal address:</EM>
Martin Henz
NUS School of Computing
Computing 1
13 Computing Drive
Singapore 117417

<EM>Visitors and delivery:</EM>
Martin Henz
Department of Computer Science
COM 1, #03-28
National University of Singapore
</PRE>
</html>

!! Brief CV
Martin Henz studied Mathematics and Computer Science at the Saarland University, Saarbr<html>&uuml;</html>cken, Germany. He obtained his ~MSc degree from the State University of New York at Stony Brook in 1991 and his doctoral degree from the Saarland University in 1997. He worked as a research scientist at the German Research Center for Artificial Intelligence, DFKI, from 1992 to 1996 and at the Department of Computer Science at the Saarland University from 1996 to 1997.

In both positions, he contributed to the design and implementation of the concurrent constraint language Oz. His integration of object-oriented programming concepts in the framework of concurrent constraint languages led to the Oz Object System used in the Mozart system and is reported in his book Objects for Concurrent Constraint Programming.

Since 1997, Martin Henz is staff member (Associate Professor since 2006) in the School of Computing at NUS, where he conducts research on combinatorial search problems, and evolutionary processes, and teaches courses on programming languages and systems.

Together with Alan Sevugan, Martin Henz founded the software company ~FriarTuck Pte Ltd in 2001. ~FriarTuck is a software company specializing in optimized workforce management. He is currently Chief Technology Officer of the company and chairs the Board of Directors. 

!! Picture
If you want to see a picture, go [[here|Martin Henz]].
!! Project Status
available
!! Description
TiddlyCard is a client-centered browser-based platform for integrating web services. Built upon established standards such as HTML, XML, JavaScript and CSS, it leverages on AJAX technologies to provide an environment in which websites and web applications can be developed and integrated. This project is concerned with developing a potential "killer" application for TiddlyCard: an IMAP-based email client. The client will seamlessly integrate into the TiddlyCard environment, with hyper-links between emails and and other TiddlyCard content, tagging, and server-side synchronization (independently from the email server).
!! Project Status
available graduate project
!! Description
Client-centered web applications make extensive use of advanced communication techniques such as AJAX and COMET. Enforcing security, reliability and efficiency of such applications is difficult because the underlying computing platform is heterogeneous. These applications need to support numerous client and server hardware, OS and software architectures. This project proposes that a high-level "operating system" is introduced between web applications and the browser and server platforms. This operating system manages resources such as storage, network and displays and provides a coherent view of data to the clients and servers.

Initial experiments towards a web operating system are promising, currently pursued by undergraduate students in the TiddlyCard group of projects. The aim of this project is to systematically investigate the services to be provided by a web operating system, identify the available technologies and propose a suitable operating system architecture. A project deliverable is a prototypical implementation of the operating system, with both client (browser) and server components.
* [[Painting]]
* [[Fiction]]
* [[Poetry]]
!! Project Status
available
!! Description
This project forms the continuation of a successful HYP project called Asalta: A WYSIWYG Webpage Editor based on DHTML. In the project, the student developed a tool for designing web pages directly within the browser, using DHTML. The project opens the opportunity to develop a JavaScript-based graphical environment in which even kids can program simple interactions with minimal effort. Animated web pages can be defined with two or three lines of code. Even computer games are within reach of this approach.
Graduate module on Constraint and Logic Programming, see 
[[module homepage|http://www.comp.nus.edu.sg/~cs5216]]
<<calendar year:2008 month:10 numberMonths:4 numberColumns:2>>
* Timetabling
** Curriculum-based Timetabling, see [[paper|publications/#PATAT2008.abstract]].
** Constraint-based Timetabling, see [[paper|publications/#AAI96.abstract]].
* Sport tournament scheduling
** Global Constraints for Round Robin Tournaments, see [[paper|publications/#ejors.abstract]].
** An application from Professional Basketball, see [[paper|publications/#acc.abstract]].
** Constraint-based round-robin scheduling, see [[paper|publications/#robin.abstract]].
* Automated Music Composition
** Intention-based Music Composition using Constraint Programming, see [[paper|publications/#COMPOzE96.abstract]].
* [[Philosophy]]
* [[Religion]]
* [[Sustainability]]
* [[Politics]]
* [[Education]]
* [[Arts]]
* [[Yoga]]
[[Daniel Quinn|http://www.ishmael.com/]]: Author of the books "Ishmael", "[[The Story of B|http://en.wikipedia.org/wiki/The_Story_of_B]]", and "My Ishmael", "Beyond Civilization", and "[[Write Sideways|http://ishmael.org/Education/Science/index.shtml]]". Argues that the only form of "civilized" human existence that ever worked over long periods is tribalism. Read his essay "[[The New Renaissance|http://www.mnforsustain.org/quinn_d_new_renaissance.htm]]".
----
* See [[Wikipedia entry on Daniel Quinn|http://en.wikipedia.org/wiki/Daniel_Quinn]]
* Also see [[Ishmael.org|http://ishmael.org/welcome.cfm]]
* Towards a Framework for Observing Artificial Life Forms, see [[paper|publications/#ALIFE2007.abstract]], joint work with Janardan Mishra.

* DiabetesInSingapore
* DiabetesClinicalPathways
* DiabetesNews
* Clinical Pathways on Diabetes in Singapore [[http://www.pubmedcentral.nih.gov/articlerender.fcgi?artid=1121513]]
* Staged Diabetes Management in Singapore [[http://www.sma.org.sg/sma_news/3304/interview.pdf]]


Clinics

* Alexandra Hospital Diabetes Centre [[http://www.alexhosp.com.sg/medical_specialty_details.asp?id=9]]
* SGH Diabetes Centre [[http://www.sgh.com.sg/MedicalSpecialtiesnServices/SpecialistCentres/Diabetes/]]

Societies

* diabetes.com.sg [[http://www.diabetes.com.sg]]
* Diabetic Society of Singapore [[http://www.dss.org.sg]]

Talks

* At Jurong [[http://www.juronghealthconnect.com.sg/eng_v2/event.aspx]]

Government

* National Diabetes Commission [[http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?cmd=Retrieve&db=PubMed&list_uids=8165466&dopt=Abstract]]

* Vegan Diet [[http://www.foxnews.com/story/0,2933,205742,00.html]]
* [[Neil Postman]]: On Luddites, Learning and Life, see folder Documents/Papers
* [[John Dewey|http://en.wikipedia.org/wiki/John_Dewey]]: Founder of pragmatism
* [[Carl Rogers|http://en.wikipedia.org/wiki/Carl_Rogers]]: Humanist approach to clinical psychotheapy; applied his approach to education, leading to a Learner-centered model (Freedom to Learn).

!! Autodidactism
* Audrey Tan
* Michael Clark
* [[Benefits of a college degree]]

----
Miscellaneous:
* [[The Best Teacher I Ever Had]]: Short article by David Owen
* [[The Ten Faces of Innovation|http://www.amazon.com/Ten-Faces-Innovation-Strategies-Organization/dp/0385512074/ref=pd_sim_b_1/102-1487986-3674520]] Highly acclaimed book on creativity by Thomas Kelley, Jonathan Littman
* [[Ray Bradbury]]
You can configure your OS X such that the files of every user are backed up automatically whenever they log out. On Mac OS X 10.3.9, I configured {{{/etc/ttys}}} as follows:
{{{
console "/System/Library/CoreServices/loginwindow.app/Contents/MacOS/loginwindow -LogoutHook /Users/martinhenz/Scripts/logout.command" vt100 on secure onoption="/usr/libexec/getty std.9600"
}}}
The script {{{logout.command}}} uses iHook to run a backup script:
{{{
#!/bin/sh
/Applications/iHook.app/Contents/MacOS/iHook /Users/martinhenz/Scripts/backup.command
}}}
...and the backup command runs {{{rsync}}}:
{{{
#!/bin/sh

echo %WINDOWSIZE MAX

echo %BACKGROUNDSCALING TOFIT

echo %BACKGROUND /Users/martinhenz/Scripts/graces.TIF

echo %TEXTCOLOR WHITE

echo %HIDETIMER

echo "%TITLE Backing up all files of `finger $USER | grep Name | sed -e 's/Login: .*Na
me: //'` to FriarTuck.net... To quit, go to iHook -> Quit iHook."

echo %SHOWTIMER

sleep 1

echo "myrootpasswordgoeshere" | sudo -S rsync -e "ssh -i /Users/Shared/Scripts/rsync-key" -avz --for
ce --progress --exclude */.Trash --exclude *.cache --exclude */Office*/*/Database --ex
clude **/Caches/* --exclude "*/old mail*/*" --exclude */Junk*/* --exclude */Fonts/* --
exclude *Cache/* --exclude */Deleted* --exclude */*AntiSpam* --exclude */cache/* --exc
lude */iPhoto\ Library --exclude *.exe --exclude *.ttf --exclude QuickTime/* --exclude
 *.dmg /Users/$USER henz@www.friartuck.net:ibook/$USER;

echo "Backup complete."

sleep 1

exit
}}}
However, I read [[here|http://developer.apple.com/documentation/MacOSX/Conceptual/BPSystemStartup/Articles/CustomLogin.html]] that this way of doing things is not recommended for OS X v10.4. The recommended way is to use the {{{defaults}}} tool, as in 
{{{
sudo defaults write com.apple.loginwindow LoginHook /path/to/script
}}}
...will try that some time.
* [[Main features|http://www.tiddlywiki.com/#MainFeatures]]
* [[Embedded Images|http://www.tiddlywiki.com/#EmbeddedImages]]
* [[Escaping WikiWords|http://www.tiddlywiki.com/#WikiWordEscape]]
* [[Pretty Links|http://www.tiddlywiki.com/#PrettyLinks]]
!! TiddlyWiki for your Homepage?
I am not claiming that this site is particularly pretty to look at or indeed more useful than traditional homepages. Honestly, I don't really know why I am such a fan of TiddlyWiki. If you happen to share my enthusiasm and want to use TiddlyWiki for your own homepage, look at the [[TiddlyWiki homepage|http://www.tiddlywiki.com]] to see how to start from a blank TiddlyWiki and add your Tiddlers to it.

!! ~Sub-Wikis
I am using my private TiddlyWiki for more than this homepage (keeping a calendar using PlasticCalendarPlugin, making course-related webpages, keeping a diary etc). I do this all in one TiddlyWiki file called {{{wiki.html}}}. I tag entries that need to go into the homepage sub-wiki with "homepage" (see [[tags in TiddlyWiki|http://www.tiddlywiki.com/#Tags]]) and use the following [[Ruby]] script to export them to a separate file, which I then copy to my homepage.
{{{
# read from html file given by first command line parameter
originalwikiname = ARGV[0]
wiki = File.new(originalwikiname+".html", "r")
# write to html file given by second command line parameter
subwikiname = ARGV[1]
output = File.new(subwikiname+".html", File::CREAT|File::TRUNC|File::RDWR, 0644)

# process each line and write it to the subwiki
wiki.each_line {|line|
  if (line =~ /<div tiddler/)==0 && ! (line =~ /tags=\"[^\"]*#{subwikiname}[^\"]*\"/) 
  then processed = ""
  else 
    if line=~ /<div tiddler=\"#{subwikiname}/
    then
      processed=line.gsub(/<div tiddler=\"#{subwikiname}/){|match| "<div tiddler=\""}
    else
      processed=line
    end
  end
  output.print processed
}
output.close
}}}
The script copies the whole wiki, but removes all tiddlers that are not tagged with a given tag. I save this script as {{{makesubwiki.rb}}}, and call it as follows (remember that my main wiki is in file {{{wiki.html}}}):
{{{
% ruby makesubwiki.rb wiki homepage
}}}
After this, the file {{{homepage.html}}} only has the tiddlers with tag {{{homepage}}}. Then, I install the sub-wiki {{{homepage.html}}} as my homepage.
{{{
% scp homepage.html henz@www.comp.nus.edu.sg:public_html/index.html
}}}
Note that the Ruby script also removes the prefix {{{subwikiname}}} from the tiddler names. This allows me to easily maintain several sub-wikis from within the same TiddlyWiki. For example, the homepage of the module [[CS 5216|http://www.comp.nus.edu.sg/~cs5216]] is done using a sub-wiki; see [[some subwiki-specific tiddlers for CS 5216|cs5216Tiddlers]]. The tiddlers SiteTitle, SiteSubtitle, and MainMenu that you see here have the names homepageSiteTitle, homepageSiteSubtitle, and homepageMainMenu, respectively, in my {{{wiki.html}}}. Removing the prefix {{{subwikiname}}} also allows me to shadow tiddlers in {{{wiki.html}}} in the sub-wiki. For example, {{{wiki.html}}} has a different tiddler with the name ~FriarTuck, whereas the FriarTuck tiddler you see here has the name {{{homepageFriarTuck}}}.

I automate the steps to make {{{homepage.html}}} and copy it to my homepage using a shell script (the equivalent of a batch file on Windows) with the following content:
{{{
#!/bin/sh
cd /Users/henz/Documents/tiddlywiki
ruby makesubwiki.rb wiki homepage
scp homepage.html henz@www.comp.nus.edu.sg:public_html/index.html
}}}
On my desktop, I have a shortcut to this script so that I can generate and install the website with one click. [There is a little complication, tough: The RSS feed for the subwikis are not generated automatically in this method. Actually the best way for all of this is to automate the process from within TiddlyWiki instead of going through a Ruby script...]
!! TiddlyWiki
* [[How To Make a Homepage Like This]]
* [[How To Do Things In TiddlyWiki]]
* Maintain a calendar in TiddlyWiki using [[PlasticCalendarPlugin]]
* Make a slide show using SlideShowPlugin
!! Mac
* [[How To Backup Automatically Upon Logout]]
* [[Turn Off Projector using Apple Remote]]
* Make the top-menu less bright using [[MenuShade|http://www.macupdate.com/info.php/id/16640]]
* Make vector-graphics drawings using [[Inkscape|http://www.inkscape.org]]
!! Project Status
Available HYP Project
!! Description
Localization and documentation pose separate but related challenges during the software development cycle. In Java, localization is handled through property files that provide the strings required for local language content. Documentation is handled through integrated documentation management software such as DocBuilder. However, in software development practice, localization and documentation are not integrated, which leads to a large communication overhead, compounded by the challenges posed by maintenance of multiple software versions.

The IDLE project aims for an integrated environment that handles both documentation and localization and is integrated with state-of-the-art version control. A promissing environment for developing IDLE is the Eclipse development platform.
* [[Basics|IT Basics]]
* [[Ruby]]
* [[TiddlyWiki]]
* [[Linux]]
* [[JavaScript]]
* [[LaTeX]]
* [[Structured Authoring]]
* [[Mac]]
* [[Flash]]
* [[Tools|IT Tools]]
!Links
* [[One Laptop Per Child|http://www.laptop.org/vision/index.shtml]]

*  [[Flowcharts|http://en.wikipedia.org/wiki/Flowchart]]
* [[Inspirational video on internet|http://www.youtube.com/watch?v=6gmP4nk0EOE&eurl=]]
* [[IT in news publishing (interesting article)|http://www.holovaty.com/blog/archive/2006/09/06/0307]]
* [[Emacs introduction|http://www.fnal.gov/docs/products/emacs/emacs/emacs_4.html#SEC7]] (what makes Emacs powerful)
* [[Inkscape|http://www.inkscape.org]]: Free SVG-based drawing tool
* [[Django (Python for web design)|http://www.djangoproject.com/]]
* [[Wikipedia entry|http://en.wikipedia.org/wiki/Jared_Diamond]]
The language is best known for its use in websites (as client-side JavaScript), but is also used to enable scripting access to objects embedded in other applications.

Despite the name, JavaScript is only distantly related to the Java programming language, the main similarity being their common debt to the C syntax. Semantically, JavaScript syntax has far more in common with the Self programming language.
----
!!!Links:
* [[JavaScript Development Environment|http://www.squarefree.com/jsenv/]]: simple JavaScript/browser based environment of JavaScript code
* [[ProtoPage|http://www.protopage.com/]]: personal space window-style, in the browser
* [[JavaScript security|http://www.windowsitlibrary.com/Content/1160/22/1.html]]
* [[Tutorial on JavaScript security|http://www.howtocreate.co.uk/tutorials/javascript/security]]
* [[Greasemonkey: JavaScript add-ons for Firefox|https://addons.mozilla.org/firefox/748/]]
* [[lots of Greasemonkey scripts|http://userscripts.org/]]
* [[Cheat sheet|file:///Users/henz/Documents/javascript/javascript_cheat_sheet.png]]
!! Project Status
Available HYP Project
!! Description
SWF is the de-facto standard for high-quality graphic-rich interactive content on the web. Its runtime environment Flash Player is ubiquitous. SWF files are usually created by compiling ~ActionScript programs. ~ActionScript is a JavaScript dialect, and shares many of its features, good and bad. 

This project uses JavaScript instead of ~ActionScript on the client side by programming Flash content. The strategy used is to compile JavaScript directly to SWF files, making use of the virtual machine embedded in the Flash Player. The language JavaScript will be augmented with a library that represents a component framework that makes the capabilities of the Player available to the Ruby programmer.

The result will be a programming environment for high-quality graphic-rich interactive web content using the language JavaScript which is familiar to a large community of programmers. 
Conventional wisdom has it that the world economy has entered a new phase, called the "knowledge economy". In that economy, the resources that matter are not physical, they are intellectual. It does not matter what treasures lie beneath a countries soil, but what happens in the countrymen's brains.

This view has been so widely propagated that it, along with "globalization" has entered the vocabulary of every editorialist worth her salt. I have attended countless lectures and seen endless piles of papers in which the "knowledge economy" is cited as the reason why things change. The lecture or article then typically zooms into one or the other aspect of society or business life that is changing as a result, analyzes the change and discusses how to adapt to the change.

It is true that life has changed. What would I do without the internet, wikipedia, google...? The question is how deep an impact these developments have on the economy at large. 

!! Economic Impact of the Knowledge Economy
If the knowledge economy has become the main driving factor in today's world of business, and if this has been going on for a while now, you should be able to see the impact of the knowledge economy in GDP growth figures.

The reasoning goes like this: The knowledge economy part of the economy in many countries should be significant by now. If that part enjoys tremendous growth, you should see countries that do well in this sector take the lead in GDP growth figures.

So I took a look at the GDP figures of 2006 from [[photius.com|http://www.photius.com/rankings/economy/gdp_real_growth_rate_2006_0.html]]
That's the only table I could find; not sure how accurate it is. After all 2006 is not over yet. Anyway, this is the list of the 25 fastest growing countries these days:
{{{
1 		Azerbaijan	19.70
2 		Angola	19.10
3 		Equatorial Guinea	18.60
4 		Chad	18.00
5 		Armenia	13.90
6 		Turkmenistan	11.00
6 		Liechtenstein	11.00
8 		Cyprus - Turkish area	10.60
9 		Faroe Islands	10.00
10		China	9.30
11 		Venezuela	9.10
12 		Uganda	9.00
12 		Kazakhstan	9.00
14 		Qatar	8.80
15 		Argentina	8.70
16 		Libya	8.50
17 		Vietnam	8.40
18 		Latvia	8.30
19 		Tajikistan	8.00
19 		Liberia	8.00
19 		Belarus	8.00
19 		Afghanistan	8.00
19 		Congo, Republic of the	8.00
24 		Pakistan	7.80
25 		Sudan	7.70
}}}

How many of these countries are growing fast because they are latching onto the knowledge economy growth engine? Maybe the Faroe Islands? Or maybe the wool of their sheep just grew a bit faster this year?

One may argue that many of these countries are growing from a low base. Correct. But being brainwashed into knowledge-economy-think over the past years, I cannot help but wonder: Where are the shining stars of the knowledge economy? If the knowledge economy is such an overwhelming force in the business world today, why does none of the likes of Ireland or Canada or Hong Kong or New Zealand maybe, make it into the list due to their ability to exploit the new way things are going?

Maybe there is something else to learn from the list. Many countries are rich in natural resources. About half of the countries are net oil exporters...

Then I took a look at the world's largest companies. The idea would be that if the knowledge economy has been dominating the world of business for a while, it should have given rise to global giants who outshine the "old economy types". So I looked at the Fortune Global 500 list of 2006 and found:

{{{
1. Exxon Mobil
2. Wal-Mart Stores
3. Royal Dutch Shell
4. BP
5. General Motors
6. Chevron
7. DaimlerChrysler
8. Toyota Motor
9. Ford Motor
10. ConocoPhillips
}}}

I'm sure all of these companies are making lots of use of IT and have very bright people to run their business, but none of them fit my idea of "knowledge economy". Half of them in fact are oil companies. The other half is making cars (with Wal-Mart as an oddity). Unlisted companies are not even included in the Global 500, otherwise the list would be topped by the Saudi-Arabian state-owned oil giant Saudi Aramco, whose size by far exceeds the biggest listed company Exxon Mobil. The questions arise: Where are the shining new Rockefeller-Carnegie-types of the 21st century? Why does this list look so "retro"?

So how about this: The knowledge economy has come to an end, and what we are seeing is a transition into the resource economy. What matters from now on is what treasures lie under your soil, how efficiently you can get these treasures out and how well you are distributing the resulting income among your population to achieve a stable society.  
!! Project Status
available
!! Description
JavaScript enjoys increasing popularity. As a general purpose programming language, however, it suffers from an absence of a lexical analyzer generator in the style of the Unix tool Lex. The result is that language processing is very cumbersome with JavaScript. This project aims to overcome this limitation by developing a full-fledged lexical analyzer generator that is written purely in JavaScript, and generates JavaScript code for the lexical analysis of a regular language as specified in form of regular expressions, given in an input file or JSON data structure.
* [[Nice intro|http://www.sci.usq.edu.au/staff/robertsa/LaTeX/latexintro.html]]
* [[Writing LaTeX Classes and Packages|http://tex.loria.fr/general/new/clsguide.html]]
* [[Beamer source|ftp://ftp.dante.de/tex-archive/macros/latex/contrib/beamer/]]
* [[The Comprehensive LaTeX Symbol List|http://www.ctan.org/tex-archive/info/symbols/comprehensive/]]
* [[Extraordinary symbols|http://www.iam.ubc.ca/~newbury/tex/symbols.html]] including large backets
* Infix notation arithmetics using calc package
* make your own floats
{{{
\usepackage{float}
\newfloat{Program}{tbp}{lop}[section] 
\listof{Program}{List of Programs}
}}}
See [[documentation of float package|http://ftp.ktug.or.kr/tex-archive/macros/latex/contrib/float/float.pdf]]
* [[Ubuntu|http://www.ubuntu.com/]]
* [[One Laptop Per Child|http://www.laptop.org/]]
M^^2^^ICAL is a model for imperfect comparison algorithms using Monte Carlo simulation and Markov chains.

~PhD student project by Oon Wee Chong.
 [[Research]]
 [[Teaching]]
[[Projects]]
[[FriarTuck]]
[[TiddlyCard]]
----
[[IT]]
[[Culture]]
[[Ramblings]]
[[HowTos]]
----
<<tag contact>>
[[Calendar]]
[[Calendar Year]]
----
[[teachingMainMenu]]
[[Current stuff|Specific Information regarding Student Support Sem 2 2007/2008]]
----
[[cs1102sMainMenu]]

[img[Martin Henz|http://www.comp.nus.edu.sg/~henz/henz.jpg]]
Yes, that's me. Or more accurately, a rather old photo of me. Am not getting prettier, so why bother taking a new photo?

A library for generating Flash based on Ming.
* [[Ming/Ruby homepage|http://rubyforge.org/projects/mingruby/]]
* [[Ikegami's Ming/Ruby page|http://madscientist.jp/~ikegami/ruby/ming/index.html]]
Social critic
* [[Kelly Reedy|http://www.kellyreedy.com]]
!! Sources
* John Rawlins article on Peak Oil: [[http://www.raisethehammer.org/index.asp?id=336]]
* [[C.J. Campbell's lecture at Clausthal in 2000|http://www.hubbertpeak.com/de/lecture.html]]: Lots of statistics, outdated now of course
* [[Predicting global health trends---Why Peak Oil matters|http://www.energybulletin.net/24397.html]] Essay by Dan Bednarz
* [[Short common-sense essay on Peak Oil and Food|http://eatthestate.org/11-09/SaveHumans.htm]] by Colin Wright
* [[Peak Oil Medicine|http://peakoilmedicine.wordyblog.com/]]
!! Further Pointers
* [[Singapore Peak Oil|http://singaporepeakoil.wordpress.com/]]
* John Rawlins: Nuclear physicist turned peak oil activist, [http://faculty.whatcom.ctc.edu/jrawlins/]
* [[Neil Postman]]: Prominent social critic
* [[John Dewey|http://en.wikipedia.org/wiki/John_Dewey]]: Founder of pragmatism
* [[Zoroaster|http://en.wikipedia.org/wiki/Zoroaster]]
* [[Elise Springer|http://espringer.web.wesleyan.edu]]: Moral philosopher who is interested in educational technology, bicycles and TiddlyWiki.
* [[Gregory Bateson]]: American anthropologist with wide-ranging interests
* [[Paul Kurtz|http://en.wikipedia.org/wiki/Paul_Kurtz]], humanist and skeptic
!! Life
* [[Does life violate the Second Law of Thermodynamics|http://www.panspermia.org/seconlaw.htm]]: Good discussion and many references
!! Memes
* [[Everything is pointless|http://everythingispointless.blogspot.com/2006/11/conversation-with-susan-blackmore.html]]: A brief conversation between Louie Savva and Susan Blackmore
* [[Happiness Meme]]
* [[John Horgan|http://www.johnhorgan.org/]]: science journalist with interesting ideas on progress, Zen, free will etc
/***
|''Name:''|PlasticCalendarPlugin|
|''Description:''|This plugin creates a custom Gregorian calendar|
|''Version:''|1.3.0|
|''Date:''|Sep 18, 2006|
|''Source:''|http://www.math.ist.utl.pt/~psoares/addons.html|
|''Author:''|Paulo Soares (psoares (at) math (dot) ist (dot) utl (dot) pt)|
|''License:''|[[BSD open source license]]|
|''~CoreVersion:''|2.1.0|
|''Browser:''|Firefox 1.0.4+; Firefox 1.5; InternetExplorer 6.0|
!Description
This plugin creates a custom Gregorian calendar. A single month calendar has navigation buttons at the top line in order to change month and year. With multiple months the calendar is static. Different categories of holidays can be defined in a configuration tiddler and those categories can be styled by the user. There's also a simple scheduling mechanism.
This plugin is based on previous work by [[TiagoDionízio|http://mega.ist.utl.pt/~tngd/twiki/twiki.cgi/]]'s.
!Usage
Copy this tiddler to your TW, tag it with 'systemConfig', save your TW, refresh your browser and drop {{{<<calendar>>}}} in a tiddler to get a calendar for the current month. You can also use any of the following options {{{<<calendar year:2007 month:6 numberMonths:6 numberColumns:2 tag:'work'>>}}}.

You can also label the schedules with multiple tags separating them with {{{#}}} such as {{{tag:'work#excludeLists'}}}. However only the first tag is used to display scheduled days in the calendar.
!Revision history
1.3.0 - 18/09/2006
*small changes to work with TW2.1
1.2.1 - 04/06/2006
*restored the use of multiple tags
1.2.0 - 18/05/2006
*plugin name changed to PlasticCalendarPlugin (because there are other ~CalendarPlugin's out there...)
*now using named parameters
*added categories of holidays (suggested by Paco Rivière)
1.1.0 - 02/10/2005
*initial release
!Code
***/
{{{
// --------------------------------------------------------------------
// Calendar
// --------------------------------------------------------------------

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

 dt_current_day.setDate(dt_current_day.getDate()+1);
 }
 }
}

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

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

store.addNotification(null, refreshCalendars);

setStylesheet("/***\n!Calendar Styles\n***/\n/*{{{*/\n .viewer .calendarHolder {\n margin-left: auto;\n margin-right: auto;\n border: none;\n}\n\n .viewer .calendarHolder table {\n border: none;\n margin: 0;\n}\n\n .viewer .calendarHolder tr {\n border: none;\n vertical-align: top;\n}\n\n .viewer .calendarHolder td {\n border: none;\n vertical-align: top;\n}\n\n .viewer #calendarWrapper {\n width: 21em;\n border: 2px solid #4682b4;\n cursor: pointer;\n}\n\n #calendarWrapper #calendarLine td {\n height: 2.5em;\n}\n\n #calendarWrapper tr {\n border:none;\n}\n\n #calendarWrapper td {\n text-align: center;\n vertical-align: middle;\n width: 14.28%;\n border:none;\n}\n\n #calendarWrapper #calendarHeader td{\n color: #ffffff;\n background-color: #4682b4;\n height: 2em;\n}\n\n #calendarWrapper #weekNames td {\n color: #ffffff;\n background-color: #87cefa;\n height: 2em;\n}\n\n #calendarWrapper .weekDay {\n background-color: #ccff99;\n}\n\n #calendarWrapper .holiDay {\n background-color: #9acd32;\n}\n\n #calendarWrapper .currentDay {\n border: solid #ff0000 2px;\n font-weight: bold;\n}\n\n #calendarWrapper .currentscheduledDay {\n border: solid #ff0000 2px;\n font-weight: bold;\n}\n\n #calendarWrapper .workingDay {\n background-color: #ffffff;\n}\n\n #calendarWrapper .scheduledDay {\n border: solid orange 2px;\n}\n\n #calendarWrapper .otherMonthDay {\n background-color: #999;\n}\n\n/*}}}*/","CalendarStyles");
}}}
* [[Robinson Jeffers|http://en.wikipedia.org/wiki/Robinson_Jeffers]]
* [[Antiwar.com|www.antiwar.com]]: news website with strong Libertarian bend; great commentary by Justin Raimondo (also chief editor)
**  [[Why Justin Raimondo writes|http://www.antiwar.com/justin/?articleid=10208]]: Brilliant reflections on empires and why they should be confronted (Christmas 2006)
* [[WikiLeaks|http://www.wikileaks.org/index.html]]: Wiki for leaking documents and whistleblowing
* [[Chris Floyd|http://www.chris-floyd.com/]]: American journalist with a keen eye on the impact of current politics on large-scale historical developments.
* [[Noam Chomsky|http://www.chomsky.info/]]: Political activist and scientist. Well known for his analysis of US post-WWII politics in the Far East (including East Timor), the Balkans and the Middle East. See [[Wikipedia entry on Chomsky|http://en.wikipedia.org/wiki/Noam_Chomsky]]
* [[Eat The State|http://eatthestate.org/]]: Smart left-leaning commentary
* [[Charley Reese on Sending Kids to Iraq|http://www.antiwar.com/reese/?articleid=10405]]
!!Iraq
* [[USAID in Iraq|http://www.usaid.gov/iraq/accomplishments/foodsec.html]]: USAID manages the Public Distribution System of food established by Saddam Hussein.
!!Somalia
Virtually ignored by the world public is the open intervention of US in Somalia on January 9, 2007, using helicopter gunships. Reports on US support of the Ethiopian invasion in Somalia Dec 2006 to Jan 2007 were not officially confirmed by the US. See:
[[Wikipedia entry on Somalia|http://en.wikipedia.org/wiki/Somalia]]
!! Proposed Graduate Projects
* [[The Impact of Web Technologies on Enterprise Software]]
* [[Towards a Formal Framework for Characterizing Evolutionary Behavior]] 	
* [[An Operating Systems Perspective for Client-centered Web Applications]]
!! Current Students
* Stanley Lew, FYP: [[LEX for JavaScript]]
* Srividhya Sridharan, FYP: [[YACC for JavaScript]]
* Li Shuyan, FYP: [[JavaScriptFlash: Compiling JavaScript to SWF]]
* N. Thyagarajan, FYP: [[IDLE: Integrated Documentation and Localization Environment]]
* Kim Ji Hoon, Peter, FYP: [[Desktop for TiddlyCard]]
* Ying Fangting, Ariel, SMP: [[Peer-to-peer Games using TiddlyCard]]
!! Former ~PhD Student
* Oon Wee Chong, ~PhD student, thesis topic: M2ICAL: A Technique for Analyzing Imperfect Comparison Algorithms Using Markov Chains, see [[thesis|students/oonwc.pdf]] (2007).
!! Former Master's Students and their Projects
* Janardan Mishra, Master's student, Project: Observing Artificial Life Evolution: A Formal Algebraic Framework, See [[thesis|students/janardan.pdf]] (2005). 
* Daniel Hogberg, Master's student, Project: Complexity in Artificial Life. See [[thesis|students/daniel.pdf]] (2005).
* Wang Zhangqing, Stella, Master's student, Project: Reconfigurable Hardware SAT Solving. See [[thesis|students/wang_zhangqing.pdf]] (2003).
* Tan Woon Kiong, Master's student, Project: GNOPL - An Implementation of a Subset of OPL. See [[thesis|students/woonkiong.pdf]] (2003).
* Choi Chiu Wo, Jefferson, project: Advanced Components for Finite Domain Constraint Programming, Master's student. See [[thesis|students/choi_thesis.pdf]] (2002).
* Tan Rey Sy, Edgar, Master's student, Project: Local Search Algorithms for SAT on Field-programmable Gate Arrays, co-supervised by Roland Yap and me. See [[thesis|students/tan_edgar_thesis.pdf]] (2001).
* Ong Kar Loon, Master's student. Project: Using the Assignment Problem for Pruning in Combinatorial Optimization. See [[thesis|students/ong_thesis.pdf]] (2001).
* Lua Seet Chong, Master's student. See [[thesis|students/lua_thesis.pdf]] (2001).
* Ng Ka Boon, Master's student, project: A Generic Software Framework for Finite Domain Constraint Programming. See [[thesis|students/ng_thesis.pdf]] (2001).
!! Former HYP Students and their Projects
* Chua Ruiwen, FYP: [[Application Management and Deployment for TiddlyCard]]. See [[report|students/ruiwen.pdf]] (2008).
* Pang Qiwen Jaysen, FYP: [[Webo: A Browser-based Animation Tool]]. See [[report|students/jaysen.pdf]] (2008).
* Chen Xi, FYP: [[Email Client for a Browser-based Application Platform]] (using Chilkat). See [[report|students/chenxi.pdf]] (2008).
* Alvin Ng, FYP: [[An Email Plugin for TiddlyCard]] (using Flash), (2008).
* Daryl Seah, Honours Year student, Project: Foundations for a Browser-based Application Platform. See [[report|students/daryl.pdf]] and [[appendix|students/daryl_appendix.pdf]] (2008).
* Lek Hsiang Hui, Honours Year student, Project: A Network Framework for a Browser-based Application Platform. See [[report|students/hsianghui.pdf]] (2008).
* Zhou Lin, Richard, Honours Year student, Project: Debugging and Testing in a Browser-based Application Platform. See [[report|students/richard.pdf]] (2008).
* Tran Khoa Nguyen, Honours Year student, Project: ~WebCollab, A Browser-based Collaborative Environment. See [[report|students/khoanguyen.pdf]] (2008).
* Tang Tung Leh, Honours Year student, Project: A Framework for Data Visualization in a Browser-based Application Platform. See [[report|students/tungleh.pdf]] (2008).
* Lem Hongjian, Honours Year student, Project: ~RubyOnFlash. See [[report|students/hongjian.pdf]] (2007). See also open-source project [[Ruby On Flash|http://sourceforge.net/projects/rubyonflash]].
* Michael Lin, Honours Year student, Project: ~TiddlyCal. See [[report|students/michael.pdf]] (2007).
* Wang Shangshang, Honours Year student, Project: ~TiddlyRSS. See [[report|students/shangshang.pdf]] (2007). 
* Siva Subramanian, Honours Year student, Project: Asalta. See [[report|students/siva.pdf]] (2007). See also open-source project [[Asalta|http://sourceforge.net/projects/asalta]].  
* J Vedvyas, Honours Year Student, Project: RISAC - Reduced Instruction Set Artificial Chemistry. See [[thesis|students/vedvyas.pdf]] (2005).
* Chua Bee Peng, Honours Year Student, Project: An Experimentation Platform for Graph Chemistries. See [[thesis|students/bee_peng.pdf]] (2005).
* Jimmo Barrion Petisme, Honours Year Student, Project: Semantics and implementation of Plankalk<html>&uuml;</html>l. See [[thesis|students/jimmo_thesis.pdf]] (2004).
*  Chew Tee Yong, Honour's Year Student. Project: ~SearchToolKit: A Toolkit for Constraint-based Tree Search. See [[thesis|students/chew_thesis.pdf]] (1999).
* Gan Tiaw Leong, Honours Year Student, Project: Constraint Programming for the Traveling Tournament Problem. See [[thesis|students/gan_tiaw_leong.pdf]] (2003).
* Zhou Jingtao, Honours Year Student, Project: Figaro: Software Design Patterns for Combinatorial Search. See [[thesis|students/zhou.pdf]] (2003).
* Gao Chao Wei, Honours Year Student, Project: Component-based Visualization of Tree Search. See [[thesis|students/gao_chao_wei.pdf]] (2003).
!! Other Student Projects
* Zhang Da, UROP student, Project: Constraint Programming Assistant (2004)
* Le Xuan Thang, Master's student by coursework, dissertation project, Project: Berlioz - Compiling Oz to Java Bytecode. See [[thesis|students/le_thesis.pdf]] (2001).
* Vivek Singh, Master's student by coursework, dissertation project. Project: Distributed Problem Solving in Mozart (Magic Knights Tour). See [[thesis|students/singh_thesis.pdf]] (2001).
* Tony Tan, UROP student. Project: An Overview of Some Simple Constraints and Their Filtering Algorithms. See [[thesis|students/tony_tan.pdf]] (2000).
* Marleen Van Brandenburg, visiting student. Project: Intermural Tournament Planning - Dutch Soccer League. See [[report|students/brandenburg.pdf]] (2000).
* Sevugan A/l Alagappan; Chung Yue Shun, Steven; Chai Jia Jih: Third Year Project "Online Tournament Scheduling" (2000).
American fiction writer known for writing [[Fahrenheit 451]].
* [[Combinatorial Optimization]]
* [[Defining Evolution]]
* [[Client-centered Web-based Computing|TiddlyCard]]
----
* [[Publications|http://www.comp.nus.edu.sg/~henz/publications]]
* Learning Ruby
** [[Ruby QuickRef|http://www.zenspider.com/Languages/Ruby/QuickRef.html]]
** [[Programming Ruby|http://www.rubycentral.com/book/]]
** [[Interactive Ruby on web page|http://tryruby.hobix.com/]]
** [[Regular expressions in Ruby|http://www.rubyist.net/~slagell/ruby/regexp.html]]
* Projects
** [[Ming/Ruby]]: A library for generating Flash based on Ming
** [[Hirameki|http://madscientist.jp/~ikegami/ruby/]]: Another library for Flash
** [[Hiki|http://hikiwiki.org/en/]]: Wiki clone written in Ruby
** [[MetaRuby|http://www.zenspider.com/Languages/Ruby/MetaRuby.html]] Implementation of Ruby in Ruby

* Community
**  [[The Impending Ruby Fracture|http://blog.lostlake.org/index.php?/archives/11-The-Impending-Ruby-Fracture.html]]
HYP student: Lem Hongjian. Project start: 12/2006

* [[Project Wiki|http://lem.tiddlyspot.com]]
!!Links
* [[Discussion on Ruby to SWF compiler|http://ariaware.com/pipermail/arp_ariaware.com/2006-January/000890.html]]
* [[Parrot|http://www.parrotcode.org/]] VM that serves as target for several implementations, including JavaScript and Ruby
* [[CASA Framework|http://casaframework.org/]]
* [[ARP Framework|http://osflash.org/arp]]
My home faculty at NUS, see [[School of Computing homepage|http://www.comp.nus.edu.sg]].
by [[Martin Henz]]
pointers and thoughts
/***
|''Name:''|SlideShowPlugin|
|''Description:''|Creates a simple slide show type display|
|''Version:''|1.5.1|
|''Date:''|Nov 10, 2006|
|''Source:''|http://www.math.ist.utl.pt/~psoares/addons.html|
|''Author:''|Paulo Soares (psoares (at) math (dot) ist (dot) utl (dot) pt) and [[Clint Checketts|http://www.checkettsweb.com]]|
|''License:''|[[BSD open source license]]|
|''~CoreVersion:''|2.1.0|
|''Browser:''|Firefox 1.0.4+; Firefox 1.5; InternetExplorer 6.0|
<<tiddler SlideShowPluginDoc>>
!Code
***/
//{{{
config.macros.slideShow = {label: "slide show", maxTOCLength: 30};
config.macros.slideShow.messages = {gotoLabel: "Go to slide:"};
config.views.wikified.slideShow = {text: "slide show", tooltip: "Start slide show"};
config.views.wikified.slideShow.quit = {text: "end", tooltip: "Quit the slide show"};
config.views.wikified.slideShow.firstSlide = {text: "<<", tooltip: "first slide"};
config.views.wikified.slideShow.previousSlide = {text: "<", tooltip: "previous slide"};
config.views.wikified.slideShow.nextSlide = {text: ">", tooltip: "next slide"};
config.views.wikified.slideShow.lastSlide = {text: ">>", tooltip: "last slide"};
config.views.wikified.slideShow.resetClock = {text: " ", tooltip: "reset"};

config.formatters.push( {
 name: "SlideSeparator",
 match: "^-s-+$\\n?",
 handler: function(w)
 {
 createTiddlyElement(w.output,"hr",null,'slideSeparator');
 }
}
)

function changeStyleSheet(tiddlerName) {
 if (tiddlerName == null) tiddlerName = "StyleSheet";
 setStylesheet(store.getRecursiveTiddlerText("StyleSheetColors"),"StyleSheetColors");
 setStylesheet(store.getRecursiveTiddlerText("StyleSheetLayout"),"StyleSheetLayout");
 var theCSS = store.getRecursiveTiddlerText(tiddlerName,"");
 setStylesheet(theCSS,"StyleSheet");
}

//Excellent (and versatile) reparser created by Paul Petterson for parsing the paramString in a macro
function reparse( params ) {
 var re = /([^:\s]+)(?:\:((?:\d+)|(?:["'](?:[^"']+)["']))|\s|$)/g;
 var ret = new Array() ;
 var m ;
 while( (m = re.exec( params )) != null ) ret[ m[1] ] = m[2]?m[2]:true ;
 return ret ;
}

function getElementsByClass(searchClass,node,tag) {
 var classElements = new Array();
 if ( node == null ) node = document;
 if ( tag == null ) tag = '*';
 var els = node.getElementsByTagName(tag);
 var elsLen = els.length;
 var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
 var j=0;
 for (var i = 0; i < elsLen; i++) {
 if ( pattern.test(els[i].className) ) {
 classElements[j] = els[i];
 j++;
 }
 }
 return classElements;
}

// 'keys' code adapted from S5 which in turn was adapted from MozPoint (http://mozpoint.mozdev.org/)
function keys(key) {
 if (document.getElementById('contentWrapper').className == "slideShowMode"){
 if (!key) {
 key = event;
 key.which = key.keyCode;
 }
 switch (key.which) {
 case 32: // spacebar
 if(time>0){
 if(autoAdvance){
 clearInterval(autoAdvance);
 autoAdvance = null;
 } else {
 autoAdvance=setInterval("GoToSlide(1)", time);
 }
 }
 break;
 case 34: // page down
 case 39: // rightkey
 GoToSlide("n");
 break;
 case 40: // downkey
 GoToSlide(-1);
 break;
 case 33: // page up
 case 37: // leftkey
 GoToSlide("p");
 break;
 case 38: // upkey
 GoToSlide(1);
 break;
 case 36: // home
 GoToSlide("f");
 break;
 case 35: // end
 GoToSlide("l");
 break;
 case 27: // escape
 endSlideShow();
 break;
 }

 }
 return false;
}

function clicker(e) {
 if (!e) var e = window.event;
 var target = resolveTarget(e);
 //Whenever something is clicked that won't advance the slide make sure that the table of contents gets hidden
 if (target.getAttribute('href') != null || isParentOrSelf(target, 'toc') || isParentOrSelf(target,'embed') || isParentOrSelf(target,'object') || isParentOrSelf(target, 'pageFooter') || isParentOrSelf(target, 'navigator')){
 //Don't hide the TOC if the indexNumbers (which trigger the index) is clicked
 if(isParentOrSelf(target,'indexNumbers') || isParentOrSelf(target,'jumpInput')){
 return true;
 }
 showHideTOC('none');
 return true;
 }
 
 //Advance a slide if the TOC is visible otherwise make sure that the TOC gets hidden
 if ((!e.which && e.button == 1) || e.which == 1) {
 if (document.getElementById('toc').style.display != 'block'){
 GoToSlide("n");
 } else {
 showHideTOC('none');
 }
 }
 
 if ((!e.which && e.button == 2) || e.which == 3) {
 if (document.getElementById('toc').style.display != 'block'){
 GoToSlide("p");
 } else {
 showHideTOC('none');
 }
 return false;
 }
}

function isParentOrSelf(element, id) {
 if (element == null || element.nodeName=='BODY') return false;
 else if (element.id == id) return true;
 else return isParentOrSelf(element.parentNode, id);
}

GoToSlide=function(step) {
 var new_pos;
 var slideHolder = document.getElementById('slideContainer');
 //The parse float ensures that the attribute is returned as a number and not a string.
 var cur_pos = parseFloat(slideHolder.getAttribute('currentslide'));
 var numberSlides = parseFloat(slideHolder.getAttribute('numberSlides'));
 switch (step) {
 case "f":
 new_pos=0;
 break;
 case "l":
 new_pos=numberSlides-1;
 break;
 case "n":
 var numberOverlays = parseFloat(slideHolder.childNodes[cur_pos].getAttribute('numberOverlays'));
 var currentOverlay = parseFloat(slideHolder.getAttribute('currentOverlay'));
 if(numberOverlays==0 || currentOverlay==numberOverlays){
 new_pos=cur_pos+1;
 } else {
 var className="Overlay"+currentOverlay;
 var overlay=getElementsByClass(className,slideHolder.childNodes[cur_pos]);
 for(var i=0; i<overlay.length; i++) {overlay[i].className=className+' previousOverlay';}
 currentOverlay++;
 slideHolder.setAttribute('currentOverlay',currentOverlay);
 className="Overlay"+currentOverlay;
 overlay=getElementsByClass(className,slideHolder.childNodes[cur_pos]);
 for(i=0; i<overlay.length; i++) {overlay[i].className=className+' currentOverlay';}
 return false;
 }
 break;
 case "p":
 var numberOverlays = parseFloat(slideHolder.childNodes[cur_pos].getAttribute('numberOverlays'));
 var currentOverlay = parseFloat(slideHolder.getAttribute('currentOverlay'));
 if(numberOverlays==0 || currentOverlay==0){
 new_pos=cur_pos-1;
 } else {
 var className="Overlay"+currentOverlay;
 var overlays=getElementsByClass(className,slideHolder.childNodes[cur_pos]);
 for(var i=0; i<overlays.length; i++) {overlays[i].className=className+' nextOverlay';}
 currentOverlay--;
 className="Overlay"+currentOverlay;
 overlays=getElementsByClass(className,slideHolder.childNodes[cur_pos]);
 for(i=0; i<overlays.length; i++) {overlays[i].className=className+' currentOverlay';}
 slideHolder.setAttribute('currentOverlay',currentOverlay);
 return false;
 }
 break;
 default:
 new_pos=cur_pos+step;
 }

 if(slideShowCircularMode && new_pos == numberSlides) new_pos=0;
 if(slideShowCircularMode && new_pos<0) new_pos=(numberSlides - 1);
 if(step!=0 && new_pos>=0 && new_pos<numberSlides) {
 slideHolder.childNodes[cur_pos].style.display='none';
 slideHolder.childNodes[new_pos].style.display='block';
 slideHolder.setAttribute('currentslide',new_pos);
 var numberOverlays = parseFloat(slideHolder.childNodes[new_pos].getAttribute('numberOverlays'));
 if(step=="p"){
 var currentOverlay=numberOverlays;
 var state=' previousOverlay';
 } else {
 var currentOverlay=0;
 var state=' nextOverlay';
 }
 slideHolder.setAttribute('currentOverlay',currentOverlay);
 if(numberOverlays>0) {
 for(var i=1; i<=numberOverlays; i++){
 var className="Overlay"+i;
 var overlays=getElementsByClass(className,slideHolder.childNodes[new_pos]);
 for(var j=0; j<overlays.length; j++) {overlays[j].className=className+state;}
 }
 if(step=="p"){
 var className="Overlay"+numberOverlays;
 var overlays=getElementsByClass(className,slideHolder.childNodes[new_pos]);
 for(var j=0; j<overlays.length; j++) {overlays[j].className=className+' currentOverlay';}
 }
 }
 new_pos++;
 var indexNumbers = document.getElementById('indexNumbers');
 indexNumbers.firstChild.data = new_pos+'/'+numberSlides;
 if((new_pos==numberSlides) && !slideShowCircularMode && autoAdvance) clearInterval(autoAdvance);
 return true;
 }
 return false;
}

function tocShowSlide(e) {
 if (!e) var e = window.event;
 var target = resolveTarget(e);
 var slide = target.getAttribute('slideNumber');
 var cur_pos = document.getElementById('slideContainer').getAttribute('currentslide');
 var step = slide-cur_pos;
 if(step!=0) GoToSlide(step);
 showHideTOC('none');
 return;
}

//Toggle the display of the table of contents
function showHideTOC(display){
 var toc = document.getElementById('toc');
 //Reset the input box
 document.getElementById('jumpInput').value = "";

 if (display == null || display.length == null){
 if (toc.style.display == 'none' || toc.style.display == ''){
 toc.style.display = 'block';
 document.getElementById('jumpInput').focus();
 } else {
 toc.style.display = 'none';
 }
 } else {
 toc.style.display = display;
 if (display == 'block')
 document.getElementById('jumpInput').focus();
 }
}

function makeSignature(title,params){
 var signature = title+store.getTiddler(title).modified;
 if(params['style']) signature += params['style'];
 if(params['repeat']) signature += "repeat";
 if(params['slidePause'] > 0) signature += params['slidePause'];
 if(params['autostart']) signature += "autostart";
 if(params['clock']) signature += params['clock'];
 if(params['noOverlays']) signature += "noOverlays";
 return signature;
}

function padZero(x){
 return (x>=10 || x<0 ? "" : "0")+x;
}

setClock=function(){
 var actualTime = new Date();
 var newTime = actualTime.getTime() - clockStartTime;
 newTime = clockMultiplier*newTime+clockInterval+clockCorrection;
 actualTime.setTime(newTime);
 newTime = padZero(actualTime.getHours()) + ":" + padZero(actualTime.getMinutes())+ ":" + padZero(actualTime.getSeconds());
 var clock = document.getElementById('slideClock');
 clock.firstChild.nodeValue = newTime;
}

resetClock=function(){
 var time = new Date(0);
 if(clockStartTime>time){
 var startTime = new Date();
 clockStartTime=startTime.getTime();
 }
}

var title;
var place;
var autoAdvance=null;
var autoStart=null;
var slideClock=null;
var noOverlays=false;
var time = 0;
var slideShowCircularMode;
var slideShowStyleSheet;
var slideShowParams;
var clockMultiplier;
var clockInterval;
var clockCorrection=0;
var clockStartTime;
var openTiddlers;

config.macros.slideShow.handler = function(aPlace,macroName,params,wikifier,paramString,tiddler){
 if(tiddler instanceof Tiddler){
 var lingo = config.views.wikified.slideShow;
 var autostart = false;
 if (!e) var e = window.event;
 
 place = aPlace;
 title = tiddler.title;
 params = reparse(paramString);
 var onclick = function(){config.macros.slideShow.onClickSlideShow(params);};
 createTiddlyButton(aPlace,lingo.text,lingo.tooltip,onclick);
 
 var slideShowHolder = document.getElementById('slideShowWrapper');
 //If no show exist previously, create it
 if(params['autostart']){
 if(slideShowHolder != null){
 var signature = slideShowHolder.getAttribute('showSignature');
 if(signature.indexOf("autostart")==-1) autostart = true;
 } else {autostart = true;}
 if(autostart){
 slideShowParams = params;
 setTimeout(config.macros.slideShow.onClickSlideShow,100);
 }
 }
 }
}

var disableFunction = function(e){return false;}
var enableFunction = function(e){}

config.macros.slideShow.onClickSlideShow = function(newParams) {
 if(typeof(newParams)=="number") newParams=slideShowParams;
 openTiddlers = new Array;
 var viewer=document.getElementById('tiddlerDisplay');
 for(var i=0; i<viewer.childNodes.length; i++){
 var name = viewer.childNodes[i].getAttribute('tiddler');
 openTiddlers.push(name);
 }
 document.oncontextmenu = disableFunction;
 clockMultiplier = 1;
 clockInterval = 0;
 var startTime = new Date(0);
 slideShowCircularMode = false;
 time = 0;
 slideShowStyleSheet = null;
 if(newParams['style']){
 slideShowStyleSheet = eval(newParams['style']);
 } 
 if(newParams['repeat']){
 slideShowCircularMode = true;
 }
 if(newParams['slidePause'] > 0){
 time = newParams['slidePause'];
 }
 if(newParams['clock']){
 clockCorrection=startTime.getTimezoneOffset()*60000;
 startTime = new Date();
 var clockType= eval(newParams['clock']);
 if(clockType != '+') {
 clockMultiplier = -1;
 clockInterval = -clockType*60000;
 }
 }
 clockStartTime=startTime.getTime();
 if(newParams['noOverlays']){
 noOverlays = true;
 }
 var contentWrapper = document.getElementById('contentWrapper');
 if (contentWrapper.className != "slideShowMode"){
 clearMessage();
 //Attach the key and mouse listeners
 document.onkeyup = keys;
 document.onmouseup = clicker;
 
 var slideShowHolder = document.getElementById('slideShowWrapper');
 story.refreshTiddler(title,"SlideShowViewTemplate",true);
 //If no show exist previously, create it
 if(slideShowHolder == null){
 createSlides(newParams);
 //If there was once waiting in the background and it matches the one we just started, resume it
 } else if (slideShowHolder.getAttribute('showSignature') == makeSignature(title,newParams)){
 
 //Remove dblClick on edit function
 var theTiddler = document.getElementById("tiddler"+title);
 theTiddler.ondblclick = function() {};

 // Grab the 'viewer' element and give it a signature so the show can be resumed if stopped
 var tiddlerElements = theTiddler.childNodes;
 var viewer;
 for (var i = 0; i < tiddlerElements.length; i++){
 if (tiddlerElements[i].className == "viewer") viewer = tiddlerElements[i];
 }
 theTiddler.insertBefore(slideShowHolder,viewer);
 theTiddler.removeChild(viewer);
 slideShowHolder.style.display = 'block';
 document.getElementById("pageFooter").className = "pageFooterOff";
 
 //If the show we started it totally new than the resumable one, create the new one and kill the resumable one
 } else {
 slideShowHolder.parentNode.removeChild(slideShowHolder);
 createSlides(newParams);
 }
 slideClock=setInterval("setClock()", 1000); 
 if(time>0) autoAdvance=setInterval("GoToSlide(1)", time); 
 story.closeAllTiddlers(title);
 toggleSlideStyles();
 } else {
 endSlideShow();
 }
 return ;
 
}

function endSlideShow(){
 //Set aside show so it can be resumed later
 var showHolder = document.getElementById('slideShowWrapper');
 showHolder.style.display = 'none';
 document.getElementById('contentWrapper').parentNode.appendChild(showHolder);
 document.oncontextmenu = enableFunction;
 if(autoAdvance) clearInterval(autoAdvance);
 if(slideClock) clearInterval(slideClock);
 story.refreshTiddler(title,null,true);
 story.closeAllTiddlers();
 toggleSlideStyles();
 story.displayTiddlers(null,openTiddlers,DEFAULT_VIEW_TEMPLATE);
 document.onmouseup = function(){};
}

function isInteger(s){
 var i;
 for (i = 0; i < s.length; i++){
 // Check that current character is number.
 var c = s.charAt(i);
 if (((c < "0") || (c > "9"))) return false;
 }
 // All characters are numbers.
 return true;
}

function jumpInputToSlide(e){
 if (!e) {
 e = window.event;
 e.which = e.keyCode;
 }
 if(e.which==13){
 var jumpInput= document.getElementById("jumpInput").value;
 if(isInteger(jumpInput)){
 var step=jumpInput-document.getElementById('slideContainer').getAttribute('currentslide')-1;
 if (GoToSlide(step)){
 showHideTOC('none'); 
 }
 }
 }
 return;
}

//Used to shorten the TOC fields
function abbreviateLabel(label){
 var maxTOCLength = config.macros.slideShow.maxTOCLength;
 if(label.length>maxTOCLength) {
 var temp = new Array();
 temp = label.split(' ');
 label = temp[0];
 for(var j=1; j<temp.length; j++){
 if((label.length+temp[j].length)<=maxTOCLength){
 label += " " + temp[j];
 } else {
 label += " ...";
 break;
 }
 }
 }
 return label;
}

createSlides = function(newParams){
 var lingo = config.views.wikified.slideShow;

 //Remove dblClick on edit function
 var theTiddler = document.getElementById("tiddler"+title);
 theTiddler.ondblclick = function() {};

 // Grab the 'viewer' element and give it a signature so the show can be resumed if stopped
 var tiddlerElements = theTiddler.childNodes;
 var viewer;
 for (var i = 0; i < tiddlerElements.length; i++){
 if (tiddlerElements[i].className == "viewer") viewer = tiddlerElements[i];
 }
 viewer.id = 'slideShowWrapper';
 viewer.setAttribute("showSignature",makeSignature(title,newParams));

 //Hide the text that comes before the first H1 element (I think I may put this into a cover page type thing)
 while(viewer.childNodes.length > 0 && viewer.firstChild.nodeName.toUpperCase() != "HR" && viewer.firstChild.className!="slideSeparator") {
 viewer.removeChild(viewer.firstChild);
 }
 
 //Cycle through the content and each time you hit an H1 begin a new slide div
 var slideNumber = 0;
 var slideHolder = document.createElement('DIV');
 slideHolder.id = "slideContainer";
 
 while(viewer.childNodes.length > 0){
 //Create a new slide a append it to the slide holder
 if (viewer.firstChild.nodeName.toUpperCase() == "HR" && viewer.firstChild.className=="slideSeparator"){
 slideNumber++;
 var slide = document.createElement('DIV');
 slide.id = "slideNumber"+slideNumber;
 slide.className = "slide";
 if (slideNumber > 1) {
 slideHolder.setAttribute('currentslide',0);
 slide.style.display='none';
 } else {
 slide.style.display='block';
 }
 slideHolder.appendChild(slide); 
 viewer.removeChild(viewer.firstChild);
 } else {
 if(viewer.firstChild.nodeName=="SPAN" && viewer.firstChild.className=="" && viewer.firstChild.hasChildNodes()) {
 var anchor=viewer.firstChild.nextSibling;
 for (var ii=0;ii<viewer.firstChild.childNodes.length;ii++) {
 var clone=viewer.firstChild.childNodes[ii].cloneNode(true);
 viewer.insertBefore(clone,anchor);
 }
 viewer.removeChild(viewer.firstChild);
 } else {
 slide.appendChild(viewer.firstChild);
 }
 }
 }
 
 //Stick the slides back into the viewer
 viewer.appendChild(slideHolder);
 slideHolder.setAttribute('numberSlides',slideNumber);
 
 //Create the navigation bar
 var pagefooter = createTiddlyElement(viewer,"DIV","pageFooter","pageFooterOff");
 var navigator = createTiddlyElement(pagefooter,"SPAN","navigator");

 //Make it so that when the footer is hovered over the class will change to make it visible
 pagefooter.onmouseover = function () {pagefooter.className = "pageFooterOn"};
 pagefooter.onmouseout = function () {pagefooter.className = "pageFooterOff"};

 //Create the control button for the navigation 
 var onClickQuit = function(){endSlideShow();};
 createTiddlyButton(navigator,lingo.quit.text,lingo.quit.tooltip,onClickQuit);
 createTiddlyButton(navigator,lingo.firstSlide.text,lingo.firstSlide.tooltip,first_slide);
 createTiddlyButton(navigator,lingo.previousSlide.text,lingo.previousSlide.tooltip,previous_slide);
 createTiddlyButton(navigator,lingo.nextSlide.text,lingo.nextSlide.tooltip,next_slide);
 createTiddlyButton(navigator,lingo.lastSlide.text,lingo.lastSlide.tooltip,last_slide); 
 createTiddlyButton(navigator,lingo.resetClock.text,lingo.resetClock.tooltip,resetClock,"button","slideClock"); 

 var indexNumbers = createTiddlyElement(pagefooter,"SPAN","indexNumbers","indexNumbers","1/"+slideNumber)
 indexNumbers.onclick = showHideTOC;
 var toc = createTiddlyElement(pagefooter,"UL","toc");
 var ovl=1;
 for (var i=0;i<slideHolder.childNodes.length;i++) {
 if(!noOverlays) {
 var ovl=1;
 while(1){
 var className="Overlay"+ovl;
 var overlays=getElementsByClass(className,slideHolder.childNodes[i]);
 if(overlays.length>0){
 for(var j=0; j<overlays.length; j++) {overlays[j].className+=' nextOverlay';}
 ovl++;
 } else {break;}
 }
 }
 slideHolder.childNodes[i].setAttribute("numberOverlays",ovl-1);
 slideHolder.setAttribute("currentOverlay",0);

 //Loop through each slide and check the header's content
 var tocLabel = null; 
 for (var j=0;j<slideHolder.childNodes[i].childNodes.length;j++) {
 var node = slideHolder.childNodes[i].childNodes[j];
 if(node.nodeName=="H1" || node.nodeName=="H2" || node.nodeName=="H3" || node.nodeName=="H4") {
 var htstring = node.innerHTML;
 var stripped = htstring.replace(/(<([^>]+)>)/ig,"");
 tocLabel = abbreviateLabel(stripped);
 var tocLevel="tocLevel"+node.nodeName.charAt(1);
 var tocItem = createTiddlyElement(toc,"LI",null,tocLevel);
 var tocLink = createTiddlyElement(tocItem,"A",null,"tocItem",tocLabel);
 tocLink.setAttribute("slideNumber",i);
 tocLink.onclick=tocShowSlide;
 }
 }
 }
 

 //Input box to jump to s specific slide
 var tocItem = createTiddlyElement(toc,"LI",null,"tocJumpItem",config.macros.slideShow.messages.gotoLabel);
 var tocJumpInput = createTiddlyElement(tocItem,"INPUT","jumpInput");
 tocJumpInput.type="text";
 tocJumpInput.onkeyup=jumpInputToSlide;
}

var next_slide= function(e){GoToSlide(1);}
var first_slide= function(e){GoToSlide("f");}
var previous_slide= function(e){GoToSlide(-1);}
var last_slide= function(e){GoToSlide("l");}

function toggleSlideStyles(){
 var contentWrapper = document.getElementById('contentWrapper');
 if (contentWrapper.className == "slideShowMode"){
 contentWrapper.className = "";
 window.applyPageTemplate();
 if(slideShowStyleSheet) changeStyleSheet();
 } else{
 contentWrapper.className = "slideShowMode";
 window.applyPageTemplate("SlideShowPageTemplate");
 if(slideShowStyleSheet) changeStyleSheet(slideShowStyleSheet);
 }
}

setStylesheet("/***\n!Slide Mode Styles\n***/\n/*{{{*/\n#contentWrapper.slideShowMode #slideContainer{\n display: block;\n}\n\n#contentWrapper.slideShowMode .Comment{\n display: none;\n}\n\n#contentWrapper.slideShowMode .nextOverlay{\n visibility: hidden;\n}\n\n#contentWrapper.slideShowMode .currentOverlay{\n visibility: visible;\n}\n\n#contentWrapper.slideShowMode .previousOverlay{\n visibility: visible;\n}\n\n#jump{\n text-align: right;\n}\n\n.pageFooterOff #navigator{\n visibility: hidden;\n}\n\n.pageFooterOn #navigator{\n visibility: visible;\n}\n\n#contentWrapper.slideShowMode #slideClock{\n cursor: pointer; margin: 0 5px 0 5px; border: 1px solid #db4\n}\n\n#contentWrapper.slideShowMode,\n #contentWrapper.slideShowMode #displayArea{\n width: 100%;\n font-size: 1.5em;\n margin: 0 !important;\n padding: 0;\n}\n\n#slideContainer{\n display: none;\n}\n\n.indexNumbers{\n cursor: pointer;\n}\n\n#navigator{\n visibility: hidden;\n bottom: 0;\n}\n\n#toc{\n display: none;\n position: absolute;\n font-size: .75em;\n bottom: 2em;\n right: 0;\n background: #fff;\n border: 1px solid #000;\n text-align: left;\n}\n\nul#toc, #toc li{\n margin: 0;\n padding: 0;\n list-style: none;\n line-height: 1em;\n}\n\n.tocJumpItem{\n margin-right: 2em;\n}\n\n.tocJumpItem input{\nmargin-right: 1em;\n border: 0;\n}\n\n#toc a,\n#toc a.button{\n display: block;\n padding: .1em;\n}\n\n#toc .tocLevel1{\nfont-size: .8em;\n}\n\n#toc .tocLevel2{\n margin-left: 1em;\n font-size: .75em;\n}\n\n#toc .tocLevel3{\n margin-left: 2em;\nfont-size: .75em;\n}\n\n#toc .tocLevel4{\n margin-left: 3em;\nfont-size: .65em;\n}\n\n#toc a{\n cursor: pointer;\n}\n\nh1{\n min-height: 1em;\n}\n\n.slide h1{\n min-height: 0;\n}\n\n/* The '&gt;' selector is ignored by IE6 and earlier so the proper rules are given */\n#pageFooter{\n position: fixed;\n bottom: 2px;\n right: 2px;\n width: 100%;\n text-align: right;\n}\n\n/* This is a hack to trick IE6 and earlier to put the navbar on the bottom of the page */\n* html #pageFooter {\n position: absolute;\n width: 100%;\n text-align: right;\n right: auto; bottom: auto;\n left: expression( ( -20 - pageFooter.offsetWidth + ( document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body.clientWidth ) + ( ignoreMe2 = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ) ) + 'px' );\n top: expression( ( -10 - pageFooter.offsetHeight + ( document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.clientHeight ) + ( ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ) ) + 'px' );\n}\n\n\n\n/*}}}*/","slideShowStyles");
//}}}
!! Motivations
* Productivity gain achieved by:
* Separation of content and presentation (single source)
* Separation of content and delivery (single source)
Productivity gain is explained well in [[Semantic, Structured Authoring|http://www.hyperwrite.com/aspscripts/framer.asp?target=../features/semantic_structured.htm]] (for productivity, go 3/4 down the page)

See also [[passionate argument for structured authoring|http://www.cmswatch.com/Feature/79]] reporting experience with inhouse tool. Conclusion:

@@But in the world of full time professional content creation (technical documentation groups being the prime example) a move to structured authoring, if done properly, can be of direct benefit to the authors and therefore has a good chance of success.
@@ //Mark Baker//

!! Tools for Structured Authoring
* [[White papers on SA and XML|http://www.scriptorium.com/papers.html]]
* [[Tools for Technical Writers|http://www.cloudnet.com/~pdunham/techwritingtools.html]]
* [[XML and FrameMaker|file:///Users/henz/Desktop/xml_fm7.pdf]] (good introduction to single-source publishing, including motivations)
* [[FrameMaker|http://en.wikipedia.org/wiki/FrameMaker]]

----
!! Background
* [[Resources for technical writers|http://www.techpubs.com/resources.html]]
----
!! Miscellaneous
* [[RoboHelp|http://www.adobe.com/products/robohelp/]]: Adobe tool for generating online help tools

!!People
* [[Daniel Quinn]]
* [[Jared Diamond]]
!!Topics
* PeakOil

* Energy sustainability in Singapore and region [http://www.nea.gov.sg/cms/sei/PSS8.html]
* Singapore Green Plan 2012 [http://app.mewr.gov.sg/sgp.asp?cid=114&nid=114&id=SAS434]
* Sustanability and Cities (Singaporean author) [http://www.worldscibooks.com/economics/5755.html]
* [[CS 1102s|http://www.comp.nus.edu.sg/~cs1102s]]: Undergraduate module on Programming Methodology; Semester II 2007/2008.
Professonal development workshop organized by [[Alfred Low]]
!! General Information on Learning Theory
* [[Learning theories|http://www.emtech.net/learning_theories.htm]]
* [[Wikipedia entry on learning theories|http://en.wikipedia.org/wiki/Learning_theory_(education)]]
* [[About learning|http://www.funderstanding.com/about_learning.cfm]]
!! Constructivist Learning Theory
http://www.learningandteaching.info/learning/constructivism.htm
* [[Constructivist learning theory|http://en.wikipedia.org/wiki/Constructivism_%28learning_theory%29]]
* [[Technology-mediated learning|http://cdtl.nus.edu.sg/brief/V8n3/sec3.htm]]: Article by Alfred.
!! Links
* [[ICTRAPS homepage|http://courseware.nus.edu.sg/ICTRAPS/web/index.htm]] (NUS-internal)
Author: David Owen, Life, October 1990: 70

 Mr. Whitson taught sixth-grade science. On the first day of class, he gave us a lecture about a creature called the cattywampus, an ill-adapted nocturnal animal that was wiped out during the Ice Age. He passed around a skull as he talked. We all took notes and later had a quiz.

When he returned my paper, I was shocked. There was a big red X through each of my answers. I had failed. There had to be some mistake! I had written down exactly what Mr. Whitson said. Then I realized that everyone in the class had failed. What had happened?

Very simple, Mr. Whitson explained. He had made up all the stuff about the cattywampus. There had never been any such animal. The information in our notes was, therefore, incorrect. Did we expect credit for incorrect answers?

Needless to say, we were outraged. What kind of test was this? And what kind of teacher?

We should have figured it out, Mr. Whitson said. After all, at the every moment he was passing around the cattywampus skull (in truth, a cat's), hadn't he been telling us that no trace of the animal remained? He had described its amazing night vision, the color of its fur and any number of other facts he couldn't have known. He had given the animal a ridiculous name, and we still hadn't been suspicious. The zeroes on our papers would be recorded in his grade book, he said. And they were.

Mr. Whitson said he hoped we would learn something from this experience. Teachers and textbooks are not infallable. In fact, no one is. He told us not to let our minds go to sleep, and to speak up if we ever thought he or the textbook was wrong.

Every class was an adventure with Mr. Whitson. I can still remember some science periods almost from beginning to end. On day he told us that his Volkswagon was a living organism. It took us two full days to put together a refutation he would accept. He didn't let us off the hook until we had proved not only that we knew what an organism was but also that we had the fortitude to stand up for the truth.

We carried our brand-new skepticism into all our classes. This caused problems for the other teachers, who weren't used to being challenged. Our history teacher would be lecturing about something, and then there would be clearings of the throat and someone would say 'cattywampus.'

If I'm ever asked to propose a solution to the problems in our schools, it will be Mr. Whitson. I haven't made any great scientific discoveries, but Mr. Whitson's class gave me and my classmates something just as important: the courage to look people in the eye and tell them they are wrong. He also showed us that you can fun doing it.

Not everyone sees the value in this. I once told an elementary school teacher about Mr. Whitson. The teacher was appalled. "He shouldn't have tricked you like that," he said. I looked that teacher right in the eye and told him that he was wrong. 
!! Project Status
available
!! Description
Enterprise software has experienced a fundamental shift with the advent of Service Oriented Architecture (SOA). However, new developments in web clients are threatening SOA by bringing unprecedented capabilities to the clients, which might lead to a move away from the 3-tiered architecture that has dominated enterprise software for the past 20 years. This project explores all aspects of client-side business logic, covering the relevant technologies, with a focus on the implications of this emerging technology on the enterprise software landscape, and software vendor eco-systems.

The ideal candidate for the project is a CS/IS major with strong business background and a keen interest in business software solutions.
HYP student: Michael Lin. Project start: 12/2006
* [[TiddlyCal website|http://lls.tiddlyspot.com/]]
----
Links:
* PlasticCalendarPlugin
* [[wikipedia entry on iCalendar|http://en.wikipedia.org/wiki/ICalendar]]
* [[Find shared calendars for iCal (mac)|http://www.apple.com/macosx/features/ical/library/?ref=&alias=http://www.apple.com/ical/library/]]
* [[icalshare|http://www.icalshare.com/]] sharing calendars
* [[http://www.icalx.com/]] iCal Exchange
* [[Little script for making calendars in TiddlyWiki|http://33ad.org/tools/gtdtwcal.php?month=2&year=2006]]
!! Overview
TiddlyCard is a framework for peer-to-peer web-based computing. It consists of a client-side "operating system" that boots within a web-browser, and an ultra-thin server side that enables peer-to-peer computing. TiddlyCard leverages on JavaScript, AJAX, COMET, TiddlyWiki and concepts from ~HyperCard to bring an environment to the web browser, in which users, developers and enterprises can breathe, live and thrive.

See also [[poster overview|students/daryl_poster.pdf]] by Daryl Seah.

!! Documents
* Daryl Seah, Honours Year student, Project: Foundations for a Browser-based Application Platform. See [[report|students/daryl.pdf]] and [[appendix|students/daryl_appendix.pdf]] (2008).
* Lek Hsiang Hui, Honours Year student, Project: A Network Framework for a Browser-based Application Platform. See [[report|students/hsianghui.pdf]] (2008).
* Zhou Lin, Richard, Honours Year student, Project: Debugging and Testing in a Browser-based Application Platform. See [[report|students/richard.pdf]] (2008).
* Chua Ruiwen, Honours Year student, Project:  [[Application Management and Deployment for TiddlyCard]]. See [[report|students/ruiwen.pdf]] (2008).
* Chen Xi, Honours Year student, Project: [[Email Client for a Browser-based Application Platform]] (using Chilkat). See [[report|students/chenxi.pdf]] (2008).
* Tran Khoa Nguyen, Honours Year student, Project: ~WebCollab, A Browser-based Collaborative Environment. See [[report|students/khoanguyen.pdf]] (2008).
* Tang Tung Leh, Honours Year student, Project: A Framework for Data Visualization in a Browser-based Application Platform. See [[report|students/tungleh.pdf]] (2008).
!! Links
* [[TiddlyWiki homepage|http://www.tiddlywiki.com]]
* [[TiddlyWiki . org|http://www.tiddlywiki.org]]
* [[FAQ on TiddlyWiki|http://twfaq.tiddlyspot.com]]
* [[Some adaptations of TiddlyWiki|http://www.socio-kybernetics.net/saurierduval/2005/07/tiddlywiki-mania.html]]
!! Plugins
* Some cool plugins at [[Paolo Soares' site|http://www.math.ist.utl.pt/~psoares/addons.html]]
* More macros and plugins at [[Jack's place|http://jackparke.googlepages.com/jtw.html]]
* Take a look at the [[Table-of-Contents Plugin|http://www.zagware.com/tw/plugins.html#DcTableOfContentsPlugin]]
* [[SlideShowPlugin]]
* [[Some more plugins (import export) at tiddlytools|http://www.howtocreate.co.uk/tutorials/javascript/security]]
!! Background Info
* On writing style, see [[Writing Microcontent|http://www.tiddlywiki.com/#MicroContent]].
* On [[single page applications|http://trimpath.com/project/wiki/SinglePageApplications]]
* On [[Single Page Application [and] Development Environments|http://trimpath.com/project/wiki/SinglePageApplicationAndDevelopmentEnvironment]]
* [[Thoughtful articles (5 parts) on TiddlyWiki|http://www.loosewireblog.com/2005/08/the_tiddlywiki_.html]]
----
!! Some Ideas
* Calendar
** Use tagging for multiple calendar views, merge calendars using tags
** Add week view
** Add day view (configurable for working week)
HYP student: Wang Shangshang

[[Project wiki|http://roca.tiddlyspot.com/]]
Next meeting: 16/2/07, 2pm

Pointers:
* Existing ~RSS-[[TiddlyWiki]] project: [[RSSExtensions|http://tiddlywiki.bidix.info/#RSSExtensions]]
* [[ProtoPage|http://www.protopage.com/]]

!! Project Status
available
!! Description
Evolutionary processes have emerged as the defining feature of "life" in Artificial Life (Alife). When studying the behavior of a particular Alife form, the question naturally arises, whether a particular run of an Alife experiment exhibits evolutionary behavior or not. This project starts from a recent proposal of an observer-centered formal decision process to answer this question. The project will extend this approach into a full-fledged framework to characterize dynamic systems with respect to their evolutionary behavior, including a characterization of genotype/phenotype dichotomy, Darwinian vs Lamarckian evolution, sexual vs asexual reproduction, etc.

The project will apply the framework to existing Alife experiments and systematically conduct new Alife experiments to populate the landscape of evolutionary behavior that the framework unfolds.
!!Reference
Towards a Framework for Observing Artificial Life Forms
Martin Henz and Janardan Misra
Proceedings of the First IEEE Symposium on Artificial Life, IEEE-ALife 2007, April 1-5 2007, Honolulu, Hawaii.
I admit that this is a rather specific topic. Anyhow: Saw a presentation recently where the speaker used the possibility of turning off the projector to a great effect. When the projector went off, I had nothing to look at but the speaker. All of a sudden, all eyes were on her. She then emphasized a particular point that went beyond what was on the slide.

I was looking for a way of turning off the projector using the Apple Remote gadget that comes with the ~MacBook Pro. I found the following ways of doing it:
!!Doing it with Adobe Reader
I often use PDF slides generated with LaTeX, and usually present them on my ~MacBook Pro using Adobe Reader (version 7.0.8). 
* Download [[Remote Buddy|http://www.iospirit.com/index.php?mode=view&obj_type=infogroup&obj_id=24&o_infogroup_objcode=infogroup-23&sid=3203925G15a258bde2e6b833]] (60-day trial; license: 10 Euro)
* Add a black slide to the end of your PDF presentation
** I do that (rather crudely) by writing
{{{
% cat mypresentation.ps blank.ps > myfullpresentation.ps
% ps2pdf myfullpresentation.ps
}}}
** The black slide, I generated using Adobe Photoshop, printing to PDF in landscape, and then using {{{pdf2ps}}} (I know a bit of round-about way, but it worked.)
* Go to Remote Buddy, Preferences, Mapping; choose Adobe Reader, and configure the Apple Remote buttons as follows:
** Plus: choose "Custom Actions"
*** Name of action: "Previous view"
*** Keystroke: Apple ~LeftArrow (click into the keystroke entry, and then press the left arrow key on your keyboard; tick the Apple option on the right)
** Minus: Last page
** Left: Previous page
** Left (held): First page
** Right: Next page
** Right (held): Last page
** Play/Pause: Next page
** Play/Pause (held): Next page
* Now you can launch your presentation in Adobe Reader and use the "-" button on your Apple Remote to "turn off the beamer" (by going to the black last page), and the "+" button for turning it on (by going to the "previous view", a function that Adobe Reader provides using the key combination "Apple-LeftArrow", see  Adobe Reader menu View, Go To, Previous View).
!! Doing It With ~PowerPoint
In ~PowerPoint, this is easier, since in presentation mode, you can turn the screen black using the key "b" (and white using the key "w"), and turn it normal by pressing "b" again. So instead of adding a black slide at the end, you can configure Remote Buddy as follows:
** Plus: choose "Custom Actions"
*** Name of action: "Toggle Black"
*** Keystroke: b
** Minus: Toggle black
** Left: Previous slide
** Left (held): Jump to first slide
** Right: Next slide
** Right (held): Jump to last slide
** Play/Pause: Next slide
** Play/Pause (held): Next slide
!! Doing it with Firefox
Sometimes I use HTML-based presentations, using tools like TiddlyWiki with SlideShowPlugin. To get Firefox do half-way decent looking presentations, you need to get rid of all the toolbars, status bar and side bar. Prepare a black slide like this:
{{{
<html>
<head>
  <title></title>
</head>
<body bgcolor="#000000">
</body>
</html>
}}}
Then load it in the browser, and after that load your presentation. Configure the buttons as follows:
** Plus: choose "Custom Actions"
*** Name of action: "Forward"
*** Keystroke: Apple-]
** Minus: choose "Custom Actions"
*** Name of action: "Backward"
*** Keystroke: Apple-[
** Left: Cursor key left
** Left (held): choose "Custom Actions"
*** Name of action: "Home"
*** Keystroke: fn-"cursor-key-left (home)"
** Right: Cursor key right
** Right (held): choose "Custom Actions"
*** Name of action: "End"
*** Keystroke: fn-"cursor-key-right (end)"
** Play/Pause: Cursor key right
** Play/Pause (held): Cursor key right
----
Note that all configurations are such that "-" turns the screen off, and when it is off, "+" turns it back on. Also, I find it convenient to have the centre button configured as "next slide/page", because it is by far the most fequently used function.
See [[project wiki|http://www.comp.nus.edu.sg/~sivasubr/wiki/]]
----
!Links
* [[TiddlyThemes|http://tiddlythemes.com/#Home]]
!! Project Status
available
!! Description
JavaScript enjoys increasing popularity. As a general purpose programming language, however, it suffers from an absence of a parser generator in the style of the Unix tool YACC. The result is that language processing is very cumbersome with JavaScript. This project aims to overcome this limitation by developing a full-fledged parser generator that is written purely in JavaScript, and generates a LALR parser written in JavaScript for parsing elements of a context-free language as specified in form of a context free grammar, given in an input file or JSON data structure.
!People
* [[Joan Seow|http://www.iyc.sg]]
* [[B.K.S. Iyengar|http://en.wikipedia.org/wiki/B.K.S._Iyengar]]
* [[Nancy Crum Stechert]]
* [[Ramanand Patel]]
* [[Swami Dayananda]]
* [[Zhander Remete]]
* [[Swami Vivekananda|http://en.wikipedia.org/wiki/Swami_Vivekananda]]

!Brief History of Yoga

Some traditions attribute the origins of Hatha Yoga with Gorakhnāth, a yogin of the 10th/11th century CE but the oldest surviving comprehensive text of Hatha Yoga is the Hatha Yoga Pradipika by Yogi Swatmarama. This work is nonetheless derived from older Sanskrit texts on Yoga besides Yogi Swatmarama's own yogic experiences. It includes information about shatkarma, asana, pranayama, chakras, kundalini, bandhas, kriyas, shakti, nadis, and mudras among other topics.

Sri Tirumalai Krishnamacharya was born in Karnataka, India, in 1888. After learning Sanskrit, the Vedas and yoga from his father, he underwent extensive studies in Varanasi. In 1916, he looked for Sri Ramamohan Brahmachari, rumoured to live in the mountains, and found him in a cave at the foot of Mount Kailash. After 7 years of study with Brahmachari, he returned to southern India to study Ajurveda and Nyaya. At the invitation of the Maharaja of Mysore, he founded a yoga school (Yogashala) there, at which he developed a vigorous form of yoga, Ashtanga Vinyasa Yoga, mostly for teenage boys. Among his students prominent in popularizing Yoga in the West were Sri K. Pattabhi Jois, famous for  popularizing Ashtanga Vinyasa Yoga, B.K.S. Iyengar who emphasizes alignment and the use of props, Indra Devi and Krishnamacharya's son T.K.V. Desikachar who developed the Viniyoga style. Desikachar founded the Krishnamacharya Yoga Mandiram in Chennai, with the aim of making available the heritage of yoga as taught by Krishnamacharya.

Another major stream of influence was Swami Sivananda of Rishikesh (1887-1963) and his many disciples, including Swami Vishnu-Devananda - founder of International Sivananda Yoga Vedanta Centres, Swami Satyananda - of the Bihar School of Yoga, and Swami Satchidananda - of Integral Yoga, among others.

As opposed to Hatha Yoga, Raja Yoga (lit. Royal Yoga) is the system of yoga outlined by Patanjali in his Yoga Sutras. Raja yoga is concerned principally with the cultivation of the mind using meditation to further one's acquaintance with reality and finally achieve liberation.

Hatha and Raja Yoga are considered two branches of  Ashtanga Yoga. However, in some schools of thought, only Raja Yoga is considered to be Ashtanga Yoga, and Hatha Yoga is thought to consist of six limbs focused on attaining Kundalini. In this scheme, the six limbs of Hatha Yoga are defined as Yama, Niyama, Asana, Pranayama, Mudra (specific postures to help help locking in the breath), Nadanusandhana (hearing of the eternal sound within the body), the whole process cultiminating in the attainment of Kundalini. Due to this, this version of Hatha yoga is also sometimes referred to as Kundalini Yoga.

Events:

* [[Yoga & Sound]]

Other links:
* [[Zen in the Art of Archery|http://en.wikipedia.org/wiki/Zen_in_the_Art_of_Archery]]
Workshop by [[Ramanand Patel]] and [[Mukesh Desai]] held 5-7/1/2007 at Shambhala Como, Singapore, , Shambhala, 583 Orchard Road #06-05 Forum, tel: 6735 2163 

Website: [[Yoga & Sound|http://shambhala.como.bz/default.asp?subpage=639&section=339]]
[[Description]]
[[Material]]
[[Projects]]
The aim of this course is to introduce the main concepts and techniques of logic programming and constraint logic programming. The module explores the range of areas within computer science in which logic and constraint-based techniques are contributing to the world of IT. These techniques range from propositional logic over predicate logic (with several extensions and modifications) to the theory of constraint satisfaction, and the application areas range from relational databases, decision support systems to combinatorial optimization. Students in-depth knowledge of a selected set of techniques and applications, as well as an appreciation for the programming language aspects of logic and constraint programming.
 [[Description]]
 [[Covered Topics]]
 [[Material]]
 [[Assignments]]
 [[Projects]]
 [[Assessment]]
 [[Other Info]]
----
 [[About this page]]
[img[http://www.comp.nus.edu.sg/~cs5216/feed-icon-32x32.png][http://www.comp.nus.edu.sg/~cs5216/cs5216.xml]]
Module homepage maintained by [[Martin Henz|http://www.comp.nus.edu.sg/~henz]]
CS 5216
* [[cs5216MainMenu]]
* [[cs5216SiteTitle]]
* [[cs5216SiteSubtitle]]
* [[cs5216DefaultTiddlers]]
* [[cs5216Material]]
* [[cs5216Projects]]
* [[cs5216Assessment]]
* [[Philosophy]]
* [[Sustainability]]
* [[Politics]]
* [[Education]]
* [[Arts]]
* [[Yoga]]
[[Research]]
[[Teaching]]
[[Projects]]
[[NUS]] startup company specializing in Optimized Workforce Management. Founded in 2001 by Alan Sevugan  (current CEO) and Martin Henz. Details on FriarTuck at [[company homepage|http://www.friartuck.net]].
[[Research]]
[[Teaching]]
[[Projects]]
[[FriarTuck]]
----
[[IT]]
[[Culture]]
[[HowTos]]
----
[[About Me]]
[img[http://www.comp.nus.edu.sg/~henz/feed-icon-32x32.png][http://www.comp.nus.edu.sg/~henz/henz.xml]]

my employer, see  [[NUS homepage|http://www.nus.edu.sg]]
Homepage of [[Martin Henz]] at [[School of Computing]], NUS
Pointers
http://www.comp.nus.edu.sg/~henz