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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

hr {height:1px;}

a {text-decoration:none;}

dt {font-weight:bold;}

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

.txtOptionInput {width:11em;}

#contentWrapper .chkOptionInput {border:0;}

.externalLink {text-decoration:underline;}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

----
Also see AdvancedOptions
<<importTiddlers>>
In Socialtext Unplugged, the selected pages of your Socialtext workspace are displayed as individual "tiddlers" on the page. When the mouse passes over a tiddler a short toolbar menu appears at the top right. Use the commands here to manipulate that particular tiddler: notably closing and editting it. (You can double click on a tiddler as a shortcut to directly enter edit mode).

Over on the right hand side of the window are commands that affect the entire page, in particular "close all" which can be useful to clear the decks when many tiddlers are open at once.

The user is encouraged to ensure that they can SaveChanges before embarking on widespread editing.
Welcome to Socialtext Unplugged. This is a specially designed web page that you can use to view and edit your Socialtext content without having to be online to your Socialtext server.

There are three steps to using Socialtext Unplugged:
* First, learn how to SaveChanges to your local hard drive. This keeps your work safe even if you close your browser or have to reboot your computer
* Secondly, find out how to BrowseAndEdit your content while it is unplugged
* Thirdly, when you can reconnect to your Socialtext server, you can SyncChanges to save your unplugged changes to the server so that other people can see them too

You should also check your system meets the SystemRequirements.
Socialtext Unplugged lets you browse and edit your content while you're offline. When you make a change you need to SaveChanges to save the change to your local hard drive, before later performing a SyncChanges to synchronise the change back to the server.

