<!--{{{-->
<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 [[ToolbarCommands::ViewToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='subtitle'><span macro='view modifier link'></span>, <span macro='view modified date'></span> (<span macro='message views.wikified.createdPrompt'></span> <span macro='view created date'></span>)</div>
<div class='tagging' macro='tagging'></div>
<div class='tagged' macro='tags'></div>
<div class='viewer' macro='view text wikified'></div>
<div class='tagClear'></div>
<!--}}}-->
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::EditToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='editor' macro='edit title'></div>
<div macro='annotations'></div>
<div class='editor' macro='edit text'></div>
<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser'></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>>
|!Ability|!Score|!Modifier|
|Str|25|+7|
|Dex|12|+1|
|Con|14|+2|
|Int|16|+3|
|Wis|6|-2|
|Cha|10|-|
|>|>|!Saves|
|Fortitude|>|9|
|Reflex|>|6|
|Will|>|6|
[[Britannia]] and [[France]] have battled for control of Africa. There is a peace treaty at the moment, but tension is sil high.

!Races
In the northern Sahara desert, [[Scorpionfolk|http://www.d20srd.org/srd/monsters/scorpionfolk.htm]] lie in wait to waylay travelers. [[Orcs|http://www.d20srd.org/srd/monsters/orc.htm]] raid in the mountains southeast of the Sahara. [[Goblin|http://www.d20srd.org/srd/monsters/goblin.htm]] slavers lead caravans to [[The Ivory Coast]], where they are sent to labor in the Americas or shipped off to prostitution, depending on race. Negroid humans can be found where there are few or no orcs.

!Natural Resources
The diamond and gold mines in south africa provide a steady inome for the British Empire. Production is often slowed or stopped because of raids by angry aboriginal tribes, since the mines are in their sacred hunting grounds.

!Strategic Importance
The British control the Suez canal, and thus the shortest way to the Indian Ocean and Asia.
!Websites
* [[The Victorian Web|http://www.victorianweb.org/]] - A comprehensive resource of all things Victorian.
Consists of Ireland, Scotland, Wales and England. An important world superpower. Quite friendly with the Dwarven Bronzeheart Clan.
Pioneers of technology and exploration. Close allies with [[Britannia]]'s goverment.

!!Chief Exports
* Technology in all shapes and sizes, but with a preference for steam-powered engines.
* Finely crafted and decorated weapons and armors.

!!Geography
Level 8 hobgoblin fighter, decorated captain of the British Indian Army. Aide to the the director of the Queens surveillance unit.

Str 20, Dex 13, Con 11, Int 13, Wis 8, Cha 8

Feats:
* [[Alertness|http://www.d20srd.org/srd/feats.htm#alertness]] (Racial)
* [[Point Blank Shot|http://www.d20srd.org/srd/feats.htm#pointBlankShot]]
* [[Precise Shot|http://www.d20srd.org/srd/feats.htm#preciseShot]]
* [[Weapon Focus|http://www.d20srd.org/srd/feats.htm#weaponFocus]] (Scimitar)
* [[Greater Weapon Focus|http://www.d20srd.org/srd/feats.htm#greaterWeaponFocus]] (Scimitar)
* [[Weapon Specialization|http://www.d20srd.org/srd/feats.htm#weaponSpecialization]] (Scimitar)
* [[Power Attack|http://www.d20srd.org/srd/feats.htm#powerAttack]]
* [[Cleave|http://www.d20srd.org/srd/feats.htm#cleave]]
* [[Weapon Focus|http://www.d20srd.org/srd/feats.htm#weaponFocus]] (Shotgun)
* [[Greater Weapon Focus|http://www.d20srd.org/srd/feats.htm#greaterWeaponFocus]] (Shotgun)
* [[Weapon Specialization|http://www.d20srd.org/srd/feats.htm#weaponSpecialization]] (Shotgun)
* All players start with 4 character points on level 1, and gains 1 character point per level. 1 character point = divine intervention, 3 skill points. 3 character points = 1 feat. 5 CP = +1 ability score
* Players are able to choose from a selection of [[merits|Merits]] and [[flaws|Flaws]]. These cost(merits) or give(flaws) character points.
!Defensive
Usually keeps to the rear of the battle, until he feels he has the advantage. May be goaded into charging prematurely.
!Offensive
Tries to lie in ambush and use the element of surprise, but his eagerness for battle often owerpowers him.
!!Before combat
Casts [[Mage Armor|http://www.d20srd.org/srd/spells/mageArmor.htm]], and [[Bull's Strength|http://www.d20srd.org/srd/spells/bullsStrength.htm]] on himself, then softens up his target(s) with a [[Lightning Bolt|http://www.d20srd.org/srd/spells/lightningBolt.htm]] and a [[Fireball|http://www.d20srd.org/srd/spells/fireball.htm]].

Before charging into melee combat, he casts [[True strike|http://www.d20srd.org/srd/spells/trueStrike.htm]] on himself.

!!During Combat
Charges the scene of battle, attempting to [[Intimidate|http://www.d20srd.org/srd/skills/intimidate.htm]] his opponents. Whoever he reaches first, he tries to overrun. He then attacks whoever irritates him the most, or the the nearest foe in sight, with his Greathammer.

!!Retreat
Casts [[Darkness|http://www.d20srd.org/srd/spells/darkness.htm]] and [[Cause Fear|http://www.d20srd.org/srd/spells/causeFear.htm]] to cover his retreat.
* Firearms ignore standard armor bonuses to AC within 100% of their range increment. Within the last ½ of its range increment, firearms ignore ½ of armor bonuses. This does not apply to magically enhanced armor.
/***
|''Name:''|DataTiddlerPlugin|
|''Version:''|1.0.6 (2006-08-26)|
|''Source:''|http://tiddlywiki.abego-software.de/#DataTiddlerPlugin|
|''Author:''|UdoBorkowski (ub [at] abego-software [dot] de)|
|''Licence:''|[[BSD open source license]]|
|''TiddlyWiki:''|1.2.38+, 2.0|
|''Browser:''|Firefox 1.0.4+; InternetExplorer 6.0|
!Description
Enhance your tiddlers with structured data (such as strings, booleans, numbers, or even arrays and compound objects) that can be easily accessed and modified through named fields (in JavaScript code).

Such tiddler data can be used in various applications. E.g. you may create tables that collect data from various tiddlers. 

''//Example: "Table with all December Expenses"//''
{{{
<<forEachTiddler
    where
        'tiddler.tags.contains("expense") && tiddler.data("month") == "Dec"'
    write
        '"|[["+tiddler.title+"]]|"+tiddler.data("descr")+"| "+tiddler.data("amount")+"|\n"'
>>
}}}
//(This assumes that expenses are stored in tiddlers tagged with "expense".)//
<<forEachTiddler
    where
        'tiddler.tags.contains("expense") && tiddler.data("month") == "Dec"'
    write
        '"|[["+tiddler.title+"]]|"+tiddler.data("descr")+"| "+tiddler.data("amount")+"|\n"'
>>
For other examples see DataTiddlerExamples.




''Access and Modify Tiddler Data''

You can "attach" data to every tiddler by assigning a JavaScript value (such as a string, boolean, number, or even arrays and compound objects) to named fields. 

These values can be accessed and modified through the following Tiddler methods:
|!Method|!Example|!Description|
|{{{data(field)}}}|{{{t.data("age")}}}|Returns the value of the given data field of the tiddler. When no such field is defined or its value is undefined {{{undefined}}} is returned.|
|{{{data(field,defaultValue)}}}|{{{t.data("isVIP",false)}}}|Returns the value of the given data field of the tiddler. When no such field is defined or its value is undefined the defaultValue is returned.|
|{{{data()}}}|{{{t.data()}}}|Returns the data object of the tiddler, with a property for every field. The properties of the returned data object may only be read and not be modified. To modify the data use DataTiddler.setData(...) or the corresponding Tiddler method.|
|{{{setData(field,value)}}}|{{{t.setData("age",42)}}}|Sets the value of the given data field of the tiddler to the value. When the value is {{{undefined}}} the field is removed.|
|{{{setData(field,value,defaultValue)}}}|{{{t.setData("isVIP",flag,false)}}}|Sets the value of the given data field of the tiddler to the value. When the value is equal to the defaultValue no value is set (and the field is removed).|

Alternatively you may use the following functions to access and modify the data. In this case the tiddler argument is either a tiddler or the name of a tiddler.
|!Method|!Description|
|{{{DataTiddler.getData(tiddler,field)}}}|Returns the value of the given data field of the tiddler. When no such field is defined or its value is undefined {{{undefined}}} is returned.|
|{{{DataTiddler.getData(tiddler,field,defaultValue)}}}|Returns the value of the given data field of the tiddler. When no such field is defined or its value is undefined the defaultValue is returned.|
|{{{DataTiddler.getDataObject(tiddler)}}}|Returns the data object of the tiddler, with a property for every field. The properties of the returned data object may only be read and not be modified. To modify the data use DataTiddler.setData(...) or the corresponding Tiddler method.|
|{{{DataTiddler.setData(tiddler,field,value)}}}|Sets the value of the given data field of the tiddler to the value. When the value is {{{undefined}}} the field is removed.|
|{{{DataTiddler.setData(tiddler,field,value,defaultValue)}}}|Sets the value of the given data field of the tiddler to the value. When the value is equal to the defaultValue no value is set (and the field is removed).|
//(For details on the various functions see the detailed comments in the source code.)//


''Data Representation in a Tiddler''

The data of a tiddler is stored as plain text in the tiddler's content/text, inside a "data" section that is framed by a {{{<data>...</data>}}} block. Inside the data section the information is stored in the [[JSON format|http://www.crockford.com/JSON/index.html]]. 

//''Data Section Example:''//
{{{
<data>{"isVIP":true,"user":"John Brown","age":34}</data>
}}}

The data section is not displayed when viewing the tiddler (see also "The showData Macro").

Beside the data section a tiddler may have all kind of other content.

Typically you will not access the data section text directly but use the methods given above. Nevertheless you may retrieve the text of the data section's content through the {{{DataTiddler.getDataText(tiddler)}}} function.


''Saving Changes''

The "setData" methods respect the "ForceMinorUpdate" and "AutoSave" configuration values. I.e. when "ForceMinorUpdate" is true changing a value using setData will not affect the "modifier" and "modified" attributes. With "AutoSave" set to true every setData will directly save the changes after a setData.


''Notifications''

No notifications are sent when a tiddler's data value is changed through the "setData" methods. 

''Escape Data Section''
In case that you want to use the text {{{<data>}}} or {{{</data>}}} in a tiddler text you must prefix the text with a tilde ('~'). Otherwise it may be wrongly considered as the data section. The tiddler text {{{~<data>}}} is displayed as {{{<data>}}}.


''The showData Macro''

By default the data of a tiddler (that is stored in the {{{<data>...</data>}}} section of the tiddler) is not displayed. If you want to display this data you may used the {{{<<showData ...>>}}} macro:

''Syntax:'' 
|>|{{{<<}}}''showData '' [''JSON''] [//tiddlerName//] {{{>>}}}|
|''JSON''|By default the data is rendered as a table with a "Name" and "Value" column. When defining ''JSON'' the data is rendered in JSON format|
|//tiddlerName//|Defines the tiddler holding the data to be displayed. When no tiddler is given the tiddler containing the showData macro is used. When the tiddler name contains spaces you must quote the name (or use the {{{[[...]]}}} syntax.)|
|>|~~Syntax formatting: Keywords in ''bold'', optional parts in [...]. 'or' means that exactly one of the two alternatives must exist.~~|


!Revision history
* v1.0.6 (2006-08-26) 
** Removed misleading comment
* v1.0.5 (2006-02-27) (Internal Release Only)
** Internal
*** Make "JSLint" conform
* v1.0.4 (2006-02-05)
** Bugfix: showData fails in TiddlyWiki 2.0
* v1.0.3 (2006-01-06)
** Support TiddlyWiki 2.0
* v1.0.2 (2005-12-22)
** Enhancements:
*** Handle texts "<data>" or "</data>" more robust when used in a tiddler text or as a field value.
*** Improved (JSON) error messages.
** Bugs fixed: 
*** References are not updated when using the DataTiddler.
*** Changes to compound objects are not always saved.
*** "~</data>" is not rendered correctly (expected "</data>")
* v1.0.1 (2005-12-13)
** Features: 
*** The showData macro supports an optional "tiddlername" argument to specify the tiddler containing the data to be displayed
** Bugs fixed: 
*** A script immediately following a data section is deleted when the data is changed. (Thanks to GeoffS for reporting.)
* v1.0.0 (2005-12-12)
** initial version

!Code
***/
//{{{
//============================================================================
//============================================================================
//                           DataTiddlerPlugin
//============================================================================
//============================================================================

// Ensure that the DataTiddler Plugin is only installed once.
//
if (!version.extensions.DataTiddlerPlugin) {



version.extensions.DataTiddlerPlugin = {
    major: 1, minor: 0, revision: 6,
    date: new Date(2006, 7, 26), 
    type: 'plugin',
    source: "http://tiddlywiki.abego-software.de/#DataTiddlerPlugin"
};

// For backward compatibility with v1.2.x
//
if (!window.story) window.story=window; 
if (!TiddlyWiki.prototype.getTiddler) {
	TiddlyWiki.prototype.getTiddler = function(title) { 
		var t = this.tiddlers[title]; 
		return (t !== undefined && t instanceof Tiddler) ? t : null; 
	};
}

//============================================================================
// DataTiddler Class
//============================================================================

// ---------------------------------------------------------------------------
// Configurations and constants 
// ---------------------------------------------------------------------------

function DataTiddler() {
}

DataTiddler = {
    // Function to stringify a JavaScript value, producing the text for the data section content.
    // (Must match the implementation of DataTiddler.parse.)
    //
    stringify : null,
    

    // Function to parse the text for the data section content, producing a JavaScript value.
    // (Must match the implementation of DataTiddler.stringify.)
    //
    parse : null
};

// Ensure access for IE
window.DataTiddler = DataTiddler;

// ---------------------------------------------------------------------------
// Data Accessor and Mutator
// ---------------------------------------------------------------------------


// Returns the value of the given data field of the tiddler.
// When no such field is defined or its value is undefined
// the defaultValue is returned.
// 
// @param tiddler either a tiddler name or a tiddler
//
DataTiddler.getData = function(tiddler, field, defaultValue) {
    var t = (typeof tiddler == "string") ? store.getTiddler(tiddler) : tiddler;
    if (!(t instanceof Tiddler)) {
        throw "Tiddler expected. Got "+tiddler;
    }

    return DataTiddler.getTiddlerDataValue(t, field, defaultValue);
};


// Sets the value of the given data field of the tiddler to
// the value. When the value is equal to the defaultValue
// no value is set (and the field is removed)
//
// Changing data of a tiddler will not trigger notifications.
// 
// @param tiddler either a tiddler name or a tiddler
//
DataTiddler.setData = function(tiddler, field, value, defaultValue) {
    var t = (typeof tiddler == "string") ? store.getTiddler(tiddler) : tiddler;
    if (!(t instanceof Tiddler)) {
        throw "Tiddler expected. Got "+tiddler+ "("+t+")";
    }

    DataTiddler.setTiddlerDataValue(t, field, value, defaultValue);
};


// Returns the data object of the tiddler, with a property for every field.
//
// The properties of the returned data object may only be read and
// not be modified. To modify the data use DataTiddler.setData(...) 
// or the corresponding Tiddler method.
//
// If no data section is defined a new (empty) object is returned.
//
// @param tiddler either a tiddler name or a Tiddler
//
DataTiddler.getDataObject = function(tiddler) {
    var t = (typeof tiddler == "string") ? store.getTiddler(tiddler) : tiddler;
    if (!(t instanceof Tiddler)) {
        throw "Tiddler expected. Got "+tiddler;
    }

    return DataTiddler.getTiddlerDataObject(t);
};

// Returns the text of the content of the data section of the tiddler.
//
// When no data section is defined for the tiddler null is returned 
//
// @param tiddler either a tiddler name or a Tiddler
// @return [may be null]
//
DataTiddler.getDataText = function(tiddler) {
    var t = (typeof tiddler == "string") ? store.getTiddler(tiddler) : tiddler;
    if (!(t instanceof Tiddler)) {
        throw "Tiddler expected. Got "+tiddler;
    }

    return DataTiddler.readDataSectionText(t);
};


// ---------------------------------------------------------------------------
// Internal helper methods (must not be used by code from outside this plugin)
// ---------------------------------------------------------------------------

// Internal.
//
// The original JSONError is not very user friendly, 
// especially it does not define a toString() method
// Therefore we extend it here.
//
DataTiddler.extendJSONError = function(ex) {
	if (ex.name == 'JSONError') {
        ex.toString = function() {
			return ex.name + ": "+ex.message+" ("+ex.text+")";
		};
	}
	return ex;
};

// Internal.
//
// @param t a Tiddler
//
DataTiddler.getTiddlerDataObject = function(t) {
    if (t.dataObject === undefined) {
        var data = DataTiddler.readData(t);
        t.dataObject = (data) ? data : {};
    }
    
    return t.dataObject;
};


// Internal.
//
// @param tiddler a Tiddler
//
DataTiddler.getTiddlerDataValue = function(tiddler, field, defaultValue) {
    var value = DataTiddler.getTiddlerDataObject(tiddler)[field];
    return (value === undefined) ? defaultValue : value;
};


// Internal.
//
// @param tiddler a Tiddler
//
DataTiddler.setTiddlerDataValue = function(tiddler, field, value, defaultValue) {
    var data = DataTiddler.getTiddlerDataObject(tiddler);
    var oldValue = data[field];
	
    if (value == defaultValue) {
        if (oldValue !== undefined) {
            delete data[field];
            DataTiddler.save(tiddler);
        }
        return;
    }
    data[field] = value;
    DataTiddler.save(tiddler);
};

// Internal.
//
// Reads the data section from the tiddler's content and returns its text
// (as a String).
//
// Returns null when no data is defined.
//
// @param tiddler a Tiddler
// @return [may be null]
//
DataTiddler.readDataSectionText = function(tiddler) {
    var matches = DataTiddler.getDataTiddlerMatches(tiddler);
    if (matches === null || !matches[2]) {
        return null;
    }
    return matches[2];
};

// Internal.
//
// Reads the data section from the tiddler's content and returns it
// (as an internalized object).
//
// Returns null when no data is defined.
//
// @param tiddler a Tiddler
// @return [may be null]
//
DataTiddler.readData = function(tiddler) {
    var text = DataTiddler.readDataSectionText(tiddler);
	try {
	    return text ? DataTiddler.parse(text) : null;
	} catch(ex) {
		throw DataTiddler.extendJSONError(ex);
	}
};

// Internal.
// 
// Returns the serialized text of the data of the given tiddler, as it
// should be stored in the data section.
//
// @param tiddler a Tiddler
//
DataTiddler.getDataTextOfTiddler = function(tiddler) {
    var data = DataTiddler.getTiddlerDataObject(tiddler);
    return DataTiddler.stringify(data);
};


// Internal.
// 
DataTiddler.indexOfNonEscapedText = function(s, subString, startIndex) {
	var index = s.indexOf(subString, startIndex);
	while ((index > 0) && (s[index-1] == '~')) { 
		index = s.indexOf(subString, index+1);
	}
	return index;
};

// Internal.
//
DataTiddler.getDataSectionInfo = function(text) {
	// Special care must be taken to handle "<data>" and "</data>" texts inside
	// a data section. 
	// Also take care not to use an escaped <data> (i.e. "~<data>") as the start 
	// of a data section. (Same for </data>)

    // NOTE: we are explicitly searching for a data section that contains a JSON
    // string, i.e. framed with braces. This way we are little bit more robust in
    // case the tiddler contains unescaped texts "<data>" or "</data>". This must
    // be changed when using a different stringifier.

	var startTagText = "<data>{";
	var endTagText = "}</data>";

	var startPos = 0;

	// Find the first not escaped "<data>".
	var startDataTagIndex = DataTiddler.indexOfNonEscapedText(text, startTagText, 0);
	if (startDataTagIndex < 0) {
		return null;
	}

	// Find the *last* not escaped "</data>".
	var endDataTagIndex = text.indexOf(endTagText, startDataTagIndex);
	if (endDataTagIndex < 0) {
		return null;
	}
	var nextEndDataTagIndex;
	while ((nextEndDataTagIndex = text.indexOf(endTagText, endDataTagIndex+1)) >= 0) {
		endDataTagIndex = nextEndDataTagIndex;
	}

	return {
		prefixEnd: startDataTagIndex, 
		dataStart: startDataTagIndex+(startTagText.length)-1, 
		dataEnd: endDataTagIndex, 
		suffixStart: endDataTagIndex+(endTagText.length)
	};
};

// Internal.
// 
// Returns the "matches" of a content of a DataTiddler on the
// "data" regular expression. Return null when no data is defined
// in the tiddler content.
//
// Group 1: text before data section (prefix)
// Group 2: content of data section
// Group 3: text behind data section (suffix)
//
// @param tiddler a Tiddler
// @return [may be null] null when the tiddler contains no data section, otherwise see above.
//
DataTiddler.getDataTiddlerMatches = function(tiddler) {
	var text = tiddler.text;
	var info = DataTiddler.getDataSectionInfo(text);
	if (!info) {
		return null;
	}

	var prefix = text.substr(0,info.prefixEnd);
	var data = text.substr(info.dataStart, info.dataEnd-info.dataStart+1);
	var suffix = text.substr(info.suffixStart);
	
	return [text, prefix, data, suffix];
};


// Internal.
//
// Saves the data in a <data> block of the given tiddler (as a minor change). 
//
// The "chkAutoSave" and "chkForceMinorUpdate" options are respected. 
// I.e. the TiddlyWiki *file* is only saved when AutoSave is on.
//
// Notifications are not send. 
//
// This method should only be called when the data really has changed. 
//
// @param tiddler
//             the tiddler to be saved.
//
DataTiddler.save = function(tiddler) {

    var matches = DataTiddler.getDataTiddlerMatches(tiddler);

    var prefix;
    var suffix;
    if (matches === null) {
        prefix = tiddler.text;
        suffix = "";
    } else {
        prefix = matches[1];
        suffix = matches[3];
    }

    var dataText = DataTiddler.getDataTextOfTiddler(tiddler);
    var newText = 
            (dataText !== null) 
                ? prefix + "<data>" + dataText + "</data>" + suffix
                : prefix + suffix;
    if (newText != tiddler.text) {
        // make the change in the tiddlers text
        
        // ... see DataTiddler.MyTiddlerChangedFunction
        tiddler.isDataTiddlerChange = true;
        
        // ... do the action change
        tiddler.set(
                tiddler.title,
                newText,
                config.options.txtUserName, 
                config.options.chkForceMinorUpdate? undefined : new Date(),
                tiddler.tags);

        // ... see DataTiddler.MyTiddlerChangedFunction
        delete tiddler.isDataTiddlerChange;

        // Mark the store as dirty.
        store.dirty = true;
 
        // AutoSave if option is selected
        if(config.options.chkAutoSave) {
           saveChanges();
        }
    }
};

// Internal.
//
DataTiddler.MyTiddlerChangedFunction = function() {
    // Remove the data object from the tiddler when the tiddler is changed
    // by code other than DataTiddler code. 
    //
    // This is necessary since the data object is just a "cached version" 
    // of the data defined in the data section of the tiddler and the 
    // "external" change may have changed the content of the data section.
    // Thus we are not sure if the data object reflects the data section 
    // contents. 
    // 
    // By deleting the data object we ensure that the data object is 
    // reconstructed the next time it is needed, with the data defined by
    // the data section in the tiddler's text.
    
    // To indicate that a change is a "DataTiddler change" a temporary
    // property "isDataTiddlerChange" is added to the tiddler.
    if (this.dataObject && !this.isDataTiddlerChange) {
        delete this.dataObject;
    }
    
    // call the original code.
	DataTiddler.originalTiddlerChangedFunction.apply(this, arguments);
};


//============================================================================
// Formatters
//============================================================================

// This formatter ensures that "~<data>" is rendered as "<data>". This is used to 
// escape the "<data>" of a data section, just in case someone really wants to use
// "<data>" as a text in a tiddler and not start a data section.
//
// Same for </data>.
//
config.formatters.push( {
    name: "data-escape",
    match: "~<\\/?data>",

    handler: function(w) {
            w.outputText(w.output,w.matchStart + 1,w.nextMatch);
    }
} );


// This formatter ensures that <data>...</data> sections are not rendered.
//
config.formatters.push( {
    name: "data",
    match: "<data>",

    handler: function(w) {
		var info = DataTiddler.getDataSectionInfo(w.source);
		if (info && info.prefixEnd == w.matchStart) {
            w.nextMatch = info.suffixStart;
		} else {
			w.outputText(w.output,w.matchStart,w.nextMatch);
		}
    }
} );


//============================================================================
// Tiddler Class Extension
//============================================================================

// "Hijack" the changed method ---------------------------------------------------

DataTiddler.originalTiddlerChangedFunction = Tiddler.prototype.changed;
Tiddler.prototype.changed = DataTiddler.MyTiddlerChangedFunction;

// Define accessor methods -------------------------------------------------------

// Returns the value of the given data field of the tiddler. When no such field 
// is defined or its value is undefined the defaultValue is returned.
//
// When field is undefined (or null) the data object is returned. (See 
// DataTiddler.getDataObject.)
//
// @param field [may be null, undefined]
// @param defaultValue [may be null, undefined]
// @return [may be null, undefined]
//
Tiddler.prototype.data = function(field, defaultValue) {
    return (field) 
         ? DataTiddler.getTiddlerDataValue(this, field, defaultValue)
         : DataTiddler.getTiddlerDataObject(this);
};

// Sets the value of the given data field of the tiddler to the value. When the 
// value is equal to the defaultValue no value is set (and the field is removed).
//
// @param value [may be null, undefined]
// @param defaultValue [may be null, undefined]
//
Tiddler.prototype.setData = function(field, value, defaultValue) {
    DataTiddler.setTiddlerDataValue(this, field, value, defaultValue);
};


//============================================================================
// showData Macro
//============================================================================

config.macros.showData = {
     // Standard Properties
     label: "showData",
     prompt: "Display the values stored in the data section of the tiddler"
};

config.macros.showData.handler = function(place,macroName,params) {
    // --- Parsing ------------------------------------------

    var i = 0; // index running over the params
    // Parse the optional "JSON"
    var showInJSONFormat = false;
    if ((i < params.length) && params[i] == "JSON") {
        i++;
        showInJSONFormat = true;
    }
    
    var tiddlerName = story.findContainingTiddler(place).id.substr(7);
    if (i < params.length) {
        tiddlerName = params[i];
        i++;
    }

    // --- Processing ------------------------------------------
    try {
        if (showInJSONFormat) {
            this.renderDataInJSONFormat(place, tiddlerName);
        } else {
            this.renderDataAsTable(place, tiddlerName);
        }
    } catch (e) {
        this.createErrorElement(place, e);
    }
};

config.macros.showData.renderDataInJSONFormat = function(place,tiddlerName) {
    var text = DataTiddler.getDataText(tiddlerName);
    if (text) {
        createTiddlyElement(place,"pre",null,null,text);
    }
};

config.macros.showData.renderDataAsTable = function(place,tiddlerName) {
    var text = "|!Name|!Value|\n";
    var data = DataTiddler.getDataObject(tiddlerName);
    if (data) {
        for (var i in data) {
            var value = data[i];
            text += "|"+i+"|"+DataTiddler.stringify(value)+"|\n";
        }
    }
    
    wikify(text, place);
};


// Internal.
//
// Creates an element that holds an error message
// 
config.macros.showData.createErrorElement = function(place, exception) {
    var message = (exception.description) ? exception.description : exception.toString();
    return createTiddlyElement(place,"span",null,"showDataError","<<showData ...>>: "+message);
};

// ---------------------------------------------------------------------------
// Stylesheet Extensions (may be overridden by local StyleSheet)
// ---------------------------------------------------------------------------
//
setStylesheet(
    ".showDataError{color: #ffffff;background-color: #880000;}",
    "showData");


} // of "install only once"
// Used Globals (for JSLint) ==============

// ... TiddlyWiki Core
/*global 	createTiddlyElement, saveChanges, store, story, wikify */
// ... DataTiddler
/*global 	DataTiddler */
// ... JSON
/*global 	JSON */
			

/***
!JSON Code, used to serialize the data
***/
/*
Copyright (c) 2005 JSON.org

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The Software shall be used for Good, not Evil.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/

/*
    The global object JSON contains two methods.

    JSON.stringify(value) takes a JavaScript value and produces a JSON text.
    The value must not be cyclical.

    JSON.parse(text) takes a JSON text and produces a JavaScript value. It will
    throw a 'JSONError' exception if there is an error.
*/
var JSON = {
    copyright: '(c)2005 JSON.org',
    license: 'http://www.crockford.com/JSON/license.html',
/*
    Stringify a JavaScript value, producing a JSON text.
*/
    stringify: function (v) {
        var a = [];

/*
    Emit a string.
*/
        function e(s) {
            a[a.length] = s;
        }

/*
    Convert a value.
*/
        function g(x) {
            var c, i, l, v;

            switch (typeof x) {
            case 'object':
                if (x) {
                    if (x instanceof Array) {
                        e('[');
                        l = a.length;
                        for (i = 0; i < x.length; i += 1) {
                            v = x[i];
                            if (typeof v != 'undefined' &&
                                    typeof v != 'function') {
                                if (l < a.length) {
                                    e(',');
                                }
                                g(v);
                            }
                        }
                        e(']');
                        return;
                    } else if (typeof x.toString != 'undefined') {
                        e('{');
                        l = a.length;
                        for (i in x) {
                            v = x[i];
                            if (x.hasOwnProperty(i) &&
                                    typeof v != 'undefined' &&
                                    typeof v != 'function') {
                                if (l < a.length) {
                                    e(',');
                                }
                                g(i);
                                e(':');
                                g(v);
                            }
                        }
                        return e('}');
                    }
                }
                e('null');
                return;
            case 'number':
                e(isFinite(x) ? +x : 'null');
                return;
            case 'string':
                l = x.length;
                e('"');
                for (i = 0; i < l; i += 1) {
                    c = x.charAt(i);
                    if (c >= ' ') {
                        if (c == '\\' || c == '"') {
                            e('\\');
                        }
                        e(c);
                    } else {
                        switch (c) {
                            case '\b':
                                e('\\b');
                                break;
                            case '\f':
                                e('\\f');
                                break;
                            case '\n':
                                e('\\n');
                                break;
                            case '\r':
                                e('\\r');
                                break;
                            case '\t':
                                e('\\t');
                                break;
                            default:
                                c = c.charCodeAt();
                                e('\\u00' + Math.floor(c / 16).toString(16) +
                                    (c % 16).toString(16));
                        }
                    }
                }
                e('"');
                return;
            case 'boolean':
                e(String(x));
                return;
            default:
                e('null');
                return;
            }
        }
        g(v);
        return a.join('');
    },
/*
    Parse a JSON text, producing a JavaScript value.
*/
    parse: function (text) {
        var p = /^\s*(([,:{}\[\]])|"(\\.|[^\x00-\x1f"\\])*"|-?\d+(\.\d*)?([eE][+-]?\d+)?|true|false|null)\s*/,
            token,
            operator;

        function error(m, t) {
            throw {
                name: 'JSONError',
                message: m,
                text: t || operator || token
            };
        }

        function next(b) {
            if (b && b != operator) {
                error("Expected '" + b + "'");
            }
            if (text) {
                var t = p.exec(text);
                if (t) {
                    if (t[2]) {
                        token = null;
                        operator = t[2];
                    } else {
                        operator = null;
                        try {
                            token = eval(t[1]);
                        } catch (e) {
                            error("Bad token", t[1]);
                        }
                    }
                    text = text.substring(t[0].length);
                } else {
                    error("Unrecognized token", text);
                }
            } else {
                token = operator = undefined;
            }
        }


        function val() {
            var k, o;
            switch (operator) {
            case '{':
                next('{');
                o = {};
                if (operator != '}') {
                    for (;;) {
                        if (operator || typeof token != 'string') {
                            error("Missing key");
                        }
                        k = token;
                        next();
                        next(':');
                        o[k] = val();
                        if (operator != ',') {
                            break;
                        }
                        next(',');
                    }
                }
                next('}');
                return o;
            case '[':
                next('[');
                o = [];
                if (operator != ']') {
                    for (;;) {
                        o.push(val());
                        if (operator != ',') {
                            break;
                        }
                        next(',');
                    }
                }
                next(']');
                return o;
            default:
                if (operator !== null) {
                    error("Missing value");
                }
                k = token;
                next();
                return k;
            }
        }
        next();
        return val();
    }
};

/***
!Setup the data serialization
***/

DataTiddler.format = "JSON";
DataTiddler.stringify = JSON.stringify;
DataTiddler.parse = JSON.parse;

//}}}

[[World]]
[[London]]
[[London]]
[[World]]
There are twelve major dwarven clans.

* [[Foambeard Clan]] - Easygoing, laidback brewer clan
* [[Stoutheart Clan]] Staunch, conservative protectors of the dwarven traditions.
* [[Bronzeheart Clan]] Artificer and exploration clan
* [[Grimtooth Clan]] Warrior clan
* [[Goldbeard Clan]] Banker clan
* [[Ironfist Clan]] Masters of working iron. Pioneers in projectile weapons and siege engines.
* [[Stoneshield Clan]] Conservative bankers and warriors.
* [[Brewstone Clan]] Brewer clan. Loves to experiment.
* [[Farsight Clan]] Tinkerers. Mad professor types.
* [[Rockface Clan]] Expert constructional engineers and stoneworkers.
* [[Axeblade Clan]] Crack mercenary teams.
* [[Longshot Clan]] Snipers and other gunmen.
!Trynk, God of Beer
A cornerstone of dwarven society and economy, the quality of dwarven beer is well known. Trynk makes this happen, according to the dwarves. He ensures the quality of crops and purity of water neccesary to produce good beer. He is also considered the god of fertility, since beer often indirectly leads to dwarven conception.

The Order of the Eternal Mug has supporters in every dwarven clan, and is the largest priestly order. It rarely meddles openly in dwarven politics, though its opinions carry a lot of weight

!Sif, Goddes of Gold
Dwarves love beautiful things. The Golden Lady keeps the dwarven treasuries full of lovely gold, to be shaped into items or raw political power. Also the goddess of crafting.

The Ladies of the Golden Locks are also loved by many, and are often used as economical advisors. Carry a great deal of politcal power in many clans.

!Ordrend, God of War
Dwarves are fierce (and expensive) warriors. Some exeptional dwarven heroes are said to have been possesed by the spirit of Ordrend. Ordrend is also the god of justice.

The Brotherhood of The Axe serve as tactical advisors, and are a valuable part of the army.

!Frendor, God of Death
Most dwarves do not fear death. They view it as an inevitable path that all living things must tread. That being said, they do not feel rushed to get there. Frendor commands the power to extend life as well as take it, and is also the god of Healing.

The Pale Hand is well recieved in most clans - healers are always welcome. The Pale Hand also contros the Pick, an elite assassin squad.
The dwarves are internally divided into [[Dwarven Clans]]. Each clan has it's own variation on the legal system, for example. Matters concerning the dwarven nation as a whole are decided in a council consisting of the leaders of the clans and representatives of the gods. An elected-for-life king presides over the council, and has limited power of veto. When the King dies, a new one is elected. This usually is one of the clan leaders, although common dwarves have been chosen.

The European dwarves are closely allied to the 'new rich' capitalists and entrepeneurs, seeing a common ground in the desire for profit at all costs. Driven by the desire (and very real possibility) of making great profits, quite a few dwarves have joined the trading companies as technical advisors. Some have even risen to positions of power.

The Dwarves have one of the finest armies in the world. It is kept battle-trained both through clan in-fighting and through being the best mercenary force avaiable - if you pay the fees (not doing so is usually devastating for the client).
Dwarves are cunning, brillant engineers and craftsmen. They are fiercely loyal to their allies, and as ferociously opposed to their enemies. They also have a great love for gold, and are quite accomplished businessmen. Many clans even accept slavery as 'the correct order of things' - free labor can't be that bad.

Dwarves are seldom seen outside their mountain kingdoms unless they have an economic incentive. They are sometimes employed for their masonry and engineering skills, and have the best standing army available (for considerable amounts of gold). 

The wealthier dwarven clans are also moneylenders.

As a general rule: where there are (geologically stable) mountains, there are (or have been) dwarves. The only known nations per se are located in the Alps and Caucasian mountains. There are dwarven settlements in Scotland, and rumors of other known dwarf nations in the mountains of Scandinavia and Russia.

Most elves travel the world in caravans, always seeking new knowledge and new peoples. They are met with suspicion in 'civilized' society though - they have a reputation for being long-fingered seducers. They are grudgingly tolerated for their extensive knowledge of all schools of magic, and creators of the finest magical artefacts.

The elves are great lovers of nature, and find the violation of nature in the name of technology apalling. They are most likely to ally with conservative, magically positive humans - the aristocrats. For the same reasons they mistrust the tecnologically advanced dwarves - some even resent the dwarves for revealing technology to humans.

There are rumors that [[Magical Contamination]] of humans is due to elven intervention, and not a shortcoming of the human race.
!Armor & Protective Items
Masterwork Chain Shirt (AC +4, arcane spell failure 15%)
!Weapons
Greathammer of fiery burst +2, 1d12 + 1d6, crit 20x2+3d6
!Major Countries
<<forEachTiddler
    where
       'tiddler.tags.contains("Europe")'

    sortBy
       'tiddler.title.toUpperCase()'

    write '" [["+tiddler.title+" ]] \"view ["+tiddler.title+"]\" [["+tiddler.title+"]] "'

        begin '"<<tabs txtMyAutoTab "'

        end '">"+">"'

        none '"//No tiddler tagged with \"Europe\"//"'
>>
When the first colonialists estalished colonies, they encountered "Savage, Exotick beings....". The term stuck, and soon became a catch-all derogatory for anything not human, elven or dwarven. Variants: Ticks (common slang), 'tickie'/'tickeys'. This also covers half-breeds.

The ticks were, in most cases, overpowered by the superior technology the invaders arrived with. Colonies were established, and a slave trade soon flourished.

Thus, players can encounter a logging operation which employs ogre lumberjacks, or a lord with hobgoblin bodyguards. Half-breeds are not unheard of, but either demoted to freak shows or born into slavery or servitude. It is rare, but not unheard of, for halfbreeds and non-humans to rise to high society. This almost exclusively happens in the colonies. They are starting to trickle into [[The Underworld]] of Europe though.
* [[Power Attack|http://www.d20srd.org/srd/feats.htm#powerAttack]]
* [[Cleave|http://www.d20srd.org/srd/feats.htm#cleave]]
* [[Great Cleave|http://www.d20srd.org/srd/feats.htm#greatCleave]]
* [[Improved Overrun|http://www.d20srd.org/srd/feats.htm#improvedOverrun]]
* [[Spell Focus|http://www.d20srd.org/srd/feats.htm#spellFocus]] (evocation)
* [[Greater Spell Focus|http://www.d20srd.org/srd/feats.htm#greaterSpellFocus]] (evocation)
* [[Spell Mastery|http://www.d20srd.org/srd/feats.htm#spellMasterySpecial]] in [[Fireball|http://www.d20srd.org/srd/spells/fireball.htm]], [[Mage Armor|http://www.d20srd.org/srd/spells/mageArmor.htm]] and [[Bull's Strength|http://www.d20srd.org/srd/spells/bullsStrength.htm]]
Type the text for 'New Tiddler'
Generally jovial and friendly, this clan has the finest dwarven brewers of dark ales and stouts. Not very militant (for a dwarf clan). Only maintanins the minimum army required by the Dwarven Code. Commoners are often brewers, fishermen or farmers.
!!Chief Exports
*Beer. Notable brands: Dirchwold Brown Ale, Fool's Heart Barley Porter.
*Grain, mostly barley and oats.
*Hops
*Fish
*Metal and ore, mostly iron and tin. Some rare metals as well.

!!Geography
Controls a sizeable portion of the farmlands near Lake Geneva as well asa th southern shore, and part of the extensive mineral deposits in the mountains to the south. The clan seat is located in the southern alps. 
!!Allied Clans
* [[Stoutheart Clan]]

!!Rival Clans
* [[Goldbeard Clan]]. Contention over the richest deposits and the rarest ores.
* [[Bronzeheart Clan]] Border dispute over the right to a pass.
/***
|''Name:''|ForEachTiddlerPlugin|
|''Version:''|1.0.8 (2007-04-12)|
|''Source:''|http://tiddlywiki.abego-software.de/#ForEachTiddlerPlugin|
|''Author:''|UdoBorkowski (ub [at] abego-software [dot] de)|
|''Licence:''|[[BSD open source license (abego Software)|http://www.abego-software.de/legal/apl-v10.html]]|
|''Copyright:''|&copy; 2005-2007 [[abego Software|http://www.abego-software.de]]|
|''TiddlyWiki:''|1.2.38+, 2.0|
|''Browser:''|Firefox 1.0.4+; Firefox 1.5; InternetExplorer 6.0|
!Description

Create customizable lists, tables etc. for your selections of tiddlers. Specify the tiddlers to include and their order through a powerful language.

''Syntax:'' 
|>|{{{<<}}}''forEachTiddler'' [''in'' //tiddlyWikiPath//] [''where'' //whereCondition//] [''sortBy'' //sortExpression// [''ascending'' //or// ''descending'']] [''script'' //scriptText//] [//action// [//actionParameters//]]{{{>>}}}|
|//tiddlyWikiPath//|The filepath to the TiddlyWiki the macro should work on. When missing the current TiddlyWiki is used.|
|//whereCondition//|(quoted) JavaScript boolean expression. May refer to the build-in variables {{{tiddler}}} and  {{{context}}}.|
|//sortExpression//|(quoted) JavaScript expression returning "comparable" objects (using '{{{<}}}','{{{>}}}','{{{==}}}'. May refer to the build-in variables {{{tiddler}}} and  {{{context}}}.|
|//scriptText//|(quoted) JavaScript text. Typically defines JavaScript functions that are called by the various JavaScript expressions (whereClause, sortClause, action arguments,...)|
|//action//|The action that should be performed on every selected tiddler, in the given order. By default the actions [[addToList|AddToListAction]] and [[write|WriteAction]] are supported. When no action is specified [[addToList|AddToListAction]]  is used.|
|//actionParameters//|(action specific) parameters the action may refer while processing the tiddlers (see action descriptions for details). <<tiddler [[JavaScript in actionParameters]]>>|
|>|~~Syntax formatting: Keywords in ''bold'', optional parts in [...]. 'or' means that exactly one of the two alternatives must exist.~~|

See details see [[ForEachTiddlerMacro]] and [[ForEachTiddlerExamples]].

!Revision history
* v1.0.8 (2007-04-12)
** Adapted to latest TiddlyWiki 2.2 Beta importTiddlyWiki API (introduced with changeset 2004). TiddlyWiki 2.2 Beta builds prior to changeset 2004 are no longer supported (but TiddlyWiki 2.1 and earlier, of cause)
* v1.0.7 (2007-03-28)
** Also support "pre" formatted TiddlyWikis (introduced with TW 2.2) (when using "in" clause to work on external tiddlers)
* v1.0.6 (2006-09-16)
** Context provides "viewerTiddler", i.e. the tiddler used to view the macro. Most times this is equal to the "inTiddler", but when using the "tiddler" macro both may be different.
** Support "begin", "end" and "none" expressions in "write" action
* v1.0.5 (2006-02-05)
** Pass tiddler containing the macro with wikify, context object also holds reference to tiddler containing the macro ("inTiddler"). Thanks to SimonBaird.
** Support Firefox 1.5.0.1
** Internal
*** Make "JSLint" conform
*** "Only install once"
* v1.0.4 (2006-01-06)
** Support TiddlyWiki 2.0
* v1.0.3 (2005-12-22)
** Features: 
*** Write output to a file supports multi-byte environments (Thanks to Bram Chen) 
*** Provide API to access the forEachTiddler functionality directly through JavaScript (see getTiddlers and performMacro)
** Enhancements:
*** Improved error messages on InternetExplorer.
* v1.0.2 (2005-12-10)
** Features: 
*** context object also holds reference to store (TiddlyWiki)
** Fixed Bugs: 
*** ForEachTiddler 1.0.1 has broken support on win32 Opera 8.51 (Thanks to BrunoSabin for reporting)
* v1.0.1 (2005-12-08)
** Features: 
*** Access tiddlers stored in separated TiddlyWikis through the "in" option. I.e. you are no longer limited to only work on the "current TiddlyWiki".
*** Write output to an external file using the "toFile" option of the "write" action. With this option you may write your customized tiddler exports.
*** Use the "script" section to define "helper" JavaScript functions etc. to be used in the various JavaScript expressions (whereClause, sortClause, action arguments,...).
*** Access and store context information for the current forEachTiddler invocation (through the build-in "context" object) .
*** Improved script evaluation (for where/sort clause and write scripts).
* v1.0.0 (2005-11-20)
** initial version

!Code
***/
//{{{

	
//============================================================================
//============================================================================
//		   ForEachTiddlerPlugin
//============================================================================
//============================================================================

// Only install once
if (!version.extensions.ForEachTiddlerPlugin) {

if (!window.abego) window.abego = {};

version.extensions.ForEachTiddlerPlugin = {
	major: 1, minor: 0, revision: 8, 
	date: new Date(2007,3,12), 
	source: "http://tiddlywiki.abego-software.de/#ForEachTiddlerPlugin",
	licence: "[[BSD open source license (abego Software)|http://www.abego-software.de/legal/apl-v10.html]]",
	copyright: "Copyright (c) abego Software GmbH, 2005-2007 (www.abego-software.de)"
};

// For backward compatibility with TW 1.2.x
//
if (!TiddlyWiki.prototype.forEachTiddler) {
	TiddlyWiki.prototype.forEachTiddler = function(callback) {
		for(var t in this.tiddlers) {
			callback.call(this,t,this.tiddlers[t]);
		}
	};
}

//============================================================================
// forEachTiddler Macro
//============================================================================

version.extensions.forEachTiddler = {
	major: 1, minor: 0, revision: 8, date: new Date(2007,3,12), provider: "http://tiddlywiki.abego-software.de"};

// ---------------------------------------------------------------------------
// Configurations and constants 
// ---------------------------------------------------------------------------

config.macros.forEachTiddler = {
	 // Standard Properties
	 label: "forEachTiddler",
	 prompt: "Perform actions on a (sorted) selection of tiddlers",

	 // actions
	 actions: {
		 addToList: {},
		 write: {}
	 }
};

// ---------------------------------------------------------------------------
//  The forEachTiddler Macro Handler 
// ---------------------------------------------------------------------------

config.macros.forEachTiddler.getContainingTiddler = function(e) {
	while(e && !hasClass(e,"tiddler"))
		e = e.parentNode;
	var title = e ? e.getAttribute("tiddler") : null; 
	return title ? store.getTiddler(title) : null;
};

config.macros.forEachTiddler.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
	// config.macros.forEachTiddler.traceMacroCall(place,macroName,params,wikifier,paramString,tiddler);

	if (!tiddler) tiddler = config.macros.forEachTiddler.getContainingTiddler(place);
	// --- Parsing ------------------------------------------

	var i = 0; // index running over the params
	// Parse the "in" clause
	var tiddlyWikiPath = undefined;
	if ((i < params.length) && params[i] == "in") {
		i++;
		if (i >= params.length) {
			this.handleError(place, "TiddlyWiki path expected behind 'in'.");
			return;
		}
		tiddlyWikiPath = this.paramEncode((i < params.length) ? params[i] : "");
		i++;
	}

	// Parse the where clause
	var whereClause ="true";
	if ((i < params.length) && params[i] == "where") {
		i++;
		whereClause = this.paramEncode((i < params.length) ? params[i] : "");
		i++;
	}

	// Parse the sort stuff
	var sortClause = null;
	var sortAscending = true; 
	if ((i < params.length) && params[i] == "sortBy") {
		i++;
		if (i >= params.length) {
			this.handleError(place, "sortClause missing behind 'sortBy'.");
			return;
		}
		sortClause = this.paramEncode(params[i]);
		i++;

		if ((i < params.length) && (params[i] == "ascending" || params[i] == "descending")) {
			 sortAscending = params[i] == "ascending";
			 i++;
		}
	}

	// Parse the script
	var scriptText = null;
	if ((i < params.length) && params[i] == "script") {
		i++;
		scriptText = this.paramEncode((i < params.length) ? params[i] : "");
		i++;
	}

	// Parse the action. 
	// When we are already at the end use the default action
	var actionName = "addToList";
	if (i < params.length) {
	   if (!config.macros.forEachTiddler.actions[params[i]]) {
			this.handleError(place, "Unknown action '"+params[i]+"'.");
			return;
		} else {
			actionName = params[i]; 
			i++;
		}
	} 
	
	// Get the action parameter
	// (the parsing is done inside the individual action implementation.)
	var actionParameter = params.slice(i);


	// --- Processing ------------------------------------------
	try {
		this.performMacro({
				place: place, 
				inTiddler: tiddler,
				whereClause: whereClause, 
				sortClause: sortClause, 
				sortAscending: sortAscending, 
				actionName: actionName, 
				actionParameter: actionParameter, 
				scriptText: scriptText, 
				tiddlyWikiPath: tiddlyWikiPath});

	} catch (e) {
		this.handleError(place, e);
	}
};

// Returns an object with properties "tiddlers" and "context".
// tiddlers holds the (sorted) tiddlers selected by the parameter,
// context the context of the execution of the macro.
//
// The action is not yet performed.
//
// @parameter see performMacro
//
config.macros.forEachTiddler.getTiddlersAndContext = function(parameter) {

	var context = config.macros.forEachTiddler.createContext(parameter.place, parameter.whereClause, parameter.sortClause, parameter.sortAscending, parameter.actionName, parameter.actionParameter, parameter.scriptText, parameter.tiddlyWikiPath, parameter.inTiddler);

	var tiddlyWiki = parameter.tiddlyWikiPath ? this.loadTiddlyWiki(parameter.tiddlyWikiPath) : store;
	context["tiddlyWiki"] = tiddlyWiki;
	
	// Get the tiddlers, as defined by the whereClause
	var tiddlers = this.findTiddlers(parameter.whereClause, context, tiddlyWiki);
	context["tiddlers"] = tiddlers;

	// Sort the tiddlers, when sorting is required.
	if (parameter.sortClause) {
		this.sortTiddlers(tiddlers, parameter.sortClause, parameter.sortAscending, context);
	}

	return {tiddlers: tiddlers, context: context};
};

// Returns the (sorted) tiddlers selected by the parameter.
//
// The action is not yet performed.
//
// @parameter see performMacro
//
config.macros.forEachTiddler.getTiddlers = function(parameter) {
	return this.getTiddlersAndContext(parameter).tiddlers;
};

// Performs the macros with the given parameter.
//
// @param parameter holds the parameter of the macro as separate properties.
//				  The following properties are supported:
//
//						place
//						whereClause
//						sortClause
//						sortAscending
//						actionName
//						actionParameter
//						scriptText
//						tiddlyWikiPath
//
//					All properties are optional. 
//					For most actions the place property must be defined.
//
config.macros.forEachTiddler.performMacro = function(parameter) {
	var tiddlersAndContext = this.getTiddlersAndContext(parameter);

	// Perform the action
	var actionName = parameter.actionName ? parameter.actionName : "addToList";
	var action = config.macros.forEachTiddler.actions[actionName];
	if (!action) {
		this.handleError(parameter.place, "Unknown action '"+actionName+"'.");
		return;
	}

	var actionHandler = action.handler;
	actionHandler(parameter.place, tiddlersAndContext.tiddlers, parameter.actionParameter, tiddlersAndContext.context);
};

// ---------------------------------------------------------------------------
//  The actions 
// ---------------------------------------------------------------------------

// Internal.
//
// --- The addToList Action -----------------------------------------------
//
config.macros.forEachTiddler.actions.addToList.handler = function(place, tiddlers, parameter, context) {
	// Parse the parameter
	var p = 0;

	// Check for extra parameters
	if (parameter.length > p) {
		config.macros.forEachTiddler.createExtraParameterErrorElement(place, "addToList", parameter, p);
		return;
	}

	// Perform the action.
	var list = document.createElement("ul");
	place.appendChild(list);
	for (var i = 0; i < tiddlers.length; i++) {
		var tiddler = tiddlers[i];
		var listItem = document.createElement("li");
		list.appendChild(listItem);
		createTiddlyLink(listItem, tiddler.title, true);
	}
};

abego.parseNamedParameter = function(name, parameter, i) {
	var beginExpression = null;
	if ((i < parameter.length) && parameter[i] == name) {
		i++;
		if (i >= parameter.length) {
			throw "Missing text behind '%0'".format([name]);
		}
		
		return config.macros.forEachTiddler.paramEncode(parameter[i]);
	}
	return null;
}

// Internal.
//
// --- The write Action ---------------------------------------------------
//
config.macros.forEachTiddler.actions.write.handler = function(place, tiddlers, parameter, context) {
	// Parse the parameter
	var p = 0;
	if (p >= parameter.length) {
		this.handleError(place, "Missing expression behind 'write'.");
		return;
	}

	var textExpression = config.macros.forEachTiddler.paramEncode(parameter[p]);
	p++;

	// Parse the "begin" option
	var beginExpression = abego.parseNamedParameter("begin", parameter, p);
	if (beginExpression !== null) 
		p += 2;
	var endExpression = abego.parseNamedParameter("end", parameter, p);
	if (endExpression !== null) 
		p += 2;
	var noneExpression = abego.parseNamedParameter("none", parameter, p);
	if (noneExpression !== null) 
		p += 2;

	// Parse the "toFile" option
	var filename = null;
	var lineSeparator = undefined;
	if ((p < parameter.length) && parameter[p] == "toFile") {
		p++;
		if (p >= parameter.length) {
			this.handleError(place, "Filename expected behind 'toFile' of 'write' action.");
			return;
		}
		
		filename = config.macros.forEachTiddler.getLocalPath(config.macros.forEachTiddler.paramEncode(parameter[p]));
		p++;
		if ((p < parameter.length) && parameter[p] == "withLineSeparator") {
			p++;
			if (p >= parameter.length) {
				this.handleError(place, "Line separator text expected behind 'withLineSeparator' of 'write' action.");
				return;
			}
			lineSeparator = config.macros.forEachTiddler.paramEncode(parameter[p]);
			p++;
		}
	}
	
	// Check for extra parameters
	if (parameter.length > p) {
		config.macros.forEachTiddler.createExtraParameterErrorElement(place, "write", parameter, p);
		return;
	}

	// Perform the action.
	var func = config.macros.forEachTiddler.getEvalTiddlerFunction(textExpression, context);
	var count = tiddlers.length;
	var text = "";
	if (count > 0 && beginExpression)
		text += config.macros.forEachTiddler.getEvalTiddlerFunction(beginExpression, context)(undefined, context, count, undefined);
	
	for (var i = 0; i < count; i++) {
		var tiddler = tiddlers[i];
		text += func(tiddler, context, count, i);
	}
	
	if (count > 0 && endExpression)
		text += config.macros.forEachTiddler.getEvalTiddlerFunction(endExpression, context)(undefined, context, count, undefined);

	if (count == 0 && noneExpression) 
		text += config.macros.forEachTiddler.getEvalTiddlerFunction(noneExpression, context)(undefined, context, count, undefined);
		

	if (filename) {
		if (lineSeparator !== undefined) {
			lineSeparator = lineSeparator.replace(/\\n/mg, "\n").replace(/\\r/mg, "\r");
			text = text.replace(/\n/mg,lineSeparator);
		}
		saveFile(filename, convertUnicodeToUTF8(text));
	} else {
		var wrapper = createTiddlyElement(place, "span");
		wikify(text, wrapper, null/* highlightRegExp */, context.inTiddler);
	}
};


// ---------------------------------------------------------------------------
//  Helpers
// ---------------------------------------------------------------------------

// Internal.
//
config.macros.forEachTiddler.createContext = function(placeParam, whereClauseParam, sortClauseParam, sortAscendingParam, actionNameParam, actionParameterParam, scriptText, tiddlyWikiPathParam, inTiddlerParam) {
	return {
		place : placeParam, 
		whereClause : whereClauseParam, 
		sortClause : sortClauseParam, 
		sortAscending : sortAscendingParam, 
		script : scriptText,
		actionName : actionNameParam, 
		actionParameter : actionParameterParam,
		tiddlyWikiPath : tiddlyWikiPathParam,
		inTiddler : inTiddlerParam, // the tiddler containing the <<forEachTiddler ...>> macro call.
		viewerTiddler : config.macros.forEachTiddler.getContainingTiddler(placeParam) // the tiddler showing the forEachTiddler result
	};
};

// Internal.
//
// Returns a TiddlyWiki with the tiddlers loaded from the TiddlyWiki of 
// the given path.
//
config.macros.forEachTiddler.loadTiddlyWiki = function(path, idPrefix) {
	if (!idPrefix) {
		idPrefix = "store";
	}
	var lenPrefix = idPrefix.length;
	
	// Read the content of the given file
	var content = loadFile(this.getLocalPath(path));
	if(content === null) {
		throw "TiddlyWiki '"+path+"' not found.";
	}
	
	var tiddlyWiki = new TiddlyWiki();

	// Starting with TW 2.2 there is a helper function to import the tiddlers
	if (tiddlyWiki.importTiddlyWiki) {
		if (!tiddlyWiki.importTiddlyWiki(content))
			throw "File '"+path+"' is not a TiddlyWiki.";
		tiddlyWiki.dirty = false;
		return tiddlyWiki;
	}
	
	// The legacy code, for TW < 2.2
	
	// Locate the storeArea div's
	var posOpeningDiv = content.indexOf(startSaveArea);
	var posClosingDiv = content.lastIndexOf(endSaveArea);
	if((posOpeningDiv == -1) || (posClosingDiv == -1)) {
		throw "File '"+path+"' is not a TiddlyWiki.";
	}
	var storageText = content.substr(posOpeningDiv + startSaveArea.length, posClosingDiv);
	
	// Create a "div" element that contains the storage text
	var myStorageDiv = document.createElement("div");
	myStorageDiv.innerHTML = storageText;
	myStorageDiv.normalize();
	
	// Create all tiddlers in a new TiddlyWiki
	// (following code is modified copy of TiddlyWiki.prototype.loadFromDiv)
	var store = myStorageDiv.childNodes;
	for(var t = 0; t < store.length; t++) {
		var e = store[t];
		var title = null;
		if(e.getAttribute)
			title = e.getAttribute("tiddler");
		if(!title && e.id && e.id.substr(0,lenPrefix) == idPrefix)
			title = e.id.substr(lenPrefix);
		if(title && title !== "") {
			var tiddler = tiddlyWiki.createTiddler(title);
			tiddler.loadFromDiv(e,title);
		}
	}
	tiddlyWiki.dirty = false;

	return tiddlyWiki;
};


	
// Internal.
//
// Returns a function that has a function body returning the given javaScriptExpression.
// The function has the parameters:
// 
//	 (tiddler, context, count, index)
//
config.macros.forEachTiddler.getEvalTiddlerFunction = function (javaScriptExpression, context) {
	var script = context["script"];
	var functionText = "var theFunction = function(tiddler, context, count, index) { return "+javaScriptExpression+"}";
	var fullText = (script ? script+";" : "")+functionText+";theFunction;";
	return eval(fullText);
};

// Internal.
//
config.macros.forEachTiddler.findTiddlers = function(whereClause, context, tiddlyWiki) {
	var result = [];
	var func = config.macros.forEachTiddler.getEvalTiddlerFunction(whereClause, context);
	tiddlyWiki.forEachTiddler(function(title,tiddler) {
		if (func(tiddler, context, undefined, undefined)) {
			result.push(tiddler);
		}
	});
	return result;
};

// Internal.
//
config.macros.forEachTiddler.createExtraParameterErrorElement = function(place, actionName, parameter, firstUnusedIndex) {
	var message = "Extra parameter behind '"+actionName+"':";
	for (var i = firstUnusedIndex; i < parameter.length; i++) {
		message += " "+parameter[i];
	}
	this.handleError(place, message);
};

// Internal.
//
config.macros.forEachTiddler.sortAscending = function(tiddlerA, tiddlerB) {
	var result = 
		(tiddlerA.forEachTiddlerSortValue == tiddlerB.forEachTiddlerSortValue) 
			? 0
			: (tiddlerA.forEachTiddlerSortValue < tiddlerB.forEachTiddlerSortValue)
			   ? -1 
			   : +1; 
	return result;
};

// Internal.
//
config.macros.forEachTiddler.sortDescending = function(tiddlerA, tiddlerB) {
	var result = 
		(tiddlerA.forEachTiddlerSortValue == tiddlerB.forEachTiddlerSortValue) 
			? 0
			: (tiddlerA.forEachTiddlerSortValue < tiddlerB.forEachTiddlerSortValue)
			   ? +1 
			   : -1; 
	return result;
};

// Internal.
//
config.macros.forEachTiddler.sortTiddlers = function(tiddlers, sortClause, ascending, context) {
	// To avoid evaluating the sortClause whenever two items are compared 
	// we pre-calculate the sortValue for every item in the array and store it in a 
	// temporary property ("forEachTiddlerSortValue") of the tiddlers.
	var func = config.macros.forEachTiddler.getEvalTiddlerFunction(sortClause, context);
	var count = tiddlers.length;
	var i;
	for (i = 0; i < count; i++) {
		var tiddler = tiddlers[i];
		tiddler.forEachTiddlerSortValue = func(tiddler,context, undefined, undefined);
	}

	// Do the sorting
	tiddlers.sort(ascending ? this.sortAscending : this.sortDescending);

	// Delete the temporary property that holds the sortValue.	
	for (i = 0; i < tiddlers.length; i++) {
		delete tiddlers[i].forEachTiddlerSortValue;
	}
};


// Internal.
//
config.macros.forEachTiddler.trace = function(message) {
	displayMessage(message);
};

// Internal.
//
config.macros.forEachTiddler.traceMacroCall = function(place,macroName,params) {
	var message ="<<"+macroName;
	for (var i = 0; i < params.length; i++) {
		message += " "+params[i];
	}
	message += ">>";
	displayMessage(message);
};


// Internal.
//
// Creates an element that holds an error message
// 
config.macros.forEachTiddler.createErrorElement = function(place, exception) {
	var message = (exception.description) ? exception.description : exception.toString();
	return createTiddlyElement(place,"span",null,"forEachTiddlerError","<<forEachTiddler ...>>: "+message);
};

// Internal.
//
// @param place [may be null]
//
config.macros.forEachTiddler.handleError = function(place, exception) {
	if (place) {
		this.createErrorElement(place, exception);
	} else {
		throw exception;
	}
};

// Internal.
//
// Encodes the given string.
//
// Replaces 
//	 "$))" to ">>"
//	 "$)" to ">"
//
config.macros.forEachTiddler.paramEncode = function(s) {
	var reGTGT = new RegExp("\\$\\)\\)","mg");
	var reGT = new RegExp("\\$\\)","mg");
	return s.replace(reGTGT, ">>").replace(reGT, ">");
};

// Internal.
//
// Returns the given original path (that is a file path, starting with "file:")
// as a path to a local file, in the systems native file format.
//
// Location information in the originalPath (i.e. the "#" and stuff following)
// is stripped.
// 
config.macros.forEachTiddler.getLocalPath = function(originalPath) {
	// Remove any location part of the URL
	var hashPos = originalPath.indexOf("#");
	if(hashPos != -1)
		originalPath = originalPath.substr(0,hashPos);
	// Convert to a native file format assuming
	// "file:///x:/path/path/path..." - pc local file --> "x:\path\path\path..."
	// "file://///server/share/path/path/path..." - FireFox pc network file --> "\\server\share\path\path\path..."
	// "file:///path/path/path..." - mac/unix local file --> "/path/path/path..."
	// "file://server/share/path/path/path..." - pc network file --> "\\server\share\path\path\path..."
	var localPath;
	if(originalPath.charAt(9) == ":") // pc local file
		localPath = unescape(originalPath.substr(8)).replace(new RegExp("/","g"),"\\");
	else if(originalPath.indexOf("file://///") === 0) // FireFox pc network file
		localPath = "\\\\" + unescape(originalPath.substr(10)).replace(new RegExp("/","g"),"\\");
	else if(originalPath.indexOf("file:///") === 0) // mac/unix local file
		localPath = unescape(originalPath.substr(7));
	else if(originalPath.indexOf("file:/") === 0) // mac/unix local file
		localPath = unescape(originalPath.substr(5));
	else // pc network file
		localPath = "\\\\" + unescape(originalPath.substr(7)).replace(new RegExp("/","g"),"\\");	
	return localPath;
};

// ---------------------------------------------------------------------------
// Stylesheet Extensions (may be overridden by local StyleSheet)
// ---------------------------------------------------------------------------
//
setStylesheet(
	".forEachTiddlerError{color: #ffffff;background-color: #880000;}",
	"forEachTiddler");

//============================================================================
// End of forEachTiddler Macro
//============================================================================


//============================================================================
// String.startsWith Function
//============================================================================
//
// Returns true if the string starts with the given prefix, false otherwise.
//
version.extensions["String.startsWith"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
String.prototype.startsWith = function(prefix) {
	var n =  prefix.length;
	return (this.length >= n) && (this.slice(0, n) == prefix);
};



//============================================================================
// String.endsWith Function
//============================================================================
//
// Returns true if the string ends with the given suffix, false otherwise.
//
version.extensions["String.endsWith"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
String.prototype.endsWith = function(suffix) {
	var n = suffix.length;
	return (this.length >= n) && (this.right(n) == suffix);
};


//============================================================================
// String.contains Function
//============================================================================
//
// Returns true when the string contains the given substring, false otherwise.
//
version.extensions["String.contains"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
String.prototype.contains = function(substring) {
	return this.indexOf(substring) >= 0;
};

//============================================================================
// Array.indexOf Function
//============================================================================
//
// Returns the index of the first occurance of the given item in the array or 
// -1 when no such item exists.
//
// @param item [may be null]
//
version.extensions["Array.indexOf"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
Array.prototype.indexOf = function(item) {
	for (var i = 0; i < this.length; i++) {
		if (this[i] == item) {
			return i;
		}
	}
	return -1;
};

//============================================================================
// Array.contains Function
//============================================================================
//
// Returns true when the array contains the given item, otherwise false. 
//
// @param item [may be null]
//
version.extensions["Array.contains"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
Array.prototype.contains = function(item) {
	return (this.indexOf(item) >= 0);
};

//============================================================================
// Array.containsAny Function
//============================================================================
//
// Returns true when the array contains at least one of the elements 
// of the item. Otherwise (or when items contains no elements) false is returned.
//
version.extensions["Array.containsAny"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
Array.prototype.containsAny = function(items) {
	for(var i = 0; i < items.length; i++) {
		if (this.contains(items[i])) {
			return true;
		}
	}
	return false;
};


//============================================================================
// Array.containsAll Function
//============================================================================
//
// Returns true when the array contains all the items, otherwise false.
// 
// When items is null false is returned (even if the array contains a null).
//
// @param items [may be null] 
//
version.extensions["Array.containsAll"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
Array.prototype.containsAll = function(items) {
	for(var i = 0; i < items.length; i++) {
		if (!this.contains(items[i])) {
			return false;
		}
	}
	return true;
};


} // of "install only once"

// Used Globals (for JSLint) ==============
// ... DOM
/*global 	document */
// ... TiddlyWiki Core
/*global 	convertUnicodeToUTF8, createTiddlyElement, createTiddlyLink, 
			displayMessage, endSaveArea, hasClass, loadFile, saveFile, 
			startSaveArea, store, wikify */
//}}}


/***
!Licence and Copyright
Copyright (c) abego Software ~GmbH, 2005 ([[www.abego-software.de|http://www.abego-software.de]])

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.

Neither the name of abego Software nor the names of its contributors may be
used to endorse or promote products derived from this software without specific
prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
***/

/***
<<checkForDataTiddlerPlugin>>
|''Name:''|FormTiddlerPlugin|
|''Version:''|1.0.6 (2007-06-24)|
|''Source:''|http://tiddlywiki.abego-software.de/#FormTiddlerPlugin|
|''Author:''|UdoBorkowski (ub [at] abego-software [dot] de)|
|''Licence:''|[[BSD open source license]]|
|''Macros:''|formTiddler, checkForDataTiddlerPlugin, newTiddlerWithForm|
|''Requires:''|DataTiddlerPlugin|
|''TiddlyWiki:''|1.2.38+, 2.0|
|''Browser:''|Firefox 1.0.4+; InternetExplorer 6.0|
!Description
Use form-based tiddlers to enter your tiddler data using text fields, listboxes, checkboxes etc. (All standard HTML Form input elements supported).

''Syntax:'' 
|>|{{{<<}}}''formTiddler'' //tiddlerName//{{{>>}}}|
|//tiddlerName//|The name of the FormTemplate tiddler to be used to edit the data of the tiddler containing the macro.|

|>|{{{<<}}}''newTiddlerWithForm'' //formTemplateName// //buttonLabel// [//titleExpression// [''askUser'']] {{{>>}}}|
|//formTemplateName//|The name of the tiddler that defines the form the new tiddler should use.|
|//buttonLabel//|The label of the button|
|//titleExpression//|A (quoted) JavaScript String expression that defines the title (/name) of the new tiddler.|
|''askUser''|Typically the user is not asked for the title when a title is specified (and not yet used). When ''askUser'' is given the user will be asked in any case. This may be used when the calculated title is just a suggestion that must be confirmed by the user|
|>|~~Syntax formatting: Keywords in ''bold'', optional parts in [...]. 'or' means that exactly one of the two alternatives must exist.~~|

For details and how to use the macros see the [[introduction|FormTiddler Introduction]] and the [[examples|FormTiddler Examples]].

!Revision history
* v1.0.6 (2007-06-24)
** Fixed problem when using SELECT component in Internet Explorer (thanks to MaikBoenig for reporting)
* v1.0.5 (2006-02-24)
** Removed "debugger;" instruction
* v1.0.4 (2006-02-07)
** Bug: On IE no data is written to data section when field values changed (thanks to KenGirard for reporting)
* v1.0.3 (2006-02-05)
** Bug: {{{"No form template specified in <<formTiddler>>"}}} when using formTiddler macro on InternetExplorer (thanks to KenGirard for reporting)
* v1.0.2 (2006-01-06)
** Support TiddlyWiki 2.0
* v1.0.1 (2005-12-22)
** Features: 
*** Support InternetExplorer
*** Added newTiddlerWithForm Macro
* v1.0.0 (2005-12-14)
** initial version

!Code
***/
//{{{

//============================================================================
//============================================================================
//						FormTiddlerPlugin
//============================================================================
//============================================================================

if (!window.abego) window.abego = {};

abego.getOptionsValue = function(element,i) {
	var v = element.options[i].value;
	if (!v && element.options[i].text)
		v = element.options[i].text;
	return v;
};

version.extensions.FormTiddlerPlugin = {
	major: 1, minor: 0, revision: 5,
	date: new Date(2006, 2, 24), 
	type: 'plugin',
	source: "http://tiddlywiki.abego-software.de/#FormTiddlerPlugin"
};

// For backward compatibility with v1.2.x
//
if (!window.story) window.story=window; 
if (!TiddlyWiki.prototype.getTiddler) TiddlyWiki.prototype.getTiddler = function(title) { return t = this.tiddlers[title]; return (t != undefined && t instanceof Tiddler) ? t : null; } 

//============================================================================
// formTiddler Macro
//============================================================================

// -------------------------------------------------------------------------------
// Configurations and constants 
// -------------------------------------------------------------------------------

config.macros.formTiddler = {
	// Standard Properties
	label: "formTiddler",
	version: {major: 1, minor: 0, revision: 4, date: new Date(2006, 2, 7)},
	prompt: "Edit tiddler data using forms",

	// Define the "setters" that set the values of INPUT elements of a given type
	// (must match the corresponding "getter")
	setter: {  
		button:				function(e, value) {/*contains no data */ },
		checkbox:			function(e, value) {e.checked = value;},
		file:				function(e, value) {try {e.value = value;} catch(e) {/* ignore, possibly security error*/}},
		hidden:				function(e, value) {e.value = value;},
		password:			function(e, value) {e.value = value;},
		radio:				function(e, value) {e.checked = (e.value == value);},
		reset:				function(e, value) {/*contains no data */ },
		"select-one":		function(e, value) {config.macros.formTiddler.setSelectOneValue(e,value);},
		"select-multiple":	function(e, value) {config.macros.formTiddler.setSelectMultipleValue(e,value);},
		submit:				function(e, value) {/*contains no data */},
		text:				function(e, value) {e.value = value;},
		textarea:			function(e, value) {e.value = value;}
	},

	// Define the "getters" that return the value of INPUT elements of a given type
	// Return undefined to not store any data.
	getter: {  
		button:				function(e, value) {return undefined;},
		checkbox:			function(e, value) {return e.checked;},
		file:				function(e, value) {return e.value;},
		hidden:				function(e, value) {return e.value;},
		password:			function(e, value) {return e.value;},
		radio:				function(e, value) {return e.checked ? e.value : undefined;},
		reset:				function(e, value) {return undefined;},
		"select-one":		function(e, value) {return config.macros.formTiddler.getSelectOneValue(e);},
		"select-multiple":	function(e, value) {return config.macros.formTiddler.getSelectMultipleValue(e);},
		submit:				function(e, value) {return undefined;},
		text:				function(e, value) {return e.value;},
		textarea:			function(e, value) {return e.value;}
	}
};


// -------------------------------------------------------------------------------
// The formTiddler Macro Handler 
// -------------------------------------------------------------------------------

config.macros.formTiddler.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
	if (!config.macros.formTiddler.checkForExtensions(place, macroName)) {
		return;
	}
	// --- Parsing ------------------------------------------

	var i = 0; // index running over the params

	// get the name of the form template tiddler
	var formTemplateName = undefined;
	if (i < params.length) {
		formTemplateName = params[i];
		i++;
	}

	if (!formTemplateName) {
		config.macros.formTiddler.createErrorElement(place, "No form template specified in <<" + macroName + ">>.");
		return;
	}


	// --- Processing ------------------------------------------

	// Get the form template text. 
	// (This contains the INPUT elements for the form.)
	var formTemplateTiddler = store.getTiddler(formTemplateName);
	if (!formTemplateTiddler) {
		config.macros.formTiddler.createErrorElement(place, "Form template '" + formTemplateName + "' not found.");
		return;
	}
	var templateText = formTemplateTiddler.text;
	if(!templateText) {
		// Shortcut: when template text is empty we do nothing.
		return;
	}

	// Get the name of the tiddler containing this "formTiddler" macro
	// (i.e. the tiddler, that will be edited and that contains the data)
	var tiddlerName = config.macros.formTiddler.getContainingTiddlerName(place);

	// Append a "form" element. 
	var formName = "form"+formTemplateName+"__"+tiddlerName;
	var e = document.createElement("form");
	e.setAttribute("name", formName);
	place.appendChild(e);

	// "Embed" the elements defined by the templateText (i.e. the INPUT elements) 
	// into the "form" element we just created
	wikify(templateText, e);

	// Initialize the INPUT elements.
	config.macros.formTiddler.initValuesAndHandlersInFormElements(formName, DataTiddler.getDataObject(tiddlerName));
}


// -------------------------------------------------------------------------------
// Form Data Access 
// -------------------------------------------------------------------------------

// Internal.
//
// Initialize the INPUT elements of the form with the values of their "matching"
// data fields in the tiddler. Also setup the onChange handler to ensure that
// changes in the INPUT elements are stored in the tiddler's data.
//
config.macros.formTiddler.initValuesAndHandlersInFormElements = function(formName, data) {
	// config.macros.formTiddler.trace("initValuesAndHandlersInFormElements(formName="+formName+", data="+data+")");

	// find the form
	var form = config.macros.formTiddler.findForm(formName);
	if (!form) {
		return;
	}

	try {
		var elems = form.elements;
		for (var i = 0; i < elems.length; i++) {
			var c = elems[i];
		
			var setter = config.macros.formTiddler.setter[c.type];
			if (setter) {
				var value = data[c.name];
				if (value != null) {
					setter(c, value);
				}
				c.onchange = onFormTiddlerChange;
			} else {
				config.macros.formTiddler.displayFormTiddlerError("No setter defined for INPUT element of type '"+c.type+"'. (Element '"+c.name+"' in form '"+formName+"')");
			}
		}
	} catch(e) {
		config.macros.formTiddler.displayFormTiddlerError("Error when updating elements with new formData. "+e);
	}
}


// Internal.
//
// @return [may be null]
//
config.macros.formTiddler.findForm = function(formName) {
	// We must manually iterate through the document's forms, since
	// IE does not support the "document[formName]" approach

	var forms = window.document.forms;
	for (var i = 0; i < forms.length; i++) {
		var form = forms[i];
		if (form.name == formName) {
			return form;
		}
	}

	return null;
}


// Internal.
//
config.macros.formTiddler.setSelectOneValue = function(element,value) {
	var n = element.options.length;
	for (var i = 0; i < n; i++) {
		element.options[i].selected = abego.getOptionsValue(element,i) == value;
	}
}

// Internal.
//
config.macros.formTiddler.setSelectMultipleValue = function(element,value) {
	var values = {};
	for (var i = 0; i < value.length; i++) {
		values[value[i]] = true;
	}
	
	var n = element.length;
	for (var i = 0; i < n; i++) {
		element.options[i].selected = !(!values[abego.getOptionsValue(element,i)]);
	}
}

// Internal.
//
config.macros.formTiddler.getSelectOneValue = function(element) {
	var i = element.selectedIndex;
	return (i >= 0) ? abego.getOptionsValue(element,i) : null;
}

// Internal.
//
config.macros.formTiddler.getSelectMultipleValue = function(element) {
	var values = [];
	var n = element.length;
	for (var i = 0; i < n; i++) {
		if (element.options[i].selected) {
			values.push(abego.getOptionsValue(element,i));
		}
	}
	return values;
}



// -------------------------------------------------------------------------------
// Helpers 
// -------------------------------------------------------------------------------

// Internal.
//
config.macros.formTiddler.checkForExtensions = function(place,macroName) {
	if (!version.extensions.DataTiddlerPlugin) {
		config.macros.formTiddler.createErrorElement(place, "<<" + macroName + ">> requires the DataTiddlerPlugin. (You can get it from http://tiddlywiki.abego-software.de/#DataTiddlerPlugin)");
		return false;
	}
	return true;
}

// Internal.
//
// Displays a trace message in the "TiddlyWiki" message pane.
// (used for debugging)
//
config.macros.formTiddler.trace = function(s) {
	displayMessage("Trace: "+s);
}

// Internal.
//
// Display some error message in the "TiddlyWiki" message pane.
//
config.macros.formTiddler.displayFormTiddlerError = function(s) {
	alert("FormTiddlerPlugin Error: "+s);
}

// Internal.
//
// Creates an element that holds an error message
// 
config.macros.formTiddler.createErrorElement = function(place, message) {
	return createTiddlyElement(place,"span",null,"formTiddlerError",message);
}

// Internal.
//
// Returns the name of the tiddler containing the given element.
// 
config.macros.formTiddler.getContainingTiddlerName = function(element) {
	return story.findContainingTiddler(element).id.substr(7);
}

// -------------------------------------------------------------------------------
// Event Handlers 
// -------------------------------------------------------------------------------

// This function must be called by the INPUT elements whenever their
// data changes. Typically this is done through an "onChange" handler.
//
function onFormTiddlerChange (e) {
	// config.macros.formTiddler.trace("onFormTiddlerChange "+e);

	if (!e) var e = window.event;

	var target = resolveTarget(e);
	var tiddlerName = config.macros.formTiddler.getContainingTiddlerName(target);
	var getter = config.macros.formTiddler.getter[target.type];
	if (getter) {
		var value = getter(target);
		DataTiddler.setData(tiddlerName, target.name, value);
	} else {
		config.macros.formTiddler.displayFormTiddlerError("No getter defined for INPUT element of type '"+target.type+"'. (Element '"+target.name+"' used in tiddler '"+tiddlerName+"')");
	}
}

// ensure that the function can be used in HTML event handler
window.onFormTiddlerChange = onFormTiddlerChange;


// -------------------------------------------------------------------------------
// Stylesheet Extensions (may be overridden by local StyleSheet)
// -------------------------------------------------------------------------------

setStylesheet(
	".formTiddlerError{color: #ffffff;background-color: #880000;}",
	"formTiddler");


//============================================================================
// checkForDataTiddlerPlugin Macro
//============================================================================

config.macros.checkForDataTiddlerPlugin = {
	// Standard Properties
	label: "checkForDataTiddlerPlugin",
	version: {major: 1, minor: 0, revision: 0, date: new Date(2005, 12, 14)},
	prompt: "Check if the DataTiddlerPlugin exists"
}

config.macros.checkForDataTiddlerPlugin.handler = function(place,macroName,params) {
	config.macros.formTiddler.checkForExtensions(place, config.macros.formTiddler.label);
}



//============================================================================
// newTiddlerWithForm Macro
//============================================================================

config.macros.newTiddlerWithForm = {
	// Standard Properties
	label: "newTiddlerWithForm",
	version: {major: 1, minor: 0, revision: 1, date: new Date(2006, 1, 6)},
	prompt: "Creates a new Tiddler with a <<formTiddler ...>> macro"
}

config.macros.newTiddlerWithForm.handler = function(place,macroName,params) {
	// --- Parsing ------------------------------------------

	var i = 0; // index running over the params

	// get the name of the form template tiddler
	var formTemplateName = undefined;
	if (i < params.length) {
		formTemplateName = params[i];
		i++;
	}

	if (!formTemplateName) {
		config.macros.formTiddler.createErrorElement(place, "No form template specified in <<" + macroName + ">>.");
		return;
	}

	// get the button label
	var buttonLabel = undefined;
	if (i < params.length) {
		buttonLabel = params[i];
		i++;
	}

	if (!buttonLabel) {
		config.macros.formTiddler.createErrorElement(place, "No button label specified in <<" + macroName + ">>.");
		return;
	}

	// get the (optional) tiddlerName script and "askUser"
	var tiddlerNameScript = undefined;
	var askUser = false;
	if (i < params.length) {
		tiddlerNameScript = params[i];
		i++;

		if (i < params.length && params[i] == "askUser") {
			askUser = true;
			i++;
		}
	}

	// --- Processing ------------------------------------------

	if(!readOnly) {
		var onClick = function() {
			var tiddlerName;
			if (tiddlerNameScript) {
				try {
					tiddlerName = eval(tiddlerNameScript);
				} catch (ex) {
				}
			}
			if (!tiddlerName || askUser) {
				tiddlerName = prompt("Please specify a tiddler name.", askUser ? tiddlerName : "");
			}
			while (tiddlerName && store.getTiddler(tiddlerName)) {
				tiddlerName = prompt("A tiddler named '"+tiddlerName+"' already exists.\n\n"+"Please specify a tiddler name.", tiddlerName);
			}

			// tiddlerName is either null (user canceled) or a name that is not yet in the store.
			if (tiddlerName) {
				var body = "<<formTiddler [["+formTemplateName+"]]>>";
				var tags = [];
				store.saveTiddler(tiddlerName,tiddlerName,body,config.options.txtUserName,new Date(),tags);
				story.displayTiddler(null,tiddlerName,1);
			}
		}

		createTiddlyButton(place,buttonLabel,buttonLabel,onClick);
    }
}

//}}}


/***
!Licence and Copyright
Copyright (c) abego Software ~GmbH, 2005 ([[www.abego-software.de|http://www.abego-software.de]])

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.

Neither the name of abego Software nor the names of its contributors may be
used to endorse or promote products derived from this software without specific
prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
***/
Controls a great wealth of natural resources. Only recently united by general Bismarck.
The Goldbeard Clan have gathered considerable wealth form controlling the pass to Lake Geneva and most of the rare mineral deposits in the nearby mountains.

!!Chief Exports
* Banking. Key customers include the government of [[France]], the [[Vatican]] and the [[Freemasons]], as well as the [[Bronzeheart Clan]]
* Valuable metals and minerals

!!Geography
Located to the northwest of the [[Foambeard Clan]]. Controls one of the mos convenient passes to [[Italy]], the White Mountain Pass.

!!Rival Clans
* [[Foambeard Clan]]. Mining rights disputes.
Dwarven operative for British Intelligence. Works as an executive in the Cairo Port Authority. Dresses like the locals, and keeps his beard well-trimmed.

Rogue lvl 7
A warrior clan. Also more capitalistic than most dwarves.
Orc [[barbarian|http://www.d20srd.org/srd/classes/barbarian.htm]] 8/[[wizard|http://www.d20srd.org/srd/classes/sorcererWizard.htm#wizard]] 6 (evoc - banned ench+illusion) - Leads an orc warband, [[The Hammer of Fire]], wich ravages the hillsides and mountains in northern Sudan. 

BAB 11/6
126 hitpoints
Rage (Str +9, Con +4(+ 28 HP, + 2 Will), AC -2), 3 times/day

<<forEachTiddler
    where
       'tiddler.tags.contains("Gruugh Firefist")'

    sortBy
       'tiddler.title.toUpperCase()'

    write '" [["+tiddler.title+" ]] \"view ["+tiddler.title+"]\" [["+tiddler.title+"]] "'

        begin '"<<tabs txtMyAutoTab "'

        end '">"+">"'

        none '"//No tiddler tagged with \"Gruugh Firefist\"//"'
>>
<<forEachTiddler
    where
       'tiddler.tags.contains("House Rules")'

    sortBy
       'tiddler.title.toUpperCase()'

    write '" [["+tiddler.title+" ]] \"view ["+tiddler.title+"]\" [["+tiddler.title+"]] "'

        begin '"<<tabs txtMyAutoTab "'

        end '">"+">"'

        none '"//No tiddler tagged with \"House Rules\"//"'
>>
Humans are the most common race by far. Their adaptability and resourcefulness serve them well. That they breed enough to constanty increase their population helps. Recent advances in medicine have also further increased the (civilized) human population.
/***
|''Name:''|abego.IncludePlugin|
|''Version:''|1.0.1 (2007-04-30)|
|''Type:''|plugin|
|''Source:''|http://tiddlywiki.abego-software.de/#IncludePlugin|
|''Author:''|Udo Borkowski (ub [at] abego-software [dot] de)|
|''Documentation:''|[[IncludePlugin Documentation|http://tiddlywiki.abego-software.de/#%5B%5BIncludePlugin%20Documentation%5D%5D]]|
|''Community:''|([[del.icio.us|http://del.icio.us/post?url=http://tiddlywiki.abego-software.de/index.html%23IncludePlugin]]) ([[Support|http://groups.google.com/group/TiddlyWiki]])|
|''Copyright:''|&copy; 2007 [[abego Software|http://www.abego-software.de]]|
|''Licence:''|[[BSD open source license (abego Software)|http://www.abego-software.de/legal/apl-v10.html]]|
|''~CoreVersion:''|2.1.3|
|''Browser:''|Firefox 1.5.0.9 or better; Internet Explorer 6.0|
***/
/***
This plugin's source code is compressed (and hidden). Use this [[link|http://tiddlywiki.abego-software.de/archive/IncludePlugin/Plugin-Include-src.1.0.0.js]] to get the readable source code.
***/
///%
if(!window.abego){window.abego={};}var invokeLater=function(_1,_2,_3){return abego.invokeLater?abego.invokeLater(_1,_2,_3):setTimeout(_1,_2);};abego.loadFile=function(_4,_5,_6){var _7=function(_8,_9,_a,_b,_c){return _8?_5(_a,_b,_9):_5(undefined,_b,_9,"Error loading %0".format([_b]));};if(_4.search(/^((http(s)?)|(file)):/)!=0){if(_4.search(/^((.\:\\)|(\\\\)|(\/))/)==0){_4="file://"+_4;}else{var _d=document.location.toString();var i=_d.lastIndexOf("/");_4=_d.substr(0,i+1)+_4;}_4=_4.replace(/\\/mg,"/");}loadRemoteFile(_4,_7,_6);};abego.loadTiddlyWikiStore=function(_f,_10,_11,_12){var _13=function(_14,_15){if(_12){_12(_14,"abego.loadTiddlyWikiStore",_15,_f,_11);}};var _16=function(_17,_18){var _19=_18.indexOf(startSaveArea);var _1a=_18.indexOf("<!--POST-BODY-END--"+">");var _1b=_18.lastIndexOf(endSaveArea,_1a==-1?_18.length:_1a);if((_19==-1)||(_1b==-1)){return config.messages.invalidFileError.format([_f]);}var _1c="<html><body>"+_18.substring(_19,_1b+endSaveArea.length)+"</body></html>";var _1d=document.createElement("iframe");_1d.style.display="none";document.body.appendChild(_1d);var doc=_1d.document;if(_1d.contentDocument){doc=_1d.contentDocument;}else{if(_1d.contentWindow){doc=_1d.contentWindow.document;}}doc.open();doc.writeln(_1c);doc.close();var _1f=doc.getElementById("storeArea");_17.loadFromDiv(_1f,"store");_1d.parentNode.removeChild(_1d);return null;};var _20=function(_21){_13("Error when loading %0".format([_f]),"Failed");_10(undefined,_f,_11,_21);return _21;};var _22=function(_23){_13("Loaded %0".format([_f]),"Done");_10(_23,_f,_11);return null;};var _24=function(_25,_26,_27,_28){if(_25===undefined){_20(_28);return;}_13("Processing %0".format([_f]),"Processing");var _29=config.messages.invalidFileError;config.messages.invalidFileError="The file '%0' does not appear to be a valid TiddlyWiki file";try{var _2a=new TiddlyWiki();var _2b=_16(_2a,_25);if(_2b){_20(_2b);}else{_22(_2a);}}catch(ex){_20(exceptionText(ex));}finally{config.messages.invalidFileError=_29;}};_13("Start loading %0".format([_f]),"Started");abego.loadFile(_f,_24,_11);};(function(){if(abego.TiddlyWikiIncluder){return;}var _2c="waiting";var _2d="loading";var _2e=1000;var _2f=-200;var _30=-100;var _31=-300;var _32;var _33=[];var _34={};var _35=[];var _36;var _37=[];var _38;var _39=function(){if(_32===undefined){_32=config.options.chkUseInclude===undefined||config.options.chkUseInclude;}return _32;};var _3a=function(url){return "No include specified for %0".format([url]);};var _3c=function(){var _3d=_35;_35=[];if(_3d.length){for(var i=0;i<_37.length;i++){_37[i](_3d);}}};var _3f;var _40=function(){if(_36!==undefined){clearInterval(_36);}_3f=0;var _41=function(){abego.TiddlyWikiIncluder.sendProgress("","","Done");};_36=setInterval(function(){_3f++;if(_3f<=10){return;}clearInterval(_36);_36=undefined;abego.TiddlyWikiIncluder.sendProgress("Refreshing...","","");refreshDisplay();invokeLater(_41,0,_2f);},1);};var _42=function(_43){var _44;for(var i=0;i<_33.length;i++){var _46=abego.TiddlyWikiIncluder.getStore(_33[i]);if(_46&&(_44=_43(_46,_33[i]))){return _44;}}};var _47=function(){if(!window.store){return invokeLater(_47,100);}var _48=store.fetchTiddler;store.fetchTiddler=function(_49){var t=_48.apply(this,arguments);if(t){return t;}if(config.shadowTiddlers[_49]!==undefined){return undefined;}if(_49==config.macros.newTiddler.title){return undefined;}return _42(function(_4b,url){var t=_4b.fetchTiddler(_49);if(t){t.includeURL=url;}return t;});};if(_33.length){_40();}};var _4e=function(){if(!window.store){return invokeLater(_4e,100);}var _4f=store.getTiddlerText("IncludeList");if(_4f){wikify(_4f,document.createElement("div"));}};var _50=function(_51){var _52=function(){var _53=store.forEachTiddler;var _54=function(_55){var _56={};var _57;var _58=function(_59,_5a){if(_56[_59]){return;}_56[_59]=1;if(_57){_5a.includeURL=_57;}_55.apply(this,arguments);};_53.call(store,_58);for(var n in config.shadowTiddlers){_56[n]=1;}_56[config.macros.newTiddler.title]=1;_42(function(_5c,url){_57=url;_5c.forEachTiddler(_58);});};store.forEachTiddler=_54;try{return _51.apply(this,arguments);}finally{store.forEachTiddler=_53;}};return _52;};var _5e=function(_5f,_60){return _5f[_60]=_50(_5f[_60]);};abego.TiddlyWikiIncluder={};abego.TiddlyWikiIncluder.setProgressFunction=function(_61){_38=_61;};abego.TiddlyWikiIncluder.getProgressFunction=function(_62){return _38;};abego.TiddlyWikiIncluder.sendProgress=function(_63,_64,_65){if(_38){_38.apply(this,arguments);}};abego.TiddlyWikiIncluder.onError=function(url,_67){displayMessage("Error when including '%0':\n%1".format([url,_67]));};abego.TiddlyWikiIncluder.hasPendingIncludes=function(){for(var i=0;i<_33.length;i++){var _69=abego.TiddlyWikiIncluder.getState(_33[i]);if(_69==_2c||_69==_2d){return true;}}return false;};abego.TiddlyWikiIncluder.getIncludes=function(){return _33.slice();};abego.TiddlyWikiIncluder.getState=function(url){var s=_34[url];if(!s){return _3a(url);}return typeof s=="string"?s:null;};abego.TiddlyWikiIncluder.getStore=function(url){var s=_34[url];if(!s){return _3a(url);}return s instanceof TiddlyWiki?s:null;};abego.TiddlyWikiIncluder.include=function(url,_6f){if(!_39()||_34[url]){return;}var _70=this;_33.push(url);_34[url]=_2c;var _71=function(_72,_73,_74,_75){if(_72===undefined){_34[url]=_75;_70.onError(url,_75);return;}_34[url]=_72;_35.push(url);invokeLater(_3c);};var _76=function(){_34[url]=_2d;abego.loadTiddlyWikiStore(url,_71,null,_38);};if(_6f){invokeLater(_76,_6f);}else{_76();}};abego.TiddlyWikiIncluder.forReallyEachTiddler=function(_77){var _78=function(){store.forEachTiddler(_77);};_50(_78).call(store);};abego.TiddlyWikiIncluder.getFunctionUsingForReallyEachTiddler=_50;abego.TiddlyWikiIncluder.useForReallyEachTiddler=_5e;abego.TiddlyWikiIncluder.addListener=function(_79){_37.push(_79);};abego.TiddlyWikiIncluder.addListener(_40);if(config.options.chkUseInclude===undefined){config.options.chkUseInclude=true;}config.shadowTiddlers.AdvancedOptions+="\n<<option chkUseInclude>> Include ~TiddlyWikis (IncludeList | IncludeState | [[help|http://tiddlywiki.abego-software.de/#%5B%5BIncludePlugin%20Documentation%5D%5D]])\n^^(Reload this ~TiddlyWiki to make changes become effective)^^";config.shadowTiddlers.IncludeState="<<includeState>>";var _7a=function(e,_7c,_7d){if(!anim||!abego.ShowAnimation){e.style.display=_7c?"block":"none";return;}anim.startAnimating(new abego.ShowAnimation(e,_7c,_7d));};abego.TiddlyWikiIncluder.getDefaultProgressFunction=function(){setStylesheet(".includeProgressState{\n"+"background-color:#FFCC00;\n"+"position:absolute;\n"+"right:0.2em;\n"+"top:0.2em;\n"+"width:7em;\n"+"padding-left:0.2em;\n"+"padding-right:0.2em\n"+"}\n","abegoInclude");var _7e=function(){var e=document.createElement("div");e.className="includeProgressState";e.style.display="none";document.body.appendChild(e);return e;};var _80=_7e();var _81=function(_82){removeChildren(_80);createTiddlyText(_80,_82);_7a(_80,true,0);};var _83=function(){invokeLater(function(){_7a(_80,false,_2e);},100,_30);};var _84=function(_85,_86,_87,url,_89){if(_87=="Done"||_87=="Failed"){_83();return;}if(_86=="abego.loadTiddlyWikiStore"){_3f=0;if(_87=="Processing"){_81("Including...");}}else{_81(_85);}};return _84;};abego.TiddlyWikiIncluder.setProgressFunction(abego.TiddlyWikiIncluder.getDefaultProgressFunction());config.macros.include={};config.macros.include.handler=function(_8a,_8b,_8c,_8d,_8e,_8f){_8c=_8e.parseParams("url",null,true,false,true);var _90=parseInt(getParam(_8c,"delay","0"));var _91=_8c[0]["url"];var _92=getFlag(_8c,"hide",false);if(!_92){createTiddlyText(createTiddlyElement(_8a,"code"),_8d.source.substring(_8d.matchStart,_8d.nextMatch));}for(var i=0;_91&&i<_91.length;i++){abego.TiddlyWikiIncluder.include(_91[i],_90);}};config.macros.includeState={};config.macros.includeState.handler=function(_94,_95,_96,_97,_98,_99){var _9a=function(){var s="";var _9c=abego.TiddlyWikiIncluder.getIncludes();if(!_9c.length){return "{{noIncludes{\nNo includes or 'include' is disabled (see AdvancedOptions)\n}}}\n";}s+="|!Address|!State|\n";for(var i=0;i<_9c.length;i++){var inc=_9c[i];s+="|{{{"+inc+"}}}|";var t=abego.TiddlyWikiIncluder.getState(inc);s+=t?"{{{"+t+"}}}":"included";s+="|\n";}s+="|includeState|k\n";return s;};var _a0=function(){removeChildren(div);wikify(_9a(),div);if(abego.TiddlyWikiIncluder.hasPendingIncludes()){invokeLater(_a0,500,_31);}};var div=createTiddlyElement(_94,"div");invokeLater(_a0,0,_31);};var _a2=Tiddler.prototype.isReadOnly;Tiddler.prototype.isReadOnly=function(){return _a2.apply(this,arguments)||this.isIncluded();};Tiddler.prototype.isIncluded=function(){return this.includeURL!=undefined;};Tiddler.prototype.getIncludeURL=function(){return this.includeURL;};var _a3={getMissingLinks:1,getOrphans:1,getTags:1,reverseLookup:1,updateTiddlers:1};for(var n in _a3){_5e(TiddlyWiki.prototype,n);}var _a5=function(){if(abego.IntelliTagger){_5e(abego.IntelliTagger,"assistTagging");}};var _a6=function(){if(config.macros.forEachTiddler){_5e(config.macros.forEachTiddler,"findTiddlers");}};_47();invokeLater(_4e,100);invokeLater(_a5,100);invokeLater(_a6,100);})();
//%/
Soot-stained walls and smog-filled air. Industrial labores live in squalour, in contrast to the fine gentlemen with great estates, [[steam-powered|Steam Power]] horses and [[Tick|Exotics]] bodyguards.

Free or escaped ticks gather in ghettos, seeking comfort among their own kind. The fight for survival is tough, given the swollen poulation. Territorial disputes are frequent. The authorities seldom interfere.

The harsh order the crime lords and their henchmen enforce in their turf gives them some respect among the poor.
Magic theory has been passed on to humans by elves, who offered their lore in return for safe passage through Europe. This treaty still stands - most of the elves who signed it are stil alive. However, humans  who suffer prolonged exposure to magic are prone to contract [[Magical Contamination]].

Divine casters draw their energy from the all-enveloping life force. Anyone who knows how can do so, but the established [[Religions]] tend to believe their way is the only way. The only correct way at least.

Magic and religious theory is considered an essential part of a gentleman's education, along with mathemathics, physics, history, Dwarven etc. Thus, anyone in a position to have had an education has a rudimentary understanding of both arcane and divine magic (bonuses to Knowledge (religion) and Knowledge (Arcane) as well as Spellcraft.

The recent advances in technology has led to a surge in magical experimentation. This is expensive, and such scholars of magic are either rich or have rich patrons. The very expensive nature of arcane magic means it is limited to the rich and very rich.

Magic items are avialable, and common among the nobility. The [[British crown jewels]] are all magical for example.
Deformities, even madness, has occured in humans who have had prolonged contact with magic. This fact is suppressed, however. The usefullness of magic itself and magic-embued items trumps most concerns. The raw material cost of magic experimentation also prevents the general populace from aquiring magic contamination.
[[World]] [[Politics]] [[Bibliography]] [[House Rules]]
Type the text for 'New Tiddler'
The Mirror of Knowledge allows the owner to see a day into the future of any location, person or object. Unless specifically directed, it will merely show the next day of its current location.

(Major Artefact)
Clairaudience
Clairvoyance
Divination
True Seeing
Discern Location
Vision
<!--{{{-->
<div class='header'>
<div id='messageArea'></div>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
<div id='mainMenu' refresh='content' tiddler='MainMenu'></div>
<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>
</div>
<div id='sidebar'>
<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>
</div>
<div id='displayArea'>
<div id='tiddlerDisplay'></div>
</div>
<!--}}}-->
The heroes have all been informed that a business proposition would be presented to them at [[55 Cobbler Street]], London.

When all heroes have arrived, [[Captain Gruushavak]] of the British Army greets them. "The [[Mirror of Knowledge]] has gone missing in transit from Khartoum to Cairo. Since the Mirror was lost in French territory, there is very little the British government can do."

"The Mirror is believed to have been stolen by the Orc warband [[The Hammer of Fire]] led by [[Gruugh Firefist]]. The warband is believed to have headquarters in the foothills near the desert".

"In [[Cairo]] you will meet my operative, [[Gorm Longhand]]. He will provide you with the equipment you will need for your journey."
The relatively recent industrialization has created a large working class, with a solidarity movement that spans national borders. There is a wide gap in prosperity from the working poor to the middle and upper classes.

The general feeling is that humans are morally and intellectually superior to most races and species, since they are so much more 'civilized'.

Imperialization leads to international tension, and a colonization race. This is resolved by treaty, dividing the colonies up rather arbitrarily. Thus, the same nomadic tribe of orcs might find their wandering grounds are spreasd across several colonies. 

The invention of the steam engine significantly simplifies travel and shortens travel times.

Strong capitalist movement, dependant on slaves for free labor. Uses technology and magic extensively and interdependently to maximize profits. At odds with the aristocrats

The beginnings of an anti-slavery movement, opposed to the capitalists.

A keep-magic-free-from-tech-corruption movement (backed by the church and aristocrats) is gaining momentum.
!0th level

!1st level
* [[Mage Armor|http://www.d20srd.org/srd/spells/mageArmor.htm]]
* [[Expedious Retreat|http://www.d20srd.org/srd/spells/expeditiousRetreat.htm]]
* [[True Strike|http://www.d20srd.org/srd/spells/trueStrike.htm]]
* [[Cause Fear|http://www.d20srd.org/srd/spells/causeFear.htm]]

!2nd level
* [[Bull's Strength|http://www.d20srd.org/srd/spells/bullsStrength.htm]]
* [[Bull's Strength|http://www.d20srd.org/srd/spells/bullsStrength.htm]]
* [[Bear's Endurance|http://www.d20srd.org/srd/spells/bearsEndurance.htm]]
* [[Darkness|http://www.d20srd.org/srd/spells/darkness.htm]]
* [[Darkness|http://www.d20srd.org/srd/spells/darkness.htm]]

!3rd level
* [[Lightning Bolt|http://www.d20srd.org/srd/spells/lightningBolt.htm]]
* [[Lightning Bolt|http://www.d20srd.org/srd/spells/lightningBolt.htm]]
* [[Fireball|http://www.d20srd.org/srd/spells/fireball.htm]]
* [[Fireball|http://www.d20srd.org/srd/spells/fireball.htm]]
* [[Daylight|http://www.d20srd.org/srd/spells/daylight.htm]]
!Humans
Pockets of [[Paganism]] still exist in isolated areas.
!!Christianity
The [[Roman Catholic Church]] insists on its supremacy, but has lost much of its former glory.

The [[Church of England]] is important in [[Britannia]] and in the [[British Colonies]]. Opposes the catholics

[[Protestantism]] in most of northern Europe. No central authority.

!![[Islam]], [[Hinduism]], [[Buddhism]]
Practiced where historically appropriate.

!Dwarves

Worship a [[Dwarven Pantheon]]. Considered beyond redemption by the Catholics. Zealous human missionaries stil persevere, and some succeed.
/***
|''Name:''|SettingsPlugin|
|''Version:''|1.1.0 (2006-07-30)|
|''Type:''|plugin|
|''Source:''|http://tiddlywiki.abego-software.de/#SettingsPlugin|
|''Author:''|Udo Borkowski (ub [at] abego-software [dot] de)|
|''Documentation:''|[[SettingsPlugin Documentation]]|
|''~SourceCode:''|[[SettingsPlugin SourceCode]]|
|''Licence:''|[[BSD open source license (abego Software)]]|
|''~CoreVersion:''|2.0.7|
|''Browser:''|Firefox 1.5.0.2 or better; Internet Explorer 6.0|
^^This tiddler contains compressed source code. [[Full Source Code|SettingsPlugin SourceCode]].^^
***/
// /%
if(!version.extensions.SettingsPlugin){if(version.major<2){(function(){var s="Use TiddlyWiki 2.0 or better to run the Settings Plugin.";alert(s);throw s;})();}version.extensions.SettingsPlugin={major:1,minor:1,revision:0,date:new Date(2006,6,30),type:"plugin",source:"http://tiddlywiki.abego-software.de/#SettingsPlugin",documentation:"[[SettingsPlugin Documentation]]",sourcecode:"[[SettingsPlugin SourceCode]]",author:"Udo Borkowski (ub [at] abego-software [dot] de)",licence:"[[BSD open source license (abego Software)]]",coreVersion:"2.0.7",browser:"Firefox 1.5.0.2 or better; Internet Explorer 6.0"};if(!window.abego){window.abego={};}if(!abego.setTiddlerText){abego.setTiddlerText=function(_2,_3,_4,_5,_6,_7){var _8=_2.getTiddler(_3);if(_8&&(_8.text==_4)){return;}var _9=config.options.chkForceMinorUpdate;var _a=!_8?_5:_8.tags;_2.suspendNotifications();try{_2.saveTiddler(_3,_3,_4,_9?undefined:config.options.txtUserName,_9?undefined:new Date(),_a);}finally{_2.resumeNotifications();}if(_7){_2.notify(_3,true);}if(!_6&&config.options.chkAutoSave){saveChanges();}};}(function(){var _b="PrivateSettings";var _c="chkUsePrivateSettings";var _d="chkMakeSettingPrivateWhenChanged";var _e=null;var _f=false;var _10=function(_11,s){var _13=s.split(";");var _14={};for(var c=0;c<_13.length;c++){var p=_13[c].indexOf("=");if(p!=-1){var _17=_13[c].substr(0,p).trim();var _18=_13[c].substr(p+1).trim();_11[_17]=unescape(_18);_14[_17]=true;}}return _14;};var _19=function(_1a){var s=store.getTiddlerText(_b);_e=s?_10(_1a,s):{};};var _1c=function(_1d){_10(_1d,document.cookie);};var _1e=function(){var _1f={};_1c(_1f);return _1f;};var _20=function(){var _21={};_19(_21);return _21;};var _22=function(_23,_24){document.cookie=_23+"="+escape(_24)+"; expires=Fri, 1 Jan 2038 12:00:00 UTC; path=/";};var _25=function(_26,s,_28){var _29=_20();if(s===null){if(!_e[_26]){return;}delete _29[_26];delete _e[_26];}else{var _2a=_29[_26];if(_2a!==undefined&&_2a==s){return;}_29[_26]=s;_e[_26]=true;}var t="";for(var i in _29){if(t){t+="; ";}t+=i+"="+escape(_29[i]);}abego.setTiddlerText(store,_b,t,["excludeLists","excludeSearch"],_28);if(!_28&&config.options.chkAutoSave){saveChanges();}};config.shadowTiddlers["BSD open source license (abego Software)"]="See [[Licence|http://tiddlywiki.abego-software.de/#%5B%5BBSD%20open%20source%20license%5D%5D]].";config.shadowTiddlers["SettingsPlugin Documentation"]="[[Documentation on abego Software website|http://tiddlywiki.abego-software.de/#%5B%5BSettingsPlugin%20Documentation%5D%5D]].\n\n^^You may copy the documentation tiddler from the website to your TiddlyWiki.\nThen you don't need to access the internet to read the documentation.^^";config.shadowTiddlers["SettingsPlugin SourceCode"]="Rightclick this [[link|http://tiddlywiki.abego-software.de/src/Plugin-Settings-src.js]] and choose 'Save target/link as...' to get the plugin source code from the abego Software website.";config.shadowTiddlers["Show Settings"]="<<showSettings>>";if(config.options[_c]===undefined){config.options[_c]=false;}if(config.options[_d]===undefined){config.options[_d]=false;}config.shadowTiddlers.AdvancedOptions+="\n''Private Settings: ''<<option "+_c+">> Use private settings.  <<option "+_d+">> Make setting private when changed.&#160;&#160;&#160;[[Show Settings]].\n^^(Private settings are stored in this ~TiddlyWiki, shared settings are stored as cookies. For more information see the [[Settings documentation|SettingsPlugin Documentation]].)^^";abego.usePrivateSettings=function(){return _f;};abego.setUsePrivateSettings=function(f){if(f!=abego.usePrivateSettings()){_f=f;loadOptionsCookie();}};abego.isUsePrivateSettingsOption=function(_2e){return _2e==_c;};abego.makeSettingPrivateWhenChanged=function(){return config.options[_d];};abego.setMakeSettingPrivateWhenChanged=function(f){config.options[_d]=f;};abego.getSettings=function(){var _30={};_1c(_30);_f=_30[_c]=="true";if(abego.usePrivateSettings()){_19(_30);}return _30;};abego.getSetting=function(_31){var s=abego.getSettings()[_31];return !s?"":s;};abego.saveSetting=function(_33,_34){if(abego.isUsePrivateSettingsOption(_33)){_22(_33,_34);abego.setUsePrivateSettings(_34=="true");loadOptionsCookie();window.alert("You changed the 'Use private settings' option.\nPlease reload your TiddlyWiki to update the settings.\n");return;}if(abego.usePrivateSettings()&&(abego.isSettingPrivate(_33)||abego.makeSettingPrivateWhenChanged())){_25(_33,_34);}else{_22(_33,_34);}};abego.isSettingPrivate=function(_35){if(abego.isUsePrivateSettingsOption(_35)){return false;}if(!_e){_20();}return !!_e[_35];};abego.isPasswordSetting=function(_36){return (_36.substr(0,3)=="pas")||(_36.substr(0,6)=="chkpas");};abego.makeSettingPrivate=function(_37,_38,_39){if(abego.isPasswordSetting(_37)){_25(_37,null,_39);return;}var _3a=_20();var _3b=_3a[_37]!==undefined;if(_38==_3b){return;}var _3c=_1e();if(_38){_25(_37,_3c[_37],_39);}else{if(_3c[_37]===undefined){_22(_37,_3a[_37]);}_25(_37,null,_39);}};abego.setAllSettingsPrivate=function(_3d,_3e){var _3f=abego.getSettings();for(var s in _3f){abego.makeSettingPrivate(s,_3d,true);}if(config.options.chkAutoSave){saveChanges();}if(_3e){story.refreshTiddler(_3e,1,true);}return false;};})();config.macros.showSettings={label:"showSettings",prompt:"Display the current TiddlyWiki settings"};config.macros.showSettings.handler=function(_41,_42,_43,_44,_45,_46){var _47=function(a){var s=a.substr(0,3);return s=="txt"||s=="chk";};var _4a=function(a,b){var s1=a.toLowerCase();var s2=b.toLowerCase();return (s1<s2)?-1:(s1==s2)?0:1;};var _4f=function(a,b){var _52=_47(a);var _53=_47(b);if(_52){if(!_53){return -1;}else{return _4a(a.substr(3),b.substr(3));}}else{if(_53){return 1;}else{return _4a(a,b);}}};var s="<html><table><tr align=\"left\"><th>Private</th><th>Name</th><th>Value</th></tr>";var c=abego.getSettings();var _56=[];for(var i in c){if(!abego.isPasswordSetting(i)){_56.push(i);}}_56.sort(_4f);for(i=0;i<_56.length;i++){var _58=_56[i];var _59=_47(_58)?_58.substr(3)+" ("+_58.substr(0,3)+"...)":_58;var _5a=abego.isUsePrivateSettingsOption(_58)?"":"<input name=\""+_58+"\" type=\"checkbox\" onclick=\"abego.onPrivateSettingClick(this)\""+(abego.isSettingPrivate(_58)?" checked":"")+"/>";s+="<tr><td align=\"right\">"+_5a+"</td><td>"+_59+"</td><td>"+c[_58]+"</td></tr>\n";}s+="</table>";s+="<a class=\"button\" title=\"Make all current settings private\" href=\"javascript:;\" onclick=\"abego.setAllSettingsPrivate(true,'"+_46.title+"',1);\">Make all private</a>";s+="<a class=\"button\" title=\"Make all current settings shared\" href=\"javascript:;\" onclick=\"abego.setAllSettingsPrivate(false,'"+_46.title+"',1);\">Make all shared</a>";s+="</html>";wikify(s,_41);};abego.onPrivateSettingClick=function(_5b){abego.makeSettingPrivate(_5b.name,_5b.checked);return false;};this.loadOptionsCookie=function(){if(safeMode){return;}var _5c=abego.getSettings();for(var _5d in _5c){var _5e=_5c[_5d];switch(_5d.substr(0,3)){case "txt":config.options[_5d]=unescape(_5e);break;case "chk":config.options[_5d]=_5e=="true";break;}}};this.saveOptionCookie=function(_5f){if(safeMode){return;}var v="";switch(_5f.substr(0,3)){case "txt":v=config.options[_5f].toString();break;case "chk":v=config.options[_5f]?"true":"false";break;}abego.saveSetting(_5f,v);};loadOptionsCookie();}
// %/

<<newTiddler>><<saveChanges>><<closeAll>><<permaview>><<search>>
A steampunkish D20 campaign setting
In the Name of Progress!
* [[Intimidate|http://www.d20srd.org/srd/skills/intimidate.htm]] +17 (17 ranks)
* Ride +15 (11 ranks, +1 dex, +2 Handle Animal)
* Survival +15 (17 ranks, -2 wis)
* Handle animal +11 (11 ranks)
* Jump + 18 (11 ranks, 7 str)
* Swim + 18 (11 ranks, 7 str)
* Climb + 18 (11 ranks, 7 str)
* Listen + 9 (11ranks -2 wiz)
* Concentration +8 (6ranks + 2 con)
* Knowledge (Arcane) +9 (6 ranks + 3 int) 
* Spellcraft +9 (6 ranks + 3 int) 
Slavery is the cornerstone of the colonial economy. The sturdier, uglier species are usually found in manual labor, as guards or even elite conscript units.

Slave traders are found among Ticks as well as humans.

Species (and races) deemed presentable enough serve as house servants etc. Quite a few familes find the very idea of non-humans in heir homes reolting, and emply humans from 'inferior' races instead.

There is a growing realization that many Ticks are as sentient as humans, and that their slavery is unethical. This movement is opposed by the capitalists, who stand to lose immense profits if their free workforce is removed.
!1st level
* [[Mage Armor|http://www.d20srd.org/srd/spells/mageArmor.htm]]
* [[Burning Hands|http://www.d20srd.org/srd/spells/burningHands.htm]]
* [[Magic Missile|http://www.d20srd.org/srd/spells/magicMissile.htm]]
* [[Ray of Enfeeblement|http://www.d20srd.org/srd/spells/rayOfEnfeeblement.htm]]
* [[Enlarge Person|http://www.d20srd.org/srd/spells/enlargePerson.htm]]
* [[Expedious Retreat|http://www.d20srd.org/srd/spells/expeditiousRetreat.htm]]
* [[True Strike|http://www.d20srd.org/srd/spells/trueStrike.htm]]
* [[Protection from Law|http://www.d20srd.org/srd/spells/protectionFromLaw.htm]]
* [[Shocking Grasp|http://www.d20srd.org/srd/spells/shockingGrasp.htm]]
* [[Summon  Monster I|http://www.d20srd.org/srd/spells/summonMonsterI.htm]]
* [[Shield|http://www.d20srd.org/srd/spells/shield.htm]]
* [[Reduce Person|http://www.d20srd.org/srd/spells/reducePerson.htm]]
* [[Magic Weapon|http://www.d20srd.org/srd/spells/magicWeapon.htm]]
* 
* 

!2nd level
* [[Bull's Strength|http://www.d20srd.org/srd/spells/bullsStrength.htm]]
* [[Darkness|http://www.d20srd.org/srd/spells/darkness.htm]]
* [[Bear's Endurance|http://www.d20srd.org/srd/spells/bearsEndurance.htm]]
* 
* 
* 
* 
* 
* 
* 

!3rd level
* [[Lightning Bolt|http://www.d20srd.org/srd/spells/lightningBolt.htm]]
* [[Fireball|http://www.d20srd.org/srd/spells/fireball.htm]]
* [[Daylight|http://www.d20srd.org/srd/spells/daylight.htm]]
* 
* 
* 
* 
* 
* 

!4th level
* 
* 
* 
* 
* 
* 

!5th level
* 
* 
* 
* 
Conservative, fear the current expansionist trends threaten the roots of drwaven tradition. Not entirely sure showing humans how technology worked was a good idea. Has fallen greatly from its former glory.

!!Chief Exports
None to speak of.

!!Income
Controls two passes, both of which lead to the [[Stone Citadel]].

!!Allied Clans
[[Foambeard Clan]]
[[Stoneshield Clan]]

!!Rival Clans
[[Bronzeheart Clan]]
[[Farsight Clan]]

These clans are too progressive and human-friendly by far.
/*{{{*/
body
	{
		font-family: Constantia;
	}
.header 
	{
		color: black;
		background-color: white;
	}
.editor,
.viewer pre
	{
		font-family: Consolas;
		font-size: .8em;
	}
#mainMenu 
	{
		position: static;
		width:auto;
		text-align: left;
		padding: 0;
	}
	.header #mainMenu a:hover {background-color: #014; color: 000;}
	#mainMenu a
		{
			width: 7em;
			text-align: center;
			display: block;
			float: left;
			border-bottom: 1px solid #ffc;
		}
#sidebarOptions {float: right;}
	#sidebarOptions a {display: block; float: left;}
	#sidebarOptions input {float:left;}
#sidebar
	{
		padding-top: 2em;
		font-size: 1.1em;
	}
#displayArea
	{
		margin-left: 0;
		font-size: 1.25em;
	}
#messageArea {position: static; float: right;}
.messageToolbar {position: inline;text-align:right; padding:0.2em 0.2em 0.2em 0.2em;}
#messageArea a {text-decoration:underline; }
.tagging {float: none;}
.isTag .tagging {display:block;}
.tagged {float: none; margin-left: 0;}
.tagging, .tagged {font-size:0.9em; padding:0.25em;}
.tagging ul, .tagged ul {list-style:none; margin:0.25em; padding:0; display: inline;}
.tagging ul li, .tagged ul li {display:inline;}
/*}}}*/
/*{{{*/
* 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;}
/*}}}*/
The human industrialization is based on concepts originally defined by [[Dwarves]]. This is not known (or believed) by many humans though. The general consensus is that humans invented tech and dwarves 'stole' it - although dwarves are admittedly better engineers, builders etc.

Due to the ready availability of [[Magic]] and [[Magic Items]], [[Technology and Magic]] has been successfully combined. There are, however, strong political movements against the 'tainting' of 'pure' magic with technology. 
A seedy bar in one of the more shady areas of London.
(Faction Leader: Jeppe)

The Cabal is an ancient group of mages, wich once commanded great power. Its powers have waned recently, and the Cabal feels the recent uprising of technology is partly to blame.

[[Magical contamination|Magical Contamination]] is ever a thorn in the side to the Cabal. It ever searches to find a way to cleanse magic of the taint wich drives humans insane, SO far, however, they have only managed to postpone the inevitable.
The Eye (also known as 'The Eye of the Empire') is a clandestine branch of British intelligence. It's purpose is to monitor the rotten underbelly of the British empire, while posing as a (rather successful) crime syndicate.

!Base of operations
The Eye is based in [[London]]. The London office also oversees the [[Europe]]an operations. There are regional headquarters in [[Cape Town]] ([[Africa]]), [[Hong Kong]] ([[Asia]]), [[Cairo]] ([[The Middle East]]) and [[New York]] ([[North America]]).

!Chain of Command
# The Stare
# Gazers
# Glancers
# Glancers
# Blinkers

!Funding and income
Illicit trade and smuggling mainly. The Eye has diversified into most areas of crime. If the need arises, they can draw on the Royal accounts.

!Religious and Political ties
[[The Church of Britain]] will aid the Eye upon occasion.
An Orc Warband, led by [[Gruugh Firefist]]'s iron hand. Consists of 20-25 ragtag orcs and half-orcs, almost all warriors. There are around 5 scouts and two or three shamans.

The Hammer of Fire never stay in one place for long. They set up a temporary camp, raid the nearby villages, and move on.

The camp supposedly has order, with sentry posts in key locations (20% chance they are not - DC 4) . Gruugh rules with an iron fist, squelching any independent thought brutally, in fear of his own position. Failure to meet Gruugh's standards are also dealt with swiftly.

!Treasure
* 1 large chest, containing gold pieces worth 1000£
* Leather pouch, containing 13 gems (5 worth 100£, 8 worth 50£)
* 1 Lesser Rod of Maximize Spell
!Tactics
!!Offensive
The band prefers to draw their targets into a trap and surround them. Scouts shoot at particularily threatening targets while the warriors charge (intimidating all the way). The shamans are dispersed throughout the warriors to provide emergency healing. 

[[Gruugh Firefist]] prefers to stay at the back of the battle until victory seems plausible. He rains destruction from afar, before he chrages into melee combat. Gruugh is extremely rash, and may be goaded to attack prematurely. 

The Hammer also attacks villages and settlements under cover of night, killing all males and raping all females, before pillaging the city. Some females are abducted to serve as slaves.

!!Defensive
The Hammer makes camp in an easily defendable position, with running water. [[Gruugh Firefist]] sleeps in a tent to the rear, guarded by 2 guards. The slaves and the shamans are close by. Horses are tied up next to the water source, with the latrines downriver from them. There is a central campfire wich the band eat and sleep around.

Sentries are placed near entry points and on natural lookouts.

!14 Warriors
(level 7)
Str 16 dex 10 con 12 int 8 wis 8 cha 7
Greatclub 1d12 + 5 str, Attack bonus 1d20+10/+5
Chain shirt, AC 14
Intimidate +8 (10 ranks)
Spot +0
43 HP

!6 Scouts
(warrior level 7)
str 14 dex 14 con 10 int 8 wis 12 cha 8
38HP
Studded Leather AC15 (+2 dex)
"Brown Bess" Musket rng 20ft, 2d10, attack bonus 1d20+9/1d20+4, 1 shot mag
Short sword 1d6, attack bonus 1d20+9/+4
Ride +12 (10 ranks)
Spot +2
10 bullets

!3 Shamans
(Adept level 8)
25HP
str 12 dex 10 con 12 int 10 wis 14 cha 6
Robes
Concentration +11 (11 ranks)
Spellcraft +11 (11 ranks)
Heal +13 (11 ranks)
Knowledge (Nature) +11 (11 ranks)
!!Prepared Spells
!!!0th level
* [[Cure Minor Wounds|http://www.d20srd.org/srd/spells/cureMinorWounds.htm]]
* [[Cure Minor Wounds|http://www.d20srd.org/srd/spells/cureMinorWounds.htm]]
* [[Cure Minor Wounds|http://www.d20srd.org/srd/spells/cureMinorWounds.htm]]
* [[Purify Food and Drink|http://www.d20srd.org/srd/spells/purifyFoodAndDrink.htm]]

!!!1st level
* [[Cure Light Wounds|http://www.d20srd.org/srd/spells/cureLightWounds.htm]]
* [[Cure Light Wounds|http://www.d20srd.org/srd/spells/cureLightWounds.htm]]
* [[Cure Light Wounds|http://www.d20srd.org/srd/spells/cureLightWounds.htm]]
* [[Bless|http://www.d20srd.org/srd/spells/bless.htm]]

!!!2nd level
* [[Cure Moderate Wounds|http://www.d20srd.org/srd/spells/cureModerateWounds.htm]]
* [[Cure Moderate Wounds|http://www.d20srd.org/srd/spells/cureModerateWounds.htm]]
* [[Bull's Strength|http://www.d20srd.org/srd/spells/bullsStrength.htm]]
The Hand (also known as 'The Crimson Hand' ) is an old assassin's guild. It has lately branched into other areas of crime. Sometimes acts on behalf of the French government.

!Base of Operations
The Hand originated in [[Paris]], and has a considerable presence in every large [[Europe]]an city. Also prevalent in the French colonies.

!Chain of Command
# The Hand
# Fists
# Grips
# Fingers
# (Finger)tips

!Funding
Primarily from assassinations. Controls a large portion of the narcotics and artefact trade from Asia to Europe.
Many are poor, and must turn to crime and prostitution to survive. The trade in virgins (of many different races) is very lucrative.

Freed slaves often gravitate here - a bugbear or half-orc is a useful henchman, and many [[Exotics]] even find a certain degree of respect here. In most cities, gangs frequently fight over territory.

!Power groups
!!London
Kobolds and goblins who have escaped the coal mines of northern England are gathering around the banner of a new crime lord. And he is gaining strength rapidly. [[The Eye]] reign supreme, and do not take kindly to the newcomer. 

!!Berlin

!!Paris
Lycanthropes are infecting the underworld. Rumor has it they have infiltrated [[The Hand]].

!!Rome
The Mafia, ruled by , reign supreme, ruled by the succubus [[Belidaria]]. Supported by the [[Medici Family]] .

!!Moscow
Vampire crimelords squabble among each other, but will work together against a common enemy.

!!Hong Kong
[[The Triads]] battle with [[The Eye]] for control of the island.
Gaia, late 19th century. A relatively stable political climate in Europe has led to a period of prosperity. The [[elves|Elves]] lament the corruption of nature and magic by steam-spewing, coal-eating engines, while the [[dwarwes|Dwarves]] revel in the new markets for coal, engines, weapons and mercenaries.

Industrialization has brought along considerable advances to the humans of Europe. [[The Cabal]] laments this course in human history - they wish to continue to sell their services as mages dearly. 

The lesser races - the [[Exotics]] that are discovered in Africa, India, the Americas are readily overpowered and enslaved by the europeans. Their primitive, ritualistic magic is - wih few exceptions - no match for guns forged from dwarwen steel.

The recent industrialization of Europe is largely due to the [[Dwarves]] teaching humans. The dwarves needed new markets for coal, iron, guns and war machines.
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::ViewToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='subtitle'><span macro='view modifier link'></span>, <span macro='view modified date'></span> (<span macro='message views.wikified.createdPrompt'></span> <span macro='view created date'></span>)</div>
<div class='viewer' macro='view text wikified'></div>
<div class='tagged' macro='tags'></div>
<div class='tagging' macro='tagging'></div>
<div class='tagClear'></div>
<!--}}}-->
|''Type:''|file|
|''URL:''|http://tiddlywiki.abego-software.de/|
|''Workspace:''|(default)|

This tiddler was automatically created to record the details of this server