The procedure for SaveChanges is slightly different for different browsers:
* SavingOnInternetExplorer
* SavingOnFireFox
* SavingOnSafari
* SavingOnOpera
You can save changes with any version of FireFox, and also many other browsers in the FireFox family, such as Camino on the Mac and MiniMo on mobile devices. The procedure is:
# Click the button labelled 'save changes' over in the right hand sidebar
# If prompted with an "Internet Security" dialog as follows, click the checkbox labelled "Remember this decision" and then the "Allow" button
## "A script from "file://" is requesting enhanced capabilities that are UNSAFE and could be used to compromise your machine or data..."
# You should then see a message at the top right of the window saying "Main TiddlyWiki file saved"
If you accidentally //deny// permission instead, you may need to UnravelFireFoxPermissions.
You can save changes with Internet Explorer versions 6 and 7, but not the earlier versions. The procedure is:
# Click the button labelled 'save changes' over in the right hand sidebar
# If prompted as follows, click "Yes":
## "An ActiveX control on this page might be unsafe to interact with other parts of the page. Do you want to allow this interaction?"
# You should then see a message at the top right of the window saying "Main TiddlyWiki file saved"
Note that there is currently [[a bug|http://trac.tiddlywiki.org/tiddlywiki/ticket/39]] that prevents Internet Explorer from saving correctly if you have specified a backup directory in AdvancedOptions.
To SaveChanges on Opera, see the instructions for using the TiddlySaver Java applet.
To SaveChanges on Safari, see the instructions for using the TiddlySaver Java applet.
<<search>><<closeAll>><<permaview>><<newTiddler 'New Tiddler' fields:'server.host:"https://saturn.ffzg.hr%2C%20saturn.ffzg.hr:443" server.workspace:"rot13" wikiformat:socialtext'>><<newJournal 'DD MMM YYYY' fields:'server.host:"https://saturn.ffzg.hr%2C%20saturn.ffzg.hr:443" server.workspace:"rot13" wikiformat:socialtext'>><<saveChanges>><<backstage sync>><<slider chkSliderOptionsPanel OptionsPanel 'options »' 'Change TiddlyWiki advanced options'>>
Dobrica Pavlinušić's random unstructured stuff
Socialtext Unplugged
https://saturn.ffzg.hr/rot13/
[[SocialtextScreenStyle]]
[[SocialtextStyleOverrides]]
[[Styles HorizontalMainMenu]]
<<sync>>
@@The user interface for synchronization is not finalized@@
To synchronize your changes back to the Socialtext server:
# click on [[Sync]] in the right-hand sidebar
<<tabs txtMoreTab Orphans 'Orphaned tiddlers' TabMoreOrphans Shadowed 'Shadowed tiddlers' TabMoreShadowed>>
Under FireFox, you can run into problems if you accidentally click 'Deny' on the permission request dialog, and have selected //Remember this decision//.

To reverse the effects, first locate the file {{{prefs.js}}} in your FireFox profile directory. Under Windows you'll find it at something like {{{C:\Documents and Settings\Jeremy\Application Data\Mozilla\Firefox\Profiles\o3dhupu6.default\prefs.js}}}, where {{{Jeremy}}} is the name of your windows profile and {{{o3dhupu6}}} will be a similar string of gobbledegook. On the Mac it'll be at {{{~/Library/Application Support/Firefox/Profiles/o3dhupu6.default/prefs.js}}} and on most versions of Linux, at {{{~/.mozilla/firefox/o3dhupu6.default/prefs.js}}}.

Open the file in a text editor and find the line {{{user_pref("capability.principal.codebase.p0.denied", "UniversalXPConnect");}}} and simply replace the word {{{denied}}} with {{{granted}}}.
//(Thanks to JonScully for figuring out this fix)//
<!--{{{-->
<div class='toolbar' macro='toolbar closeTiddler closeOthers +editTiddler references > fields syncing jump'></div>
<div class='workspace' id='st-page-wiki-title' macro='view socialtext.workspace'></div>
<div class='title' id='st-page-titletext' macro='view title'></div>
<div class='subtitle'>
Created on <span macro='view created date [[MMM DD, 0hh:0mm]]'></span>.
Updated by <span macro='view modifier link'></span>
on <span macro='view modified date [[MMM DD, 0hh:0mm]]'></span></div>
<div class='tagging' macro='tagging'></div>
<div class='tagged' macro='tags'></span></div>
<div class='viewer' macro='view text wikified'></div>
<div class='tagClear'></div>
<!--}}}-->
/***
To use, add {{{[[Styles HorizontalMainMenu]]}}} to your StyleSheet tiddler.
See http://www.w3schools.com/css/css_colors.asp for a color chart.
***/
/*{{{*/
#mainMenu {position:relative;left:auto;width:auto;text-align:left;line-height:normal;padding 0em 1em 0em 1em;font-size:normal;}
#mainMenu br {display:none;}
#mainMenu {background:#336699;}
#mainMenu {padding:2px;}
#mainMenu .button, #mainMenu .tiddlyLink {padding-left:0.5em;padding-right:0.5em;color:white;font-size:115%;}

#displayArea {
	margin-top:0;margin-right:20em;margin-bottom:0;margin-left:1em;
	padding-top:.1em;padding-bottom:.1em;
}
/*}}}*/
|''Type:''|socialtext|
|''URL:''|https://saturn.ffzg.hr%2C%20saturn.ffzg.hr:443 |
|''Workspace:''|rot13|
|''WorkspaceList:''||
|''Description:''|Dobrica Pavlinušić's random unstructured stuff|
The TiddlySaver Java applet allows TiddlyWiki from a {{{file://}}} URL to save changes Safari, Opera and other browsers.

It is a small file named [["TiddlySaver.jar"|TiddlySaver.jar]] that must be placed in the same directory as your TiddlyWiki file. Before you can use it, you need to give it the necessary privileges by editting your {{{.java.policy}}} file.

For Windows, the file will be at {{{C:\Documents and Settings\your-user-name\.java.policy}}}. Add the following lines (substituting the directory of your TiddlyWiki file as appropriate):
{{{
grant codeBase "file:${user.home}/My Documents/tiddlywiki-folder/*" {
  permission java.io.FilePermission "${user.home}${/}My Documents${/}tiddlywiki-folder${/}*", "read,write";
};
}}}
On Mac OS X, the file is found at {{{/Users/your-user-name/.java.policy}}}:
{{{
grant codeBase "file:${user.home}/Documents/tiddlywiki-folder/*" {
  permission java.io.FilePermission "${user.home}${/}Documents${/}tiddlywiki-folder${/}*", "read,write";
};
}}}
It can be tricky creating files whose name starts with a period, so you can use this [[pre-built .java.policy file|.java.policy]]. The same file is suitable for Macs too, just edit it and delete the "My " bit, leaving just "Documents". Make sure you save it in the right place for each operating system!

If you have trouble setting up the permissions correctly, you can try granting broader permissions to the applet like this:

{{{
grant codeBase "file://localhost/home/users/Desktop/
TiddlySaver.jar"
 { permission java.security.AllPermission; };
}}}

Note that there is currently [[a bug|http://trac.tiddlywiki.org/ticket/172]] that prevents TiddlySaver from working if you have specified a backup directory in AdvancedOptions.
/***
|''Name:''|SocialtextLocaleOverrides|
|''Description:''|Text changes for Socialtext|
***/

//{{{
merge(config.views.wikified.tag,{
	labelNoTags: "No Tags",
	labelTags: "Tags"});

merge(config.commands.references,{
	text: "incoming links",
	tooltip: "Show tiddlers that link to this one",
	popupNone: "No incoming links"});
//}}}
/***
|''Name:''|SocialtextTweaksPlugin|
|''Description:''|Allows changes to be synchronised with a Socialtext server|
|''Source:''|http://stunplugged.tiddlywiki.com/#SocialtextTweaksPlugin|
|''Author:''|JeremyRuston (jeremy (at) osmosoft (dot) com)|
|''Version:''|1.0.2|
|''Date:''|Jun 15, 2006|
|''Comments:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev|
|''License:''|[[BSD open source license]]|
|''~CoreVersion:''|2.2|

Make minor configuration tweaks specific to Socialtext Unplugged
***/

//{{{
// Ensure that the SocialtextTweaksPlugin is only installed once.
if(!version.extensions.SocialtextTweaksPlugin) {
version.extensions.SocialtextTweaksPlugin = {installed:true};
// Check version number of core code
if(version.major < 2 || (version.major == 2 && version.minor < 2))
	{alertAndThrow("SocialtextTweaksPlugin requires TiddlyWiki 2.2 or later.");}

merge(config.defaultCustomFields,{
	wikiformat:'socialtext',
	'server.host':'https://saturn.ffzg.hr%2C%20saturn.ffzg.hr:443'
});

config.options.chkSinglePageMode = true;
config.options.chkEnableAnimations = true;

} // end of "install only once"
//}}}
/***
|''Name:''|SocialtextFormatterPlugin|
|''Description:''|Allows Tiddlers to use [[Socialtext|http://www.socialtext.com/]] text formatting|
|''Author:''|Martin Budden (mjbudden (at) gmail (dot) com)|
|''Source:''|http://www.martinswiki.com/#SocialtextFormatterPlugin|
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/formatters/SocialtextFormatterPlugin.js|
|''Version:''|0.9.4|
|''Date:''|Jan 21, 2007|
|''Comments:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev|
|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|''~CoreVersion:''|2.1.0|

This is the SocialtextFormatterPlugin, which allows you to insert Socialtext formated text into a TiddlyWiki.

The aim is not to fully emulate Socialtext, but to allow you to work with Socialtext content off-line and then resync the content with your Socialtext wiki later on, with the expectation that only minor edits will be required.

To use Socialtext format in a Tiddler, tag the Tiddler with SocialtextFormat or set the tiddler's {{{wikiformat}}} extended field to {{{socialtext}}}

Please report any defects you find at http://groups.google.co.uk/group/TiddlyWikiDev
***/

//{{{
// Ensure that the SocialtextFormatter Plugin is only installed once.
if(!version.extensions.SocialtextFormatterPlugin) {
version.extensions.SocialtextFormatterPlugin = {installed:true};

if(version.major < 2 || (version.major == 2 && version.minor < 1))
	{alertAndThrow('SocialtextFormatterPlugin requires TiddlyWiki 2.1 or later.');}

SocialtextFormatter = {}; // 'namespace' for local functions

wikify = function(source,output,highlightRegExp,tiddler)
{
	if(source && source != '') {
		var w = new Wikifier(source,getParser(tiddler),highlightRegExp,tiddler);
		var out = output;
		if(tiddler && (tiddler.isTagged(config.parsers.socialtextFormatter.formatTag) || (tiddler.fields.wikiformat==config.parsers.socialtextFormatter.format)) ) {
			var d1 = createTiddlyElement(output,'div','content-display-body','content-section-visible');
			var d2 = createTiddlyElement(d1,'div','wikipage');
			out = createTiddlyElement(d2,'div',null,'wiki');
		}
		var time1,time0 = new Date();
		w.subWikifyUnterm(out);
		if(tiddler && config.options.chkDisplayInstrumentation) {
			time1 = new Date();
			var t = tiddler ? tiddler.title : source.substr(0,10);
			displayMessage("Wikify '"+t+"' in " + (time1-time0) + " ms");
		}
	}
};

stDebug = function(out,str)
{
	createTiddlyText(out,str.replace(/\n/mg,'\\n').replace(/\r/mg,'RR'));
	createTiddlyElement(out,'br');
};

SocialtextFormatter.Tiddler_changed = Tiddler.prototype.changed;
Tiddler.prototype.changed = function()
{
	if((this.fields.wikiformat==config.parsers.socialtextFormatter.format) || this.isTagged(config.parsers.socialtextFormatter.formatTag)) {
		// update the links array, by checking for Socialtext format links
		this.links = [];
		var tiddlerLinkRegExp = /(?:\"(.*?)\" ?)?\[([^\]]*?)\]/mg;
		tiddlerLinkRegExp.lastIndex = 0;
		var match = tiddlerLinkRegExp.exec(this.text);
		while(match) {
			var link = match[2];
			this.links.pushUnique(link);
			match = tiddlerLinkRegExp.exec(this.text);
		}
	}/* else {
		return SocialtextFormatter.Tiddler_changed.apply(this,arguments);
	}*/
	this.linksUpdated = true;
};

SocialtextFormatter.wafl = function(w)
{
	this.lookaheadRegExp.lastIndex = w.matchStart;
	var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
	if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
		var lm2 = lookaheadMatch[2];
		switch(lookaheadMatch[1]) {
		case 'image':
			var img = createTiddlyElement(w.output,'img');
			img.src = w.tiddler.title + '/' + lm2;
			createTiddlyText(img,lm2);
			break;
		case 'file':
			var s = createTiddlyElement(w.output,'span',null,'nlw_phrase');
			var a = createTiddlyElement(s,'a');
			a.href = w.tiddler.title + '/' + lm2;
			createTiddlyText(a,lm2);
			break;
		case 'link':
			s = createTiddlyElement(w.output,'span',null,'nlw_phrase');
			a = createTiddlyElement(s,'a');
			var t = w.tiddler ? w.tiddler.title + ':' : '';
			a.setAttribute('href','#' + t + lm2);
			a.title = 'section link';
			createTiddlyText(a,lm2);
			break;
		case 'weblog':
			s = createTiddlyElement(w.output,'span',null,'nlw_phrase');
			var text = lm2;
			var link = 'Weblog: ' + lm2;
			createTiddlyText(createTiddlyLink(s,link,false,null,w.isStatic),text);
			break;
		case 'section':
			a = createTiddlyElement(w.output,'a');// drop anchor
			t = w.tiddler ? w.tiddler.title + ':' : '';
			a.setAttribute('name',t + lm2);
			break;
		case 'date':
			createTiddlyText(w.output,lm2);
			break;
		case 'user':
			var oldSource = w.source;
			w.source = lm2;
			w.nextMatch = 0;
			w.subWikifyUnterm(w.output);
			w.source = oldSource;
			break;
// Shortcut expansions - not strictly syntax
		case 'google':
			s = createTiddlyElement(w.output,'span',null,'nlw_phrase');
			a = createExternalLink(s,'http://www.google.com/search?q='+lm2);
			createTiddlyText(a,lm2);
			break;
		case 'fedex':
			s = createTiddlyElement(w.output,'span',null,'nlw_phrase');
			a = createExternalLink(s,'http://www.fedex.com/Tracking?tracknumbers='+lm2);
			createTiddlyText(a,lm2);
			break;
		case 'map':
			s = createTiddlyElement(w.output,'span',null,'nlw_phrase');
			a = createExternalLink(s,'http://maps.google.com/maps?q='+lm2);
			createTiddlyText(a,lm2);
			break;
		case 'wikipedia':
			s = createTiddlyElement(w.output,'span',null,'nlw_phrase');
			a = createExternalLink(s,'http://en.wikipedia.org/wiki/'+lm2);
			createTiddlyText(a,lm2);
			break;
		case 'rt':
			s = createTiddlyElement(w.output,'span',null,'nlw_phrase');
			a = createExternalLink(s,'http://rt.socialtext.net/Ticket/Display.html?id='+lm2);
			createTiddlyText(a,lm2);
			break;
		case 'stcal':
			s = createTiddlyElement(w.output,'span',null,'nlw_phrase');
			a = createExternalLink(s,'https://calendar.socialtext.net:445/view_t.php?timeb=1&id=3&date='+lm2);
			createTiddlyText(a,lm2);
			break;
		case 'svn':
			s = createTiddlyElement(w.output,'span',null,'nlw_phrase');
			a = createExternalLink(s,'https://repo.socialtext.net/listing.php?rev='+lm2+'sc=1');
			createTiddlyText(a,lm2);
			break;
		default:
			w.outputText(w.output,w.matchStart,w.nextMatch);
			return;
		}
		w.nextMatch = this.lookaheadRegExp.lastIndex;
	} else {
		w.outputText(w.output,w.matchStart,w.nextMatch);
	}
};

SocialtextFormatter.presence = function(w)
{
	this.lookaheadRegExp.lastIndex = w.matchStart;
	var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
	if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
		var p = lookaheadMatch[1];
		var text = lookaheadMatch[2];
		var link;
		var src;
		if(p=='aim') {
			link = 'aim:goim?screenname=' + text + '&message=hello';
			src = 'http://big.oscar.aol.com/sleepleft?on_url=http://www.aim.com/remote/gr/MNB_online.gif&amp;off_url=http://www.aim.com/remote/gr/MNB_offline.gif';
		} else if(p=='yahoo'||p=='ymsgr') {
			link = 'ymsgr:sendIM?'+text;
			src = 'http://opi.yahoo.com/online?u=chrislondonbridge&f=.gif';
		} else if(p=='skype'||p=='callto') {
			link = 'callto:'+text;
			src = 'http://goodies.skype.com/graphics/skypeme_btn_small_green.gif';
		} else if(p=='asap') {
			link = 'http://asap2.convoq.com/AsapLinks/Meet.aspx?l='+text;
			src = 'http://asap2.convoq.com/AsapLinks/Presence.aspx?l='+text;
		}
		var s = createTiddlyElement(w.output,'span',null,'nlw_phrase');
		var a = createExternalLink(s,link);
		var img = createTiddlyElement(a,'img');
		createTiddlyText(a,text);
		img.src = src;
		img.border='0';
		img.alt = '(' + lookaheadMatch[1] + ')';
		if(p=='aim') {
			img.width='11'; img.height='13';
		}
		w.nextMatch = this.lookaheadRegExp.lastIndex;
	}
};

config.formatterHelpers.singleCharFormat = function(w)
{
	this.lookaheadRegExp.lastIndex = w.matchStart;
	var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
	if(lookaheadMatch && lookaheadMatch.index == w.matchStart && lookaheadMatch[0].substr(lookaheadMatch[0].length-2,1) != ' ') {
		w.subWikifyTerm(createTiddlyElement(w.output,this.element),this.termRegExp);
	} else {
		w.outputText(w.output,w.matchStart,w.nextMatch);
	}
};

config.socialtext = {};
config.socialtext.formatters = [
{
	name: 'socialtextHeading',
	match: '^\\^{1,6} ?',
	termRegExp: /(\n+)/mg,
	handler: function(w)
	{
		var len = w.matchText.trim().length;
		var e = createTiddlyElement(w.output,'h' + len);
		var a = createTiddlyElement(e,'a');// drop anchor
		var t = w.tiddler ? w.tiddler.title + ':' : '';
		len = w.source.substr(w.nextMatch).indexOf('\n');
		a.setAttribute('name',t+w.source.substr(w.nextMatch,len));
		w.subWikifyTerm(e,this.termRegExp);
	}
},

{
	name: 'socialtextTable',
	match: '^\\|(?:(?:.|\n)*)\\|$',
	lookaheadRegExp: /^\|(?:(?:.|\n)*)\|$/mg,
	cellRegExp: /(?:\|(?:[^\|]*)\|)(\n|$)?/mg,
	cellTermRegExp: /((?:\x20*)\|)/mg,
	handler: function(w)
	{
		var table = createTiddlyElement(w.output,'table');
		var rowContainer = createTiddlyElement(table,'tbody');
		var prevColumns = [];
		w.nextMatch = w.matchStart;
		this.lookaheadRegExp.lastIndex = w.nextMatch;
		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
		while(lookaheadMatch && lookaheadMatch.index == w.nextMatch) {
			var r = this.rowHandler(w,createTiddlyElement(rowContainer,'tr'),prevColumns);
			if(!r) {
				w.nextMatch++;
				break;
			}
			this.lookaheadRegExp.lastIndex = w.nextMatch;
			lookaheadMatch = this.lookaheadRegExp.exec(w.source);
		}
	},
	rowHandler: function(w,e,prevColumns)
	{
		this.cellRegExp.lastIndex = w.nextMatch;
		var cellMatch = this.cellRegExp.exec(w.source);
		while(cellMatch && cellMatch.index == w.nextMatch) {
			w.nextMatch++;
			var cell = createTiddlyElement(e,'td');
			w.subWikifyTerm(cell,this.cellTermRegExp);
			if(cellMatch[1]) {
				// End of row
				w.nextMatch = this.cellRegExp.lastIndex;
				return true;
			}
			// Cell
			w.nextMatch--;
			this.cellRegExp.lastIndex = w.nextMatch;
			cellMatch = this.cellRegExp.exec(w.source);
		}
		return false;
	}
},

{
	name: 'socialtextList',
	match: '^[\\*#]+ ',
	lookaheadRegExp: /^([\*#])+ /mg,
	termRegExp: /(\n+)/mg,
	handler: function(w)
	{
		var stack = [w.output];
		var currLevel = 0, currType = null;
		var itemType = 'li';
		w.nextMatch = w.matchStart;
		this.lookaheadRegExp.lastIndex = w.nextMatch;
		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
		while(lookaheadMatch && lookaheadMatch.index == w.nextMatch) {
			var listType = lookaheadMatch[1] == '*' ? 'ul' : 'ol';
			var listLevel = lookaheadMatch[0].length;
			w.nextMatch += listLevel;
			if(listLevel > currLevel) {
				for(var i=currLevel; i<listLevel; i++) {
					stack.push(createTiddlyElement(stack[stack.length-1],listType));
				}
			} else if(listLevel < currLevel) {
				for(i=currLevel; i>listLevel; i--) {
					stack.pop();
				}
			} else if(listLevel == currLevel && listType != currType) {
				stack.pop();
				stack.push(createTiddlyElement(stack[stack.length-1],listType));
			}
			currLevel = listLevel;
			currType = listType;
			var e = createTiddlyElement(stack[stack.length-1],itemType);
			w.subWikifyTerm(e,this.termRegExp);
			this.lookaheadRegExp.lastIndex = w.nextMatch;
			lookaheadMatch = this.lookaheadRegExp.exec(w.source);
		}
	}
},

{
	name: 'socialtextQuoteByLine',
	match: '^>+',
	lookaheadRegExp: /^>+/mg,
	termRegExp: /(\n)/mg,
	element: 'blockquote',
	handler: function(w)
	{
		var stack = [w.output];
		var currLevel = 0;
		var newLevel = w.matchLength;
		var i;
		do {
			if(newLevel > currLevel) {
				for(i=currLevel; i<newLevel; i++) {
					stack.push(createTiddlyElement(stack[stack.length-1],this.element));
				}
			} else if(newLevel < currLevel) {
				for(i=currLevel; i>newLevel; i--) {
					stack.pop();
				}
			}
			currLevel = newLevel;
			w.subWikifyTerm(stack[stack.length-1],this.termRegExp);
			createTiddlyElement(stack[stack.length-1],'br');
			this.lookaheadRegExp.lastIndex = w.nextMatch;
			var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
			var matched = lookaheadMatch && lookaheadMatch.index == w.nextMatch;
			if(matched) {
				newLevel = lookaheadMatch[0].length;
				w.nextMatch += newLevel;
			}
		} while(matched);
	}
},

{
	name: 'socialtextRule',
	match: '^----+$\\n+',
	handler: function(w)
	{
		createTiddlyElement(w.output,'hr');
	}
},

{
	name: 'socialtextPreformatted',
	match: '^\\.pre\\s*\\n',
	lookaheadRegExp: /^.pre\s*\n((?:.|\n)*?)\n.pre\s*\n/mg,
	element: 'pre',
	handler: config.formatterHelpers.enclosedTextHelper
},

{
	name: 'socialtextHtml',
	match: '^\\.html',
	lookaheadRegExp: /\.html((?:.|\n)*?)\.html/mg,
	handler: function(w)
	{
		this.lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
			createTiddlyElement(w.output,'span').innerHTML = lookaheadMatch[1];
			w.nextMatch = this.lookaheadRegExp.lastIndex;
		}
	}
},

{
	name: 'macro',
	match: '<<',
	lookaheadRegExp: /<<([^>\s]+)(?:\s*)((?:[^>]|(?:>(?!>)))*)>>/mg,
	handler: function(w)
	{
		this.lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart && lookaheadMatch[1]) {
			w.nextMatch = this.lookaheadRegExp.lastIndex;
			invokeMacro(w.output,lookaheadMatch[1],lookaheadMatch[2],w,w.tiddler);
		}
	}
},

{
	name: 'socialtextExplicitLink',
	match: '(?:".*?" ?)?\\[',
	lookaheadRegExp: /(?:\"(.*?)\" ?)?\[([^\]]*?)\]/mg,
	handler: function(w)
	{
		this.lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
			var link = lookaheadMatch[2];
			var text = lookaheadMatch[1] ? lookaheadMatch[1] : link;
			createTiddlyText(createTiddlyLink(w.output,link,false,null,w.isStatic,w.tiddler),text);
			w.nextMatch = this.lookaheadRegExp.lastIndex;
		}
	}
},

{
	name: 'socialtextExternalLink',
	match: '(?:".*?" ?)?<[a-z]{2,8}:',
	lookaheadRegExp: /(?:\"(.*?)\" ?)?<([a-z]{2,8}:.*?)>/mg,
	imgRegExp: /\.(?:gif|ico|jpg|png)/g,
	handler: function(w)
	{
		this.lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
			var link = lookaheadMatch[2];
			var text = lookaheadMatch[1] ? lookaheadMatch[1] : link;
			this.imgRegExp.lastIndex = 0;
			if(this.imgRegExp.exec(link)) {
				var img = createTiddlyElement(w.output,'img');
				if(lookaheadMatch[1]) {
					img.title = text;
				}
				img.alt = text;
				img.src = link;
			} else {
				createTiddlyText(createExternalLink(w.output,link),text);
			}
			w.nextMatch = this.lookaheadRegExp.lastIndex;
		}
	}
},

{
	name: 'socialtextUrlLink',
	match: config.textPrimitives.urlPattern,
	handler: function(w)
	{
		w.outputText(createExternalLink(w.output,w.matchText),w.matchStart,w.nextMatch);
	}
},

{
	name: 'socialtextBold',
	match: '\\*(?![\\s\\*])',
	lookaheadRegExp: /\*(?!\s)(?:.*?)(?!\s)\*(?=[$\s\|\._\-,])/mg,
	termRegExp: /((?!\s)\*(?=[$\s\|\.\-_,]))/mg,
	element: 'strong',
	handler: config.formatterHelpers.singleCharFormat
},

{
	name: 'socialtextItalic',
	match: '_(?![\\s_])',
	lookaheadRegExp: /_(?!\s)(?:.*?)(?!\s)_(?=[$\s\|\.\*\-,])/mg,
	termRegExp: /((?!\s)_(?=[$\s\|\.\*\-,]))/mg,
	element: 'em',
	handler: config.formatterHelpers.singleCharFormat
},

{
	name: 'socialtextStrike',
	match: '-(?![\\s\\-])',
	lookaheadRegExp: /-(?!\s)(?:.*?)(?!\s)-(?=[$\s\|\.\*_,])/mg,
	termRegExp: /((?!\s)-(?=[$\s\|\.\*_,]))/mg,
	element: 'del',
	handler: config.formatterHelpers.singleCharFormat
},

{
	name: 'socialtextMonoSpaced',
	match: '`(?![\\s`])',
	lookaheadRegExp: /`(?!\s)(?:.*?)(?!\s)`(?=[$\s\.\*\-_,])/mg,
	termRegExp: /((?!\s)`(?=[$\s\.\*\-_,]))/mg,
	element: 'tt',
	handler: config.formatterHelpers.singleCharFormat
},

{
	name: 'socialtextParagraph',
	match: '\\n{2,}',
	handler: function(w)
	{
		createTiddlyElement(w.output,'p');
	}
},

{
	name: 'socialtextLineBreak',
	match: '\\n',
	handler: function(w)
	{
		createTiddlyElement(w.output,'br');
	}
},

{
	name: 'socialtextNoWiki',
	match: '\\{\\{',
	lookaheadRegExp: /\{\{((?:.|\n)*?)\}\}/mg,
	element: 'span',
	handler: config.formatterHelpers.enclosedTextHelper
},

{
	name: 'socialtextTrademark',
	match: '\\{tm\\}',
	handler: function(w)
	{
		createTiddlyElement(w.output,'span').innerHTML = '&trade;';
	}
},

{
	name: 'socialtextWafl',
	match: '\\{(?:[a-z]{2,16}): ?.*?\\}',
	lookaheadRegExp: /\{([a-z]{2,16}): ?(.*?)\}/mg,
	handler: SocialtextFormatter.wafl
},

{
	name: 'socialtextPresence',
	match: '(?:aim|yahoo|ymsgr|skype|callto|asap):\\w+',
	lookaheadRegExp: /(aim|yahoo|ymsgr|skype|callto|asap):(\w+)/mg,
	handler: SocialtextFormatter.presence
},

{
	name: 'socialtextMailTo',
	match: '[\\w\.]+@[\\w]+\.[\\w\.]+',
	lookaheadRegExp: /([\w\.]+@[\w]+\.[\w\.]+)/mg,
	handler: function(w)
	{
		this.lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
			var text = lookaheadMatch[1];
			createTiddlyText(createExternalLink(w.output,'mailto:'+text),text);
			w.nextMatch = this.lookaheadRegExp.lastIndex;
		}
	}
},

{
	name: 'socialtextHtmlEntitiesEncoding',
	match: '&#?[a-zA-Z0-9]{2,8};',
	handler: function(w)
	{
		createTiddlyElement(w.output,'span').innerHTML = w.matchText;
	}
}
];

config.parsers.socialtextFormatter = new Formatter(config.socialtext.formatters);
config.parsers.socialtextFormatter.format = 'socialtext';
config.parsers.socialtextFormatter.formatTag = 'SocialtextFormat';

} // end of 'install only once'
//}}}
/***
|''Name:''|SocialtextAdaptorPlugin|
|''Description:''|Adaptor for moving and converting data to and from Socialtext Wikis|
|''Author:''|Martin Budden (mjbudden (at) gmail (dot) com) and JeremyRuston (jeremy (at) osmosoft (dot) com)|
|''Source:''|http://www.martinswiki.com/#SocialtextAdaptorPlugin|
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/adaptors/SocialtextAdaptorPlugin.js|
|''Version:''|0.5.1|
|''Date:''|Feb 25, 2007|
|''Comments:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev|
|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|''~CoreVersion:''|2.2.0|

Socialtext REST documentation is at:
http://www.eu.socialtext.net/st-rest-docs/index.cgi?socialtext_rest_documentation

***/

//{{{
if(!version.extensions.SocialtextAdaptorPlugin) {
version.extensions.SocialtextAdaptorPlugin = {installed:true};

function SocialtextAdaptor()
{
	this.host = null;
	this.workspace = null;
	return this;
}

SocialtextAdaptor.mimeType = 'text/x.socialtext-wiki';
SocialtextAdaptor.serverType = 'socialtext';
SocialtextAdaptor.serverParsingErrorMessage = "Error parsing result from server";
SocialtextAdaptor.errorInFunctionMessage = "Error in function SocialtextAdaptor.%0";

SocialtextAdaptor.prototype.setContext = function(context,userParams,callback)
{
	if(!context) context = {};
	context.userParams = userParams;
	if(callback) context.callback = callback;
	context.adaptor = this;
	if(!context.host)
		context.host = this.host;
	if(!context.workspace && this.workspace)
		context.workspace = this.workspace;
	return context;
};

SocialtextAdaptor.doHttpGET = function(uri,callback,params,headers,data,contentType,username,password)
{
	return doHttp('GET',uri,data,contentType,username,password,callback,params,headers);
};

SocialtextAdaptor.doHttpPOST = function(uri,callback,params,headers,data,contentType,username,password)
{
	return doHttp('POST',uri,data,contentType,username,password,callback,params,headers);
};

SocialtextAdaptor.fullHostName = function(host)
{
	if(!host)
		return '';
	if(!host.match(/:\/\//))
		host = 'http://' + host;
	if(host.substr(host.length-1) != '/')
		host = host + '/';
	return host;
};

SocialtextAdaptor.minHostName = function(host)
{
	return host ? host.replace(/^http:\/\//,'').replace(/\/$/,'') : '';
};

// Convert a page title to the normalized form used in uris
SocialtextAdaptor.normalizedTitle = function(title)
{
	var n = title.toLowerCase();
	n = n.replace(/\s/g,'_').replace(/\//g,'_').replace(/\./g,'_').replace(/:/g,'').replace(/\?/g,'');
	if(n.charAt(0)=='_')
		n = n.substr(1);
	return String(n);
};

// Convert a Socialtext date in YYYY-MM-DD hh:mm format into a JavaScript Date object
SocialtextAdaptor.dateFromEditTime = function(editTime)
{
	var dt = editTime;
	return new Date(Date.UTC(dt.substr(0,4),dt.substr(5,2)-1,dt.substr(8,2),dt.substr(11,2),dt.substr(14,2)));
};

SocialtextAdaptor.prototype.openHost = function(host,context,userParams,callback)
{
	this.host = SocialtextAdaptor.fullHostName(host);
	context = this.setContext(context,userParams,callback);
	if(context.callback) {
		context.status = true;
		window.setTimeout(function() {callback(context,userParams);},0);
	}
	return true;
};

SocialtextAdaptor.prototype.openWorkspace = function(workspace,context,userParams,callback)
{
	this.workspace = workspace;
	context = this.setContext(context,userParams,callback);
	if(context.callback) {
		context.status = true;
		window.setTimeout(function() {callback(context,userParams);},0);
	}
	return true;
};


SocialtextAdaptor.prototype.getWorkspaceList = function(context,userParams,callback)
{
	context = this.setContext(context,userParams,callback);
	var uriTemplate = '%0data/workspaces';
	var uri = uriTemplate.format([context.host]);
	var req = SocialtextAdaptor.doHttpGET(uri,SocialtextAdaptor.getWorkspaceListCallback,context,{'accept':'application/json'});
	return typeof req == 'string' ? req : true;
};

SocialtextAdaptor.getWorkspaceListCallback = function(status,context,responseText,uri,xhr)
{
	context.status = false;
	context.statusText = SocialtextAdaptor.errorInFunctionMessage.format(['getWorkspaceListCallback']);
	if(status) {
		try {
			eval('var info=' + responseText);
		} catch (ex) {
			context.statusText = exceptionText(ex,SocialtextAdaptor.serverParsingErrorMessage);
			if(context.callback)
				context.callback(context,context.userParams);
			return;
		}
		var list = [];
		for(var i=0; i<info.length; i++) {
			var item = {
				title:info[i].title,
				name:info[i].name,
				modified:SocialtextAdaptor.dateFromEditTime(info[i].modified_time)
				};
			list.push(item);
		}
		context.workspaces = list;
		context.status = true;
	} else {
		context.statusText = xhr.statusText;
	}
	if(context.callback)
		context.callback(context,context.userParams);
};

SocialtextAdaptor.prototype.getTiddlerList = function(context,userParams,callback)
{
	context = this.setContext(context,userParams,callback);
	var uriTemplate = '%0data/workspaces/%1/pages?order=newest';//!! ? or ;
	var uri = uriTemplate.format([context.host,context.workspace]);
	var req = SocialtextAdaptor.doHttpGET(uri,SocialtextAdaptor.getTiddlerListCallback,context,{'accept':'application/json'});
	return typeof req == 'string' ? req : true;
};


SocialtextAdaptor.getTiddlerListCallback = function(status,context,responseText,uri,xhr)
{
	context.status = false;
	context.statusText = SocialtextAdaptor.errorInFunctionMessage.format(['getTiddlerListCallback']);
	if(status) {
		try {
			eval('var info=' + responseText);
		} catch (ex) {
			context.statusText = exceptionText(ex,SocialtextAdaptor.serverParsingErrorMessage);
			if(context.callback)
				context.callback(context,context.userParams);
			return;
		}
		var list = [];
		for(var i=0; i<info.length; i++) {
			var tiddler = new Tiddler(info[i].name);
			tiddler.modified = SocialtextAdaptor.dateFromEditTime(info[i].last_edit_time);
			tiddler.modifier = info[i].last_editor;
			tiddler.tags = info[i].tags;
			tiddler.fields['server.page.id'] = info[i].page_id;
			tiddler.fields['server.page.name'] = info[i].name;
			tiddler.fields['server.page.revision'] = String(info[i].revision_id);
			list.push(tiddler);
		}
		context.tiddlers = list;
		context.status = true;
	} else {
		context.statusText = xhr.statusText;
	}
	if(context.callback)
		context.callback(context,context.userParams);
};

SocialtextAdaptor.prototype.generateTiddlerInfo = function(tiddler)
{
	var info = {};
	var host = this && this.host ? this.host : SocialtextAdaptor.fullHostName(tiddler.fields['server.host']);
	var workspace = this && this.workspace ? this.workspace : tiddler.fields['server.workspace'];
	uriTemplate = '%0%1/index.cgi?%2';
	info.uri = uriTemplate.format([host,workspace,SocialtextAdaptor.normalizedTitle(tiddler.title)]);
	return info;
};

SocialtextAdaptor.prototype.getTiddler = function(title,context,userParams,callback)
{
	return this.getTiddlerRevision(title,null,context,userParams,callback);
};

SocialtextAdaptor.prototype.getTiddlerRevision = function(title,revision,context,userParams,callback)
{
	context = this.setContext(context,userParams,callback);

	// request the page in json format to get the page attributes
	if(revision) {
		var uriTemplate = '%0data/workspaces/%1/pages/%2/revisions/%3';
		context.revision = revision;
	} else {
		uriTemplate = '%0data/workspaces/%1/pages/%2';
		context.revision = null;
	}
	uri = uriTemplate.format([context.host,context.workspace,SocialtextAdaptor.normalizedTitle(title),revision]);

	context.tiddler = new Tiddler(title);
	context.tiddler.fields.wikiformat = 'socialtext';
	context.tiddler.fields['server.host'] = SocialtextAdaptor.minHostName(context.host);
	context.tiddler.fields['server.workspace'] = context.workspace;
	var req = SocialtextAdaptor.doHttpGET(uri,SocialtextAdaptor.getTiddlerCallback,context,{'accept':'application/json'});
	return typeof req == 'string' ? req : true;
};


SocialtextAdaptor.getTiddlerCallback = function(status,context,responseText,uri,xhr)
{
	context.status = false;
	context.statusText = SocialtextAdaptor.errorInFunctionMessage.format(['getTiddlerCallback']);
	if(status) {
		try {
			eval('var info=' + responseText);
			context.tiddler.tags = info.tags;
			context.tiddler.fields['server.page.id'] = info.page_id;
			context.tiddler.fields['server.page.name'] = info.name;
			context.tiddler.fields['server.page.revision'] = String(info.revision_id);
			context.tiddler.modifier = info.last_editor;
			context.tiddler.modified = SocialtextAdaptor.dateFromEditTime(info.last_edit_time);
		} catch (ex) {
			context.statusText = exceptionText(ex,SocialtextAdaptor.serverParsingErrorMessage);
			if(context.callback)
				context.callback(context,context.userParams);
			return;
		}
		context.status = true;
	} else {
		context.statusText = xhr.statusText;
		if(context.callback)
			context.callback(context,context.userParams);
		return;
	}
	var uriTemplate = context.revision ? '%0data/workspaces/%1/pages/%2/revisions/%3' : '%0data/workspaces/%1/pages/%2';
	var host = SocialtextAdaptor.fullHostName(context.tiddler.fields['server.host']);
	var workspace = context.workspace ? context.workspace : context.tiddler.fields['server.workspace'];
	uri = uriTemplate.format([host,workspace,SocialtextAdaptor.normalizedTitle(context.tiddler.title),context.revision]);
	var req = SocialtextAdaptor.doHttpGET(uri,SocialtextAdaptor.getTiddlerCallback2,context,{'accept':SocialtextAdaptor.mimeType});
};

SocialtextAdaptor.getTiddlerCallback2 = function(status,context,responseText,uri,xhr)
{
	context.tiddler.text = responseText;
	if(status) {
		context.status = true;
	} else {
		context.status = false;
		context.statusText = xhr.statusText;
	}
	if(context.callback)
		context.callback(context,context.userParams);
};

SocialtextAdaptor.prototype.getTiddlerRevisionList = function(title,limit,context,userParams,callback)
{
	context = this.setContext(context,userParams,callback);

	var uriTemplate = '%0data/workspaces/%1/pages/%2/revisions?accept=application/json';
	if(!limit)
		limit = 5;
	var uri = uriTemplate.format([context.host,context.workspace,SocialtextAdaptor.normalizedTitle(title),limit]);

	var req = SocialtextAdaptor.doHttpGET(uri,SocialtextAdaptor.getTiddlerRevisionListCallback,context);
	return typeof req == 'string' ? req : true;
};

SocialtextAdaptor.getTiddlerRevisionListCallback = function(status,context,responseText,uri,xhr)
{
	context.status = false;
	if(status) {
		var content = null;
		try {
			eval('var info=' + responseText);
		} catch (ex) {
			context.statusText = exceptionText(ex,SocialtextAdaptor.serverParsingErrorMessage);
			if(context.callback)
				context.callback(context,context.userParams);
			return;
		}
		list = [];
		for(var i=0; i<info.length; i++) {
			var tiddler = new Tiddler(info[i].name);
			tiddler.modified = SocialtextAdaptor.dateFromEditTime(info[i].last_edit_time);
			tiddler.modifier = info[i].last_editor;
			tiddler.tags = info[i].tags;
			tiddler.fields['server.page.id'] = info[i].page_id;
			tiddler.fields['server.page.name'] = info[i].name;
			tiddler.fields['server.page.revision'] = info[i].revision_id;
			list.push(tiddler);
		}
		var sortField = 'server.page.revision';
		list.sort(function(a,b) {return a.fields[sortField] < b.fields[sortField] ? +1 : (a.fields[sortField] == b.fields[sortField] ? 0 : -1);});
		context.revisions = list;
		context.status = true;
	} else {
		context.statusText = xhr.statusText;
	}
	if(context.callback)
		context.callback(context,context.userParams);
};

SocialtextAdaptor.prototype.putTiddler = function(tiddler,context,userParams,callback)
{
	context = this.setContext(context,userParams,callback);
	context.tiddler = tiddler;
	context.title = tiddler.title;
	var uriTemplate = '%0data/workspaces/%1/pages/%2';
	var host = context.host ? context.host : SocialtextAdaptor.fullHostName(tiddler.fields['server.host']);
	var workspace = context.workspace ? context.workspace : tiddler.fields['server.workspace'];
	var uri = uriTemplate.format([host,workspace,tiddler.title,tiddler.text]);
	//var req = doHttp('POST',uri,tiddler.text,SocialtextAdaptor.mimeType,null,null,SocialtextAdaptor.putTiddlerCallback,context,{"X-Http-Method": "PUT"});
	var req = SocialtextAdaptor.doHttpPOST(uri,SocialtextAdaptor.putTiddlerCallback,context,{"X-Http-Method": "PUT"},tiddler.text,SocialtextAdaptor.mimeType);
	return typeof req == 'string' ? req : true;
};

SocialtextAdaptor.putTiddlerCallback = function(status,context,responseText,uri,xhr)
{
	if(status) {
		context.status = true;
	} else {
		context.status = false;
		context.statusText = xhr.statusText;
	}
	if(context.callback)
		context.callback(context,context.userParams);
};

SocialtextAdaptor.prototype.close = function()
{
	return true;
};

config.adaptors[SocialtextAdaptor.serverType] = SocialtextAdaptor;
} //# end of 'install only once'
//}}}
/***
SocialtextStyleOverrides
***/

/*{{{*/
.headerShadow {padding: 2em 0em .5em 1em;}
.headerForeground {padding: 2em 0em .5em 1em;}

#st-page-wiki-title {
	font-size: 80%;
}
.subtitle {
	font-style: italic;
	font-size 80%;
}

/* from #st-tags */
.tagged {
	border-color: #bbeebb;
	background-color: #f4fff4;
}

.tagged .listTitle {
	color: #595;
	font-weight: bold;
}

.tagged .button {
	color: #000;
}

.selected .tagged {
	background-color: ColorPalette::TertiaryLight;
	border: 1px solid ColorPalette::TertiaryMid;
}

/* from #st-incoming-links */
.tagging {
	border-color: #ebb;
	background-color: #fff4f4;
}

.tagging .listTitle {
	color: #b78;
	font-weight: bold;
}

.tagging .button {
	color: #999;
}

.selected .tagging {
	background-color: ColorPalette::TertiaryLight;
	border: 1px solid ColorPalette::TertiaryMid;
}

.tiddler {/* Tiddler body */
	border:1px solid #ccc;
	margin:0.5em;
	background:#fff;
	padding:0.5em;
}

.viewer blockquote {border-left: 0px solid}

.tiddlyLinkNonExisting {
	font-style: italic;
	border-bottom: 1px dashed;
}

.editor input, .editor textarea {
	background: #ffd;
	border-style: solid;
	border-color: #888 #ccc #ccc #888;
	border-width: 2px;
}

.tabContents {white-space: nowrap;}

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

#sidebar {
	position: absolute;
	right: 3px;
	width: 21em;
	font-size: .9em;
}

#sidebarOptions .button {
	border-color: #eee;
}

#sidebarTabs .tabContents {
	width: 20em;
	overflow: hidden;
}

.viewer tt {
	font-size: 1.2em;
	line-height: 1.4em;
}

ul {list-style-type: square;}
ul ul {list-style-type: circle;}

ol {list-style-type: decimal;}
ol ol {list-style-type: decimal;}
ol ol ol {list-style-type: decimal;}
ol ol ol ol {list-style-type: decimal;}
ol ol ol ol ol {list-style-type: decimal;}
ol ol ol ol ol ol {list-style-type: decimal;}

/*}}}*/
/***
SocialtextScreenStyle
http://www.eu.socialtext.net/static/2.0.0.1/css/st/screen.css
***/

/*{{{*/
body {
	font-family: Arial, sans-serif;
	color: #000;
	background: #eee;
	margin: 0;
}

/* Wiki Navigation */

.st-wiki-nav {
	clear: both;
	margin-left: 10px;
	margin-right: 10px;
}
.st-wiki-nav-content {
	background: url('../../images/st/wiki-nav/solid.gif') repeat-x left bottom;
	margin-left: 24px;
	margin-right: 24px;
	padding-top: 3px;
	min-height: 24px;
}
* html .st-wiki-nav-content {
	padding-bottom: 3px;
	height: 24px;
}

.st-wiki-nav-right {
	background: url('../../images/st/wiki-nav/right-round.gif') no-repeat bottom right;
}

.st-wiki-nav-left {
	background: url('../../images/st/wiki-nav/left-round.gif') no-repeat bottom left;
}

#st-home {
	float: left;
	margin-right: 60px;
	padding-top: 2px;
}

#st-home-link {
	color: white;
	text-decoration: none;
	font-weight: bold;
	font-family: Helvetica, sans-serif;
	font-size: 90%;
}

#st-editing-prefix-container {
	border-collapse: collapse;
	width: 100%;
	padding: 0px;
	margin: 0px;
	margin-bottom: -20px;
}

#st-editing-prefix-container tr td {
	margin: 0px;
	padding: 0px;
}

#st-editing-title {
	color: black;
	background-color: white;
	text-decoration: none;
	font-weight: bold;
	font-family: Helvetica, sans-serif;
	font-size: 90%;
	margin-bottom: 0.4em;
}

#st-wiki-title-invite {
	font-size: 50%;
	font-family: Helvetica, sans-serif;
}

#st-wiki-title-central-page-link {
	font-size: 50%;
	font-family: Helvetica, sans-serif;
}

#st-wiki-title-invite a {
	color: #00f;
}

#st-wiki-logo {
	text-align: center;
	clear: both;
}

#st-wiki-logo-image {
}

.st-wiki-nav-actions {
	float: right;
	color: black;
	font-size: 75%;
	padding-top: 3px;
}

.st-wiki-nav-actions a {
	padding: 2px;
	color: white;
	text-decoration: none;
	font-family: Helvetica, sans-serif;
}

/* Wiki Subnav */

#st-wiki-subnav {
	margin-top: 2px;
	font-size: 70%;
	font-weight: bold;
	font-family: Helvetica, sans-serif;
	color: #888;
}

#st-wiki-subnav a {
	padding: 2px;
	color: #008;
	text-decoration: none;
}

#st-wiki-subnav-right {
	float: right;
	margin-right: 6em;
}

#st-wiki-subnav-left {
	float: left;
	margin-left: 6em;
}
* html #st-wiki-subnav-left {
	margin-left: 3em;
}

/* Wiki Navigation Search Bar */

#st-search-form {
	margin: 0;
	padding: 0;
	padding-top: 1px;
}

#st-search-form .button-table {
	float: left;
	font-size: 79%;
	font-weight: bold;
	margin-left: 5px;
	margin-top: 1px;
}

#st-search-form #st-search-term {
	float: left;
	font-size: 60%;
}

/* Content Outline */

#st-content-border, #st-edit-border {
	position: relative;
	clear: both;
	margin-left: 3px;
	margin-right: 2px;
	margin-bottom: 0px;
	margin-top: 0px;
	border-bottom: 1px solid #eee;
}

#st-content-border-left, #st-edit-border-left {
	background: url('../../images/st/page-shadow/left.gif') left top repeat-y;
	position: relative;
}

#st-content-border-right, #st-edit-border-right {
	background: url('../../images/st/page-shadow/right.gif') right top repeat-y;
	position: relative;
}

#st-content-border-top, #st-edit-border-top {
	position: relative;
	background: url('../../images/st/page-shadow/top.gif') left top repeat-x;
}

#st-content-border-bottom, #st-edit-border-bottom {
	background: url('../../images/st/page-shadow/bottom.gif') left bottom repeat-x;
	position: relative;
}

#st-content-border-left-top, #st-edit-border-left-top {
	background: url('../../images/st/page-shadow/left-top.gif') left top no-repeat;
	position: relative;
}
#st-content-border-right-top, #st-edit-border-right-top {
	background: url('../../images/st/page-shadow/right-top.gif') right top no-repeat;
	position: relative;
}

#st-content-border-left-bottom, #st-edit-border-left-bottom {
	background: url('../../images/st/page-shadow/left-bottom.gif') left bottom no-repeat;
	position: relative;
}

#st-content-border-right-bottom, #st-edit-border-right-bottom {
	background: url('../../images/st/page-shadow/right-bottom.gif') right bottom no-repeat;
	padding-top: 5px;
	padding-bottom: 9px;
	position: relative;
}

* html #st-content-border-right-bottom, * html #st-edit-border-right-bottom {
	padding-top: 4px;
	padding-left: 7px;
	padding-right: 8px;
	position: relative;
}

.st-content-width-controller {
	width: 100%;
	position: relative;
	border-collapse: collapse;
}
.st-content-width-controller td {
	vertical-align: top;
}
.st-content {
	position: relative;
	background-color: white;
	margin-top: 0px;
	margin-left: 7px;
	margin-right: 8px;
	margin-bottom: -1px;
	border-left: 1px dotted #80a9f3;
	border-right: 1px dotted #80a9f3;
	border: 1px solid #80a9f3;
	padding: 6px 12px 12px 12px;
}
* html .st-content {
	margin-top: 0px;
	margin-left: 0px;
	margin-right: 0px;
}

/* This textarea is only for Safari. However, if we use display:none; here Safari ignores the .value operation in JS */
#st-raw-wikitext-textarea {
	width:1px;
	height:1px;
	margin:0;
	padding:0;
}

/* Action Buttons */
.button-table, .button-table tr td {
	border-collapse: collapse;
	margin: 0;
	padding: 0;
}
.button-rounded {
	background: url('../../images/st/grey-button/left-top-rounded.png') top left no-repeat;
	margin: 0;
}
.button-rounded-right-top {
	background: url('../../images/st/grey-button/right-top-rounded.png') top right no-repeat;
	margin: 0;
}
.button-rounded-left-bottom {
	background: url('../../images/st/grey-button/left-bottom-rounded.png') bottom left no-repeat;
	margin: 0;
}
.button-rounded-right-bottom {
	background: url('../../images/st/grey-button/right-bottom-rounded.png') bottom right no-repeat;
	margin: 0;
}
.button-straight {
	background: url('../../images/st/grey-button/left-top-straight.png') top left no-repeat;
	margin: 0;
}
.button-straight-right-top {
	background: url('../../images/st/grey-button/right-top-straight.png') top right no-repeat;
	margin: 0;
}
.button-straight-left-bottom {
	background: url('../../images/st/grey-button/left-bottom-straight.png') bottom left no-repeat;
	margin: 0;
}
.button-straight-right-bottom {
	background: url('../../images/st/grey-button/right-bottom-straight.png') bottom right no-repeat;
	margin: 0;
}
.button-content {
	font-size: 90%;
}
.button-content a {
	display: block;
	padding: 2px;
	padding-left: 10px;
	padding-right: 10px;
	font-family: Helvetica, Verdana, sans-serif;
	font-weight: bold;
	text-decoration: none;
	color: black;
}

.button-content input.submit {
	border: 0px;
	padding: 2px;
	padding-left: 10px;
	padding-right: 10px;
	font-family: Helvetica, Verdana, sans-serif;
	font-weight: bold;
	text-decoration: none;
	color: black;
	background-color: transparent;
}

/* Personal Homepage */

#st-homepage {
	background: white url('../../images/st/homepage/blue-fade.gif') top left no-repeat;
}

#st-homepage-layout {
	margin-top: 15px;
	clear: both;
	width: 100%;
	border-collapse: collapse;
}

#st-homepage-layout tr td.st-homepage-layout-cell {
	padding: 5px;
	vertical-align: top;
}

#st-homepage-layout-dashboard {
	width: 50%
}

#st-homepage-layout-notes {
	width: 50%;
}

#st-homepage-notes, #st-homepage-dashboard {
	text-align: left;
	width: 95%;
}

#st-user-greeting, #st-wiki-title {
	font-family: Helvetica, Verdana, sans-serif;
	font-size: 150%;
}
#st-wiki-title {
	margin-left: 5px;
}

#st-user-greeting {
	position: relative;
	text-align: right;
	float: right;
}

#st-group-notes-content, #st-personal-notes-content {
}

.st-homepage-section {
	margin-bottom: 15px;
}

#st-homepage-notes .st-homepage-section {
	background-color: white;
	border: 1px solid #aaa;
	padding: 15px;
}

.st-homepage-section-title {
	font-size: 110%;
	font-family: Helvetica, Verdana, sans-serif;
}

#st-homepage-notes .st-homepage-section-title {
	color: #aaa;
	text-decoration: underline;
}

.st-homepage-notes-edit-link {
	background: url('../../images/st/homepage/edit-icon.gif') no-repeat left top;
	display: block;
	text-indent: -2000px;
	height: 13px;
	width: 36px;
	text-decoration: none;
	padding:0;
}
* html .st-homepage-notes-edit-link {
	border:1px solid white;
}

.st-homepage-notes-edit {
	font-family: Verdana, sans-serif;
	font-size: 65%;
	float: right;
}

.st-homepage-notes-content {
	font-size: 85%;
	margin-top: 10px;
	padding-top: 0px;
	padding-bottom: 0px;
	font-family: Verdana, Helvetica, sans-serif;
}

#st-dyk {
	border-color: #cca !important;
	background-color: #ffe !important;
}

#st-dyk-title {
	color: #e4a020 !important;
	text-decoration: none !important;
}


/* Homepage Simple List */

#st-whats-new-title-link {
	background: url('../../images/st/homepage/icon-28-pages.gif') no-repeat left top;
}
#st-watchlist-title-link {
	background: url('../../images/st/homepage/icon-28-star.gif') no-repeat left top;
}
#st-wikis-title-link {
	background: url('../../images/st/homepage/icon-28-group.gif') no-repeat left top;
}
.st-homepage-simplelist-title-link {
	display: block;
	padding-left: 32px;
	min-height: 32px;
}
* html .st-homepage-simplelist-title-link {
	height: 32px;
}

.st-homepage-simplelist-title {
}

.st-homepage-simplelist-table {
	margin-left: 25px;
	border: 1px dashed #ddd;
	border-collapse: collapse;
	font-family: Verdana, Helvetica, sans-serif;
	font-size: 80%;
	width: 95%;
}

.st-homepage-simplelist-table td {
	padding: 2px;
}

.st-homepage-simplelist-table tr.st-homepage-simplelist-row-odd {
	background-color: #f3f7f7;
}

.st-homepage-simplelist-table tr.st-homepage-simplelist-row-even {
	background-color: white;
}

.st-homepage-simplelist-table a {
	color: #4f55dd;
	text-decoration: none;
}

.st-homepage-simplelist-table a:visited {
	color: #551a8b;
}

.st-homepage-simplelist-subleft {
	font-size: 80%;
	margin-left: 1em;
	color: #666;
}

.st-homepage-simplelist-right {
	width: 20%;
}

.st-homepage-simplelist-subright {
	font-size: 80%;
	color: #666;
}

.st-homepage-simplelist {
}

.st-homepage-simplelist-header {
	min-height: 35px;
}

.st-homepage-simplelist-header .button-table {
	float: right;
	margin-right: 15px;
	font-size: 95%;
}

.st-homepage-simplelist-header .button-table .button-content {
	padding: 1px;
}

.st-homepage-whatsnew-author, .st-homepage-whatsnew-date {
	color: #555;
}
.st-homepage-whatsnew-attribution {
	padding-left: 1em;
	font-size: 80%;
	color: #aaa;
}

/* Homepage Wikis List */

#st-wikis-title {
}

/* Data and Templates */

.st-jst-template, .st-json {
	display: none;
}

/* Page Sidebox Common Styles */

#st-page-boxes-toggle {
	position: relative;
	float: right;
	text-align: right;
	font-family: Verdana, Arial, sans-serif;
	font-weight: bold;
	font-size: 80%;
	margin-bottom: 0.7em;
}

#st-page-boxes-toggle-link {
	text-decoration: none;
}

#st-page-boxes-underlay {
	float: right;
	margin-top: -10px;
	margin-right: 10px;
	background: white;
	z-index: 198;
	clear: both;
	margin-left: 15px;
}
* html #st-page-boxes-underlay {
	margin-right: 4px;
}
#st-page-boxes {
	background: inherit;
	position: absolute;
	right: 23px;
	z-index: 199;
	margin-top: 15px;
	margin-left: 20px;
}
#st-page-boxes, #st-page-boxes-underlay {
	width: 225px;
	/* padding-left: 15px; */ /* Gives the white border effect, cwest dislikes it. */
}

.st-page-box {
	border: 1px solid black;
	padding: 5px;
	font-family: Verdana, Helvetica, sans-serif;
	font-size: 80%;
	margin-top: 15px;
}

.st-page-box-title {
	font-family: Helvetica, Verdana, sans-serif;
	font-weight: bold;
	margin-bottom: 10px;
}

.st-page-box-listing {
	margin: 0;
	padding: 0;
}

.st-page-box-listing-entry {
	display: block;
}

.st-page-boxes-nobacklinks {
	font-family: Verdana, Helvetica, sans-serif;
	font-size: 90%;
	color: #888;
}

.st-page-box-first {
	margin-top: 0px;
}

/* Page Display */

#st-page-content {
	clear: left;
	margin-top: 6px;
	margin-bottom: 0;
	padding-bottom: 0;
}

#st-page-content, #st-page-content td {
	font-family: Verdana, Helvetica, sans-serif;
	font-size: 90%;
}

#st-page-wiki-title {
	font-family: Helvetica, Verdana, sans-serif;
	font-size: 65%;
	font-weight: bold;
	color: #aaa;
	margin-bottom: 0.2em;
	margin-top: 0.1em;
	padding-top: 0;
}

#wiki {
	margin: 0;
	padding: 0;
}

#st-page-title {
}

#st-page-titletext, .st-page-title {
	font-family: Helvetica, Verdana, sans-serif;
	font-size: 150%;
	font-weight: bold;
	color: #888;
	border-bottom: 1px solid #888;
}

#st-newpage-pagename-edit {
	font-family: inherit;
	font-size: inherit;
	font-weight: inherit;
	color: #000;
	border: 1px solid black;
	padding-left: 0.3em;
	background-color: #ffd;
}

#st-page-details {
	font-style: italic;
	font-size: 75%;
	font-family: Georgia, serif;
	margin: 6px 10px 0 10px;
}

#st-page-details-feed-icon {
	vertical-align: middle;
	border: none;
}

#st-page-stats {
	float: right;
	vertical-align: middle;
}

#st-attribution {
	float: left;
	margin-bottom: 10px;
}

#st-page-editing-wysiwyg {
	background: #ffd;
	border-style: solid;
	border-color: #888 #ccc #ccc #888;
	border-width: 2px;
	width: 100%;
}

#st-page-editing-toolbar {
	margin-left: -6px;
	overflow: hidden;
	float: left;
	height: 25px;
}

#wikiwyg_wikitext_textarea {
	margin-top: 4px;
	background: #ffd;
	border-style: solid;
	border-color: #888 #ccc #ccc #888;
	border-width: 2px;
	width: 100%;
	font-family: monospace;
}

#st-page-maincontent {
}

#st-page-editing, #wikiwyg_wikitext_textarea {
}

#st-page-editing-pagebody-decoy, #st-page-editing-wysiwyg {
	display: none;
}

#st-editing-tools-edit {
	display: none;
}

#st-mode-wysiwyg-button
{
	font-size: 70%;
	margin-left: 4em;
}

#st-mode-wikitext-button
{
	font-size: 70%;
}

#st-edit-tips
{
	font-size: 70%;
}

.wikiwyg_button {
	background: #FFFFFF;
	border: 1px solid #FFFFFF;
	cursor: pointer;
	width: 20px;
	height: 20px;
	vertical-align: bottom;
}

.wikiwyg_button:hover {
	border: 1px outset;
}

.wikiwyg_button:active {
	border: 1px inset;
}

#wikiwyg_toolbar {
	display: none;
}

/* Sidebox Pagetools: Revisions, Watchlist */
#st-side-box-pagetools {
	border-collapse: collapse;
}

#st-rewind-norevisions {
	font-family: Helvetica, Arial, sans-serif;
	font-size: 11px;
	color: #777;
	text-decoration: none;
}

#st-side-box-pagetools a {
	font-family: Helvetica, Arial, sans-serif;
	font-size: 11px;
	color: #555;
	text-decoration: none;
}

/* Page View Tags/Incoming Links Sidebox */

#st-tags {
	background: #f4fff4;
	border-color: #bbeebb;
	color: #999;
}

#st-tags-title {
	color: #595;
}

#st-tags-addlink, #st-tags-addbutton {
	font-weight: bold;
}

#st-tags-listing {
	margin-bottom: 5px;
}

#st-tags-addinput, #st-tags-message, #st-tags-suggestion {
	display: none;
}

#st-tags-deletemessage {
	font-size: 90%;
	color: #555;
	display: none;
	margin-top: 0.5em;
	margin-bottom: 0.5em;
}

#st-tags-suggestion {
	margin-top: 2px;
}

.st-tags-level1 {
	font-size: 90%;
}

.st-tags-level2 {
	font-size: 100%;
}

.st-tags-level3 {
	font-size: 110%;
}

.st-tags-level4 {
	font-size: 120%;
}

.st-tags-level5 {
	font-size: 130%;
}

.st-tags-tagline .st-tags-tagdelete {
	text-decoration: none;
	color: #ccc;
}

.st-tags-tagline a {
	text-decoration: none;
	color: #444;
}

#st-tags-field {
	width: 95%;
}

#st-incoming-links {
	border-color: #ebb;
	background-color: #fff4f4;
}

#st-incoming-links-title {
	color: #b78;
}

#st-attachments {
	border-color: #bbe;
	background-color: #f4f4ff;
}

#st-attachments-uploadbutton, #st-attachments-managebutton {

}
#st-attachments-buttons-uploadbutton {
	margin: 0px;
	padding: 0px;
	padding-left: 2px;
}
#st-attachments-buttons-managebutton {
	margin: 0px;
	padding: 0px;
	padding-right: 2px;
}

#st-attachments-buttons td {
	padding-right: 3px;
	font-size: 99%;
}

#st-attachments-buttons {
	border-collapse: collapse;
	margin: 0px;
	padding: 0px;
	margin-top: 5px;
}

#st-attachments-title {
	color: #77b;
}

.st-attachments-line {
	width:100%;
	overflow:hidden;
}

/* Actions Bar */

#st-actions-bar-spacer {
	clear:both;
	height:0.5em;
	overflow:hidden;
}

#st-actions-bar-spacer-clear {
	clear:both;
	height:1px;
	overflow:hidden;
}


#st-actions-bar, #st-editing-tools-bar {
	margin-left: 30px !important;
	margin-right: 30px !important;
}

/* Footer */
#st-footer {
	margin-top: -8px;
	margin-bottom: 5px;
	clear: both;
}

/* Socialtext Attribution */

#st-socialtext-attribution {
	clear: both;
	text-align: center;
	font-size: 80%;
	font-family: Helvetica, sans-serif;
}

#st-socialtext-attribution-link {
	text-decoration: none;
}

#st-socialtext-attribution-image {
	border: 0;
}


/* Page Actions */

#st-edit-button-border-left-middle, #st-login-to-edit-button-border-left-middle {
	background: url('../../images/st/button-blue/left-middle.gif') left top repeat-y;
}
#st-edit-button-border-right-middle, #st-login-to-edit-button-border-right-middle {
	background: url('../../images/st/button-blue/right-middle.gif') right top repeat-y;
}

#st-edit-button-border-left-top, #st-login-to-edit-button-border-left-top {
	background: url('../../images/st/button-blue/left-top.gif') left top no-repeat;
}
#st-edit-button-border-right-top, #st-login-to-edit-button-border-right-top {
	background: url('../../images/st/button-blue/right-top.gif') right top no-repeat;
}

#st-edit-button-border-left-bottom, #st-login-to-edit-button-border-left-bottom {
	background: url('../../images/st/button-blue/left-bottom.gif') left bottom no-repeat;
}

#st-edit-button-border-right-bottom, #st-login-to-edit-button-border-right-bottom {
	background: url('../../images/st/button-blue/right-bottom.gif') right bottom no-repeat;
}

#st-edit-button-link, #st-login-to-edit-button-link {
}

#st-comment-button-border-left-middle {
	background: url('../../images/st/button-purple/left-middle.gif') left top repeat-y;
}

#st-comment-button-border-right-middle {
	background: url('../../images/st/button-purple/right-middle.gif') right top repeat-y;
}

#st-comment-button-border-left-top {
	background: url('../../images/st/button-purple/left-top.gif') left top no-repeat;
}

#st-comment-button-border-right-top {
	background: url('../../images/st/button-purple/right-top.gif') right top no-repeat;
}

#st-comment-button-border-left-bottom {
	background: url('../../images/st/button-purple/left-bottom.gif') left bottom no-repeat;
}

#st-comment-button-border-right-bottom {
	background: url('../../images/st/button-purple/right-bottom.gif') right bottom no-repeat;
}

#st-comment-button-link {
}

#st-save-button-border-left-middle {
	background: url('../../images/st/button-green/left-middle.gif') left top repeat-y;
}
#st-save-button-border-right-middle {
	background: url('../../images/st/button-green/right-middle.gif') right top repeat-y;
}

#st-save-button-border-left-top {
	background: url('../../images/st/button-green/left-top.gif') left top no-repeat;
}
#st-save-button-border-right-top {
	background: url('../../images/st/button-green/right-top.gif') right top no-repeat;
}

#st-save-button-border-left-bottom {
	background: url('../../images/st/button-green/left-bottom.gif') left bottom no-repeat;
}

#st-save-button-border-right-bottom {
	background: url('../../images/st/button-green/right-bottom.gif') right bottom no-repeat;
}

#st-save-button-link {
}

#st-preview-button-border-left-middle {
	background: url('../../images/st/button-gold/left-middle.gif') left top repeat-y;
}
#st-preview-button-border-right-middle {
	background: url('../../images/st/button-gold/right-middle.gif') right top repeat-y;
}

#st-preview-button-border-left-top {
	background: url('../../images/st/button-gold/left-top.gif') left top no-repeat;
}
#st-preview-button-border-right-top {
	background: url('../../images/st/button-gold/right-top.gif') right top no-repeat;
}

#st-preview-button-border-left-bottom {
	background: url('../../images/st/button-gold/left-bottom.gif') left bottom no-repeat;
}

#st-preview-button-border-right-bottom {
	background: url('../../images/st/button-gold/right-bottom.gif') right bottom no-repeat;
}

#st-preview-button-link {
}

#st-cancel-button-border-left-middle {
	background: url('../../images/st/button-crimson/left-middle.gif') left top repeat-y;
}
#st-cancel-button-border-right-middle {
	background: url('../../images/st/button-crimson/right-middle.gif') right top repeat-y;
}

#st-cancel-button-border-left-top {
	background: url('../../images/st/button-crimson/left-top.gif') left top no-repeat;
}
#st-cancel-button-border-right-top {
	background: url('../../images/st/button-crimson/right-top.gif') right top no-repeat;
}

#st-cancel-button-border-left-bottom {
	background: url('../../images/st/button-crimson/left-bottom.gif') left bottom no-repeat;
}

#st-cancel-button-border-right-bottom {
	background: url('../../images/st/button-crimson/right-bottom.gif') right bottom no-repeat;
}

#st-cancel-button-link {
}

#st-edit-more-button-border-left-middle {
	background: url('../../images/st/button-blue/left-middle.gif') left top repeat-y;
}
#st-edit-more-button-border-right-middle {
	background: url('../../images/st/button-blue/right-middle.gif') right top repeat-y;
}

#st-edit-more-button-border-left-top {
	background: url('../../images/st/button-blue/left-top.gif') left top no-repeat;
}
#st-edit-more-button-border-right-top {
	background: url('../../images/st/button-blue/right-top.gif') right top no-repeat;
}

#st-edit-more-button-border-left-bottom {
	background: url('../../images/st/button-blue/left-bottom.gif') left bottom no-repeat;
}

#st-edit-more-button-border-right-bottom {
	background: url('../../images/st/button-blue/right-bottom.gif') right bottom no-repeat;
}

#st-edit-more-button-link {
}

.st-page-action-button-link {
	min-height: 24px;
	min-width: 100px;
	text-align: center;
	font-family: Helvetica, Verdana, sans-serif;
	font-size: 90%;
	text-decoration: none;
	color: #fff;
	font-weight: bold;
	display: block;
	padding-top: 8px;
	padding-bottom: 0px;
	margin-bottom: -3px;
	width: 100%;
	margin-left: -2px;
}
* html .st-page-action-button-link {
	padding-top: 5px;
	padding-bottom: 0px;
	height: 24px;
}

.st-page-action-button {
	float: left;
	margin: 0;
	padding: 0;
	margin-right: 10px;
	min-height: 20px;
	border-collapse: collapse;
	width: 100px;
}

/* Attach File Interface */

#st-attachments-attachinterface {
	font-family: Helvetica, sans-serif;
	font-size: 90%;
	display: none;
	position: fixed;
	left: 0px;
	top: 0px;
	width: 100%;
	height: 100%;
	z-index: 2000;
	background-image: url('../../images/st/popup/bg.png');
}
#st-attachments-manageinterface {
	font-family: Helvetica, sans-serif;
	font-size: 90%;
	display: none;
	position: absolute;
	left: 0px;
	top: 0px;
	width: 100%;
	height: 100%;
	z-index: 2000;
	background-image: url('../../images/st/popup/bg.png');
}

* html #st-attachments-attachinterface {
	background-image: none;
}
* html #st-attachments-manageinterface {
	background-image: none;
}
* html .popup-overlay {
	background-image: url('../../images/st/popup/bg.png');
	background-color: #000;
	opacity: .70;
	position: absolute;
	left: 0px;
	top: 0px;
	width: 100%;
	height: 100%;
	z-index: 2001;
}

#st-attachments-attach-interface {
	z-index: 2002;
	background-color: #fff;
	color: #000;
	border: 4px solid #ccc;
	padding: 1em;
	width: 520px;
	margin-left: auto;
	margin-right: auto;
	margin-top: 10%;
	position: absolute;
	top: 0px;
}

* html #st-attachments-attach-interface {
}

#st-attachments-attach-formtarget {
	width: 0px;
	height: 0px;
	border: 0;
	padding: 0;
	margin: 0;
}

#st-attachments-attach-message {
	font-size: 90%;
	font-family: Verdana, Arial, Helvetica, Sans-Serif;
}

#st-attachments-attach-title {
	font-weight: bold;
	font-size: 120%;
}

#st-attachments-attach-close {
	float: right;
	margin-top: 6px;
}

#st-attachments-attach-uploadbutton {
	float: right;
	margin-right: 6px;
	margin-top: 6px;
	padding-bottom: 0;
}

#st-attachments-attach-fileprompt {
	margin: 0.2em 0 0.4em 0;
	padding-bottom: 0px;
}

#st-attachments-attach-submit {
	font-size: 90%;
	font-weight: bold;
}

#st-attachments-attach-filename {
	font-size: 90%;
}

#st-attachments-attach-uploadmessage {
	font-weight: bold;
	margin-bottom: 1em;
	display: none;
}

#st-attachments-attach-error {
	font-weight: bold;
	color: #f00;
	margin-bottom: 1em;
	display: none;
}

#st-attachments-attach-list {
	display: none;
	color: #666;
	font-size: 90%;
	margin-top: 1em;
	margin-bottom: 1em;
	border-top: 1px solid #4949BA;
	border-bottom: 1px solid #4949BA;
	background-color: #F5F5F5;
	padding: 3px;
}

.st-attachments-attach-listlabel {
	font-size: 90%;
	color: #4949BA;
}

/* Queue File Dialog */

#st-attachmentsqueue-interface {
	font-family: Helvetica, sans-serif;
	font-size: 90%;
	display: none;
	position: fixed;
	left: 0px;
	top: 0px;
	width: 100%;
	height: 100%;
	background-image: url('../../images/st/popup/bg.png'); /* Don't forget IE hack for ship! */
	z-index: 2000;
}

* html #st-attachmentsqueue-interface {
	background-image: none;
}

#st-attachmentsqueue-dialog {
	z-index: 2002;
	background-color: #fff;
	color: #000;
	border: 4px solid #ccc;
	padding: 1em;
	width: 530px;
	margin-left: auto;
	margin-right: auto;
	margin-top: 10%;
	position: absolute;
	top: 0px;
}

* html #st-attachmentsqueue-dialog {
}

#st-attachmentsqueue-fileprompt {
	margin-bottom: 0.4em;
	margin-top: 0;
	padding-bottom: 0;
}

#st-attachmentsqueue-title {
	font-weight: bold;
	font-size: 120%;
}

#st-attachmentsqueue-close {
	float: right;
	margin-top: 6px;
}

#st-attachmentsqueue-uploadbutton {
	float: right;
	margin-right: 6px;
	margin-top: 6px;
	padding-bottom: 0;
}

#st-attachmentsqueue-submit {
	font-size: 90%;
}

#st-attachmentsqueue-filename {
	font-size: 90%;
}

#st-attachmentsqueue-message {
	font-size: 90%;
	font-family: Verdana, Arial, Helvetica, Sans-Serif;
}

#st-attachmentsqueue-uploadmessage {
	font-weight: bold;
	margin-bottom: 1em;
	display: none;
}

#st-attachmentsqueue-error {
	font-weight: bold;
	color: #f00;
	margin-bottom: 1em;
	display: none;
}

#st-attachmentsqueue-list {
	display: none;
	color: #666;
	font-size: 90%;
	margin-top: 1em;
	margin-bottom: 1em;
	border-top: 1px solid #4949BA;
	border-bottom: 1px solid #4949BA;
	background-color: #F5F5F5;
	padding: 3px;
}

.st-attachmentsqueue-listlabel {
	font-size: 90%;
	color: #4949BA;
}

/* Lists */

tr.st-trbg-even, tr.st-trbg-even td{
	background-color: #f3f7f7;
}

tr.w-st-even-row, tr.w-st-even-row td {
	background-color: #f3f7f7;
}

.query-results-header-title, .query-results-header-last-edit-by {
	text-align: left;
}


.query-results-row-revisions {
	text-align: right;
}

.query-results-content {
	font-size: 85%;
	border-collapse: collapse;
	border: 1px dashed #ddd;
	border-left: 1px solid #ddd;
	border-right: 1px solid #ddd;
}

.query-results-row {
	border-collapse: collapse;
	border: 1px dashed #ddd;
	border-left: 1px solid #ddd;
	border-right: 1px solid #ddd;
}

.query-results-row a {
	text-decoration: underline;
	color: #00f;
}

.query-results-row td {
	font-family: Verdana;
	padding: 0.3em;
	border-left: 1px dashed #ddd;
	border-right: 1px dashed #ddd;
	border-top: 1px solid #ddd;
	border-bottom: 1px solid #ddd;
}

.query-results-header-row {
	border-collapse: collapse;
	border: 1px dashed #ddd;
	border-left: 1px solid #ddd;
	border-right: 1px solid #ddd;
}

.query-results-header-row a {
	text-decoration: underline;
	color: #00f;
}

.query-results-header-row th {
	font-family: Helvetica;
	padding: 0.3em;
	border-left: 1px dashed #ddd;
	border-right: 1px dashed #ddd;
	border-top: 1px solid #ddd;
	border-bottom: 1px solid #ddd;
}

div.st-actionbutton {
	float: left;
}

div#deleteme-st-actions-bar {
	clear: both;
	margin: 0.8em 20px 0.2em auto;
	padding: 0;
}

/* Manage File Interface */



#st-attachments-manage-interface {
	z-index: 2002;
	background-color: #fff;
	color: #000;
	border: 4px solid #ccc;
	padding: 1em;
	width: 520px;
	margin-left: auto;
	margin-right: auto;
	margin-top: 10%;
	position: absolute;
	top: 0px;
}

#st-attachments-manage-filetable {
	height: 150px;
	margin: 0;
	padding: 0;
	width: 100%;
	overflow: auto;
	border: 1px solid #ccc;
}

#st-attachments-manage-filelisting tbody td {
	font-size: 90%;
}
#st-attachments-manage-filelisting {
	width: 100%;
	border-collapse: collapse;
	border: 0;
	margin: 0;
	padding: 0;
}

#st-attachments-manage-fileheader {
	background: #ccc;
	font-weight: bold;
	border-bottom: 1px black solid;
}

#st-attachments-manage-close {
	float: right;
	margin-top: 3px;
	margin-right: -2px;
	font-weight: bold;
}

#st-attachments-manage-delete {
	margin-top: 3px;
	float: left;
	font-weight: bold;
}

.st-attachments-manage-filerow {
	border-bottom: 1px solid #ccc;
}

.row-odd {
	background-color: #eee;
}

.row-even {
	background-color: #fff;
}

.row-on {
	background-color: #009 !important;
	color: white !important;
}

.row-on a {
	color: #fff !important;
}

#st-attachments-manage-deletemessage {
	color: red;
}

/* Page tools icons */

#st-pagetools-print {
	background: url('../../images/st/pagetools/print.gif')
	left center no-repeat;
}

#st-pagetools-email {
	background: url('../../images/st/pagetools/email.gif')
	left center no-repeat;
}

#st-pagetools-tools {
	background: url('../../images/st/pagetools/tools.gif')
	left center no-repeat;
}

/*
 #st-pagetools-watch {
	background: url('../../images/st/pagetools/watch-blue.gif')
	left center no-repeat;
}
*/


/* *********** Settings *********** */

#st-settings-pane {
}
* html #settings-pane { font-size: 85%;}

.settings-start-table {
}
* html .settings-start-table { font-size: 90%;}

#st-settings-select {
	padding: 0px 10px 10px 10px;
	vertical-align: top;
	width: 1px;

	background-color: #eff1ec;
	border: none;
}

#st-settings-section {
	padding: 0px 10px 10px 10px;
	vertical-align: top;
}

.settings-top-header {
	margin-top: 1em;
	font-weight: bold;
	width: 15em;
}

.settings-header {
	margin-top: 1em;
	font-weight: bold;
}

.settings-selections {
	padding: 0px 0px 0px 20px;
	line-height: 1.5em;
}

.settings-selections a:visited, .settings-selections a:active {
	color: #0000ff;
}

.settings-link {
	clear: both;
	display: block;
}

.settings-section-left {
	text-align: right;
}

.settings-label {
	font-weight: bold;
}

.settings-help {
	color: #888;
}

.settings-comment {
}

.users-invite-message {
	padding: 0.5em 0.5em 0.5em 2em;
	background-color: #eee;
	/* This seems necessary to fix an IE bug that sometimes
		causes the text in this div to be invisible */
	z-index: 1000;
}

.workspace-entry-header {
	margin-top: .5em;
	font-weight: bold;
}

.workspace-entry {
	margin-left: 3em;
}

.workspace-entry-p {
	margin-top: .5em;
	margin-bottom: .75em;
}

.workspace-subentry {
	font-style: italic;
	font-weight: bold;
	margin-left: 1.5em;
}

.preferences-td {
	padding:.5em 0 1.5em 0;
}

.preferences-query {
	text-align: left;
}

.preference-radio {
	background-color: #cec;
}
.user-settings-listall-headings td {
	background-color: #eff3ef;
}

#st-settings-save {
	padding-bottom: 0.5em;
}

.standard-button-cancel {
	font-weight: bold;
	background-color: #71004b;

	border-left: 1px solid #aaa;
	border-top: 1px solid #aaa;
	border-bottom: 2px solid #333;
	border-right: 2px solid #333;
	color: #f4f3b9;
	width: 8em;
}

.standard-button-submit {
	font-weight: bold;
	background-color: #656084;

	border-left: 1px solid #aaa;
	border-top: 1px solid #aaa;
	border-bottom: 2px solid #333;
	border-right: 2px solid #333;
	color: #f4f3b9;
	width: 8em;
}

#st-settings {
	font-family: Verdana, Arial, Helvetica, Sans-Serif;
	font-size: 90%;
}


/* Listview Tabs */


#st-listview a:visited {
	color: #551a8b;
}
#st-listview-tabs ul {
	display: block;
	list-style: none outside;
	margin: 0 0 0 4em;
	padding: 0;
	font-family: Helvetica, Arial, Sans-serif;
	font-size: 80%;
}

#st-listview-tabs li {
	display: block;
	float: left;
	margin: 0 0.8em 0 0;
	padding: 3px 0.6em 0 0.6em;
	border: 1px solid #d8d8d8;
	border-bottom: 1px solid rgb(128, 169, 243);
	background-color: #f4f4f4;
	position: relative;
	bottom: -2px;
}

#st-listview-tabs li.spacer {
	margin: 0 0.8em 0 2em;
}

#st-listview-tabs a {
	color: #bbb;
	text-decoration: none;
}

#st-listview-tabs li.selected {
	background-color: #fff !important;
	border: 1px solid rgb(128, 169, 243) !important;
	border-bottom: 1px solid #fff !important;
	font-weight: bold !important;
}

#st-listview-tabs li.selected a {
	color: #000 !important;
}

/* Category List Display */

#st-category-display-links {
	margin-bottom: 1em;
	font-size: 90%;
}

#st-tag-listbody {
	font-family: Helvetica, Verdana, sans-serif;
}

/* Attachments List Display */

#st-attachments-list-body table.button-table {
	margin-top: 0.1em;
	font-size: 80%;
}


/* ********** PageTools Menu ************** */

div#st-editing-tools {
	float: left;
}

div#st-pagetools {
	z-index: 300;
	font-family: Helvetica, Verdana, sans-serif;
	font-size: 10px;
	float: right;
	margin: 18px 0 0 0em;
	color: #000;
	vertical-align: bottom;
	position: relative;
}

#st-pagetools a {
	text-decoration: none;
	color: black;
	padding-left: 17px;
}

#st-pagetools span {
	color: inherit;
	padding-left: 17px;
	vertical-align: top;
}

#st-pagetools span.st-watchlist-link {
	color: inherit;
	vertical-align: top;
}

.st-watchlist-link {
	cursor: pointer;
}

div#st-pagetools ul.level2 {
	z-index: 300;
	margin: 0;
	padding: 0;
	background: white;
	border: 1px solid #CCC;
	border-width: 0 1px;
}

div#st-pagetools li {
	position: relative;
	list-style: none;
	margin: 0;
	float: left;
	width: 7em;
	line-height: 11px;
}

div#st-pagetools ul ul li:hover {
	background: #BFE2FF;
}

div#st-pagetools li a {
	display: block;
	text-decoration: none;
}

div#st-pagetools>ul a {
	width: auto;
}

div#st-pagetools ul ul {
	position: absolute;
	width: auto;
	display: none;
}

div#st-pagetools ul ul li {
	line-height: 1.5em;
/*	width: 100%; */
	width: 14em;
}

.first {
	border-top: 1px solid #CCC;
}

.separator {
	border-bottom: 1px solid #CCC;
}

div#st-pagetools ul ul li a {
	border-bottom: 1px solid #CCC;
	padding-left: 15px;
	padding-right: 3px;
	margin-right: 3px;
	border: 0px;
}

div#st-pagetools li.submenu li.submenu:hover {
	z-index: 300;
	background-color: #BFE2FF;
}

div#st-pagetools ul.level1 li.submenu:hover ul.level2 {
	display:block;
}

div#st-pagetools ul.level2 {
	top: 1.0em;
	left: -9.5em;
}

/*

=head2 Revision List Display

Change these styles to update the page revision list.

*/

#st-revision-list-table {
	border-collapse: collapse;
	font-size: 85%;
	color: #000;
}

.st-page-title-decorator {
	color: #C80000;
}

.st-revision-header-emphasis {
	color: #C80000;
}

.st-revision-list-compare-button-row {
}

.st-revision-list-compare-button-cell {
	padding-top: 0.3em;
	text-align: center;
}

.st-revision-list-compare-button {
}

#st-revision-list-header-row {
}

#st-revision-list-header-select {
	padding: 6px 2px 2px 2px;
	text-align: center;
}

#st-revision-list-header-revision {
	padding: 6px 2px 2px 2px;
	text-align: left;
}

#st-revision-list-header-edited-by {
	padding: 6px 2px 2px 2px;
	text-align: center;
}

#st-revision-list-header-date {
	padding: 6px 2px 2px 2px;
	text-align: center;
}

.st-revision-list-row {
	border-collapse: collapse;
	border: 1px dashed #ddd;
	border-left: 1px solid #ddd;
	border-right: 1px solid #ddd;
}

.st-revision-list-row td {
	font-family: Verdana;
	padding: 0.3em;
	border-left: 1px dashed #ddd;
	border-right: 1px dashed #ddd;
	border-top: 1px solid #ddd;
	border-bottom: 1px solid #ddd;
}

.st-revision-list-row-select {
	padding: 3px 0 2px 0;
	text-align: center;
}

.st-revision-list-row-select-old {
}

.st-revision-list-row-select-new {
}

.st-revision-list-row-revision {
}

.st-revision-list-row-revision-link {
}

.st-revision-list-row-edited-by {
}

.st-revision-list-row-date {
}

/* Revision Menu */

#st-pagetools.st-revision-view-bar {
	float: left;
}

ul.st-revision-menu {
	list-style: none;
	margin: 0;
	padding: 0.2em;
	font-size: 80%;
}

ul.st-revision-menu li {
	float: left;
	padding: 0 0.4em 0 0.4em;
	border-right: thin solid #000000;
}

ul.st-revision-menu li.st-last {
	border-right: none;
}

#st-restore-revision-button {
	font-size: 80%;
}

/*

=head2 Revision Compare Display

When comparing two revisions of a page, these styles apply.

*/

#st-revision-compare-table {
	background-color: #f0f0f0;
}

#st-revision-compare-table td {
	background-color: white;
}

.st-revision-compare-old {
	background-color: #fdd;
	text-decoration: line-through;
}
.st-revision-compare-new {
	background-color: #dfd;
	font-weight: bold;
}

/* Weblog View */

#st-weblog {
	padding: 0;
}

#st-content-weblog-display-width-controller {
}
#st-content-weblog-display-width-controller-nav {
	width: 230px;
	margin-left: 15px;
	border-left: 5px solid #ddd;
	margin-top: -1px;
}

#st-weblog-content {
	font-family: Verdana, Helvetica, sans-serif;
	margin-top: -1px;
	margin-bottom: -1px;
	border-top: 1px solid #80a9f3;
	border-bottom: 1px solid #80a9f3;
}

#st-weblog-title {
	font-family: 'Trebuchet MS', Verdana, Helvetica, sans-serif;
	font-family: 'Times New Roman', serif;
	background-color: #80a9f3;
	color: #fff;
	font-size: 150%;
	font-weight: bold;
	padding: 0.2em;
	padding-left: 1em;
}

#st-weblog-wikititle {
	font-family: Helvetica, Verdana, sans-serif;
	font-style: italic;
	font-size: 40%;
	color: #fff;
	margin-bottom: 0.2em;
	margin-top: 0.1em;
	padding-top: 0;
}

#st-weblog-titletext {
	font-family: Helvetica, Verdana, sans-serif;
	font-weight: bold;
	color: #fff;
}

div.st-weblog-entry {
	margin-top: 0.2em;
	margin-bottom: 4.8em;
	padding: 0 1.5em 0 1.5em;
}

.st-page-title {
	clear: both;
}

div.st-weblog-entrytitle span.text {
	font-family: Helvetica, Verdana, sans-serif;
	font-size: 150%;
	font-weight: bold;
	color: #000;
}

.st-weblog-entrycontent {
	font-family: Verdana, Helvetica, sans-serif;
	font-size: 90%;
	border-bottom: 1px solid #888;
}

.st-weblog-byline {
	float: left;
	text-align: left;
	font-style: italic;
	font-size: 70%;
	font-family: Verdana, Helvetica, sans-serif;
}

.st-weblog-post-links {
	float: right;
	text-align: right;
	font-size: 70%;
	font-family: Verdana, Helvetica, sans-serif;
}

#st-weblog-archives, #st-weblog-navigation {
	position: relative;
	float: right;
	width: 230px;
}

#st-weblog-archives {
	margin-top: 15px;
	clear: right;
}

#st-weblog-archives-title, #st-weblog-navigation-title {
	margin-left: 15px;
	font-family: Helvetica, sans-serif;
	font-size: 95%;
	font-weight: bold;
	color: #999;
	border-bottom: 2px solid #f99;
	padding-bottom: 5px;
	padding-top: 5px;
	margin-bottom: 5px;
}

#st-weblog-navigation-content {
	margin-left: 15px;
	font-size: 80%;
}

#st-weblog-archives ul {
	margin: 0;
	padding: 0;
}

#st-weblog-archives ul li {
	/* list-type: none; */
	display: block;
	font-size: 80%;
	font-family: Helvetica, sans-serif;
	padding-left: 15px;
}

#st-weblog-newpost {
	padding: 0.5em 0.7em 0.3em 0.3em;
}

#st-weblog-newpost-button {
}

#st-weblog-actionbar-chooseweblog {
	float: right;
}

#st-weblog-postbyemail {
	font-size: 70%;
	font-family: Verdana, Helvetica, sans-serif;
	color: #def;
	padding-top: 0.4em;
}

#st-weblog-postbyemail-link {
	color: #00c;
}

.st-weblog-chooseprompt {
	font-size: 90%;
	font-family: Verdana, Helvetica, sans-serif;
	padding-right: 0.2em;
	color: #000;
}

.st-spacer {
	padding-right: 0.1em;
	padding-left: 0.1em;
}

.st-weblog-preventries {
	padding-bottom: 20px;
	clear: both;
}
.st-weblog-nextentries {
	clear: both;
}

div.st-weblog-entrynav {
	margin-top: 0.2em;
	margin-bottom: 1.8em;
	padding: 0;
}

span.st-weblog-previousentries, span.st-weblog-nextentries {
	font-size: 90%;
	font-family: Verdana, Helvetica, sans-serif;
	padding-left: 1em;
}

/* ******* Page Stats ******** */

#st-usagereport-navbar {
	font-size: 80%;
	padding: 0;
	margin: 0;
}

#st-usagereport-date {
	font-weight: bold;
	margin-top: 1em;
}

#st-page-usagereport h1 {
	font-size: 1.3em;
	font-weight: bold;
	margin-top: 1.2em;
	margin-bottom: 0.3em;
}

#st-page-usagereport h2 {
	font-size: 1.1em;
	font-weight: bold;
	margin-top: 0.8em;
	margin-bottom: 0.3em;
}

/* New Page */
#st-newpage-save, #st-newpage-duplicate {
	display: none;
	position: fixed;
	left: 0px;
	top: 0px;
	width: 100%;
	height: 100%;
	background: url('../../images/st/popup/bg.png'); /* Don't forget IE hack for ship! */
	z-index: 2000;
}

#st-newpage-save-interface {
	background-color: #fff;
	color: #000;
	border: 4px solid #ccc;
	padding: 0.5em;
	width: 450px;
	margin-left: auto;
	margin-right: auto;
	margin-top: 10%;
	position:absolute;
	top:0px;
	z-index:2003;
}

#st-newpage-duplicate-interface {
	background-color: #fff;
	color: #000;
	border: 4px solid #ccc;
	padding: 0.5em;
	width: 530px;
	margin-left: auto;
	margin-right: auto;
	margin-top: 10%;
	position:absolute;
	top:0px;
	z-index:2003;
}

#st-newpage-save-title, #st-newpage-duplicate-title {
	margin: 0;
	padding: 0;
	font-weight: bold;
	font-family: Helvetica, sans-serif;
	font-size: 100%;
}

#st-newpage-save-prompt, #st-newpage-duplicate-prompt {
	font-family: Helvetica, sans-serif;
	font-size: 90%;
	margin-bottom: 0.4em;
}

#st-newpage-save-buttons, #st-newpage-duplicate-buttons {
	margin-top: 0.8em;
	text-align: right;
}

.st-newpage-duplicate-option {
	font-family: Helvetica, sans-serif;
	font-size: 90%;
	margin: 0;
	padding: 0;
}

#st-newpage-duplicate-pagename {
	font-size: 90%;
}

.st-newpage-duplicate-emphasis {
	background-color: #FFFF00;
	font-weight: bold;
}

#st-newpage-save-field-pagename {
	margin-bottom: 0;
	margin-top: 0.2em;
	padding-bottom: 0;
	font-size: 90%;
}

#st-newpage-save-tip {
	margin-bottom: 0;
	margin-top: 1.2em;
	padding-bottom: 0;
	font-size: 75%;
	color: #888;
}

/* Wikitext Styling */

.wiki {
}

.wiki hr {
	margin-top: .4em;
	margin-bottom: .4em;
}

.wiki .short-rule {
	width: 25%;
}

.wiki .medium-rule {
	width: 50%
}

.wiki ul,
.wiki ol,
.wiki blockquote {
	margin-left: 2em;
	padding-left: 0em;
}

.wiki table {
	border-collapse: collapse;
}

.wiki td {
	border: 1px;
	border-style: solid;
	padding: .2em;
	vertical-align: top;
}

.wiki h1,
.wiki h2,
.wiki h3,
.wiki h4,
.wiki h5,
.wiki h6 {
	font-weight: bold;
	font-style: normal;
	margin-top: 0.1em;
	margin-bottom: 8px;
}

.wiki h1 {font-size: 200%;}
.wiki h2 {font-size: 170%;}
.wiki h3 {font-size: 145%;}
.wiki h4 {font-size: 125%;}
.wiki h5 {font-size: 110%;}
.wiki h6 {font-size: 100%;}

.wiki pre {
	background-color: #eee; /* XXX */
	margin-left: 1em;
	margin-right: 1em;
	padding: .2em;
}

.wiki .incipient {
	text-decoration: none;
	border-bottom: 1px dashed;
}

.wiki-include-title {
	background-color: #ccccff;
}

.wiki .wiki {
	position: relative;
	background-color: #ddddff;
	border: 1px solid #ccccff;
	padding: 3px;
}

.wafl_existence_error {
	color: rgb(200,0,0);
	border-bottom: 0.2em dashed rgb(200,0,0);
}

#st-edit-mode-container {
}

#st-edit-mode-view {
}

#st-page-editing-uploadbutton {
	z-index: 1500;
	float: left;
}

/* Comment UI */


body#st-commentui {
	background: #ffffff;
}

#st-commentui-container {
}

#st-commentui-container a:visited,
#st-commentui-container a:active {
	color: #00f;
}

#st-commentui-notetop {
}

#st-commentui-controls {
}

#st-commentui-savelink {
	background-color: #fffebd;
}

#st-commentui-cancellink {
}

#st-commentui-customfield {
}

#st-commentui-customfield .customfield-label {
}

#st-commentui-customfield .customfield-input {
}

#st-commentui-textarea {
	padding: 0;
	border-style: inset;
	border-width: thin;
	background-color: #ffd;
	color: black;
	width: 99%;
	height: 150px;
}

/*

=head2 Send Page by Email

Styles for the 'Send Page by Email' popup, accessed from the 'Email' dropdown
menu on the page bar.

*/

#email-page {
	background: #ffffff;
	font-size: 80%;
}

.email-page-row {
	clear: both;
}

.email-page-row-label {
	font-weight: bold;
	float: left;
	width: 5em;
	margin-left: 1.2em;
	margin-right: 1.2em;
	text-align: right;
}

.email-page-row-content {
	float: left;
	padding-bottom: 1.2em;
}

.email-page-user-select-column {
	float: left;
	padding-right: 1.2em;
	width: 14em;
}

#email-page-user-select-column-center {
	width: 10em;
}

.email-page-user-select-label {
	text-align: center;
}

#email-page-user-select-add-label {
	padding-top: 1em;
}

.email-page-user-select-button-group {
	padding-bottom: 2em;
}

.email-page-input {
	width: 120px;
	clear: both;
	display: block;
}


.email-page-select {
	width: 175px;
	font-size: x-small;
}

#email-page-error-message {
	text-align: center;
}

#email-page-buttons-container {
	clear: both;
}

#email-page-buttons {
	text-align: center;
}

.email-page-input-new {
	width: 175px;
}

/* System Status, Red with icon */

#st-system-status-alert {
	clear: both;
	width: 50%;
	margin-left: 25%;
	margin-top: 10px;
	padding: 5px;
	color: #c00;
	font-weight: bold;
	font-size: 80%;
	background: transparent url('../../images/st/system-message/important-note.gif') no-repeat 5px center;
	padding-left: 60px;
	min-height: 38px;
}
* html #st-system-status-alert {
	height: 38px;
}

/* System Status, Green */

#st-system-status {
	clear: both;
	text-align:center;
	width: 80%;
	margin-left: 10%;
	padding: 8px 0 3px 0;
	color: #0a0;
	font-family: Arial, Helvetica, sans-serif;
	font-size: 80%;
}

.socialtextLogo {
	text-align: center;
}
/*}}}*/
/***
|''Name:''|SparklinePlugin|
|''Description:''|Sparklines macro|
***/
//{{{
if(!version.extensions.SparklinePlugin) {
version.extensions.SparklinePlugin = {installed:true};

//--
//-- Sparklines
//--

config.macros.sparkline = {};
config.macros.sparkline.handler = function(place,macroName,params)
{
	var data = [];
	var min = 0;
	var max = 0;
	var v;
	for(var t=0; t<params.length; t++) {
		v = parseInt(params[t]);
		if(v < min)
			min = v;
		if(v > max)
			max = v;
		data.push(v);
	}
	if(data.length < 1)
		return;
	var box = createTiddlyElement(place,"span",null,"sparkline",String.fromCharCode(160));
	box.title = data.join(",");
	var w = box.offsetWidth;
	var h = box.offsetHeight;
	box.style.paddingRight = (data.length * 2 - w) + "px";
	box.style.position = "relative";
	for(var d=0; d<data.length; d++) {
		var tick = document.createElement("img");
		tick.border = 0;
		tick.className = "sparktick";
		tick.style.position = "absolute";
		tick.src = "data:image/gif,GIF89a%01%00%01%00%91%FF%00%FF%FF%FF%00%00%00%C0%C0%C0%00%00%00!%F9%04%01%00%00%02%00%2C%00%00%00%00%01%00%01%00%40%02%02T%01%00%3B";
		tick.style.left = d*2 + "px";
		tick.style.width = "2px";
		v = Math.floor(((data[d] - min)/(max-min)) * h);
		tick.style.top = (h-v) + "px";
		tick.style.height = v + "px";
		box.appendChild(tick);
	}
};


}
//}}}
/***
|''Name:''|CryptoFunctionsPlugin|
|''Description:''|Support for cryptographic functions|
***/
//{{{
if(!version.extensions.CryptoFunctionsPlugin) {
version.extensions.CryptoFunctionsPlugin = {installed:true};

//--
//-- Crypto functions and associated conversion routines
//--

// Crypto "namespace"
function Crypto() {}

// Convert a string to an array of big-endian 32-bit words
Crypto.strToBe32s = function(str)
{
	var be = Array();
	var len = Math.floor(str.length/4);
	var i, j;
	for(i=0, j=0; i<len; i++, j+=4) {
		be[i] = ((str.charCodeAt(j)&0xff) << 24)|((str.charCodeAt(j+1)&0xff) << 16)|((str.charCodeAt(j+2)&0xff) << 8)|(str.charCodeAt(j+3)&0xff);
	}
	while (j<str.length) {
		be[j>>2] |= (str.charCodeAt(j)&0xff)<<(24-(j*8)%32);
		j++;
	}
	return be;
};

// Convert an array of big-endian 32-bit words to a string
Crypto.be32sToStr = function(be)
{
	var str = "";
	for(var i=0;i<be.length*32;i+=8)
		str += String.fromCharCode((be[i>>5]>>>(24-i%32)) & 0xff);
	return str;
};

// Convert an array of big-endian 32-bit words to a hex string
Crypto.be32sToHex = function(be)
{
	var hex = "0123456789ABCDEF";
	var str = "";
	for(var i=0;i<be.length*4;i++)
		str += hex.charAt((be[i>>2]>>((3-i%4)*8+4))&0xF) + hex.charAt((be[i>>2]>>((3-i%4)*8))&0xF);
	return str;
};

// Return, in hex, the SHA-1 hash of a string
Crypto.hexSha1Str = function(str)
{
	return Crypto.be32sToHex(Crypto.sha1Str(str));
};

// Return the SHA-1 hash of a string
Crypto.sha1Str = function(str)
{
	return Crypto.sha1(Crypto.strToBe32s(str),str.length);
};

// Calculate the SHA-1 hash of an array of blen bytes of big-endian 32-bit words
Crypto.sha1 = function(x,blen)
{
	// Add 32-bit integers, wrapping at 32 bits
	add32 = function(a,b)
	{
		var lsw = (a&0xFFFF)+(b&0xFFFF);
		var msw = (a>>16)+(b>>16)+(lsw>>16);
		return (msw<<16)|(lsw&0xFFFF);
	};
	// Add five 32-bit integers, wrapping at 32 bits
	add32x5 = function(a,b,c,d,e)
	{
		var lsw = (a&0xFFFF)+(b&0xFFFF)+(c&0xFFFF)+(d&0xFFFF)+(e&0xFFFF);
		var msw = (a>>16)+(b>>16)+(c>>16)+(d>>16)+(e>>16)+(lsw>>16);
		return (msw<<16)|(lsw&0xFFFF);
	};
	// Bitwise rotate left a 32-bit integer by 1 bit
	rol32 = function(n)
	{
		return (n>>>31)|(n<<1);
	};

	var len = blen*8;
	// Append padding so length in bits is 448 mod 512
	x[len>>5] |= 0x80 << (24-len%32);
	// Append length
	x[((len+64>>9)<<4)+15] = len;
	var w = Array(80);

	var k1 = 0x5A827999;
	var k2 = 0x6ED9EBA1;
	var k3 = 0x8F1BBCDC;
	var k4 = 0xCA62C1D6;

	var h0 = 0x67452301;
	var h1 = 0xEFCDAB89;
	var h2 = 0x98BADCFE;
	var h3 = 0x10325476;
	var h4 = 0xC3D2E1F0;

	for(var i=0;i<x.length;i+=16) {
		var j,t;
		var a = h0;
		var b = h1;
		var c = h2;
		var d = h3;
		var e = h4;
		for(j = 0;j<16;j++) {
			w[j] = x[i+j];
			t = add32x5(e,(a>>>27)|(a<<5),d^(b&(c^d)),w[j],k1);
			e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
		}
		for(j=16;j<20;j++) {
			w[j] = rol32(w[j-3]^w[j-8]^w[j-14]^w[j-16]);
			t = add32x5(e,(a>>>27)|(a<<5),d^(b&(c^d)),w[j],k1);
			e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
		}
		for(j=20;j<40;j++) {
			w[j] = rol32(w[j-3]^w[j-8]^w[j-14]^w[j-16]);
			t = add32x5(e,(a>>>27)|(a<<5),b^c^d,w[j],k2);
			e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
		}
		for(j=40;j<60;j++) {
			w[j] = rol32(w[j-3]^w[j-8]^w[j-14]^w[j-16]);
			t = add32x5(e,(a>>>27)|(a<<5),(b&c)|(d&(b|c)),w[j],k3);
			e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
		}
		for(j=60;j<80;j++) {
			w[j] = rol32(w[j-3]^w[j-8]^w[j-14]^w[j-16]);
			t = add32x5(e,(a>>>27)|(a<<5),b^c^d,w[j],k4);
			e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
		}

		h0 = add32(h0,a);
		h1 = add32(h1,b);
		h2 = add32(h2,c);
		h3 = add32(h3,d);
		h4 = add32(h4,e);
	}
	return Array(h0,h1,h2,h3,h4);
};


}
//}}}
/***
|''Name:''|DeprecatedFunctionsPlugin|
|''Description:''|Support for deprecated functions removed from core|
***/
//{{{
if(!version.extensions.DeprecatedFunctionsPlugin) {
version.extensions.DeprecatedFunctionsPlugin = {installed:true};

//--
//-- Deprecated code
//--

// @Deprecated: Use createElementAndWikify and this.termRegExp instead
config.formatterHelpers.charFormatHelper = function(w)
{
	w.subWikify(createTiddlyElement(w.output,this.element),this.terminator);
};

// @Deprecated: Use enclosedTextHelper and this.lookaheadRegExp instead
config.formatterHelpers.monospacedByLineHelper = function(w)
{
	var lookaheadRegExp = new RegExp(this.lookahead,"mg");
	lookaheadRegExp.lastIndex = w.matchStart;
	var lookaheadMatch = lookaheadRegExp.exec(w.source);
	if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
		var text = lookaheadMatch[1];
		if(config.browser.isIE)
			text = text.replace(/\n/g,"\r");
		createTiddlyElement(w.output,"pre",null,null,text);
		w.nextMatch = lookaheadRegExp.lastIndex;
	}
};

// @Deprecated: Use <br> or <br /> instead of <<br>>
config.macros.br = {};
config.macros.br.handler = function(place)
{
	createTiddlyElement(place,"br");
};

// Find an entry in an array. Returns the array index or null
// @Deprecated: Use indexOf instead
Array.prototype.find = function(item)
{
	var i = this.indexOf(item);
	return i == -1 ? null : i;
};

// Load a tiddler from an HTML DIV. The caller should make sure to later call Tiddler.changed()
// @Deprecated: Use store.getLoader().internalizeTiddler instead
Tiddler.prototype.loadFromDiv = function(divRef,title)
{
	return store.getLoader().internalizeTiddler(store,this,title,divRef);
};

// Format the text for storage in an HTML DIV
// @Deprecated Use store.getSaver().externalizeTiddler instead.
Tiddler.prototype.saveToDiv = function()
{
	return store.getSaver().externalizeTiddler(store,this);
};

// @Deprecated: Use store.allTiddlersAsHtml() instead
function allTiddlersAsHtml()
{
	return store.allTiddlersAsHtml();
}

// @Deprecated: Use refreshPageTemplate instead
function applyPageTemplate(title)
{
	refreshPageTemplate(title);
}

// @Deprecated: Use story.displayTiddlers instead
function displayTiddlers(srcElement,titles,template,unused1,unused2,animate,unused3)
{
	story.displayTiddlers(srcElement,titles,template,animate);
}

// @Deprecated: Use story.displayTiddler instead
function displayTiddler(srcElement,title,template,unused1,unused2,animate,unused3)
{
	story.displayTiddler(srcElement,title,template,animate);
}

// @Deprecated: Use functions on right hand side directly instead
var createTiddlerPopup = Popup.create;
var scrollToTiddlerPopup = Popup.show;
var hideTiddlerPopup = Popup.remove;

// @Deprecated: Use right hand side directly instead
var regexpBackSlashEn = new RegExp("\\\\n","mg");
var regexpBackSlash = new RegExp("\\\\","mg");
var regexpBackSlashEss = new RegExp("\\\\s","mg");
var regexpNewLine = new RegExp("\n","mg");
var regexpCarriageReturn = new RegExp("\r","mg");

}
//}}}
This is the home page for Dobrica Pavlinušić's random unstructured stuff.

Welcome to my new unsorted stuff site. If you are here to "learn about rot13"<http://en.wikipedia.org/wiki/ROT13> this might not be the right place.

If you are, however looking latest and/or unsorted snippets which didn't made to "my homepage"<http://www.rot13.org/~dpavlin/> or "blog"<http://blog.rot13.org/> you might be on right place.

| {search: category: projects} | {search: category: howto} | {recent_changes: rot13} |

{fetchrss: http://blog.rot13.org/index.xml}
{file: PrintrBot_Plus_LC.diff}

Old 3D printer which never worked well.

DXF files: https://www.youmagine.com/designs/printrbot-lc-1302

https://web.archive.org/web/20130115210644/http://printrbot.com/shop/plus/

{toc: }

^ PrintrBot Plus LC

The Printrbot PLUS is the larger printrbot kit–containing an 8x8x8 build volume, laser cut birch construction, an assembled Ubis hot end, and 12mm Z-axis rods in an all-in-one kit. This kit also includes 1 lb of ABS filament.

This kit includes everything you need to build the printrbot PLUS:

* printrboard: all-in-one assembled electronics with integrated SD card slot (no soldering required)
* 5 NEMA 17 stepper motors complete with cable ends attached
* laser cut birch construction
* a few printed plastic parts (gears, etc)
* WOOD Extruder Kit
* hardware (8mm smooth rods, threaded rods, and bearings
** Z axis is 12mm smooth rods and 12 mm linear bearings )
* assembled Ubis hot end
* nuts, bolts, washers, zip ties
* laser cut print bed
* 8×8 heated bed
* misc assembled cables (no soldering required)
* 3 mechanical end stops (no soldering required)
* micro USB cable

^^ nozzle

The Getting Started Guide says that all Printrbots currently ship with 0.4mm nozzles.
The convention for identifying nozzles is based on notches (or "rings") cut into the sides (vertices) of the hexagonal brass "nut".
No notch = 0.5mm
1 notch = 0.4mm
2 notches = 0.35mm

^ info

Most of information about it vanished from internet so here is some overview:

* http://reprap.org/wiki/Printrbot
* http://reprap.org/wiki/Printrboard

* https://github.com/Printrbot/printrboard

Rev.B https://github.com/Printrbot/printrboard/releases/tag/revB

^ PrintrBoard pinout

Annotated headers from http://blog.think3dprint3d.com/2012/07/panelolu-with-printrboard.html

{image: Printrboard Headers.JPG}

^ serial

.pre
[Sun Mar 18 08:23:50 2018] usb 2-4.4: new full-speed USB device number 61 using xhci_hcd
[Sun Mar 18 08:23:50 2018] usb 2-4.4: New USB device found, idVendor=16c0, idProduct=0483
[Sun Mar 18 08:23:50 2018] usb 2-4.4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[Sun Mar 18 08:23:50 2018] usb 2-4.4: Product: USB Serial
[Sun Mar 18 08:23:50 2018] usb 2-4.4: Manufacturer: Teensyduino
[Sun Mar 18 08:23:50 2018] usb 2-4.4: SerialNumber: 12345
[Sun Mar 18 08:23:50 2018] cdc_acm 2-4.4:1.0: ttyACM0: USB ACM device

dpavlin@nuc:~$ microcom p /dev/ttyACM0 
connected to /dev/ttyACM0
Escape character: Ctrl\
Type the escape character to get to the prompt.


start
echo:PowerUp
 Brown out Reset
Marlin: 1.0.0 RC2
echo: Last Updated: 2012-02-25 | Author: erik
echo: Free Memory: 4907  Pla




echo:SD init fail
workDir open failed
echo:Unknown command:"echo"
ok
echo:Unknown command:"SD init fail"
ok
echo:Unknown command:"workDir open failed"
ok
.pre

^ settings

https://github.com/Printrbot/Marlin

.pre
M501
echo:Stored settings retreived:
echo:Steps per unit:
echo:  M92 X62.11 Y64.67 Z2272.72 E536.00
echo:Maximum feedrates (mm/s):
echo:  M203 X60.00 Y60.00 Z2.00 E14.00
echo:Maximum Acceleration (mm/s2):
echo:  M201 X2000 Y2000 Z30 E10000
echo:Acceleration: S=acceleration, T=retract acceleration
echo:  M204 S3000.00 T3000.00
echo:Advanced variables: S=Min feedrate (mm/s), T=Min travel feedrate (mm/s), B=minimum segment time (ms), X=maximum xY jerk (mm/s),  Z=maximum Z jerk (mm/s)
echo:  M205 S0.00 T0.00 B20000 X20.00 Z0.40 E5.00
echo:PID settings:
echo:   M301 P22.20 I1.08 D114.00

M115
FIRMWARE_NAME:Marlin V1; Sprinter/grbl mashup for gen6 FIRMWARE_URL:http://www.mendel-parts.com PROTOCOL_VERSION:1.0 MACHINE_TYPE:Mendel EXTRUDER_COUNT:1

.pre

If this doesn't work, you can try `M503` which should display all settings without loading them from flash.

^ software bed leveler

* https://github.com/emard/zleveler

^ schematics

{file: Printrboard_RevB_Schematic150.png}

{file: Printrboard-schematics.pdf}

^ Marlin

* https://github.com/MarlinFirmware/Marlin
* http://marlinfw.org/meta/gcode/

.pre
dpavlin@nuc:/nuc/PrintrBot$ git clone https://github.com/dpavlin/Marlin

dpavlin@nuc:/nuc/PrintrBot$ cd Marlin/
.pre

^^ compile Marlin 1.1.8

https://github.com/dpavlin/Marlin/tree/PrintrBot_Plus_LC-1.1.8

.pre
dpavlin@nuc:/nuc/PrintrBot/Marlin$ git checkout PrintrBot_Plus_LC-1.1.8 

dpavlin@nuc:/nuc/PrintrBot/Marlin$ platformio run -e printrboard
Warning! Ignore unknown `envs_dir` option in `[platformio]` section

Processing printrboard (platform: teensy; board: teensy20pp; framework: arduino)
-----------------------------------------------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
PLATFORM: Teensy > Teensy++ 2.0
SYSTEM: AT90USB1286 16MHz 8KB RAM (127KB Flash)
.pre

^^ compile Marlin 1.1.9

different enviroment compared to 1.1.8?

.pre
dpavlin@nuc:/nuc/PrintrBot/Marlin$ git checkout PrintrBot_Plus_LC-1.1.9 

dpavlin@nuc:/nuc/PrintrBot/Marlin$ platformio run -e teensy20
.pre

^^ flashing

open boot jumper, press button

.pre
[Sun Apr 15 12:20:34 2018] usb 1-1.1: new full-speed USB device number 30 using xhci_hcd
[Sun Apr 15 12:20:34 2018] usb 1-1.1: unable to get BOS descriptor
[Sun Apr 15 12:20:34 2018] usb 1-1.1: New USB device found, idVendor=03eb, idProduct=2ffb
[Sun Apr 15 12:20:34 2018] usb 1-1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[Sun Apr 15 12:20:34 2018] usb 1-1.1: Product: AT90USB128 DFU
[Sun Apr 15 12:20:34 2018] usb 1-1.1: Manufacturer: ATMEL
[Sun Apr 15 12:20:34 2018] usb 1-1.1: SerialNumber: 1.0.0


root@nuc:/nuc/PrintrBot/Marlin# apt-get install dfu-programmer


root@nuc:/nuc/PrintrBot/Marlin# dfu-programmer --targets 2>&1 | grep at90usb128
    at89c5132          at90usb1287        at90usb1286        at90usb1287-4k
    at90usb1286-4k     at90usb647         at90usb646         at90usb162

root@nuc:/nuc/PrintrBot/Marlin# dfu-programmer at90usb1286 dump --debug 99
     target: at90usb1286
    chip_id: 0x2ffb
  vendor_id: 0x03eb
    command: dump
      quiet: false
      debug: 99
device_type: AVR
------ command specific below ------

commands.c:625: dump 122880 bytes
atmel.c:579: atmel_read_flash( 0x7ffe83facaf0, 0x00000000, 0x0001e000, 0x564ef5df7000, 122880, false )
atmel.c:847: atmel_select_page( 0x7ffe83facaf0, 0 )
atmel.c:510: __atmel_read_page( 0x7ffe83facaf0, 0, 65536, 0x564ef5df7000, false )
atmel.c:537: result: -9
Unknown error.  Try enabling debug.
Failed to read 122880 bytes from device.



.pre

other useful debug levels are 100, 200, 300 - https://www.avrfreaks.net/forum/how-use-dfu-programmer

hmmm... can't backup firmware?

^^ flash firmware

.pre
dpavlin@nuc:/nuc/PrintrBot/Marlin$ dfu-programmer at90usb1286 erase
dpavlin@nuc:/nuc/PrintrBot/Marlin$ dfu-programmer at90usb1286 flash .pioenvs/printrboard/firmware.hex
Validating...
Flash did not validate. Did you erase first?

dpavlin@nuc:/nuc/PrintrBot/Marlin$ dfu-programmer at90usb1286 erase --debug 100
     target: at90usb1286
    chip_id: 0x2ffb
  vendor_id: 0x03eb
    command: erase
      quiet: false
      debug: 100
device_type: AVR
------ command specific below ------
   validate: true

commands.c:69: erase 122879 bytes
atmel.c:281: atmel_erase_flash( 0x7ffc5df9bff0, 4 )
atmel.c:671: atmel_blank_check( 0x7ffc5df9bff0, 0x00000000, 0x0001dfff )
atmel.c:847: atmel_select_page( 0x7ffc5df9bff0, 0 )
atmel.c:647: __atmel_blank_check_internal( 0x7ffc5df9bff0, 0x00000000, 0x0000ffff )
atmel.c:847: atmel_select_page( 0x7ffc5df9bff0, 1 )
atmel.c:647: __atmel_blank_check_internal( 0x7ffc5df9bff0, 0x00000000, 0x0000dfff )

.pre

^^ teensy setup pjrc

udev rule: https://www.pjrc.com/teensy/49-teensy.rules
loader: https://github.com/PaulStoffregen/teensy_loader_cli

^^ unlock chip using flip

It seems that chip is protected. However, trying to erase and program it did destry data in it (expect bootloader) for some reason, and it seem that dfu-programmer doesn't know how to work with protection features.

So, next step is to try atmel's flip under linux but this also doesn't work well.

* patch path to /dev/bus/usb/ - https://www.avrfreaks.net/forum/instructions-get-batchisp-working-ubuntu-lucid-1004?name=PNphpBB2&file=viewtopic&t=97673

.pre
root@nuc:/nuc/PrintrBot/flip.3.2.1# cat debian-install.sh 
sudo apt-get install openjdk-9-jre:i386 libusb-0.1-4:i386

root@nuc:/nuc/PrintrBot/flip.3.2.1# cat env.sh 
export JAVA_HOME=/usr/lib/jvm/java-9-openjdk-i386/
export FLIP_HOME=/nuc/PrintrBot/flip.3.2.1/bin/


root@nuc:/nuc/PrintrBot/flip.3.2.1# cd bin/
root@nuc:/nuc/PrintrBot/flip.3.2.1/bin# cp -apv libatlibusbdfu.so libatlibusbdfu.so.orig
root@nuc:/nuc/PrintrBot/flip.3.2.1/bin# sed 's/\/sys\/bus\/usb/\/dev\/bus\/usb/g' libatlibusbdfu.so.orig > libatlibusbdfu.so


# run from bin directory or it won't work (?!)

root@nuc:/nuc/PrintrBot/flip.3.2.1/bin# ./flip.sh

.pre

^ avrdude

made cable to convert 10 pin ICSP on usbasp to 6 pin ICSP on printrboard

http://reprap.org/wiki/Printrboard#Bootloaders

Pin 1 (not red wire on my harness because of re-wiring) is closest to the SD card slot.

.pre
root@nuc:/nuc/PrintrBot# avrdude -p usb1286 -c usbasp 

avrdude: warning: cannot set sck period. please check for usbasp firmware update.
avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e9782 (probably usb1287)

avrdude: safemode: Fuses OK (E:F3, H:99, L:5E)

avrdude done.  Thank you.
.pre

ok, factory bootloader

^^ fuses

.pre
# disable jtag
avrdude -c usbtiny -p at90usb1286 -U lfuse:w:0xde:m -U hfuse:w:0xdb:m -U efuse:w:0xf0:m

# enabled jtag
avrdude -c usbtiny -p at90usb1286 -U lfuse:w:0xDE:m -U hfuse:w:0x9B:m -U efuse:w:0xF0:m

root@nuc:/nuc/PrintrBot# avrdude -c usbtiny -p at90usb1286 -U lfuse:w:0xde:m -U hfuse:w:0xdb:m -U efuse:w:0xf0:m
avrdude: Error: Could not find USBtiny device (0x1781/0xc9f)

avrdude done.  Thank you.

root@nuc:/nuc/PrintrBot# avrdude -c usbasp -p at90usb1286 -U lfuse:w:0xde:m -U hfuse:w:0xdb:m -U efuse:w:0xf0:m

avrdude: warning: cannot set sck period. please check for usbasp firmware update.
avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e9782 (probably usb1287)
avrdude: reading input file "0xde"
avrdude: writing lfuse (1 bytes):

Writing |                                                    | 0% 0.00s ***failed;
Writing | ################################################## | 100% 0.06s

avrdude: 1 bytes of lfuse written
avrdude: verifying lfuse memory against 0xde:
avrdude: load data lfuse data from input file 0xde:
avrdude: input file 0xde contains 1 bytes
avrdude: reading on-chip lfuse data:

Reading | ################################################## | 100% 0.00s

avrdude: verifying ...
avrdude: verification error, first mismatch at byte 0x0000
         0x5e != 0xde
avrdude: verification error; content mismatch

avrdude: safemode: lfuse changed! Was de, and is now 5e
[Tue Apr 17 07:12:19 2018] usb 1-1.4: USB disconnect, device number 20
[Tue Apr 17 07:12:19 2018] usb 1-1.4: USB disconnect, device number 20
Would you like this fuse to be changed back? [y/n]
Would you like this fuse to be changed back? [y/n] n
avrdude: safemode: Fuses OK (E:F3, H:99, L:DE)

avrdude done.  Thank you.


root@nuc:/nuc/PrintrBot# avrdude -p usb1286 -c usbasp 

avrdude: warning: cannot set sck period. please check for usbasp firmware update.
avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e9782 (probably usb1287)

avrdude: safemode: Fuses OK (E:F3, H:99, L:5E)

avrdude done.  Thank you.

.pre

^^ flash bootloader

huh, hum, program bootloader anyway from http://blog.lincomatic.com/?p=548

.pre
root@nuc:/nuc/PrintrBot# avrdude -p usb1286 -c usbasp -U flash:w:BootloaderDFU.hex
.pre

power cycle, return jumper re-try programming fuses

.pre
root@nuc:/nuc/PrintrBot# avrdude -c usbasp -p at90usb1286 -U lfuse:w:0xDE:m -U hfuse:w:0x9B:m -U efuse:w:0xF0:m
.pre

^^ dfu programming works

re-try dfu programming

.pre
root@nuc:/nuc/PrintrBot# dfu-programmer at90usb1286 erase
root@nuc:/nuc/PrintrBot# dfu-programmer at90usb1286 flash Marlin/.pioenvs/printrboard/firmware.hex
Validating...
61322 bytes used (49.90%)


.pre

^^ avrdude programming

.pre
dpavlin@nuc:/nuc/PrintrBot/Marlin$ avrdude -c usbasp -p usb1286 -U flash:w:.pioenvs/printrboard/firmware.hex

avrdude: warning: cannot set sck period. please check for usbasp firmware update.
avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e9782 (probably usb1287)
avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
         To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: warning: cannot set sck period. please check for usbasp firmware update.
avrdude: reading input file ".pioenvs/printrboard/firmware.hex"
avrdude: input file .pioenvs/printrboard/firmware.hex auto detected as Intel Hex
avrdude: writing flash (87280 bytes):

Writing | ################################################## | 100% 58.04s

avrdude: 87280 bytes of flash written
avrdude: verifying flash memory against .pioenvs/printrboard/firmware.hex:
avrdude: load data flash data from input file .pioenvs/printrboard/firmware.hex:
avrdude: input file .pioenvs/printrboard/firmware.hex auto detected as Intel Hex
avrdude: input file .pioenvs/printrboard/firmware.hex contains 87280 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 38.49s

avrdude: verifying ...
avrdude: 87280 bytes of flash verified

avrdude: safemode: Fuses OK (E:F0, H:9B, L:DE)

avrdude done.  Thank you.
.pre

^ RepRapDiscount Full Graphic Smart Controller

* http://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller

^^ pinouts

{file: printrboard-lcd-pinout.png}

{image: printrboard-lcd-pinout-800px.png}

^^ Marlin pinout

.pre
diff --git a/Marlin/pins_PRINTRBOARD.h b/Marlin/pins_PRINTRBOARD.h
index 42632d174..8146505a3 100644
--- a/Marlin/pins_PRINTRBOARD.h
+++ b/Marlin/pins_PRINTRBOARD.h
@@ -166,3 +166,19 @@
   #endif
 
 #endif // ULTRA_LCD && NEWPANEL
+
+// XXX dpavlin -- my pinout
+#define LCD_PINS_RS       9   // E1       JP11-11
+#define LCD_PINS_ENABLE   8   // E0       JP11-10
+#define LCD_PINS_D4       7   // D7       JP11-8
+#define LCD_PINS_D5       6   // D6       JP11-7
+#define LCD_PINS_D6       5   // D5       JP11-6
+#define LCD_PINS_D7       4   // D4       JP11-5
+
+#define BTN_EN1        10   // C0       JP11-12
+#define BTN_EN2        11   // C1       JP11-13
+#define BTN_ENC        12   // C2       JP11-14
+
+// display delays are added to
+// Marlin/ultralcd_st7920_u8glib_rrd.h
+
diff --git a/Marlin/ultralcd_st7920_u8glib_rrd.h b/Marlin/ultralcd_st7920_u8glib_rrd.h
index db6224e47..8474bef24 100644
--- a/Marlin/ultralcd_st7920_u8glib_rrd.h
+++ b/Marlin/ultralcd_st7920_u8glib_rrd.h
@@ -49,7 +49,7 @@
   #define CPU_ST7920_DELAY_1 DELAY_NS(0)
   #define CPU_ST7920_DELAY_2 DELAY_NS(0)
   #define CPU_ST7920_DELAY_3 DELAY_NS(50)
-#elif MB(3DRAG) || MB(K8200) || MB(K8400) || MB(SILVER_GATE)
+#elif MB(3DRAG) || MB(K8200) || MB(K8400) || MB(SILVER_GATE) || MB(PRINTRBOARD)
   #define CPU_ST7920_DELAY_1 DELAY_NS(0)
   #define CPU_ST7920_DELAY_2 DELAY_NS(188)
   #define CPU_ST7920_DELAY_3 DELAY_NS(0)
.pre

^ Hardware upgrade

^^ RAMPS1.4 LCD 12864

* RAMPS1.4 LCD 12864 Control Panel 3D Printer Smart Controller LCD Display $10
** https://www.aliexpress.com/item/1-pcs-RAMPS1-4-LCD-12864-Control-Panel-3D-Printer-Smart-Controller-LCD-Display-Free-Shipping/32312042967.html
** $10 - works well, needs custom cable, well worth it from usability perspective

^^ LM8UU

* 10pcs/lot LM8UU Ball Bearings 8mm Bushing For CNC 3D Printers Parts Rail Linear Long Rod Shaft Part 8mm*15mm*24mm Aluminum Bush
** https://www.aliexpress.com/item/10pcs-lot-LM8UU-Ball-Bearings-8mm-Bushing-For-CNC-3D-Printers-Parts-Rail-Linear-Long-Rod/32834729285.html
** $4.24 - NOT recomended, worse that original VXB.com -- seller specified brand as FYSETC, parts don't have any markings

^^ Y axis coupler

* 3D Printer Parts Accessory Stepper Motor Aluminum Alloy Z Axis Flexible Coupling Coupler Shaft Couplings 5mm*8mm*25mm
** https://www.aliexpress.com/item/10pcs-lot-LM8UU-Ball-Bearings-8mm-Bushing-For-CNC-3D-Printers-Parts-Rail-Linear-Long-Rod/32834729285.html
** $0.75 - NOT for Y axis, since they are flexible
* 3D Printer Blue Aluminum Alloy Coupler for 5 x 5mm/5 x 8mm Shaft for Stepper Motor Shaft
** https://www.aliexpress.com/item/3D-Printer-Blue-Aluminum-Alloy-Coupler-for-5-x-5mm-5-x-8mm-Shaft-for-Stepper/32854452012.html
** $0.71 - great, much better than 3d printed part

^^ belts and pulleys

* 2pcs GT2 20teeth 20 Teeth Bore 5mm/8mm Timing Alumium Pulley + 2Meters Rubber GT2-6mm Open Timing Belt Width 6mm for 3D Printer
** https://www.aliexpress.com/item/2Pcs-GT2-20teeth-20-Teeth-Bore-5mm-8mm-Timing-Alumium-Pulley-2Meters-Rubber-GT2-6mm-Open/32711078503.html
** $1.90 - great, pully nut doesn't interfere with clip which is holding glass since nut is flush as opposed to 3d printed part

^^ Y axes rod

* T8 Lead Screw OD 8mm Pitch 2mm Lead 2mm 150mm 200mm 250mm 300mm 350mm 400mm 500mm with Brass Nut for Reprap 3D Printer Z Axis
** 250mm with Nut
** https://www.aliexpress.com/item/T8-Lead-Screw-Rod-OD-8mm-Pitch-2mm-Lead-2mm-Length-150mm-500mm-Threaded-Rods-with/32760102869.html
** $5.14 x 2 - great, our rods where bent from out of box

Needs 3d printed adapter for nut to fit: https://www.thingiverse.com/thing:2963508

Nut is friction fit which I consider somewhat as safety feature, if I found problems with it, I will probably add a bit of ABS goo in holes to fix it in place

^^ bed leveling

self-made sensor from RFID card, paper clip and case intrusion switch, connected in parallel with z-axis switch (it has to be normally closed, so that trigger interrupts signal)

^ BL touch

* 1 Set Newest BL Touch Auto Bed Leveling Sensor 3D Touch Auto Leveling Sensor For Anet A8 3D Printer Improve Printing Precision
** https://www.aliexpress.com/store/product/1-Set-Newest-BL-Touch-Auto-Bed-Leveling-Sensor-3D-Touch-for-3D-Printer-Improve-Printing/3108017_32837521614.html

http://www.geeetech.com/wiki/index.php/3DTouch_Auto_Leveling_Sensor

pinout, right to left

| pin | wire color | board label |
| 5 | green | G |
| 4 | red | 5V |
| 3 | yellow | S |
| 2 | black | G |
| 1 | white | Z- |

Needs additional pin for servo control (S - servo)

^^ Marlin configuration

.pre
commit 18396a8cd25585d5d562d4345ed851b91fb58821 (HEAD -> PrintrBot_Plus_LC-1.1.9)
Author: Dobrica Pavlinusic <dpavlin@rot13.org>
Date:   Sat Sep 8 11:05:54 2018 +0200

    probe offset from extruder

diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index 438494220..aeed322a7 100644
--- a/Marlin/Configuration.h
+++ b/Marlin/Configuration.h
@@ -770,8 +770,8 @@
  *      O-- FRONT --+
  *    (0,0)
  */
-#define X_PROBE_OFFSET_FROM_EXTRUDER 10  // X offset: -left  +right  [of the nozzle]
-#define Y_PROBE_OFFSET_FROM_EXTRUDER 10  // Y offset: -front +behind [the nozzle]
+#define X_PROBE_OFFSET_FROM_EXTRUDER 35  // X offset: -left  +right  [of the nozzle]
+#define Y_PROBE_OFFSET_FROM_EXTRUDER 5   // Y offset: -front +behind [the nozzle]
 #define Z_PROBE_OFFSET_FROM_EXTRUDER 0   // Z offset: -below +above  [the nozzle]
 
 // Certain types of probes need to stay away from edges

commit 2329e561e0f2997e78495c249706e9ce62608293
Author: Dobrica Pavlinusic <dpavlin@rot13.org>
Date:   Sat Sep 8 10:51:07 2018 +0200

    enable bed leveling
    
    AUTO_BED_LEVELING_UBL doesn't seem to compile for me ATM

diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index 38e0c343b..438494220 100644
--- a/Marlin/Configuration.h
+++ b/Marlin/Configuration.h
@@ -969,7 +969,7 @@
  */
 //#define AUTO_BED_LEVELING_3POINT
 //#define AUTO_BED_LEVELING_LINEAR
-//#define AUTO_BED_LEVELING_BILINEAR
+#define AUTO_BED_LEVELING_BILINEAR
 //#define AUTO_BED_LEVELING_UBL
 //#define MESH_BED_LEVELING
 
@@ -1023,6 +1023,8 @@
   //#define FRONT_PROBE_BED_POSITION MIN_PROBE_EDGE
   //#define BACK_PROBE_BED_POSITION (Y_BED_SIZE - MIN_PROBE_EDGE)
 
+  #define RIGHT_PROBE_BED_POSITION 190 // dpavlin -- probe overhangs on the right
+
   // Probe along the Y axis, advancing X after each column
   //#define PROBE_Y_FIRST
 

commit b867a948cd3b64d69e900b99a1306631d62753df
Author: Dobrica Pavlinusic <dpavlin@rot13.org>
Date:   Sun Sep 2 08:40:52 2018 +0200

    added bltouch config and pin on e-stop

diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index fd8463456..38e0c343b 100644
--- a/Marlin/Configuration.h
+++ b/Marlin/Configuration.h
@@ -721,7 +721,7 @@
 /**
  * The BLTouch probe uses a Hall effect sensor and emulates a servo.
  */
-//#define BLTOUCH
+#define BLTOUCH
 #if ENABLED(BLTOUCH)
   //#define BLTOUCH_DELAY 375   // (ms) Enable and increase if needed
 #endif
@@ -1909,7 +1909,7 @@
  * Set this manually if there are extra servos needing manual control.
  * Leave undefined or set to 0 to entirely disable the servo subsystem.
  */
-//#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command
+#define NUM_SERVOS 1 // Servo index starts with 0 for M280 command
 
 // Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle.
 // 300ms is a good value but you can try less delay.
diff --git a/Marlin/pins_PRINTRBOARD.h b/Marlin/pins_PRINTRBOARD.h
index 8146505a3..a68802725 100644
--- a/Marlin/pins_PRINTRBOARD.h
+++ b/Marlin/pins_PRINTRBOARD.h
@@ -182,3 +182,9 @@
 // display delays are added to
 // Marlin/ultralcd_st7920_u8glib_rrd.h
 
+// bltouch - use e-stop for servo
+// dpavlin@nuc:/nuc/PrintrBot/Marlin$ grep E5 m43-pins.txt 
+// PIN:  37   Port: E5        <unused/unknown>            Input  = 1
+//
+#define SERVO0_PIN	37	// E5 E-STOP
+
.pre

^^ gcode for bl-touch

M280 P0 S10 ; pushes the pin down

M280 P0 S90 ; pulls the pin up

M280 P0 S120 ; Self test – keeps going until you do pin up/down or release alarm

M280 P0 S160 ; Release alarm

M420 V ; display bed leveling

.pre
Bilinear Leveling Grid:
      0      1      2
 0 +0.445 +0.402 +0.284
 1 -0.083 +0.013 +0.023
 2 -0.678 -0.432 -0.264

echo:Bed Leveling On 
echo:Fade Height Off
.pre

----

^ Notes for Ender 3 V1.1.3

* install sanguino board support in ardunino ide https://github.com/Lauszus/Sanguino
* turn on power supply when flashing if you didn't disconnect steppers or it won't get enough power
* burn boot loader using usbasp programmer from arduino ide to make arudino ide work for upload
{toc}

^ [RaspberryPi] 3

^^ GATT

* doesn't really compile for me -- https://github.com/comarius/bunget
** https://www.raspberrypi.org/forums/viewtopic.php?uid=25856&f=41&t=148449&start=0
* https://github.com/msaunby/ble-sensor-pi
* https://github.com/ecc1/ble

^ nRF24L01+

* http://dmitry.gr/index.php?r=05.Projects&proj=11.%20Bluetooth%20LE%20fakery
* https://github.com/sandeepmistry/arduino-nRF24L01-BLE
* http://simonebaracchi.eu/posts/temperature-beacon/


^ Quintic BLE

Quintic Private Profile Guide http://www.nxp.com/documents/application_note/AN11846.pdf
Q 9021 http://cache.nxp.com/documents/data_sheet/QN902X.pdf?pspll=1

* serial port tools: https://github.com/Informatic/qn902x-tools
* BLE pyhton lib https://github.com/IanHarvey/bluepy
* https://github.com/dpavlin/quintic-ble


^^ [RaspberryPi] 3

unbind device in phone app

.pre
root@rpi3:/home/pi# hcitool lescan
LE Scan ...
08:7C:BE:92:85:23 Quintic BLE
08:7C:BE:92:85:23 (unknown)



.pre

^^ Android

using BLE Scanner

.pre
nRF Master Control Panel, 2016-05-21
Quintic BLE (08:7C:BE:92:85:23)
V	07:17:01.689	Connecting to 08:7C:BE:92:85:23...
D	07:17:01.701	gatt = device.connectGatt(autoConnect = false)
D	07:17:01.907	[Callback] Connection state changed with status: 0 and new state: CONNECTED (2)
D	07:17:01.939	[Broadcast] Action received: android.bluetooth.device.action.ACL_CONNECTED
I	07:17:01.962	Connected to 08:7C:BE:92:85:23
D	07:17:01.987	wait(600ms)
V	07:17:02.614	Discovering services...
D	07:17:02.628	gatt.discoverServices()
D	07:17:03.328	[Callback] Services discovered with status: 0
I	07:17:03.352	Services discovered
V	07:17:03.422	Generic Access (0x1800)
- Device Name [R W] (0x2A00)
- Appearance [R] (0x2A01)
- Peripheral Privacy Flag [R W] (0x2A02)
- Peripheral Preferred Connection Parameters [R] (0x2A04)
- Reconnection Address [R W WNR] (0x2A03)
Generic Attribute (0x1801)
- Service Changed [I R] (0x2A05)
   Client Characteristic Configuration (0x2902)
Unknown Service (0000fee8-0000-1000-8000-00805f9b34fb)
- Unknown Characteristic [N] (003784cf-f7e3-55b4-6c4c-9fd140100a16)
   Client Characteristic Configuration (0x2902)
   Characteristic User Description (0x2901)
- Unknown Characteristic [WNR] (013784cf-f7e3-55b4-6c4c-9fd140100a16)
Unknown Service (0000fee9-0000-1000-8000-00805f9b34fb)
- Unknown Characteristic [W WNR] (d44bc439-abfd-45a2-b575-925416129600)
   Characteristic User Description (0x2901)
- Unknown Characteristic [N] (d44bc439-abfd-45a2-b575-925416129601)
   Client Characteristic Configuration (0x2902)
V	07:17:29.219	Reading all characteristics...
V	07:17:29.236	Reading characteristic 00002a00-0000-1000-8000-00805f9b34fb
D	07:17:29.250	gatt.readCharacteristic(00002a00-0000-1000-8000-00805f9b34fb)
I	07:17:29.465	Read Response received from 00002a00-0000-1000-8000-00805f9b34fb, value: (0x) 51-75-69-6E-74-69-63-20-42-4C-45, "Quintic BLE"
A	07:17:29.484	"Quintic BLE" received
V	07:17:29.497	Reading characteristic 00002a01-0000-1000-8000-00805f9b34fb
D	07:17:29.512	gatt.readCharacteristic(00002a01-0000-1000-8000-00805f9b34fb)
I	07:17:29.660	Read Response received from 00002a01-0000-1000-8000-00805f9b34fb, value: (0x) 00-00
A	07:17:29.670	"[0] Unknown" received
V	07:17:29.681	Reading characteristic 00002a02-0000-1000-8000-00805f9b34fb
D	07:17:29.692	gatt.readCharacteristic(00002a02-0000-1000-8000-00805f9b34fb)
I	07:17:29.853	Read Response received from 00002a02-0000-1000-8000-00805f9b34fb, value: (0x) 00
A	07:17:29.873	"(0x) 00" received
V	07:17:29.886	Reading characteristic 00002a04-0000-1000-8000-00805f9b34fb
D	07:17:29.897	gatt.readCharacteristic(00002a04-0000-1000-8000-00805f9b34fb)
I	07:17:30.050	Read Response received from 00002a04-0000-1000-8000-00805f9b34fb, value: (0x) 64-00-C8-00-00-00-D0-07
A	07:17:30.061	"Connection Interval: 125.00ms - 250.00ms,
Slave Latency: 0,
Supervision Timeout Multiplier: 2000" received
V	07:17:30.074	Reading characteristic 00002a03-0000-1000-8000-00805f9b34fb
D	07:17:30.085	gatt.readCharacteristic(00002a03-0000-1000-8000-00805f9b34fb)
I	07:17:30.243	Read Response received from 00002a03-0000-1000-8000-00805f9b34fb, value: 0 bytes
V	07:17:30.254	Reading characteristic 00002a05-0000-1000-8000-00805f9b34fb
D	07:17:30.265	gatt.readCharacteristic(00002a05-0000-1000-8000-00805f9b34fb)
I	07:17:30.439	Read Response received from 00002a05-0000-1000-8000-00805f9b34fb, value: (0x) 01-00-FF-FF
A	07:17:30.451	"Affected Attribute Handle Range: 0x0001 - 0xFFFF" received
V	07:17:35.488	Enabling services...
V	07:17:35.507	Enabling indications for 00002a05-0000-1000-8000-00805f9b34fb
D	07:17:35.527	gatt.writeDescriptor(00002902-0000-1000-8000-00805f9b34fb, value=0x0200)
I	07:17:35.704	Data written to descr. 00002902-0000-1000-8000-00805f9b34fb, value: (0x) 02-00
A	07:17:35.713	"Indications enabled" sent
D	07:17:35.736	gatt.setCharacteristicNotification(00002a05-0000-1000-8000-00805f9b34fb, true)
V	07:17:35.754	Indications enabled for 00002a05-0000-1000-8000-00805f9b34fb
V	07:17:35.764	Enabling notifications for 003784cf-f7e3-55b4-6c4c-9fd140100a16
D	07:17:35.775	gatt.writeDescriptor(00002902-0000-1000-8000-00805f9b34fb, value=0x0100)
I	07:17:35.995	Data written to descr. 00002902-0000-1000-8000-00805f9b34fb, value: (0x) 01-00
A	07:17:36.007	"Notifications enabled" sent
D	07:17:36.030	gatt.setCharacteristicNotification(003784cf-f7e3-55b4-6c4c-9fd140100a16, true)
V	07:17:36.042	Notifications enabled for 003784cf-f7e3-55b4-6c4c-9fd140100a16
V	07:17:36.055	Enabling notifications for d44bc439-abfd-45a2-b575-925416129601
D	07:17:36.066	gatt.writeDescriptor(00002902-0000-1000-8000-00805f9b34fb, value=0x0100)
I	07:17:36.191	Data written to descr. 00002902-0000-1000-8000-00805f9b34fb, value: (0x) 01-00
A	07:17:36.203	"Notifications enabled" sent
D	07:17:36.227	gatt.setCharacteristicNotification(d44bc439-abfd-45a2-b575-925416129601, true)
V	07:17:36.240	Notifications enabled for d44bc439-abfd-45a2-b575-925416129601
V	07:17:36.251	All services enabled
V	07:17:38.528	Reading remote RSSI...
D	07:17:38.542	gatt.readRemoteRssi()
I	07:17:38.564	Remote RSSI received: -64 dBm
.pre

^ nRF51822

Brand: Makibes
Model: ID107
Bluetooth version: V4.0 BLE
Waterproof rating: Life-level waterproof
Main chip: Nordic nRF51822
Pulse sensor: Silicon labs Si1142
G-sensor: kx022-1020
{toc: }

^ Firmware update

^^ switch to bootloader mode

.pre
dpavlin@blue:~$ microcom -p /dev/ttyACM0 
connected to /dev/ttyACM0
Escape character: Ctrl-\
Type the escape character followed by c to get to the menu or q to quit
# press v to get version
V212
# press $ to go into bootloader mode
exiting
.pre

^^ flash new bootloader

http://blog.rot13.org/2013/04/usb-ir-toy---pic-18f2550-fw-update-under-linux.html

https://github.com/dpavlin/fw_update

.pre
dpavlin@blue:/blue/IR_Toy_v2/fw_update$ sudo ./fw_update  -e -w -v -m flash -vid 0x04d8 -pid 0xfd0b -ix /blue/IR_Toy_v2/USB_IR_Toy/package/firmware/USBIRToy.v22.hex
U2IO flash erasing: DONE.
U2IO flash programming: DONE.
U2IO flash verifying: DONE.
RESET Device
Operation successfully completed.
.pre

^ use

https://github.com/myshen/IRToyRecPlay

^^ record

.pre
dpavlin@blue:/blue/IR_Toy_v2/IRToyRecPlay$ ./IRToy -d /dev/ttyACM0 -f lg-power -r -v 1 
+-----------------------------------------+
|IR Toy Recorder/Player utility v21 (CC-0)|
|http://dangerousprototypes.com           |
+-----------------------------------------+
Opening IR Toy on /dev/ttyACM0 at 115200bps...
opening serial port /dev/ttyACM0
Setting up serial port...
Initializing IR Toy...
Asking for firmware version...(0/2)...wrote v...
Firmware version: V222
Entering IRs sample mode...(0/2)...wrote S...
IRs sampler version: S01
Current sample timer resolution: 21.3333us
binary mode
Recording at Resolution= 21.333300us
Recording started.
Press a button on the remote or any key to exit... 
got 512 bytes9E01 D300 1600 1D00 1600 1D00 1500 5200 1600 1D00 1500 1D00 1600 1D00 1500 1D00 1500 1D00 1500 5100 1700 
 5200 1500 1D00 1500 5200 1600 5000 1700 5200 1600 5100 1700 5100 1700 1D00 1500 1D00 1500 1E00 1500 5200 1500 1D00 1600
 1D00 1500 1E00 1500 1E00 1500 5200 1600 5200 1500 5200 1600 1D00 1600 5100 1600 5100 1700 5200 1600 5200 1600 F208 9E01
 D300 1600 1D00 1500 1D00 1500 5100 1700 1D00 1500 1D00 1500 1E00 1500 1D00 1600 1D00 1500 5200 1600 5100 1600 1D00 1500
 5200 1700 5100 1600 5100 1600 5100 1600 5200 1600 1D00 1500 1E00 1500 1D00 1500 5200 1600 1D00 1500 1D00 1500 1D00 1500
 1E00 1500 5200 1600 5100 1700 5100 1600 1D00 1500 5200 1600 5200 1600 5100 1700 5100 1600 6B07 9E01 6C00 1700 D012 9E01
 D200 1700 1D00 1500 1D00 1500 5200 1600 1D00 1500 1D00 1500 1D00 1500 1E00 1500 1E00 1500 5200 1600 5200 1600 1D00 1500
 5200 1600 5100 1600 5100 1600 5200 1600 5100 1600 1D00 1600 1D00 1500 1E00 1500 5200 1600 1D00 1500 1D00 1600 1D00 1500
 1E00 1500 5200 1600 5100 1600 5200 1600 1D00 1500 5200 1600 5200 1600 5100 1600 5200 1600 6B07 9E01 6D00 1600 970A 9F01
 D300 1600 1D00 1500 1D00 1600 5100 1700 1D00 1600 1D00 1500 1D00 1500 1E00 1500 1D00 1500 5200 1600 5100 1600 1D00 1600
 5100 1600 5200 1600 5100 1600 5100 1600 5200 1600 1D00 1500 1D00 1500 1D00 1500 5200 1600 1D00 
got 54 bytes1500 1E00 1500 1D00 1500 1E00 1500 5200 1600 5200 1500 5200 1700 1C00 1600 5100 1700 5100 1600 5200 1600 5100
 1600 6B07 9E01 6D00 1600 got 2 bytesFFFF 
Captured command.
Creating file: lg-power_000.bin
Press a button on the remote or any key to exit... 

Recording finished.
shutting down...wait for serial port to clear...done.
.pre

^^ play

To have it work reliably you have to turn off autosuspend of usb devices, see http://dangerousprototypes.com/forum/viewtopic.php?f=29&t=3336

.pre
echo "options usbcore autosuspend=-1" > /etc/modprobe.d/irtoy.conf
.pre

And then play recorded codes with:

.pre
dpavlin@blue:/blue/IR_Toy_v2/IRToyRecPlay$ ./IRToy -d /dev/ttyACM0 -f lg-power -p -v 1
.pre
This page tries to describe protocol used by CAME automatic gates

^ Information on internet

* Came code finder http://www.electronika.fr/blog/?p=1064
* decoding signals http://www.electronika.fr/blog/?p=777

^ RBE4RC

http://www.cameuk.com/camenew/tech-docs/03_Remotes%20and%20receivers/RB%20Receiver%20(needs%20AF%20card)/RBE4rc_119RS71/S71v2_GB.pdf

* ATOMO four-channel AM 433.92 MHz frequency Rolling Code Receiver

^ KeeLoq

* http://www.pittnerovi.com/jiri/hobby/electronics/keeloq/
I will try to collect here useful tips for making Android development work for command-line loving person like me. See [Android G1] if you are interested in hardware.

{toc: }

^ ADB

Part of http://developer.android.com/sdk/index.html

^^ Remote adb access

.pre
dpavlin@t61p:~/Downloads/android$ adb shell
# setprop service.adb.tcp.port 5555
.pre

.pre
dpavlin@t61p:~$ ssh -R 5555:192.168.1.40:5555 klin
.pre

.pre
dpavlin@klin:~$ adb connect 127.0.0.1:5555

dpavlin@klin:~$ adb devices
List of devices attached 
127.0.0.1:5555  device
.pre

^^ provision device

* http://balloonboard.org/balloonwiki/AndroidBalloon

.pre
adb shell
su
cd /data/data/com.android.providers.settings/databases
sqlite3 settings.db
INSERT INTO system (name, value) VALUES ('device_provisioned', 1);
.exit
.pre

^ CyanogenMod

* http://wiki.cyanogenmod.com/index.php?title=Compile_CyanogenMod_for_Dream_%26_Sapphire
* enable swap with {file: 99swapon} in /system/etc/init.d/

^^ Google apps

.pre
dpavlin@android:/srv/cyanogen$ wget \
--referer=http://developer.htc.com/google-io-device.html \
-O dream_sapphire_update.zip \
http://member.america.htc.com/download/RomCode/ADP/signed-google_ion-ota-14721.zip?
--2010-10-01 17:42:10--  http://member.america.htc.com/download/RomCode/ADP/signed-google_ion-ota-14721.zip?
Resolving member.america.htc.com... 216.139.227.226
Connecting to member.america.htc.com|216.139.227.226|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 53965203 (51M) [application/x-zip-compressed]
Saving to: `dream_sapphire_update.zip'

100%[=========================================================================>] 53,965,203   376K/s   in 2m 29s  

2010-10-01 17:44:39 (354 KB/s) - `dream_sapphire_update.zip' saved [53965203/53965203]

dpavlin@android:/srv/cyanogen$ cd device/htc/dream_sapphire
dpavlin@android:/srv/cyanogen/device/htc/dream_sapphire$ ./unzip-files.sh
.pre

^^ Build

A *lot* of host dependencies to install and build.

.pre
dpavlin@android:/srv/cyanogen$ . build/envsetup.sh
dpavlin@android:/srv/cyanogen$ lunch
dpavlin@android:/srv/cyanogen$ make -j8
.pre

^^ flashing

Transfer files you just built:

.pre
dpavlin@x200:/virtual/android/cyanogen$ rsync -v android:/srv/cyanogen/out/target/product/dream_sapphire/{boot.img,recovery.img,system.img,android-info.txt} 2010-09-25/
.pre

Download fastboot from http://developer.htc.com/adp.html

Start G1 by pressing camera+power button

.pre
dpavlin@x200:/virtual/android/cyanogen$ sudo ./fastboot devices
HT840GZ00000    fastboot

dpavlin@x200:/virtual/android/cyanogen$ sudo sh -c "ANDROID_PRODUCT_OUT=2010-09-25/ ./fastboot flashall"
--------------------------------------------
Bootloader Version...: 1.33.2005
Baseband Version.....: 2.22.19.26I
Serial Number........: HT840GZ33728
--------------------------------------------
checking product... OKAY
checking version-bootloader... OKAY
sending 'boot' (2234 KB)... OKAY
writing 'boot'... OKAY
sending 'recovery' (3308 KB)... OKAY
writing 'recovery'... OKAY
sending 'system' (92239 KB)... OKAY
writing 'system'... OKAY
rebooting... 
.pre

* review changes: http://github.com/CyanogenMod/android_vendor_cyanogen/blob/froyo/CHANGELOG.mkdn

^ SL4A

* http://code.google.com/p/android-scripting/wiki/RemoteControl

^ x86

* http://www.android-x86.org/getsourcecode

^^ froyo 2.2

.pre
dpavlin@android:/srv/android-x86$ repo init -u git://git.android-x86.org/manifest.git -b froyo-x86
dpavlin@android:/srv/android-x86$ repo sync

# configure build
dpavlin@android:/srv/android-x86$ . build/envsetup.sh
dpavlin@android:/srv/android-x86$ lunch

# build
dpavlin@android:/srv/android-x86$ make -j8
.pre

audio doesn't work

alternativly, you can build `generix_x86`

We need `/sbin` in `PATH` to access `e2fsprogs` utilities needed to build image

.pre
dpavlin@android:/srv/android-x86$ export PATH=/sbin:$PATH
dpavlin@android:/srv/android-x86$ make -j8 iso_img TARGET_PRODUCT=generic_x86
.pre

^^ eclair 2.1

.pre
dpavlin@android:/srv/android-x86$ repo init -u git://git.android-x86.org/manifest.git -b eclair-x86
dpavlin@android:/srv/android-x86$ repo sync
dpavlin@android:/srv/android-x86$ make -j8 iso_img TARGET_PRODUCT=generic_x86
# doesn't work

dpavlin@android:/srv/android-x86$ make -j8 iso_img TARGET_PRODUCT=eeepc
.pre

^ Application build process

* http://www.alittlemadness.com/2010/06/07/understanding-the-android-build-process/

^ repo

* http://source.android.com/source/git-repo.html
* enviroment vars: REPO_PROJECT REPO_PATH REPO_REMOTE
* see git command output: `export REPO_TRACE=1`
* export md5 hashes of verything (create tag): `repo manifest -r -o tag.xml`

^ repack applications

* http://code.google.com/p/android-apktool/

^ repository with scripts

{fetchatom: http://github.com/dpavlin/android-command-line/commits/master.atom full}
* https://osmocom.org/projects/osmo-fl2k/wiki/Osmo-fl2k

see also [rtl-sdr] for receiver part

.pre
dpavlin@nuc:~$ lsusb -d 1d5c:2000 
Bus 003 Device 007: ID 1d5c:2000  

dpavlin@nuc:~$ sudo fl2k_test -s 162e6
[sudo] password for dpavlin: 
Using 6 zero-copy buffers
libusb: error [op_dev_mem_alloc] alloc dev mem failed errno 12
Failed to allocate zerocopy buffer for transfer 4
Reporting PPM error measurement every 10 seconds...
Press ^C after a few minutes.
real sample rate: 144376742 current PPM: -108786 cumulative PPM: -108786
real sample rate: 144270861 current PPM: -109439 cumulative PPM: -109125
real sample rate: 144227755 current PPM: -109705 cumulative PPM: -109323
^CSignal caught, exiting!


.pre
http://www.computer-engineering.org/ps2protocol/

| female socket | male plug |
| {image: ps2-female-socket.JPG} | {image: ps2-male-plug.JPG} |

6-pin Mini-DIN (PS/2): 
1 - Data 
2 - Not Implemented 
3 - Ground 
4 - Vcc (+5V) 
5 - Clock 
6 - Not Implemented
{toc: }

^ loader

https://github.com/GadgetFactory/Papilio-Loader/pull/6

.pre
dpavlin@blue:/blue-zfs/FPGA/Papilio$ git clone https://github.com/GadgetFactory/Papilio-Loader.git
dpavlin@blue:/blue-zfs/FPGA/Papilio$ cd Papilio-Loader/papilio-prog
dpavlin@blue:/blue-zfs/FPGA/Papilio/Papilio-Loader/papilio-prog$ git checkout -b revert-libftdi2 261d0dd02f5489c63e8227c6f916af5efacfbe7a
dpavlin@blue:/blue-zfs/FPGA/Papilio/Papilio-Loader/papilio-prog$ ./autogen.sh 
dpavlin@blue:/blue-zfs/FPGA/Papilio/Papilio-Loader/papilio-prog$ ./configure && make

# check compiled binary
dpavlin@blue:/blue-zfs/FPGA/Papilio/Papilio-Loader/papilio-prog$ ./papilio-prog -v -j
Using built-in device list
JTAG chainpos: 0 Device IDCODE = 0x24001093     Desc: XC6SLX9
USB transactions: Write 3 read 2 retries 1

.pre

^ ZAP IDE

^^ compilation

.pre
dpavlin@blue:/blue-zfs/FPGA/Papilio$ git clone https://github.com/GadgetFactory/ZAP--ZPUino-Arduino-Papilio--IDE.git

dpavlin@blue:/blue-zfs/FPGA/Papilio$ cd ZAP--ZPUino-Arduino-Papilio--IDE/build/
dpavlin@blue:/blue-zfs/FPGA/Papilio/ZAP--ZPUino-Arduino-Papilio--IDE/build$ ant

dpavlin@blue:/blue-zfs/FPGA/Papilio/ZAP--ZPUino-Arduino-Papilio--IDE/build/linux$ ln -s zpu_tools_linux32.tar.bz2 zpu_tools_linux64.tar.bz2 
.pre

^^ fix papilio-prog to use Linux binary

.pre
dpavlin@blue:/blue-zfs/FPGA/Papilio/ZAP--ZPUino-Arduino-Papilio--IDE/build/linux/work$ vi ./hardware/zpuino/zpu/platform.txt

# fix papilioprog to papilio-prog
tools.papilioprog.cmd=papilio-prog

# remove .exe from this line
tools.papilioprog.erase.pattern="{path}/bin/papilio-prog" -c


dpavlin@blue:/blue-zfs/FPGA/Papilio/ZAP--ZPUino-Arduino-Papilio--IDE/build/linux/work$ chmod 755 hardware/tools/papilio/papilio_loader/Papilio_Programmer.sh 


# copy compiled papilio-prog to correct location and fix permissions
dpavlin@blue:/blue-zfs/FPGA/Papilio/ZAP--ZPUino-Arduino-Papilio--IDE/build/linux/work$ cp ../../../../Papilio-Loader/papilio-prog/papilio-prog hardware/tools/papilio/papilio_loader/bin/
dpavlin@blue:/blue-zfs/FPGA/Papilio/ZAP--ZPUino-Arduino-Papilio--IDE/build/linux/work$ chmod 755 hardware/tools/papilio/papilio_loader/bin/papilio-prog
.pre

^^ running IDE

Run arduino GUI:

.pre
dpavlin@blue:/blue-zfs/FPGA/Papilio/ZAP--ZPUino-Arduino-Papilio--IDE/build/linux/work$ ./arduino
.pre

Compilation works, but programming doesn't with error:

.pre
Board: Unknown board @ 96000000 Hz (0xa4041700)
.pre

so, let's rebuild zpuprogrammer

http://forum.gadgetfactory.net/index.php?/topic/1588-how-to-program-the-arduino-sketch-for-zpuino-to-the-spi-flash/page-2#entry11242

.pre
dpavlin@blue:/blue-zfs/ZPUino/ZPUino-HDL/zpu/hdl/zpuino/programmer$ git remote -v
origin  https://github.com/alvieboy/ZPUino-HDL/ (fetch)
origin  https://github.com/alvieboy/ZPUino-HDL/ (push)

dpavlin@blue:/blue-zfs/ZPUino/ZPUino-HDL/zpu/hdl/zpuino/programmer$ autoreconf --install
dpavlin@blue:/blue-zfs/ZPUino/ZPUino-HDL/zpu/hdl/zpuino/programmer$ ./configure
dpavlin@blue:/blue-zfs/ZPUino/ZPUino-HDL/zpu/hdl/zpuino/programmer$ make
dpavlin@blue:/blue-zfs/ZPUino/ZPUino-HDL/zpu/hdl/zpuino/programmer$ cp zpuinoprogrammer /blue-zfs/FPGA/Papilio/ZAP--ZPUino-Arduino-Papilio--IDE/build/linux/dist/tools/
# this one is for already built version
dpavlin@blue:/blue-zfs/ZPUino/ZPUino-HDL/zpu/hdl/zpuino/programmer$ cp zpuinoprogrammer /blue-zfs/FPGA/Papilio/ZAP--ZPUino-Arduino-Papilio--IDE/build/linux/work/hardware/tools/zpu/bin/zpuinoprogrammer
.pre

program boot file (IDE doesn't have permission to do so)

.pre
dpavlin@blue:/blue-zfs/FPGA/Papilio$ ./papilio-prog -v -f ./zap-2.0.5/hardware/zpuino/zpu/bootloaders/lx9/zpuino-1.0-PapilioPro-S6LX9-RetroCade-1.0.bit
Using built-in device list
JTAG chainpos: 0 Device IDCODE = 0x24001093     Desc: XC6SLX9
Created from NCD file: papilio_pro_routed.ncd;UserID=0xFFFFFFFF
Target device: 6slx9tqg144
Created: 2012/11/20 00:16:43
Bitstream length: 2727072 bits

Uploading "./zap-2.0.5/hardware/zpuino/zpu/bootloaders/lx9/zpuino-1.0-PapilioPro-S6LX9-RetroCade-1.0.bit". DNA is 0x190efd25eb57c9fe
Done.
Programming time 549.2 ms
USB transactions: Write 176 read 8 retries 5
.pre

run IDE

.pre
dpavlin@blue:/blue-zfs/FPGA/Papilio/ZAP--ZPUino-Arduino-Papilio--IDE/build/linux/work$ ./arduino
Experimental:  JNI_OnLoad called.
Stable Library
=========================================
Native lib Version = RXTX-2.1-7
Java lib Version   = RXTX-2.1-7
.pre

verification will fail, so just upload sketch:

.pre
dpavlin@blue:/blue-zfs/FPGA/Papilio/Papilio-SOC/zpu/hdl/zpuino/programmer$ ./zpuinoprogrammer -s 1000000 -R -d /dev/ttyUSB1 -b /tmp/build383944339812357036.tmp/Autoscroll.cpp.bin -U
Board: GadgetFactory Papilio Pro LX9 @ 96000000 Hz (0xa4041700)
Upload completed successfully in 0.05 seconds.
.pre

^ zpugcc

.pre
dpavlin@blue:/blue-zfs/FPGA/Papilio$ git clone git://repo.or.cz/zpugcc.git
Cloning into 'zpugcc'...
remote: Counting objects: 35519, done.
remote: Compressing objects: 100% (26110/26110), done.
remote: Total 35519 (delta 8445), reused 35519 (delta 8445)
Receiving objects: 100% (35519/35519), 70.18 MiB | 426.00 KiB/s, done.
Resolving deltas: 100% (8445/8445), done.
Checking connectivity... done.
Checking out files: 100% (35311/35311), done.
dpavlin@blue:/blue-zfs/FPGA/Papilio$ cd zpugcc/toolchain
dpavlin@blue:/blue-zfs/FPGA/Papilio/zpugcc/toolchain$ git diff build.sh
diff --git a/toolchain/build.sh b/toolchain/build.sh
index 783beaa..034929c 100644
--- a/toolchain/build.sh
+++ b/toolchain/build.sh
@@ -3,6 +3,9 @@ set -e
 rm -rf build
 mkdir build
 cd build
+mkdir bin
+ln -s /bin/true bin/makeinfo
+export PATH=`pwd`/bin:$PATH
 ../binutils/configure --target=zpu-elf --prefix=`pwd`/../install
 make
 make install
dpavlin@blue:/blue-zfs/FPGA/Papilio/zpugcc/toolchain$ sh -x build.sh
.pre

^ RetroCade MegaWing

http://retrocade.gadgetfactory.net/index.php?n=Main.RetroCadeMegaWing

^^ LCD

Modify Examples/LiqueidCrystal/Autoscroll

.pre
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(26, 24, 23, 22, 21, 20);

void setup() {
  // contrast to GND
  pinMode(46, OUTPUT);
  digitalWrite(46, LOW);
  // RW to ground
  pinMode(25, OUTPUT);
  digitalWrite(25, LOW);

  // set up the LCD's number of columns and rows: 
  lcd.begin(16,2);
}
.pre

^ ZPU (without Arduino IDE)

* http://forum.gadgetfactory.net/index.php?/topic/1863-bare-metal-zpu-hello-world/

^ Xilinx Virtual Cable Daemon

* https://github.com/tmbinc/xvcd/tree/ftdi
MiniPCIe/PCI/LPC Combo-Debug Card

[Altera] MAX 3000A CPLD

EPM3064ATC100

^ JTAG

6 pin header left of LCD, pull-up/down checked by unimer

1   3V
2   TMS pull-up
3   TDI pull-up
4   GND
5   TDO pull-down?
6   TCK pull-up

^^ pull-up/down pins

pull-up: TDO TMS TDI
pull-down: TCK

^^ [urjtag]

.pre
pi@raspberrypi ~ $ sudo dpkg -i urjtag_0.10-gpio-1_armhf.deb

pi@raspberrypi ~ $ sudo jtag
jtag> cable gpio tms=8 tdi=10 tdo=9 tck=11
Initializing GPIO JTAG Chain
jtag> detect
IR length: 10
Chain length: 1
Device Id: 00010111000001100100000011011101 (0x170640DD)
  Manufacturer: Altera (0x0DD)
  Part(0):      EPM3064A (0x7064)
  Stepping:     1
  Filename:     /usr/local/share/urjtag/altera/epm3064a/epm3064a

jtag> print chain
 No. Manufacturer              Part                 Stepping Instruction          Register
---------------------------------------------------------------------------------------------
*  0 Altera                    EPM3064A             1        BYPASS               BYPASS

jtag> include /usr/local/share/urjtag/altera/epm3064a/t100

jtag> instruction SAMPLE/PRELOAD
jtag> shift ir
jtag> shift dr
jtag> get signal IO2
jtag> get signal IN88


.pre
{image: CY7C68013A.jpg}

{toc}

^ Cypress CY7C68013A EZ-USB FX2LP

{file: U2CY7C68013-56.pdf}

1. With CY7C68013A-56 chip: low-power version of the enhanced 51-core, 16KBprogram data areas, frequency of 48Mhz, 480Mbps high-speed transmission protocol standards, compatible with USB2.0

2. Firmware, EEPROM: Complete in-system programming solution with a USB cabledirectly to download firmware, on-board to provide 16K (24LC128) a large program memory (EEPROM), used as storage VID / PID and the USB firmware, the program space to meet the CY7C68013A Needs.

3. All the GPIO pin through the 2.54mm standard leads to very convenient for learners toexpand DIYdesign.

4. With the board firmware can be achieved through the core function of the logic analyzer

5. PDF format, provide the schematic and code

.pre
dpavlin@blue:/bluez/CY7C68013A$ lsusb -d 04b4:8613
Bus 003 Device 023: ID 04b4:8613 Cypress Semiconductor Corp. CY7C68013 EZ-USB FX2 USB 2.0 Development Kit
.pre

Be sure to disable any udev rules which try to load firmware for other devices with FX2

^ [Altera] USBBlaster clone

* http://fpga4u.epfl.ch/wiki/FX2

^^ pull-up TMS, TDI, pull-down TCK

Altera recommends that you use pull-up resistor values between 1k and 10k ohms on the TMS and TDI pins and a pull-down resistor valueof 1k ohmson the TCK pin.

.pre
dpavlin@blue:/bluez/CY7C68013A/USB-Blaster/fx2fw-sdcc$ make
asx8051 -plosgff vectors.a51
make: asx8051: Command not found
Makefile:42: recipe for target 'vectors.rel' failed
make: *** [vectors.rel] Error 127

dpavlin@blue:/bluez/CY7C68013A/USB-Blaster/fx2fw-sdcc$ dpkg -l sdcc
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name                    Version          Architecture     Description
+++-=======================-================-================-====================================================
ii  sdcc                    3.4.0+dfsg-2     amd64            Small Device C Compiler


.pre

^^ Loading firmware

.pre
Aug 17 17:38:26 blue kernel: [13787.802348] usb 3-1.6.4.4: new high-speed USB device number 26 using ehci-pci
Aug 17 17:38:26 blue kernel: [13787.894557] usb 3-1.6.4.4: New USB device found, idVendor=04b4, idProduct=8613
Aug 17 17:38:26 blue kernel: [13787.894563] usb 3-1.6.4.4: New USB device strings: Mfr=0, Product=0, SerialNumber=0
Aug 17 17:38:26 blue kernel: [13787.894945] usbtest 3-1.6.4.4:1.0: FX2 device
Aug 17 17:38:26 blue kernel: [13787.894950] usbtest 3-1.6.4.4:1.0: high-speed {control bulk-in bulk-out} tests (+alt)

root@blue:/bluez/CY7C68013A/USB-Blaster/fx2fw-sdcc# DEVICE=/dev/bus/usb/003/026 /sbin/fxload -t fx2lp -I usbjtag.hex -v 
microcontroller type: fx2lp
single stage:  load on-chip memory
open RAM hexfile image usbjtag.hex
stop CPU
write on-chip, addr 0x0000 len    6 (0x0006)
write on-chip, addr 0x000b len    3 (0x0003)
write on-chip, addr 0x0013 len    3 (0x0003)
write on-chip, addr 0x001b len    3 (0x0003)
write on-chip, addr 0x0023 len    3 (0x0003)
write on-chip, addr 0x002b len    3 (0x0003)
write on-chip, addr 0x0033 len    3 (0x0003)
write on-chip, addr 0x003b len    3 (0x0003)
write on-chip, addr 0x0043 len    3 (0x0003)
write on-chip, addr 0x004b len    3 (0x0003)
write on-chip, addr 0x0053 len    3 (0x0003)
write on-chip, addr 0x005b len    3 (0x0003)
write on-chip, addr 0x0063 len    3 (0x0003)
write on-chip, addr 0x006b len    1 (0x0001)
write on-chip, addr 0x0080 len   56 (0x0038)
write on-chip, addr 0x0100 len  128 (0x0080)
write on-chip, addr 0x0fa0 len    3 (0x0003)
write on-chip, addr 0x0fb9 len    3 (0x0003)
write on-chip, addr 0x0fa3 len    3 (0x0003)
write on-chip, addr 0x0180 len 1008 (0x03f0)
write on-chip, addr 0x0570 len   77 (0x004d)
write on-chip, addr 0x0fbc len    6 (0x0006)
write on-chip, addr 0xe100 len   83 (0x0053)
write on-chip, addr 0xe154 len  150 (0x0096)
write on-chip, addr 0x05bd len  452 (0x01c4)
write on-chip, addr 0x0f98 len    2 (0x0002)
write on-chip, addr 0x0781 len  440 (0x01b8)
write on-chip, addr 0x0fb3 len    6 (0x0006)
write on-chip, addr 0x0f9a len    6 (0x0006)
write on-chip, addr 0x0939 len 1008 (0x03f0)
write on-chip, addr 0x0d29 len  595 (0x0253)
write on-chip, addr 0x0fa6 len   13 (0x000d)
write on-chip, addr 0x0f7c len   28 (0x001c)
... WROTE: 4110 bytes, 33 segments, avg 124
reset CPU
root@blue:/bluez/CY7C68013A/USB-Blaster/fx2fw-sdcc# 

Aug 17 17:41:23 blue kernel: [13964.652392] usb 3-1.6.4.4: USB disconnect, device number 26
Aug 17 17:41:24 blue kernel: [13965.107683] usb 3-1.6.4.4: new high-speed USB device number 27 using ehci-pci
Aug 17 17:41:24 blue kernel: [13965.199976] usb 3-1.6.4.4: config 1 interface 0 altsetting 0 bulk endpoint 0x81 has invalid maxpacket 64
Aug 17 17:41:24 blue kernel: [13965.199981] usb 3-1.6.4.4: config 1 interface 0 altsetting 0 bulk endpoint 0x2 has invalid maxpacket 64
Aug 17 17:41:24 blue kernel: [13965.201001] usb 3-1.6.4.4: New USB device found, idVendor=09fb, idProduct=6001
Aug 17 17:41:24 blue kernel: [13965.201005] usb 3-1.6.4.4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
Aug 17 17:41:24 blue kernel: [13965.201008] usb 3-1.6.4.4: Product: USB-Blaster
Aug 17 17:41:24 blue kernel: [13965.201009] usb 3-1.6.4.4: Manufacturer: EPFL
Aug 17 17:41:24 blue kernel: [13965.201011] usb 3-1.6.4.4: SerialNumber: 00000000

.pre

^ FX2 lib

* https://github.com/djmuhlestein/fx2lib

^ libfx2loader

* https://github.com/makestuff/libfx2loader

.pre
dpavlin@blue:/bluez/CY7C68013A$ wget http://www.swaton.ukfsn.org/bin/makestuff-lindar-20130719.tar.gz

dpavlin@blue:/bluez/CY7C68013A$ tar xvf makestuff-lindar-20130719.tar.gz

dpavlin@blue:/bluez/CY7C68013A$ cd makestuff/libs/

dpavlin@blue:/bluez/CY7C68013A/makestuff/libs$ ../scripts/msgit.sh makestuff/libfx2loader
Cloning into 'libfx2loader'...
remote: Counting objects: 174, done.
remote: Total 174 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (174/174), 58.68 KiB | 0 bytes/s, done.
Resolving deltas: 100% (112/112), done.
Checking connectivity... done.

dpavlin@blue:/bluez/CY7C68013A/makestuff/3rd$ ln -s ../../fx2lib/

dpavlin@blue:/bluez/CY7C68013A/makestuff/libs$ cd libfx2loader/

.pre

^ smbus

* http://www.karosium.com/p/smbusb.html
* https://github.com/karosium/smbusb
{toc: }

Board version: v7.0

* Lattice ECP5 `LFE5U-25F-6BG256C` ("product page"<https://www.latticesemi.com/Products/FPGAandCPLD/ECP5>)
* Winbond `25Q32JVSIQ`, 32 Mbits SPI flash ("datasheet"<https://github.com/q3k/chubby75/blob/master/5a-75b/datasheets/w25q32jv_spi_revc_08302016.pdf>)
* 2x Broadcom `B50612D` Gigabit Ethernet PHYs ("datasheet"<https://github.com/q3k/chubby75/blob/master/5a-75b/datasheets/B50610-DS07-RDS.pdf>)
* 2x ESMT `M12L16161A-5T` 1M x 16bit 200MHz SDRAMs (organized as 1M x 32bit) ("datasheet"<https://github.com/q3k/chubby75/blob/master/5a-75b/datasheets/M12L16161A.pdf>)
* 12x `74HC245T` Octal Bidirectional Transceiver (used for level translation to 5V)

{image: cl-5a-75b-v70-front-800.jpg}

^ links

* https://hackaday.com/2020/01/24/new-part-day-led-driver-is-fpga-dev-board-in-disguise/

^^ chubby75

* https://github.com/q3k/chubby75/tree/master/5a-75b
** upstream: https://github.com/tomverbeure/chubby75/tree/5a-75b/5a-75b
** upstream for v7 board: https://github.com/miek/chubby75/blob/5a-75b-v7_pinout/5a-75b/hardware_V7.0.md

^^ original protocol

* send data to original fpga image: https://github.com/FalconChristmas/fpp/blob/master/src/channeloutput/ColorLight-5a-75.cpp

^^ replace level shifters to get input

* https://twitter.com/edu_arana/status/1231466891354525698

https://twitter.com/Claude1079/status/1231194849350647808

 SN74CBT3245APW 8bit bidirectional FET switches
QS3245QG

{image: colorLight5A-75b.jpg}

^^ chiselwatt

https://github.com/antonblanchard/chiselwatt/commit/5a7fcbc8142ed2b390e1f8bfaaa801fe09a60351

UART RX is on J19, labelled key+ on the silk screen on the back
UART TX is on J1, pin 1.

LOCATE COMP "clock" SITE "P6";

LOCATE COMP "io_tx" SITE "F3";
LOCATE COMP "io_rx" SITE "M13";

^ litex

basic example of litex on colorLight 5A-75B based on fpga_101/lab004

* https://github.com/trabucayre/litexOnColorlightLab004/
* https://github.com/NiklasFauth/colorlight-led-cube
* https://github.com/ghent360/riscvOnColorlight-5A-75B

^ fpga pin mapping

https://twitter.com/adamgreig/status/1297255957320421383

I don't want to load a new image onto this totally blind, so I used the prjtrellis tools (<https://github.com/YosysHQ/prjtrellis/>) to write a script (<https://github.com/adamgreig/cl/blob/master/pins.py>) which works out input/output/bidi for all pins used in any ECP5 bitstream. It found only one unused pin...

https://github.com/adamgreig/cl/blob/master/pins.py

^ fpga images

* https://github.com/suglover/5a-75x-images
* ecpprog (FTDI jtag probe): https://github.com/gregdavill/ecpprog
{file: BusBlaster-v2.0a1.sch.landscape.pdf}

http://dangerousprototypes.com/docs/Bus_Blaster_v2_design_overview

[Xilinx CoolRunner-II]

I have two boards: v2.0a1 and v2.5

{toc}

^ UrJTAG

.pre
root@blue:/bluez/FPGA/Altera-x300# jtag 

UrJTAG 0.10 #2007
Copyright (C) 2002, 2003 ETC s.r.o.
Copyright (C) 2007, 2008, 2009 Kolja Waschk and the respective authors

UrJTAG is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
There is absolutely no warranty for UrJTAG.

warning: UrJTAG may damage your hardware!
Type "quit" to exit, "help" for help.

jtag> cable jtagkey vid=0x0403 pid=0x6010 interface=1
Connected to libftdi driver.
jtag> detect
IR length: 8
Chain length: 1
Device Id: 00000110111000011100000010010011 (0x06E1C093)
  Manufacturer: Xilinx (0x093)
  Part(0):      xc2c32a-vq44 (0x6E1C)
  Stepping:     0
  Filename:     /usr/share/urjtag/xilinx/xc2c32a-vq44/xc2c32a-vq44
Segmentation fault
# WTF?
.pre

So, compile urjtag with "libft2xx"<http://www.ftdichip.com/Drivers/D2XX.htm>

You must remove kernel modules:

.pre
jtag> cable ft2232 interface=1
error: Couldn't connect to suitable USB device.
error: ftdi/ftd2xx error: ftdi_usb_open_desc() failed: device not found
jtag> quit

root@blue:~# rmmod ftdi_sio

root@blue:~# jtag
jtag> cable ft2232 interface=1
Connected to libftd2xx driver.
jtag> detect
IR length: 8
Chain length: 1
Device Id: 00000110111000011100000010010011 (0x06E1C093)
  Manufacturer: Xilinx (0x093)
  Part(0):      xc2c32a-vq44 (0x6E1C)
  Stepping:     0
  Filename:     /usr/local/share/urjtag/xilinx/xc2c32a-vq44/xc2c32a-vq44
.pre

^ Update CPLD logic

http://dangerousprototypes.com/docs/Bus_Blaster_buffer_logic

.pre
root@blue:~# jtag

UrJTAG 0.10 #2051
Copyright (C) 2002, 2003 ETC s.r.o.
Copyright (C) 2007, 2008, 2009 Kolja Waschk and the respective authors

UrJTAG is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
There is absolutely no warranty for UrJTAG.

warning: UrJTAG may damage your hardware!
Type "quit" to exit, "help" for help.

jtag> cable ft2232 interface=1
Connected to libftd2xx driver.
jtag> detect
IR length: 8
Chain length: 1
Device Id: 00000110111000011100000010010011 (0x06E1C093)
  Manufacturer: Xilinx (0x093)
  Part(0):      xc2c32a-vq44 (0x6E1C)
  Stepping:     0
  Filename:     /usr/local/share/urjtag/xilinx/xc2c32a-vq44/xc2c32a-vq44
jtag> svf /blue-zfs/dangerous-prototypes-open-hardware/Bus_Blaster/buffer_logic/BBv2-JTAGkey-v1.4-VHDL.svf stop progress
detail: Parsing    660/664 ( 99%)detail: 
detail: Scanned device output matched expected TDO values.
.pre
{image: down-button.jpg}

{image: composite.png}

.pre
dpavlin@blue:/bluez/FPGA/ULX2S/uk101$ KERNEL[16887.354856] add      /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1.1/3-1.1.3 (usb)
KERNEL[16887.358543] add      /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1.1/3-1.1.3/3-1.1.3:1.0 (usb)
UDEV  [16887.365476] add      /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1.1/3-1.1.3 (usb)
KERNEL[16888.370326] add      /module/usbserial (module)
KERNEL[16888.370344] add      /bus/usb-serial (bus)
KERNEL[16888.370378] add      /bus/usb/drivers/usbserial (drivers)
KERNEL[16888.370396] add      /bus/usb/drivers/usbserial_generic (drivers)
KERNEL[16888.370413] add      /bus/usb-serial/drivers/generic (drivers)
UDEV  [16888.370685] add      /module/usbserial (module)
UDEV  [16888.370725] add      /bus/usb-serial (bus)
UDEV  [16888.370879] add      /bus/usb/drivers/usbserial (drivers)
UDEV  [16888.370901] add      /bus/usb-serial/drivers/generic (drivers)
UDEV  [16888.370928] add      /bus/usb/drivers/usbserial_generic (drivers)
KERNEL[16888.371900] add      /module/ftdi_sio (module)
KERNEL[16888.371923] add      /bus/usb/drivers/ftdi_sio (drivers)
KERNEL[16888.371945] add      /bus/usb-serial/drivers/ftdi_sio (drivers)
UDEV  [16888.371980] add      /module/ftdi_sio (module)
UDEV  [16888.372050] add      /bus/usb-serial/drivers/ftdi_sio (drivers)
KERNEL[16888.372098] add      /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1.1/3-1.1.3/3-1.1.3:1.0/ttyUSB0 (usb-serial)
UDEV  [16888.372124] add      /bus/usb/drivers/ftdi_sio (drivers)
KERNEL[16888.372401] add      /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1.1/3-1.1.3/3-1.1.3:1.0/ttyUSB0/tty/ttyUSB0 (tty)
UDEV  [16888.372546] add      /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1.1/3-1.1.3/3-1.1.3:1.0 (usb)
UDEV  [16888.372888] add      /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1.1/3-1.1.3/3-1.1.3:1.0/ttyUSB0 (usb-serial)
UDEV  [16888.374650] add      /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1.1/3-1.1.3/3-1.1.3:1.0/ttyUSB0/tty/ttyUSB0 (tty)
KERNEL[16929.333395] add      /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1.6/3-1.6.3 (usb)
KERNEL[16929.333629] add      /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1.6/3-1.6.3/3-1.6.3:1.0 (usb)
UDEV  [16929.338304] add      /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1.6/3-1.6.3 (usb)
UDEV  [16929.338759] add      /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1.6/3-1.6.3/3-1.6.3:1.0 (usb)
KERNEL[16929.708966] add      /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1.6/3-1.6.3/3-1.6.3.2 (usb)
KERNEL[16929.712382] add      /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1.6/3-1.6.3/3-1.6.3.2/3-1.6.3.2:1.0 (usb)
KERNEL[16929.712433] add      /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1.6/3-1.6.3/3-1.6.3.2/3-1.6.3.2:1.0/media0 (media)
KERNEL[16929.773679] add      /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1.6/3-1.6.3/3-1.6.3.2/3-1.6.3.2:1.0/video4linux/video0 (video4linux)
KERNEL[16929.773733] add      /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1.6/3-1.6.3/3-1.6.3.2/3-1.6.3.2:1.0/input/input30 (input)
KERNEL[16929.773790] add      /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1.6/3-1.6.3/3-1.6.3.2/3-1.6.3.2:1.0/input/input30/event16 (input)
KERNEL[16929.773883] add      /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1.6/3-1.6.3/3-1.6.3.2/3-1.6.3.2:1.1 (usb)
KERNEL[16929.942458] add      /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1.6/3-1.6.3/3-1.6.3.3 (usb)
KERNEL[16929.943007] add      /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1.6/3-1.6.3/3-1.6.3.3/3-1.6.3.3:1.0 (usb)
KERNEL[16929.943064] add      /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1.6/3-1.6.3/3-1.6.3.3/3-1.6.3.3:1.0/video4linux/video2 (video4linux)
UDEV  [16929.949326] add      /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1.6/3-1.6.3/3-1.6.3.2 (usb)
UDEV  [16929.949933] add      /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1.6/3-1.6.3/3-1.6.3.2/3-1.6.3.2:1.1 (usb)
UDEV  [16929.949946] add      /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1.6/3-1.6.3/3-1.6.3.2/3-1.6.3.2:1.0 (usb)
UDEV  [16929.950176] add      /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1.6/3-1.6.3/3-1.6.3.3 (usb)
UDEV  [16929.950550] add      /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1.6/3-1.6.3/3-1.6.3.2/3-1.6.3.2:1.0/media0 (media)
UDEV  [16929.950861] add      /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1.6/3-1.6.3/3-1.6.3.2/3-1.6.3.2:1.0/input/input30 (input)
UDEV  [16929.951576] add      /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1.6/3-1.6.3/3-1.6.3.2/3-1.6.3.2:1.0/input/input30/event16 (input)
UDEV  [16929.952469] add      /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1.6/3-1.6.3/3-1.6.3.2/3-1.6.3.2:1.0/video4linux/video0 (video4linux)
UDEV  [16930.953075] add      /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1.6/3-1.6.3/3-1.6.3.3/3-1.6.3.3:1.0 (usb)
UDEV  [16930.954337] add      /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1.6/3-1.6.3/3-1.6.3.3/3-1.6.3.3:1.0/video4linux/video2 (video4linux)

dpavlin@blue:/bluez/FPGA/ULX2S/uk101$ 
dpavlin@blue:/bluez/FPGA/ULX2S/uk101$ ../ujprog-x86-64 ./uk101-ulx2s8k.jed 
ULX2S JTAG programmer v 1.07 $Id: ujprog.c 1748 2014-01-09 15:07:43Z marko $
KERNEL[17115.768270] remove   /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1.1/3-1.1.3/3-1.1.3:1.0/ttyUSB0/tty/ttyUSB0 (tty)
KERNEL[17115.768305] remove   /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1.1/3-1.1.3/3-1.1.3:1.0/ttyUSB0 (usb-serial)
Using USB JTAG cable.
UDEV  [17115.769313] remove   /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1.1/3-1.1.3/3-1.1.3:1.0/ttyUSB0/tty/ttyUSB0 (tty)
UDEV  [17115.769664] remove   /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1.1/3-1.1.3/3-1.1.3:1.0/ttyUSB0 (usb-serial)
Programming: 100%  
Completed in 5.88 seconds.
dpavlin@blue:/bluez/FPGA/ULX2S/uk101$ 
.pre
{toc: }

^ X300 dongle

* [Altera] EPM3064A TC44-10N ftp://ftp.altera.com/outgoing/download/bsdl/3064at44.bsd
* LD1117A L33AUD

^^ JTAG

I took picture of both sides of board, corrected it using perspective tool in gimp and added layers with VCC (5V and 3.3V) and GND (checked with unimer continuity test).

{image: x300_dongle-jtag.jpg}

JTAG pinout doesn't match silkscreen designation of pin 1 (it's rotated). It also doesn't have VCC pin connected, so you need to supply 5V power via other means (I used PS/2 connector).

[Bus Blaster] jtag try:

.pre
jtag> cable jtagkey vid=0x0403 pid=0x6010 interface=0
Connected to libftd2xx driver.
jtag> detect
IR length: 10
Chain length: 1
Device Id: 00010111000001100100000011011101 (0x170640DD)
  Manufacturer: Altera (0x0DD)
  Part(0):      EPM3064A (0x7064)
  Stepping:     1
  Filename:     /usr/local/share/urjtag/altera/epm3064a/epm3064a

jtag> print chain
 No. Manufacturer              Part                 Stepping Instruction          Register
-------------------------------------------------------------------------------------------------------------------
*  0 Altera                    EPM3064A             1        BYPASS               BYPASS

# IMPORTANT: load signal aliases for this package
jtag> include /usr/local/share/urjtag/altera/epm3064a/t44

# get values of all pins

jtag> instruction SAMPLE/PRELOAD
jtag> shift ir
jtag> shift dr
jtag> dr
010010111010111010010111010010010010111111111010111010
111010010010010111010010010010010010010010010010010010
010010010010010010010010010010010010010010010010010010
010010010010010111010111010010
 (0x0000000000000000000000000000000024924924924975D2)

jtag> print chain
 No. Manufacturer              Part                 Stepping Instruction          Register
-------------------------------------------------------------------------------------------------------------------
*  0 Altera                    EPM3064A             1        SAMPLE/PRELOAD       BSR

jtag> get signal IO2
IO2 = 1
jtag> get signal IO3
IO3 = 1
jtag> get signal IO43
IO43 = 1
jtag> get signal IO44
IO44 = 1

# toggle single pin

jtag> instruction EXTEST
jtag> shift ir

jtag> print chain
 No. Manufacturer              Part                 Stepping Instruction          Register
-------------------------------------------------------------------------------------------------------------------
*  0 Altera                    EPM3064A             1        EXTEST               BSR

jtag> set signal IO10 out 0
jtag> shift dr

# re-read values of all pins

jtag> instruction SAMPLE/PRELOAD
jtag> shift ir
jtag> shift dr
jtag> get signal IO10
IO10 = 0

.pre

^^ SVF programming

.pre
jtag> svf /blue-zfs/FPGA/Altera-x300/x300_dongle/output_files/dongle1.svf stop progress
detail: Parsing     20/520 (  3%)warning: unimplemented mode 'ABSENT' for TRST
detail: Parsing    520/520 (100%)detail: 
detail: Scanned device output matched expected TDO values.
.pre

^^ VHDL to toggle pins

Toggle pins on all four sides of CPLD and create additional two images with all one and all zero for easy test where pin is

{file: dongle1.vhd}

Then I connected logic analyzer on pins and tried different svf files (all-0, all-1, left, bottom, right, top) to locate which pin change depending on image loaded. To isolate pins I used EXTEST and toggled pins.

^^ RJ45

{image: rj45-pins.jpg} {image: Pro050-rj45.png}

| pin | pull | cable |
| 1 |  | GND |
| 2 | 1 | VGA? | 
| 3 | 0 | IO? |
| 4 | 1 | VGA? |
| 5 | 0 | IO? |
| 6 | 1 | VGA? |
| 7 |  | IO10 |
| 8 |  | 5V |

^^ PS2

{include: [PS2]}

Keyboard (left, purple)

| pin | IO |
| 1 (data) | IO43 |
| 5 (clock) | IO44 |

Mouse (right, green)

| pin | IO |
| 1 (data) | IO34 |
| 5 (clock) | IO35 |

^ Audio jack

R2R D2A

all measurements are done on Hantek 2090 with 500mV/div setting which may account for some accuracy errors

^^ channel 1

| state | min | max |
| off  | 64.17 mV | 95.54 mV |
| IO23 | 1.664 V | 1.696 V |
| IO22 | 864 mv | 895 mV |
| IO21 | 472 mV | 503 mV |
| IO20 | 283 mV | 299 mV |
| IO19 | 189 mv | 221 mV |




^^ channel 2

| state | min | max |
| off | 3.3 | 50 mV |
| IO33 | 113 mV | 144 mV |
| IO31 | 207 mV | 254 mV | 
| IO28 | 395 mV | 442 mV |
| IO27 | 803 mV | 850 mV |
| IO25 | 1.603 V | 1.635 V |
Board sticker: M8S PRO R4 S912 3G 32G DDR4 DQ

{toc: }

{image: M8S-PRO.jpg}

It doesn't have button soldered, it works like power button in android

Serial port is marked on bottom of board (tx/rx are from cpu perspective)

probably: https://www.geekbuying.com/item/MECOOL-M8S-PRO-S912-KODI-17-0-4K-HDR10-3GB-DDR4-32GB-eMMC-TV-Box-380737.html

^ Android info

Android 7.1 bootlog from serial: {file: m8s-android-bootlog.txt.gz}

.pre
U-Boot 2015.01-g9331ff1-dirty (Mar 15 2018 - 16:16:24)

DRAM:  3 GiB
...
        aml_dt soc: gxm platform: q20xrmii variant: 3g
        dtb 0 soc: gxm   plat: q20xrmii   vari: 2g
        dtb 1 soc: gxm   plat: q20xrmii   vari: 3g
      Find match dtb: 1
...
parts: 10
00:      logo	0000000002000000 1
01:  recovery	0000000002000000 1
02:       rsv	0000000000800000 1
03:       tee	0000000000800000 1
04:     crypt	0000000002000000 1
05:      misc	0000000002000000 1
06:      boot	0000000002000000 1
07:    system	0000000080000000 1
08:     cache	0000000020000000 2
09:      data	ffffffffffffffff 4

M8SPRO:/ # uname -a
Linux localhost 3.14.29 #46 SMP PREEMPT Thu Apr 12 19:43:12 CST 2018 armv8l

M8SPRO:/ # cat /proc/cmdline
rootfstype=ramfs init=/init console=ttyS0,115200 no_console_suspend earlyprintk=aml-uart,0xc81004c0 ramoops.pstore_en=1 ramoops.record_size=0x8000 ramoops.console_size=0x4000 androidboot.selinux=permissive logo=osd1,loaded,0x3d800000,1080p60hz maxcpus=8 vout=1080p60hz,enable hdmimode=1080p60hz cvbsmode=576cvbs hdmitx= cvbsdrv=0 pq= androidboot.firstboot=0 jtag=apao androidboot.hardware=amlogic mac=D0:76:58:0E:63:A3 androidboot.mac=D0:76:58:0E:63:A3 androidboot.slot_suffix=_a buildvariant=userdebug

M8SPRO:/ # cat /proc/cpuinfo
Processor	: AArch64 Processor rev 4 (aarch64)
processor	: 0
processor	: 1
processor	: 2
processor	: 3
processor	: 4
processor	: 5
processor	: 6
processor	: 7
Features	: fp asimd evtstrm aes pmull sha1 sha2 crc32 wp half thumb fastmult vfp edsp neon vfpv3 tlsi vfpv4 idiva idivt 
CPU implementer	: 0x41
CPU architecture: 8
CPU variant	: 0x0
CPU part	: 0xd03
CPU revision	: 4

Hardware	: Amlogic
Serial		: 220a82006da41365fedf301742726826

M8SPRO:/ # free
		total        used        free      shared     buffers
Mem:       2876604416  2210639872   665964544           0    31326208
-/+ buffers/cache:     2179313664   697290752
Swap:       524283904           0   524283904

M8SPRO:/ # df
ilesystem        1K-blocks    Used Available Use% Mounted on
mpfs               1404592     504   1404088   1% /dev
tmpfs               1404592       0   1404592   0% /mnt
/dev/block/system   2031440  973788   1057652  48% /system
/dev/block/data    26969964 3050864  23919100  12% /data
/dev/block/cache     507848    2860    504988   1% /cache
/dev/block/tee         5115      45      5070   1% /tee
/dev/fuse          26969964 3050864  23919100  12% /mnt/runtime/default/emulated
/dev/fuse          26969964 3050864  23919100  12% /mnt/runtime/read/emulated
/dev/fuse          26969964 3050864  23919100  12% /mnt/runtime/write/emulated

.pre

^ recovery sd

https://www.cnx-software.com/2016/11/19/how-to-create-a-bootable-recovery-sd-card-for-amlogic-tv-boxes/

^ amlogic info

http://www.linux-meson.com/doku.php

^ armbian

https://forum.armbian.com/topic/12162-single-armbian-image-for-rk-aml-aw-aarch64-armv8/

.pre
dpavlin@nuc:~/Downloads$ xzcat Armbian_20.09_Arm-64_bullseye_current_5.8.5.img.xz | dd iflag=fullblock oflag=direct conv=fsync status=progress bs=1M of=/dev/sdb
dpavlin@nuc:~/Downloads$ sudo mount /dev/sdb1 /mnt/sdb1/
dpavlin@nuc:~/Downloads$ cd /mnt/sdb1/

root@nuc:/mnt/sdb1# cp u-boot-s905x-s912 u-boot.ext

root@nuc:/mnt/sdb1# vi extlinux/extlinux.conf

root@nuc:/mnt/sdb1# grep -v '^#' extlinux/extlinux.conf
LABEL Armbian
LINUX /zImage
INITRD /uInitrd

FDT /dtb/amlogic/meson-gxm-q201.dtb
APPEND root=LABEL=ROOTFS rootflags=data=writeback rw console=ttyAML0,115200n8 console=tty0 no_console_suspend consoleblank=0 fsck.fix=yes fsck.repair=yes net.ifnames=0

.pre

Note that this board uses *meson-gxm-q201.dtb* which is internal rmii to make ethernet work!

issue `reboot update` from android shell to boot from sdcard

^^ ath10k wifi sdio firmware

After booting, you will get error message about missing firmware:

.pre
[    7.861827] ath10k_sdio mmc2:0001:1: Failed to find firmware-N.bin (N between 2 and 6) from ath10k/QCA9377/hw1.0: -2
[    7.861838] ath10k_sdio mmc2:0001:1: could not fetch firmware files (-2)
.pre

Package `firmware-atheros` is installed, so it's a bit puzzeling what file is missing, however, if we go to

https://github.com/kvalo/ath10k-firmware.git

we can find sdio firmware at https://github.com/kvalo/ath10k-firmware/tree/master/QCA9377/hw1.0/untested

.pre
dpavlin@m8s:~/ath10k-firmware$ git remote -v
origin	https://github.com/kvalo/ath10k-firmware.git (fetch)
origin	https://github.com/kvalo/ath10k-firmware.git (push)

dpavlin@m8s:~/ath10k-firmware$ sudo cp QCA9377/hw1.0/untested/firmware-sdio-5.bin_WLAN.TF.1.1.1-00061-QCATFSWPZ-1 /lib/firmware/ath10k/QCA9377/hw1.0/firmware-sdio-5.bin
.pre

After running `nmtui` and configuring wifi it's available but dies after a while under load.

^^ kernel source

https://github.com/150balbes/Amlogic_s905-kernel

currently, I'm using

.pre
dpavlin@m8s:~/linux$ git remote -v
origin	https://github.com/xdarklight/linux (fetch)
origin	https://github.com/xdarklight/linux (push)
dpavlin@m8s:~/linux$ git branch
  master
  meson-mx-integration-5.11-20210124
  meson-mx-integration-5.13-20210503
* meson-mx-integration-5.13-20210523
dpavlin@m8s:~/linux$ cat mason-build.sh
# https://github.com/SLAzurin/armbian-aml-s8xx-kernel-build-steps

# https://github.com/xdarklight/linux

make -j 8 Image dtbs modules && sudo make modules_install dtbs_install install
.pre

Installing armbian kernel package doesn't work because /boot partition is vfat and not ext2/4

^^ u-boot source

https://github.com/150balbes/Amlogic_S905-u-boot

^^ balbes150 updates

installing linux image and headers does return error, but works

https://users.armbian.com/balbes150/

^ gpiod

.pre
sudo apt install gpiod
.pre

^^ button - gpio 2

.pre
root@arm-64:~# gpioget gpiochip0 2 # not pressed
1
root@arm-64:~# gpioget gpiochip0 2 # pressed
0
.pre

^^ led - gpio 9

.pre
root@arm-64:~# gpioset gpiochip0 9=0 # red

root@arm-64:~# gpioset gpiochip0 9=1 # blue (default)
.pre

^ u-boot

old https://github.com/endlessm/u-boot-meson

I wanted serial console which seems to be missing from armbian build above

wiki seems to suggest repository

https://gitlab.denx.de/u-boot/custodians/u-boot-amlogic

but we are going to use upstream u-boot

.pre
dpavlin@m8s:~/u-boot-amlogic$ git remote -v
github	https://github.com/u-boot/u-boot (fetch)

dpavlin@m8s:~/u-boot-amlogic$ libretech-cc_defconfig
dpavlin@m8s:~/u-boot-amlogic$ make -j 8
dpavlin@m8s:~/u-boot-amlogic$ cp u-boot.bin /boot/
.pre

abort u-boot with key press and boot new one with

.pre
fatload mmc 1 0x1000000 u-boot.bin
go 0x1000000
.pre

^ 2020-10 status for amlogic

U-Boot: Porting and Maintaining a Bootloader for a Multimedia SoC Family - Neil Armstrong, BayLibre SAS

https://youtu.be/u0-swEMDFp0
{toc}

^ pinout

{image: nRF24L01_pinout.jpg}

It seems that v2.0 devies are 32k while Internet wants us to beleve that they are 16k (v1.0 maybe?)

^ original firmware output

.pre
[11985.181504] usb 2-2.1: new full-speed USB device number 7 using xhci_hcd
[11985.285687] usb 2-2.1: New USB device found, idVendor=1915, idProduct=002b
[11985.285690] usb 2-2.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[11985.285692] usb 2-2.1: Product: Nordic Semiconductor nRFready Basic Remote Dongle
[11985.285694] usb 2-2.1: Manufacturer: Nordic Semiconductor
[11985.285695] usb 2-2.1: SerialNumber: \xffffffef\xffffffbf\xffffffbf\xffffffef\xffffffbf\xffffffbf\xffffffef\xffffffbf\xffffffbf\xffffffef\xffffffbf\xffffffbf\xffffffef\xffffffbf\xffffffbf\xffffffef\xffffffbf\xffffffbf\xffffffef\xffffffbf\xffffffbf\xffffffef\xffffffbf\xffffffbf\xffffffef\xffffffbf\xffffffbf\xffffffef\xffffffbf\xffffffbf
[11985.301719] input: Nordic Semiconductor Nordic Semiconductor nRFready Basic Remote Dongle as /devices/pci0000:00/0000:00:14.0/usb2/2-2/2-2.1/2-2.1:1.0/0003:1915:002B.0005/input/input11
[11985.361937] hid-generic 0003:1915:002B.0005: input,hiddev0,hidraw2: USB HID v1.11 Keyboard [Nordic Semiconductor Nordic Semiconductor nRFready Basic Remote Dongle] on usb-0000:00:14.0-2.1/input0
.pre

^ mouse jack tools

https://github.com/BastilleResearch/mousejack

^^ find device address

.pre
dpavlin@nuc:/nuc/nRF24L01/mousejack/nrf-research-firmware/tools$ ./nrf24-scanner.py 
[2017-01-07 13:50:59.174]  12   0  65:6F:91:A9:07  
[2017-01-07 13:51:07.012]   8  10  65:6F:91:A9:07  00:C2:00:00:F8:FF:FE:00:00:49
[2017-01-07 13:51:15.216]   8  10  65:6F:91:A9:07  00:C2:00:00:17:D0:FF:00:00:58
[2017-01-07 13:51:15.231]   8   0  65:6F:91:A9:07  
[2017-01-07 13:51:15.698]  12   0  65:6F:91:A9:07  
[2017-01-07 13:51:23.456]   8  10  65:6F:91:A9:07  00:C2:00:00:EB:BF:FF:00:00:95
[2017-01-07 13:51:23.503]   8  10  65:6F:91:A9:07  00:C2:00:00:FF:0F:FF:00:00:31
[2017-01-07 13:51:23.509]   8   0  65:6F:91:A9:07  
[2017-01-07 13:51:23.840]  12   0  65:6F:91:A9:07  
.pre

^^ sniff

.pre
dpavlin@nuc:/nuc/nRF24L01/mousejack/nrf-research-firmware/tools$ ./nrf24-sniffer.py -c 8 12 -a 65:6F:91:A9:07
[2017-01-07 13:53:34.922]   8   5  65:6F:91:A9:07  00:40:00:08:B8
[2017-01-07 13:53:34.930]   8   5  65:6F:91:A9:07  00:40:00:08:B8
[2017-01-07 13:53:34.938]   8   5  65:6F:91:A9:07  00:40:00:08:B8
[2017-01-07 13:53:34.946]   8   5  65:6F:91:A9:07  00:40:00:08:B8
[2017-01-07 13:53:34.962]   8   5  65:6F:91:A9:07  00:40:00:08:B8
[2017-01-07 13:53:34.970]   8   5  65:6F:91:A9:07  00:40:00:08:B8
[2017-01-07 13:53:34.979]   8  22  65:6F:91:A9:07  00:D3:44:0F:5C:E6:CD:54:B5:71:8C:F9:99:33:00:00:00:00:00:00:00:00
[2017-01-07 13:53:34.986]   8   5  65:6F:91:A9:07  00:40:00:08:B8
[2017-01-07 13:53:34.994]   8  10  65:6F:91:A9:07  00:4F:00:01:18:00:00:00:00:98
[2017-01-07 13:53:35.125]   8   5  65:6F:91:A9:07  00:40:01:18:A7
[2017-01-07 13:53:35.278]   8  22  65:6F:91:A9:07  00:D3:B0:F4:B3:27:E3:BE:34:72:8C:F9:99:34:00:00:00:00:00:00:00:16
[2017-01-07 13:53:35.285]   8   5  65:6F:91:A9:07  00:40:00:08:B8
[2017-01-07 13:53:35.301]   8   5  65:6F:91:A9:07  00:40:00:08:B8
.pre


^ flashing

https://github.com/BastilleResearch/mousejack/issues/6
https://wiki.bitcraze.io/projects:crazyradio:spi_programming


^^ bus pirate

https://github.com/koolatron/buspirate_nrf24lu1p

| Bus Pirate || nRF24LU1+ |
| 3V3  | -> | VDD  |
| AUX  | -> | PROG |
| SCK  | -> | SCK  |
| MOSI | -> | MOSI |
| MISO | -> | MISO |
| CS   | -> | CSN  |
| GND  | -> | GND  |

.pre
dpavlin@nuc:/nuc/nRF24L01/buspirate_nrf24lu1p$ ./flasher.pl -device /dev/ttyUSB0 -input ../mousejack/nrf-research-firmware/bin/dongle.bin 

.pre

^ bootloader

^^ 512 byte replacement

https://github.com/ahtn/nrf24lu1p-512-bootloader

^^ original bootloader

https://github.com/al177/buspirate_nrf24lu1p

^ Logitech C-U0007

Version with fixed ctrl+c exit bug: https://github.com/cl0udz/mousejack

.pre
dpavlin@x230:/x230/mousejack$ git remote -v
cl0udz  https://github.com/cl0udz/mousejack (fetch)
cl0udz  https://github.com/cl0udz/mousejack (push)

dpavlin@x230:/x230/mousejack/nrf-research-firmware$ make logitech_install

[Fri Apr 27 22:10:16 2018] usb 1-1.2: new full-speed USB device number 23 using ehci-pci
[Fri Apr 27 22:10:16 2018] usb 1-1.2: New USB device found, idVendor=1915, idProduct=0102
[Fri Apr 27 22:10:16 2018] usb 1-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[Fri Apr 27 22:10:16 2018] usb 1-1.2: Product: Research Firmware
[Fri Apr 27 22:10:16 2018] usb 1-1.2: Manufacturer: RFStorm

dpavlin@x230:/x230/mousejack/nrf-research-firmware$ ./tools/nrf24-scanner.py 
[2018-04-29 14:23:51.370]   5  22  65:6F:91:A9:07  00:D3:D5:D7:4F:76:ED:63:55:70:EC:77:61:0F:00:00:00:00:00:00:00:D4
[2018-04-29 14:23:51.786]   9   5  65:6F:91:A9:07  00:40:00:08:B8




.pre
Spin-off from [Chromebook] papge to document running mainline u-boot and Linux on Exynos

{toc: }

^ u-boot

^^ SPI eeprom image

.pre
dpavlin@klin:/klin/u-boot$ cat build-spi.sh 
#!/bin/sh -xe

make
#cp /klin/books/Chromebook/spi/snow-bricked.rom .
cp snow-bricked.rom snow-mix.rom
dd conv=notrunc if=spl/smdk5250-spl.bin of=snow-mix.rom seek=$((0x00002000)) bs=1
dd conv=notrunc if=u-boot.bin of=snow-mix.rom seek=$((0x00006000)) bs=1
scp snow-mix.rom rpi2:chromebook/

.pre

Upstream u-boot works, but can't find mmc devices, so internal flash is not accessable, so I had to boot from USB network using u-boot pxe

^^ chromiumos build

.pre
dpavlin@klin:/klin/chromebook$ . env.sh 
dpavlin@klin:/klin/chromebook/chromiumos$ cros_sdk
.pre

* apply some patches (or not) as described at

.pre
(cr) (altAddr) dpavlin@klin ~/trunk/src/third_party/u-boot/files $ emerge-${BOARD} chromeos-u-boot


.pre

^^ pxelinux config

.pre
dpavlin@x230:/var/tftp/pxelinux.cfg$ cat default-arm-exynos 
TIMEOUT 10

MENU TITLE TFTP boot

LABEL snow
        MENU LABEL sdcard?
        LINUX ../zImage
        FDTDIR ../
        APPEND console=tty1 console=ttyS0,115200n8 loglevel=8 rootwait rw earlyprintk root=/dev/sdcard0

.pre

^ kernel

doesn't boot ATM

.pre
dpavlin@klin:/klin/imx6/linux-imx$ cat build-chromebook.sh 
# 

cd /klin/chromebook/chromiumos/src/third_party/kernel/v4.4

export CROSS_COMPILE="arm-linux-gnueabihf-" ARCH=arm

test ! -f .config && make exynos_defconfig
make -j4 zImage exynos5250-snow.dtb
cp -v arch/arm/boot/zImage arch/arm/boot/dts/exynos5250-snow.dtb /media/boot/

.pre

^^ chromiumos kernel

https://github.com/dnschneid/crouton/wiki/Build-chrome-os-kernel-and-kernel-modules

^ security

(might not be related, but useful to keep track of)

* https://fredericb.info/2020/06/exynos8890-bootrom-dump-dump-exynos-8890-bootrom-from-samsung-galaxy-s7.html
* https://fredericb.info/2020/06/reverse-engineer-usb-stack-of-exynos-bootrom.html
** https://github.com/frederic/exynos8890-bootrom-dump
Quick guide based on "stunnel for mysql - server and client"<http://www.edna.narrabilis.com/2006/06/01/stunnel-for-mysql-server-and-client/> to add https to existing http server on demand.

{toc: }

^ Installation

.pre
apt-get install stunnel4
.pre

^ Create certificate

.pre
cd /etc/stunnel
openssl req -x509 -nodes -days 365 -newkey rsa:1024 -keyout https.pem -out https.pem
.pre

^ Configuration file

`/etc/stunnel/httpd.conf`

.pre
cert = /etc/stunnel/https.pem
sslVersion = SSLv3
debug = 7

[https]
accept  = 443
connect = 80
TIMEOUTclose = 0
.pre

^ Start tunnel

.pre
stunnel4 /etc/stunnel/https.conf
.pre
Here are some quick notes about my installation and configuration of munin.

First, I made a "local repository"<http://svn.rot13.org/index.cgi/munin-modules> to track my changes and imported upstream munin plugins into it.