<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://performiq.com/kb/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=PeterHarding</id>
	<title>PeformIQ Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://performiq.com/kb/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=PeterHarding"/>
	<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php/Special:Contributions/PeterHarding"/>
	<updated>2026-05-18T17:25:08Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.37.1</generator>
	<entry>
		<id>https://performiq.com/kb/index.php?title=Category:Firewalls&amp;diff=5530</id>
		<title>Category:Firewalls</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=Category:Firewalls&amp;diff=5530"/>
		<updated>2026-03-17T22:21:10Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: Created page with &amp;quot;Firewall links, route and references...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Firewall links, route and references...&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=3D_Imaging_Notes&amp;diff=5529</id>
		<title>3D Imaging Notes</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=3D_Imaging_Notes&amp;diff=5529"/>
		<updated>2026-03-02T10:40:59Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Links =&lt;br /&gt;
&lt;br /&gt;
* https://www.codeproject.com/Articles/1182854/D-Face-Viewer-and-Matcher&lt;br /&gt;
&lt;br /&gt;
[[Category:Imaging]]&lt;br /&gt;
[[Category:3D]]&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=Papers&amp;diff=5528</id>
		<title>Papers</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=Papers&amp;diff=5528"/>
		<updated>2026-03-02T10:37:12Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Back to [[Main Page]]&lt;br /&gt;
&lt;br /&gt;
= Significant Papers =&lt;br /&gt;
&lt;br /&gt;
[[Category:Papers]]&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=Papers&amp;diff=5527</id>
		<title>Papers</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=Papers&amp;diff=5527"/>
		<updated>2026-03-02T10:36:51Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Back to [[Index]]&lt;br /&gt;
&lt;br /&gt;
= Significant Papers =&lt;br /&gt;
&lt;br /&gt;
[[Category:Papers]]&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=Middleware&amp;diff=5526</id>
		<title>Middleware</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=Middleware&amp;diff=5526"/>
		<updated>2026-03-02T10:31:51Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Links =&lt;br /&gt;
&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Middleware Wikipedia entry on Middleware]&lt;br /&gt;
&lt;br /&gt;
[[Category:Middleware]]&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=Java&amp;diff=5525</id>
		<title>Java</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=Java&amp;diff=5525"/>
		<updated>2026-03-02T10:19:08Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Full Name ==&lt;br /&gt;
&lt;br /&gt;
Java&lt;br /&gt;
&lt;br /&gt;
== Information ==&lt;br /&gt;
&lt;br /&gt;
An [[object-oriented]] programming language for portable interpretive codes that supports interaction among remote objects. [[Javascript]] ([[JScript]] or [[JavaScript]]) . When [[Javascript]] is included in an [[HTML]] file it relies upon the browser to interpret the [[Javascript]]. If [[Javascript]] is combined with [[Cascading Style Sheets]] ([[CSS]]) and later versions of [[HTML]] (4.0 and later) the result is often called [[DHTML]].&lt;br /&gt;
&lt;br /&gt;
== Related Links ==&lt;br /&gt;
&lt;br /&gt;
* https://en.wikipedia.org/wiki/Java_%28programming_language%29&lt;br /&gt;
* [https://docs.oracle.com/en/java/ Java Documentation]&lt;br /&gt;
* [https://www.oracle.com/java/technologies/  Oracle Java web-site]&lt;br /&gt;
* [[Java Enterprise Edition]]&lt;br /&gt;
* [http://www.netbeans.org/ NetBeans IDE]&lt;br /&gt;
* [[Java Beans]]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Java_Class_Library Java Class Library]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Java_%28programming_language%29 Wikipedia entry on Java]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Java_Virtual_Machine JVM]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Java_Platform%2C_Enterprise_Edition JEE]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Special:Search?search=Java&amp;amp;fulltext=Search Java References on Wikipedia]&lt;br /&gt;
* [[Eclipse]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:TERMINOLOGY]]&lt;br /&gt;
[[Category:Internet]]&lt;br /&gt;
[[Category:SOFTWARE]]&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=Performance_Analysis&amp;diff=5524</id>
		<title>Performance Analysis</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=Performance_Analysis&amp;diff=5524"/>
		<updated>2026-03-02T10:01:58Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
&lt;br /&gt;
Check out [http://en.wikipedia.org/wiki/Neil_Gunther Dr Neil Gunther]&amp;#039;s site - [http://www.perfdynamics.com/ Peformance Dynamics]...&lt;br /&gt;
&lt;br /&gt;
Some interesting links:&lt;br /&gt;
&lt;br /&gt;
* https://www.perfdynamics.com/Manifesto/gcaprules.html&lt;br /&gt;
* https://www.perfdynamics.com/Manifesto/USLScalability.html&lt;br /&gt;
* https://queue.acm.org/detail.cfm?id=2789974 - Hadoop Superlinear Scalability&lt;br /&gt;
&lt;br /&gt;
= PDQ =&lt;br /&gt;
&lt;br /&gt;
[http://www.perfdynamics.com/Tools/PDQ.html Pretty Damn Quick - PDQ]&lt;br /&gt;
&lt;br /&gt;
[[Category:Performance]]&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=Scala&amp;diff=5523</id>
		<title>Scala</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=Scala&amp;diff=5523"/>
		<updated>2026-03-02T09:51:47Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Scala Notes =&lt;br /&gt;
&lt;br /&gt;
* https://en.wikipedia.org/wiki/Scala_(programming_language)&lt;br /&gt;
&lt;br /&gt;
= Use of &amp;#039;_&amp;#039; =&lt;br /&gt;
&lt;br /&gt;
From - https://stackoverflow.com/questions/8000903/what-are-all-the-uses-of-an-underscore-in-scala&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import scala._                   // Wild card -- all of Scala is imported&lt;br /&gt;
import scala.{ Predef =&amp;gt; _, _ }  // Exception, everything except Predef&lt;br /&gt;
def f[M[_]]                      // Higher kinded type parameter&lt;br /&gt;
def f(m: M[_])                   // Existential type&lt;br /&gt;
_ + _                            // Anonymous function placeholder parameter&lt;br /&gt;
m _                              // Eta expansion of method into method value&lt;br /&gt;
m(_)                             // Partial function application&lt;br /&gt;
_ =&amp;gt; 5                           // Discarded parameter&lt;br /&gt;
case _ =&amp;gt;                        // Wild card pattern -- matches anything&lt;br /&gt;
val (a, _) = (1, 2)              // same thing&lt;br /&gt;
for (_ &amp;lt;- 1 to 10)               // same thing&lt;br /&gt;
f(xs: _*)                        // Sequence xs is passed as multiple parameters to f(ys: T*)&lt;br /&gt;
case Seq(xs @ _*)                // Identifier xs is bound to the whole matched sequence&lt;br /&gt;
var i: Int = _                   // Initialization to the default value&lt;br /&gt;
def abc_&amp;lt;&amp;gt;!                      // An underscore must separate alphanumerics from symbols on identifiers&lt;br /&gt;
t._2                             // Part of a method name, such as tuple getters&lt;br /&gt;
1_000_000                        // Numeric literal separator (Scala 2.13+)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So...&lt;br /&gt;
&lt;br /&gt;
==Existential types==&lt;br /&gt;
 def foo(l: List[Option[_]]) = ...&lt;br /&gt;
==Higher kinded type parameters==&lt;br /&gt;
 case class A[K[_],T](a: K[T])&lt;br /&gt;
==Ignored variables==&lt;br /&gt;
 val _ = 5&lt;br /&gt;
==Ignored parameters==&lt;br /&gt;
 List(1, 2, 3) foreach { _ =&amp;gt; println(&amp;quot;Hi&amp;quot;) }&lt;br /&gt;
==Ignored names of self types==&lt;br /&gt;
 trait MySeq { _: Seq[_] =&amp;gt; }&lt;br /&gt;
==Wildcard patterns==&lt;br /&gt;
 Some(5) match { case Some(_) =&amp;gt; println(&amp;quot;Yes&amp;quot;) }&lt;br /&gt;
==Wildcard patterns in interpolations==&lt;br /&gt;
 &amp;quot;abc&amp;quot; match { case s&amp;quot;a$_c&amp;quot; =&amp;gt; }&lt;br /&gt;
==Sequence wildcard in patterns==&lt;br /&gt;
 C(1, 2, 3) match { case C(vs @ _*) =&amp;gt; vs.foreach(f(_)) }&lt;br /&gt;
==Wildcard imports==&lt;br /&gt;
 import java.util._&lt;br /&gt;
==Hiding imports==&lt;br /&gt;
 import java.util.{ArrayList =&amp;gt; _, _}&lt;br /&gt;
==Joining letters to operators==&lt;br /&gt;
 def bang_!(x: Int) = 5&lt;br /&gt;
==Assignment operators==&lt;br /&gt;
 def foo_=(x: Int) { ... }&lt;br /&gt;
==Placeholder syntax==&lt;br /&gt;
 List(1, 2, 3) map (_ + 2)&lt;br /&gt;
==Method values==&lt;br /&gt;
 List(1, 2, 3) foreach println _&lt;br /&gt;
==Converting call-by-name parameters to functions==&lt;br /&gt;
 def toFunction(callByName: =&amp;gt; Int): () =&amp;gt; Int = callByName _&lt;br /&gt;
==Default initializer==&lt;br /&gt;
 var x: String = _   // unloved syntax may be eliminated&lt;br /&gt;
&lt;br /&gt;
=Other=&lt;br /&gt;
&lt;br /&gt;
* https://alvinalexander.com/scala/how-to-use-scala-match-expression-like-switch-case-statement/&lt;br /&gt;
&lt;br /&gt;
=Match Expressions=&lt;br /&gt;
&lt;br /&gt;
* https://docs.scala-lang.org/overviews/scala-book/match-expressions.html&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def getClassAsString(x: Any): String = x match {&lt;br /&gt;
    case s: String =&amp;gt; s + &amp;quot; is a String&amp;quot;&lt;br /&gt;
    case i: Int =&amp;gt; &amp;quot;Int&amp;quot;&lt;br /&gt;
    case f: Float =&amp;gt; &amp;quot;Float&amp;quot;&lt;br /&gt;
    case l: List[_] =&amp;gt; &amp;quot;List&amp;quot;&lt;br /&gt;
    case p: Person =&amp;gt; &amp;quot;Person&amp;quot;&lt;br /&gt;
    case _ =&amp;gt; &amp;quot;Unknown&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def isTrue(a: Any) = a match {&lt;br /&gt;
    case 0 | &amp;quot;&amp;quot; =&amp;gt; false&lt;br /&gt;
    case _ =&amp;gt; true&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Version 1 - compiles to a tableswitch&lt;br /&gt;
import scala.annotation.switch&lt;br /&gt;
&lt;br /&gt;
class SwitchDemo {&lt;br /&gt;
    val i = 1&lt;br /&gt;
    val x = (i: @switch) match {&lt;br /&gt;
        case 1  =&amp;gt; &amp;quot;One&amp;quot;&lt;br /&gt;
        case 2  =&amp;gt; &amp;quot;Two&amp;quot;&lt;br /&gt;
        case _  =&amp;gt; &amp;quot;Other&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
expr match {&lt;br /&gt;
  case List(1,_,_) =&amp;gt; &amp;quot;A List with three elements&amp;quot;&lt;br /&gt;
  case List(_ *) =&amp;gt; &amp;quot;A List with zero or more elements&amp;quot;&lt;br /&gt;
  case Map(_,_) =&amp;gt; &amp;quot;A Map with any Key and Value type&amp;quot;&lt;br /&gt;
  case _ =&amp;gt; &amp;quot;Anythiong else&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Getters and Setters=&lt;br /&gt;
&lt;br /&gt;
According to the Scala docs:&lt;br /&gt;
&lt;br /&gt;
Scala does not follow the Java convention of prepending set/get to mutator and accessor methods (respectively). Instead, the following conventions are used:&lt;br /&gt;
&lt;br /&gt;
* For accessors of properties, the name of the method should be the name of the property.&lt;br /&gt;
* In some instances, it is acceptable to prepend “is” on a boolean accessor (e.g. isEmpty). This should only be the case when no corresponding mutator is provided.&lt;br /&gt;
* For mutators, the name of the method should be the name of the property with “_=” appended.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Foo {&lt;br /&gt;
  def bar = ...&lt;br /&gt;
  def bar_=(bar: Bar) {&lt;br /&gt;
    ...&lt;br /&gt;
  }&lt;br /&gt;
  def isBaz = ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
val nums = List(1,2,3,4,5,6,7,8,9)&lt;br /&gt;
&lt;br /&gt;
nums filter (_ % 2 == 0)&lt;br /&gt;
nums reduce (_ + _)&lt;br /&gt;
nums.exists (_ &amp;gt; 5)&lt;br /&gt;
nums.takeWhile(_ &amp;lt; 8)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As used in Swift for un-named or unused values:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def getProps = {&lt;br /&gt;
   Config.getHost, Config.getPort, Config.getIp, Config.getMask&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
val (host, port, ignore1, ignore2) = getProps&lt;br /&gt;
&lt;br /&gt;
val (host, port, _, _) = getProps&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Types=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
type StringMatcher = String =&amp;gt; (String =&amp;gt; Boolean)&lt;br /&gt;
&lt;br /&gt;
def starts: StringMatcher = (prefix:String) =&amp;gt; _ startsWith prefix&lt;br /&gt;
&lt;br /&gt;
...or...&lt;br /&gt;
&lt;br /&gt;
def starts: StringMatcher = (prefix:String) =&amp;gt; (s) =&amp;gt; s startsWith prefix&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Generating Random Strings=&lt;br /&gt;
&lt;br /&gt;
One liner:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Random.alphanumeric.take(10).mkString&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
From - https://alvinalexander.com/scala/creating-random-strings-in-scala/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import scala.annotation.tailrec&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Examples of different ways to write &amp;quot;random string&amp;quot; methods in Scala.&lt;br /&gt;
 * See the main method for examples of how each method is called.&lt;br /&gt;
 * Created by Alvin Alexander, https://alvinalexander.com&lt;br /&gt;
 */&lt;br /&gt;
object RandomStringExamples {&lt;br /&gt;
  &lt;br /&gt;
  def main(args: Array[String]) {&lt;br /&gt;
    println(&amp;quot;1:  &amp;quot; + randomString(10))&lt;br /&gt;
    println(&amp;quot;2:  &amp;quot; + randomStringArray(10))&lt;br /&gt;
    println(&amp;quot;3:  &amp;quot; + randomStringRecursive(10).mkString)&lt;br /&gt;
    println(&amp;quot;3:  &amp;quot; + randomStringRecursive2(10).mkString)&lt;br /&gt;
    println(&amp;quot;4:  &amp;quot; + randomStringTailRecursive(10, Nil).mkString)&lt;br /&gt;
    println(&amp;quot;5:  &amp;quot; + randomStringRecursive2Wrapper(10))&lt;br /&gt;
    println(&amp;quot;6:  &amp;quot; + randomAlphaNumericString(10))&lt;br /&gt;
    println(&amp;quot;6:  &amp;quot; + randomAlphaNumericString(10))&lt;br /&gt;
    println(&amp;quot;6:  &amp;quot; + randomAlphaNumericString(10))&lt;br /&gt;
    println(&amp;quot;x2: &amp;quot; + x2(10, (&amp;#039;a&amp;#039; to &amp;#039;z&amp;#039;) ++ (&amp;#039;A&amp;#039; to &amp;#039;Z&amp;#039;)))&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // 1 - a java-esque approach&lt;br /&gt;
  def randomString(length: Int) = {&lt;br /&gt;
    val r = new scala.util.Random&lt;br /&gt;
    val sb = new StringBuilder&lt;br /&gt;
    for (i &amp;lt;- 1 to length) {&lt;br /&gt;
      sb.append(r.nextPrintableChar)&lt;br /&gt;
    }&lt;br /&gt;
    sb.toString&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // 2 - similar to #1, but using an array&lt;br /&gt;
  def randomStringUsingArray(length: Int): String = {&lt;br /&gt;
    val r = new scala.util.Random&lt;br /&gt;
    val a = new Array[Char](length)&lt;br /&gt;
    val sb = new StringBuilder&lt;br /&gt;
    for (i &amp;lt;- 0 to length-1) {&lt;br /&gt;
      a(i) = r.nextPrintableChar&lt;br /&gt;
    }&lt;br /&gt;
    a.mkString&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // 3 - recursive, but not tail-recursive&lt;br /&gt;
  def randomStringRecursive(n: Int): List[Char] = {&lt;br /&gt;
    n match {&lt;br /&gt;
      case 1 =&amp;gt; List(util.Random.nextPrintableChar)&lt;br /&gt;
      case _ =&amp;gt; List(util.Random.nextPrintableChar) ++ randomStringRecursive(n-1)&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // 3b - recursive, but not tail-recursive&lt;br /&gt;
  def randomStringRecursive2(n: Int): String = {&lt;br /&gt;
    n match {&lt;br /&gt;
      case 1 =&amp;gt; util.Random.nextPrintableChar.toString&lt;br /&gt;
      case _ =&amp;gt; util.Random.nextPrintableChar.toString ++ randomStringRecursive2(n-1).toString&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // 4 - tail recursive, no wrapper&lt;br /&gt;
  @tailrec&lt;br /&gt;
  def randomStringTailRecursive(n: Int, list: List[Char]):List[Char] = {&lt;br /&gt;
    if (n == 1) util.Random.nextPrintableChar :: list&lt;br /&gt;
    else randomStringTailRecursive(n-1, util.Random.nextPrintableChar :: list)&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // 5 - a wrapper around the tail-recursive approach&lt;br /&gt;
  def randomStringRecursive2Wrapper(n: Int): String = {&lt;br /&gt;
    randomStringTailRecursive(n, Nil).mkString&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  // 6 - random alphanumeric&lt;br /&gt;
  def randomAlphaNumericString(length: Int): String = {&lt;br /&gt;
    val chars = (&amp;#039;a&amp;#039; to &amp;#039;z&amp;#039;) ++ (&amp;#039;A&amp;#039; to &amp;#039;Z&amp;#039;) ++ (&amp;#039;0&amp;#039; to &amp;#039;9&amp;#039;)&lt;br /&gt;
    randomStringFromCharList(length, chars)&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  // 7 - random alpha&lt;br /&gt;
  def randomAlpha(length: Int): String = {&lt;br /&gt;
    val chars = (&amp;#039;a&amp;#039; to &amp;#039;z&amp;#039;) ++ (&amp;#039;A&amp;#039; to &amp;#039;Z&amp;#039;)&lt;br /&gt;
    randomStringFromCharList(length, chars)&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // used by #6 and #7&lt;br /&gt;
  def randomStringFromCharList(length: Int, chars: Seq[Char]): String = {&lt;br /&gt;
    val sb = new StringBuilder&lt;br /&gt;
    for (i &amp;lt;- 1 to length) {&lt;br /&gt;
      val randomNum = util.Random.nextInt(chars.length)&lt;br /&gt;
      sb.append(chars(randomNum))&lt;br /&gt;
    }&lt;br /&gt;
    sb.toString&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  def x(length: Int, chars: Seq[Char]): String = {&lt;br /&gt;
    val list = List.range(1, length)&lt;br /&gt;
    val arr = new Array[Char](length)&lt;br /&gt;
    list.foreach{ e =&amp;gt; arr(e) = chars(util.Random.nextInt(chars.length)) }&lt;br /&gt;
    list.mkString&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  // create a fake list so i can use map (or flatMap)&lt;br /&gt;
  def x2(length: Int, chars: Seq[Char]): String = {&lt;br /&gt;
    val tmpList = List.range(0, length)&lt;br /&gt;
    val charList = tmpList.map{ e =&amp;gt; chars(util.Random.nextInt(chars.length)) }&lt;br /&gt;
    return charList.mkString&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Scala]]&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=MongoDB&amp;diff=5522</id>
		<title>MongoDB</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=MongoDB&amp;diff=5522"/>
		<updated>2026-03-02T09:48:53Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
&lt;br /&gt;
A NoSQL database which used JSON documents as its storage objects.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
&lt;br /&gt;
* https://en.wikipedia.org/wiki/MongoDB&lt;br /&gt;
* https://www.mongodb.com/&lt;br /&gt;
* https://docs.mongodb.com/manual/tutorial/install-mongodb-on-debian/&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
= Use with Python =&lt;br /&gt;
&lt;br /&gt;
* https://stackoverflow.com/questions/9447629/mongokit-vs-mongoengine-vs-flask-mongoalchemy-for-flask&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
[[Category:MongoDB]]&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=Angular&amp;diff=5521</id>
		<title>Angular</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=Angular&amp;diff=5521"/>
		<updated>2026-03-02T09:41:42Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Setting up a new CLI Project =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ng new project-name&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
cd project-name&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Angular]]&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=React&amp;diff=5520</id>
		<title>React</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=React&amp;diff=5520"/>
		<updated>2026-03-02T09:40:34Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
&lt;br /&gt;
* https://en.wikipedia.org/wiki/React_(JavaScript_library)&lt;br /&gt;
* https://reactjs.org/&lt;br /&gt;
* https://github.com/facebook/react&lt;br /&gt;
* https://github.com/ReactTraining/react-router/tree/dev/docs&lt;br /&gt;
* &lt;br /&gt;
* xxx&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:React]]&lt;br /&gt;
[[Category:SPA]]&lt;br /&gt;
[[Category:Web]]&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=Kafka&amp;diff=5519</id>
		<title>Kafka</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=Kafka&amp;diff=5519"/>
		<updated>2026-03-02T09:37:56Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
&lt;br /&gt;
Apache Kafka is an implementation  of a distributed event streaming platform.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
&lt;br /&gt;
* https://kafka.apache.org/&lt;br /&gt;
* https://kafka-tutorials.confluent.io/&lt;br /&gt;
* https://kafka.apache.org/quickstart&lt;br /&gt;
* https://docs.confluent.io/platform/current/overview.html&lt;br /&gt;
* &lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
= Using with Docker =&lt;br /&gt;
&lt;br /&gt;
* https://docs.confluent.io/platform/current/quickstart/ce-docker-quickstart.html&lt;br /&gt;
* &lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Kafka]]&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=Kafka&amp;diff=5518</id>
		<title>Kafka</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=Kafka&amp;diff=5518"/>
		<updated>2026-03-02T09:37:45Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overvie w=&lt;br /&gt;
&lt;br /&gt;
Apache Kafka is an implementation  of a distributed event streaming platform.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
&lt;br /&gt;
* https://kafka.apache.org/&lt;br /&gt;
* https://kafka-tutorials.confluent.io/&lt;br /&gt;
* https://kafka.apache.org/quickstart&lt;br /&gt;
* https://docs.confluent.io/platform/current/overview.html&lt;br /&gt;
* &lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
= Using with Docker =&lt;br /&gt;
&lt;br /&gt;
* https://docs.confluent.io/platform/current/quickstart/ce-docker-quickstart.html&lt;br /&gt;
* &lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Kafka]]&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=3D_Imaging_Notes&amp;diff=5517</id>
		<title>3D Imaging Notes</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=3D_Imaging_Notes&amp;diff=5517"/>
		<updated>2026-02-27T23:03:28Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Links =&lt;br /&gt;
&lt;br /&gt;
* https://www.codeproject.com/Articles/1182854/D-Face-Viewer-and-Matcher&lt;br /&gt;
&lt;br /&gt;
[[Category:Imaging]]&lt;br /&gt;
[[Category:3D]]&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=Markup_Notes&amp;diff=5516</id>
		<title>Markup Notes</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=Markup_Notes&amp;diff=5516"/>
		<updated>2026-02-25T23:02:39Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Forms of Documentation Markup = &lt;br /&gt;
&lt;br /&gt;
In the past, many solutions have evolved to facilitate the easy creation of documents and documentation. These range from lightweight human-readable formats like Markdown, to highly capable typesetting systems like TeX/LaTeX, to structured data formats like XML. The choice of markup language typically reflects a trade-off between ease of authoring, rendering fidelity, and the intended output medium.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Historical Background ==&lt;br /&gt;
&lt;br /&gt;
The concept of &amp;quot;markup&amp;quot; predates computers — editors and typesetters would literally mark up manuscripts with instructions for printers. With the arrival of electronic publishing in the 1960s and 70s, these conventions were formalised into machine-readable languages. Early systems were tightly coupled to specific hardware (typesetters, printers, terminals), and over time higher-level, more portable formats emerged.&lt;br /&gt;
&lt;br /&gt;
== Markup Languages and Formats ==&lt;br /&gt;
&lt;br /&gt;
=== Runoff / Roff Family (1964 onwards) ===&lt;br /&gt;
&lt;br /&gt;
The roff family traces its roots to the &amp;lt;code&amp;gt;RUNOFF&amp;lt;/code&amp;gt; program written by Jerome Saltzer at MIT in 1964. It was the dominant document formatting system on early UNIX systems.&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;nroff&amp;#039;&amp;#039;&amp;#039; — formats text for fixed-width terminal output&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;troff&amp;#039;&amp;#039;&amp;#039; — the typesetting variant, targeting phototypesetting devices&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;groff&amp;#039;&amp;#039;&amp;#039; (GNU roff) — the modern open source successor, still widely used today for Unix man pages&lt;br /&gt;
&lt;br /&gt;
Roff documents use dot-prefixed commands (e.g. &amp;lt;code&amp;gt;.PP&amp;lt;/code&amp;gt; for paragraph, &amp;lt;code&amp;gt;.B&amp;lt;/code&amp;gt; for bold) and remain the standard format for Linux/Unix manual pages.&lt;br /&gt;
&lt;br /&gt;
=== SGML — Standard Generalised Markup Language (1986) ===&lt;br /&gt;
&lt;br /&gt;
SGML is a meta-language for defining markup languages, standardised as ISO 8879:1986. It introduced the concept of separating document structure from presentation, and was the parent of both HTML and XML. Its complexity limited widespread adoption outside publishing and aerospace/defence industries, but its influence is enormous.&lt;br /&gt;
&lt;br /&gt;
=== TeX and LaTeX (1978 / 1984) ===&lt;br /&gt;
&lt;br /&gt;
Created by Donald Knuth, &amp;#039;&amp;#039;&amp;#039;TeX&amp;#039;&amp;#039;&amp;#039; is a typesetting system renowned for its precise, beautiful rendering of mathematical and scientific notation. &amp;#039;&amp;#039;&amp;#039;LaTeX&amp;#039;&amp;#039;&amp;#039;, built on top of TeX by Leslie Lamport, added higher-level macros that made document authoring far more approachable. LaTeX remains the dominant format for academic papers, theses, and scientific publishing worldwide. Documents use commands such as &amp;lt;code&amp;gt;\section{}&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;\textbf{}&amp;lt;/code&amp;gt;, and the &amp;lt;code&amp;gt;equation&amp;lt;/code&amp;gt; environment.&lt;br /&gt;
&lt;br /&gt;
=== RTF — Rich Text Format (1987) ===&lt;br /&gt;
&lt;br /&gt;
Developed by Microsoft for cross-application and cross-platform document exchange. RTF encodes formatting as plain-text control words (e.g. &amp;lt;code&amp;gt;\b&amp;lt;/code&amp;gt; for bold), making it human-readable in theory but verbose in practice. It was the default format for WordPad and early versions of Word, and served as a common interchange format before the dominance of OOXML and PDF.&lt;br /&gt;
&lt;br /&gt;
=== HTML — HyperText Markup Language (1991) ===&lt;br /&gt;
&lt;br /&gt;
Proposed by Tim Berners-Lee at CERN, HTML is an SGML-derived language that became the lingua franca of the World Wide Web. It separates document structure (tags like &amp;lt;code&amp;gt;&amp;amp;lt;h1&amp;amp;gt;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;amp;lt;p&amp;amp;gt;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;amp;lt;a&amp;amp;gt;&amp;lt;/code&amp;gt;) from presentation (originally handled inline, later delegated to CSS). HTML5 (2014) significantly expanded its capabilities to include multimedia, semantic elements, and application-level features.&lt;br /&gt;
&lt;br /&gt;
=== DocBook (1991) ===&lt;br /&gt;
&lt;br /&gt;
An XML/SGML-based markup language originally developed by HaL Computer Systems and O&amp;#039;Reilly. DocBook is specifically designed for technical documentation and supports rich semantic tagging (&amp;lt;code&amp;gt;&amp;amp;lt;procedure&amp;amp;gt;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;amp;lt;varlistentry&amp;amp;gt;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;amp;lt;programlisting&amp;amp;gt;&amp;lt;/code&amp;gt;, etc.). It can be transformed to HTML, PDF, man pages and other formats via XSLT stylesheets. Widely used in open source projects and technical publishing.&lt;br /&gt;
&lt;br /&gt;
=== XML — eXtensible Markup Language (1998) ===&lt;br /&gt;
&lt;br /&gt;
A simplified subset of SGML designed for general-purpose structured data. While not a document format per se, XML underpins many documentation formats (DocBook, OOXML, DITA). Its strict well-formedness rules and wide tooling support made it a foundational technology for data interchange in the 2000s, though JSON has displaced it for many API use cases.&lt;br /&gt;
&lt;br /&gt;
=== reStructuredText / RST (2002) ===&lt;br /&gt;
&lt;br /&gt;
Developed by David Goodger as part of the Python &amp;lt;code&amp;gt;docutils&amp;lt;/code&amp;gt; project. RST is a lightweight markup language designed to be readable as plain text while being processable into HTML, LaTeX, PDF, and man pages. It is the native format of Python&amp;#039;s official documentation and the Sphinx documentation generator, making it extremely prevalent in the Python ecosystem.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Example RST:&lt;br /&gt;
Section Title&lt;br /&gt;
=============&lt;br /&gt;
Some **bold** text and a `hyperlink &amp;lt;http://example.com&amp;gt;`_.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== AsciiDoc (2002) and Asciidoctor (2013) ===&lt;br /&gt;
&lt;br /&gt;
AsciiDoc fills a niche between Markdown&amp;#039;s simplicity and DocBook&amp;#039;s power. It was designed for writing books and technical documentation, supporting features like cross-references, includes, callouts, and multiple output formats natively. &amp;#039;&amp;#039;&amp;#039;Asciidoctor&amp;#039;&amp;#039;&amp;#039;, a Ruby reimplementation, significantly revitalised the ecosystem. It is used by the Git project, Spring Framework, and many others for their documentation.&lt;br /&gt;
&lt;br /&gt;
=== Markdown (2004) ===&lt;br /&gt;
&lt;br /&gt;
Created by John Gruber (with input from Aaron Swartz), Markdown was explicitly designed to be readable as-is in plain-text form, with its syntax inspired by email conventions. It converts to HTML and is now the de facto standard for README files, static site generators, wikis, and developer documentation. Its simplicity came at the cost of standardisation — numerous dialects emerged (GitHub Flavored Markdown, CommonMark, MultiMarkdown) with incompatible extensions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Example Markdown:&lt;br /&gt;
## Section Title&lt;br /&gt;
Some **bold** text and a [hyperlink](http://example.com).&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Wiki Markup ===&lt;br /&gt;
&lt;br /&gt;
Most wiki platforms developed their own lightweight markup languages before Markdown became dominant. Examples include:&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;MediaWiki markup&amp;#039;&amp;#039;&amp;#039; — used by Wikipedia; uses &amp;lt;code&amp;gt;&amp;#039;&amp;#039;italic&amp;#039;&amp;#039;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;#039;&amp;#039;&amp;#039;bold&amp;#039;&amp;#039;&amp;#039;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;== headings ==&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;TWiki / Foswiki markup&amp;#039;&amp;#039;&amp;#039; — uses &amp;lt;code&amp;gt;---+&amp;lt;/code&amp;gt; headings, &amp;lt;code&amp;gt;*bold*&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;_italic_&amp;lt;/code&amp;gt;, and TML (Topic Markup Language) for structured data&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Confluence wiki markup&amp;#039;&amp;#039;&amp;#039; — Atlassian&amp;#039;s proprietary variant&lt;br /&gt;
&lt;br /&gt;
=== Org-mode (2003) ===&lt;br /&gt;
&lt;br /&gt;
An outlining and plain-text markup system embedded within the Emacs text editor, created by Carsten Dominik. Org-mode is exceptionally powerful for note-taking, project planning, literate programming, and publishing. It can export to HTML, LaTeX, PDF, ODT and many other formats, and its &amp;lt;code&amp;gt;babel&amp;lt;/code&amp;gt; feature allows executable code blocks in dozens of languages.&lt;br /&gt;
&lt;br /&gt;
=== CommonMark and Pandoc ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;CommonMark&amp;#039;&amp;#039;&amp;#039; (2014) was an effort to produce a rigorous, unambiguous specification for Markdown to resolve the fragmentation of dialects. &amp;#039;&amp;#039;&amp;#039;Pandoc&amp;#039;&amp;#039;&amp;#039;, created by John MacFarlane, is a universal document converter supporting dozens of input and output formats, and has become an essential tool for anyone working across multiple markup ecosystems.&lt;br /&gt;
&lt;br /&gt;
== Summary Comparison ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Format !! Created !! Primary Use !! Output Targets !! Complexity&lt;br /&gt;
|-&lt;br /&gt;
| Roff/groff || 1964+ || Man pages, UNIX docs || Terminal, PostScript || Medium&lt;br /&gt;
|-&lt;br /&gt;
| TeX/LaTeX || 1978/1984 || Academic &amp;amp; scientific publishing || PDF, DVI || High&lt;br /&gt;
|-&lt;br /&gt;
| SGML || 1986 || Meta-language, publishing || Varies || Very High&lt;br /&gt;
|-&lt;br /&gt;
| RTF || 1987 || Word processing interchange || Print, screen || Medium&lt;br /&gt;
|-&lt;br /&gt;
| HTML || 1991 || Web pages || Browser || Low–Medium&lt;br /&gt;
|-&lt;br /&gt;
| DocBook || 1991 || Technical documentation || HTML, PDF, man || High&lt;br /&gt;
|-&lt;br /&gt;
| XML || 1998 || Structured data &amp;amp; documents || Varies || Medium&lt;br /&gt;
|-&lt;br /&gt;
| RST || 2002 || Python/developer docs || HTML, PDF, man || Medium&lt;br /&gt;
|-&lt;br /&gt;
| AsciiDoc || 2002 || Technical books &amp;amp; docs || HTML, PDF, ePub || Medium&lt;br /&gt;
|-&lt;br /&gt;
| Org-mode || 2003 || Notes, literate programming || HTML, PDF, ODT || Medium–High&lt;br /&gt;
|-&lt;br /&gt;
| Markdown || 2004 || READMEs, wikis, web || HTML || Low&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[Markdown Syntax|Markdown Syntax Reference]]&lt;br /&gt;
* [https://pandoc.org Pandoc — Universal Document Converter]&lt;br /&gt;
* [https://commonmark.org CommonMark Specification]&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Help:Formatting MediaWiki Formatting Help]&lt;br /&gt;
&lt;br /&gt;
[[Category:Languages]]&lt;br /&gt;
[[Category:Documentation]]&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=Markup_Notes&amp;diff=5515</id>
		<title>Markup Notes</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=Markup_Notes&amp;diff=5515"/>
		<updated>2026-02-25T22:58:57Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: Created page with &amp;quot;= Forms of Documentation Markup =   In the past, many solutions have evolved to facilitate the easy creation of documents and documentation. These range from lightweight human-readable formats like Markdown, to highly capable typesetting systems like TeX/LaTeX, to structured data formats like XML. The choice of markup language typically reflects a trade-off between ease of authoring, rendering fidelity, and the intended output medium.  ---++ Historical Background  The co...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Forms of Documentation Markup = &lt;br /&gt;
&lt;br /&gt;
In the past, many solutions have evolved to facilitate the easy creation of documents and documentation. These range from lightweight human-readable formats like Markdown, to highly capable typesetting systems like TeX/LaTeX, to structured data formats like XML. The choice of markup language typically reflects a trade-off between ease of authoring, rendering fidelity, and the intended output medium.&lt;br /&gt;
&lt;br /&gt;
---++ Historical Background&lt;br /&gt;
&lt;br /&gt;
The concept of &amp;quot;markup&amp;quot; predates computers — editors and typesetters would literally mark up manuscripts with instructions for printers. With the arrival of electronic publishing in the 1960s and 70s, these conventions were formalised into machine-readable languages. Early systems were tightly coupled to specific hardware (typesetters, printers, terminals), and over time higher-level, more portable formats emerged.&lt;br /&gt;
&lt;br /&gt;
---++ Markup Languages and Formats&lt;br /&gt;
&lt;br /&gt;
---+++ Runoff / Roff Family (1964 onwards)&lt;br /&gt;
The roff family traces its roots to the =RUNOFF= program written by Jerome Saltzer at MIT in 1964. It was the dominant document formatting system on early UNIX systems.&lt;br /&gt;
   * *nroff* — formats text for fixed-width terminal output&lt;br /&gt;
   * *troff* — the typesetting variant, targeting phototypesetting devices&lt;br /&gt;
   * *groff* (GNU roff) — the modern open source successor, still widely used today for Unix man pages&lt;br /&gt;
&lt;br /&gt;
Roff documents use dot-prefixed commands (e.g. =.PP= for paragraph, =.B= for bold) and remain the standard format for Linux/Unix manual pages.&lt;br /&gt;
&lt;br /&gt;
---+++ SGML — Standard Generalised Markup Language (1986)&lt;br /&gt;
SGML is a meta-language for defining markup languages, standardised as ISO 8879:1986. It introduced the concept of separating document structure from presentation, and was the parent of both HTML and XML. Its complexity limited widespread adoption outside publishing and aerospace/defence industries, but its influence is enormous.&lt;br /&gt;
&lt;br /&gt;
---+++ TeX and LaTeX (1978 / 1984)&lt;br /&gt;
Created by Donald Knuth, *TeX* is a typesetting system renowned for its precise, beautiful rendering of mathematical and scientific notation. *LaTeX*, built on top of TeX by Leslie Lamport, added higher-level macros that made document authoring far more approachable. LaTeX remains the dominant format for academic papers, theses, and scientific publishing worldwide. Documents use commands such as =\section{}=, =\textbf{}=, and the =equation= environment.&lt;br /&gt;
&lt;br /&gt;
---+++ RTF — Rich Text Format (1987)&lt;br /&gt;
Developed by Microsoft for cross-application and cross-platform document exchange. RTF encodes formatting as plain-text control words (e.g. =\b= for bold), making it human-readable in theory but verbose in practice. It was the default format for WordPad and early versions of Word, and served as a common interchange format before the dominance of OOXML and PDF.&lt;br /&gt;
&lt;br /&gt;
---+++ HTML — HyperText Markup Language (1991)&lt;br /&gt;
Proposed by Tim Berners-Lee at CERN, HTML is an SGML-derived language that became the lingua franca of the World Wide Web. It separates document structure (tags like =&amp;lt;h1&amp;gt;=, =&amp;lt;p&amp;gt;=, =&amp;lt;a&amp;gt;=) from presentation (originally handled inline, later delegated to CSS). HTML5 (2014) significantly expanded its capabilities to include multimedia, semantic elements, and application-level features.&lt;br /&gt;
&lt;br /&gt;
---+++ DocBook (1991)&lt;br /&gt;
An XML/SGML-based markup language originally developed by HaL Computer Systems and O&amp;#039;Reilly. DocBook is specifically designed for technical documentation and supports rich semantic tagging (=&amp;lt;procedure&amp;gt;=, =&amp;lt;varlistentry&amp;gt;=, =&amp;lt;programlisting&amp;gt;=, etc.). It can be transformed to HTML, PDF, man pages and other formats via XSLT stylesheets. Widely used in open source projects and technical publishing.&lt;br /&gt;
&lt;br /&gt;
---+++ XML — eXtensible Markup Language (1998)&lt;br /&gt;
A simplified subset of SGML designed for general-purpose structured data. While not a document format per se, XML underpins many documentation formats (DocBook, OOXML, DITA). Its strict well-formedness rules and wide tooling support made it a foundational technology for data interchange in the 2000s, though JSON has displaced it for many API use cases.&lt;br /&gt;
&lt;br /&gt;
---+++ reStructuredText / RST (2002)&lt;br /&gt;
Developed by David Goodger as part of the Python =docutils= project. RST is a lightweight markup language designed to be readable as plain text while being processable into HTML, LaTeX, PDF, and man pages. It is the native format of Python&amp;#039;s official documentation and the Sphinx documentation generator, making it extremely prevalent in the Python ecosystem.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;verbatim&amp;gt;&lt;br /&gt;
Example RST:&lt;br /&gt;
Section Title&lt;br /&gt;
=============&lt;br /&gt;
Some **bold** text and a `hyperlink &amp;lt;http://example.com&amp;gt;`_.&lt;br /&gt;
&amp;lt;/verbatim&amp;gt;&lt;br /&gt;
&lt;br /&gt;
---+++ Markdown (2004)&lt;br /&gt;
Created by John Gruber (with input from Aaron Swartz), Markdown was explicitly designed to be readable as-is in plain-text form, with its syntax inspired by email conventions. It converts to HTML and is now the de facto standard for README files, static site generators, wikis, and developer documentation. Its simplicity came at the cost of standardisation — numerous dialects emerged (GitHub Flavored Markdown, CommonMark, MultiMarkdown) with incompatible extensions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;verbatim&amp;gt;&lt;br /&gt;
Example Markdown:&lt;br /&gt;
## Section Title&lt;br /&gt;
Some **bold** text and a [hyperlink](http://example.com).&lt;br /&gt;
&amp;lt;/verbatim&amp;gt;&lt;br /&gt;
&lt;br /&gt;
---+++ AsciiDoc (2002) and Asciidoctor (2013)&lt;br /&gt;
AsciiDoc fills a niche between Markdown&amp;#039;s simplicity and DocBook&amp;#039;s power. It was designed for writing books and technical documentation, supporting features like cross-references, includes, callouts, and multiple output formats natively. *Asciidoctor*, a Ruby reimplementation, significantly revitalised the ecosystem. It is used by the Git project, Spring Framework, and many others for their documentation.&lt;br /&gt;
&lt;br /&gt;
---+++ Wiki Markup&lt;br /&gt;
Most wiki platforms developed their own lightweight markup languages before Markdown became dominant. Examples include:&lt;br /&gt;
   * *MediaWiki markup* — used by Wikipedia; uses =&amp;#039;&amp;#039;italic&amp;#039;&amp;#039;=, =&amp;#039;&amp;#039;&amp;#039;bold&amp;#039;&amp;#039;&amp;#039;=, ===headings===&lt;br /&gt;
   * *TWiki / Foswiki markup* — uses ==---+= headings, =*bold*=, =_italic_=, and TML (Topic Markup Language) for structured data&lt;br /&gt;
   * *Confluence wiki markup* — Atlassian&amp;#039;s proprietary variant&lt;br /&gt;
&lt;br /&gt;
---+++ Org-mode (2003)&lt;br /&gt;
An outlining and plain-text markup system embedded within the Emacs text editor, created by Carsten Dominik. Org-mode is exceptionally powerful for note-taking, project planning, literate programming, and publishing. It can export to HTML, LaTeX, PDF, ODT and many other formats, and its =babel= feature allows executable code blocks in dozens of languages.&lt;br /&gt;
&lt;br /&gt;
---+++ CommonMark and Pandoc&lt;br /&gt;
*CommonMark* (2014) was an effort to produce a rigorous, unambiguous specification for Markdown to resolve the fragmentation of dialects. *Pandoc*, created by John MacFarlane, is a universal document converter supporting dozens of input and output formats, and has become an essential tool for anyone working across multiple markup ecosystems.&lt;br /&gt;
&lt;br /&gt;
---++ Summary Comparison&lt;br /&gt;
&lt;br /&gt;
| *Format* | *Created* | *Primary Use* | *Output Targets* | *Complexity* |&lt;br /&gt;
| Roff/groff | 1964+ | Man pages, UNIX docs | Terminal, PostScript | Medium |&lt;br /&gt;
| TeX/LaTeX | 1978/1984 | Academic &amp;amp; scientific publishing | PDF, DVI | High |&lt;br /&gt;
| SGML | 1986 | Meta-language, publishing | Varies | Very High |&lt;br /&gt;
| RTF | 1987 | Word processing interchange | Print, screen | Medium |&lt;br /&gt;
| HTML | 1991 | Web pages | Browser | Low–Medium |&lt;br /&gt;
| DocBook | 1991 | Technical documentation | HTML, PDF, man | High |&lt;br /&gt;
| XML | 1998 | Structured data &amp;amp; documents | Varies | Medium |&lt;br /&gt;
| RST | 2002 | Python/developer docs | HTML, PDF, man | Medium |&lt;br /&gt;
| AsciiDoc | 2002 | Technical books &amp;amp; docs | HTML, PDF, ePub | Medium |&lt;br /&gt;
| Markdown | 2004 | READMEs, wikis, web | HTML | Low |&lt;br /&gt;
| Org-mode | 2003 | Notes, literate programming | HTML, PDF, ODT | Medium–High |&lt;br /&gt;
&lt;br /&gt;
---++ See Also&lt;br /&gt;
   * [[MarkdownSyntax][Markdown Syntax Reference]]&lt;br /&gt;
   * [[WikiSyntax][Foswiki Markup Reference]]&lt;br /&gt;
   * [[https://pandoc.org][Pandoc — Universal Document Converter]]&lt;br /&gt;
   * [[https://commonmark.org][CommonMark Specification]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Languages]]&lt;br /&gt;
[[Category:Documentation]]&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=Foswiki_Notes&amp;diff=5514</id>
		<title>Foswiki Notes</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=Foswiki_Notes&amp;diff=5514"/>
		<updated>2026-01-31T21:11:28Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview = &lt;br /&gt;
&lt;br /&gt;
* https://foswiki.org/Home/WebHome&lt;br /&gt;
* https://en.wikipedia.org/wiki/Foswiki&lt;br /&gt;
* https://foswiki.web.cern.ch/&lt;br /&gt;
* https://www.wikimatrix.org/show/Foswiki&lt;br /&gt;
* https://collab.phys.unsw.edu.au:4431/bin/view/System/TwentyMinuteTutorial&lt;br /&gt;
* &lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
= Summary = &lt;br /&gt;
&lt;br /&gt;
Foswiki is a fork of TWiki that was created in 2008.&lt;br /&gt;
&lt;br /&gt;
The split happened due to disagreements within the TWiki community about governance and development direction. A significant portion of TWiki&amp;#039;s core development team and community members decided to fork the project, creating Foswiki as a separate open-source wiki platform.&lt;br /&gt;
&lt;br /&gt;
The key connection is that Foswiki started from the same TWiki codebase, so they share:&lt;br /&gt;
&lt;br /&gt;
* Similar architecture and Perl-based implementation&lt;br /&gt;
* Compatible data structures and file formats (at least initially)&lt;br /&gt;
* Similar markup syntax and features&lt;br /&gt;
* Many of the same concepts (webs, topics, plugins, etc.)&lt;br /&gt;
&lt;br /&gt;
After the fork, both projects continued independent development. Foswiki was positioned as having a more community-driven governance model, while TWiki continued under its existing leadership.&lt;br /&gt;
&lt;br /&gt;
= FosWiki Docker =&lt;br /&gt;
&lt;br /&gt;
* https://hub.docker.com/r/timlegge/docker-foswiki&lt;br /&gt;
* https://foswiki.org/Blog/UpdatingDockerFoswikiTo217&lt;br /&gt;
* &lt;br /&gt;
* &lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Wiki]]&lt;br /&gt;
[[Category:TWiki]]&lt;br /&gt;
[[Category:Foswiki]]&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=Category:Foswiki&amp;diff=5513</id>
		<title>Category:Foswiki</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=Category:Foswiki&amp;diff=5513"/>
		<updated>2026-01-30T07:21:20Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: Created page with &amp;quot;Foswiki links, notes and references...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Foswiki links, notes and references...&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=Foswiki_Notes&amp;diff=5512</id>
		<title>Foswiki Notes</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=Foswiki_Notes&amp;diff=5512"/>
		<updated>2026-01-30T07:21:06Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: /* FosWiki Docker */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview = &lt;br /&gt;
&lt;br /&gt;
* https://foswiki.org/Home/WebHome&lt;br /&gt;
* https://en.wikipedia.org/wiki/Foswiki&lt;br /&gt;
* https://foswiki.web.cern.ch/&lt;br /&gt;
* https://www.wikimatrix.org/show/Foswiki&lt;br /&gt;
* https://collab.phys.unsw.edu.au:4431/bin/view/System/TwentyMinuteTutorial&lt;br /&gt;
* &lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
= Summary = &lt;br /&gt;
&lt;br /&gt;
Foswiki is a fork of TWiki that was created in 2008.&lt;br /&gt;
&lt;br /&gt;
The split happened due to disagreements within the TWiki community about governance and development direction. A significant portion of TWiki&amp;#039;s core development team and community members decided to fork the project, creating Foswiki as a separate open-source wiki platform.&lt;br /&gt;
&lt;br /&gt;
The key connection is that Foswiki started from the same TWiki codebase, so they share:&lt;br /&gt;
&lt;br /&gt;
* Similar architecture and Perl-based implementation&lt;br /&gt;
* Compatible data structures and file formats (at least initially)&lt;br /&gt;
* Similar markup syntax and features&lt;br /&gt;
* Many of the same concepts (webs, topics, plugins, etc.)&lt;br /&gt;
&lt;br /&gt;
After the fork, both projects continued independent development. Foswiki was positioned as having a more community-driven governance model, while TWiki continued under its existing leadership.&lt;br /&gt;
&lt;br /&gt;
= FosWiki Docker =&lt;br /&gt;
&lt;br /&gt;
* https://hub.docker.com/r/timlegge/docker-foswiki&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Wiki]]&lt;br /&gt;
[[Category:TWiki]]&lt;br /&gt;
[[Category:Foswiki]]&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=Category:FosWiki&amp;diff=5511</id>
		<title>Category:FosWiki</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=Category:FosWiki&amp;diff=5511"/>
		<updated>2026-01-30T07:20:52Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: Created page with &amp;quot;Foswiki links, notes and references...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Foswiki links, notes and references...&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=Category:TWiki&amp;diff=5510</id>
		<title>Category:TWiki</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=Category:TWiki&amp;diff=5510"/>
		<updated>2026-01-30T07:20:29Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: Created page with &amp;quot;TWiki links, notes and references...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;TWiki links, notes and references...&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=Foswiki_Notes&amp;diff=5509</id>
		<title>Foswiki Notes</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=Foswiki_Notes&amp;diff=5509"/>
		<updated>2026-01-30T07:20:12Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview = &lt;br /&gt;
&lt;br /&gt;
* https://foswiki.org/Home/WebHome&lt;br /&gt;
* https://en.wikipedia.org/wiki/Foswiki&lt;br /&gt;
* https://foswiki.web.cern.ch/&lt;br /&gt;
* https://www.wikimatrix.org/show/Foswiki&lt;br /&gt;
* https://collab.phys.unsw.edu.au:4431/bin/view/System/TwentyMinuteTutorial&lt;br /&gt;
* &lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
= Summary = &lt;br /&gt;
&lt;br /&gt;
Foswiki is a fork of TWiki that was created in 2008.&lt;br /&gt;
&lt;br /&gt;
The split happened due to disagreements within the TWiki community about governance and development direction. A significant portion of TWiki&amp;#039;s core development team and community members decided to fork the project, creating Foswiki as a separate open-source wiki platform.&lt;br /&gt;
&lt;br /&gt;
The key connection is that Foswiki started from the same TWiki codebase, so they share:&lt;br /&gt;
&lt;br /&gt;
* Similar architecture and Perl-based implementation&lt;br /&gt;
* Compatible data structures and file formats (at least initially)&lt;br /&gt;
* Similar markup syntax and features&lt;br /&gt;
* Many of the same concepts (webs, topics, plugins, etc.)&lt;br /&gt;
&lt;br /&gt;
After the fork, both projects continued independent development. Foswiki was positioned as having a more community-driven governance model, while TWiki continued under its existing leadership.&lt;br /&gt;
&lt;br /&gt;
= FosWiki Docker =&lt;br /&gt;
&lt;br /&gt;
* https://hub.docker.com/r/timlegge/docker-foswiki&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Wiki]]&lt;br /&gt;
[[Category:TWiki]]&lt;br /&gt;
[[Category:FosWiki]]&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=Foswiki_Notes&amp;diff=5508</id>
		<title>Foswiki Notes</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=Foswiki_Notes&amp;diff=5508"/>
		<updated>2026-01-30T07:19:07Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview = &lt;br /&gt;
&lt;br /&gt;
* https://foswiki.org/Home/WebHome&lt;br /&gt;
* https://en.wikipedia.org/wiki/Foswiki&lt;br /&gt;
* https://foswiki.web.cern.ch/&lt;br /&gt;
* https://www.wikimatrix.org/show/Foswiki&lt;br /&gt;
* https://collab.phys.unsw.edu.au:4431/bin/view/System/TwentyMinuteTutorial&lt;br /&gt;
* &lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
= Summary = &lt;br /&gt;
&lt;br /&gt;
Foswiki is a fork of TWiki that was created in 2008.&lt;br /&gt;
&lt;br /&gt;
The split happened due to disagreements within the TWiki community about governance and development direction. A significant portion of TWiki&amp;#039;s core development team and community members decided to fork the project, creating Foswiki as a separate open-source wiki platform.&lt;br /&gt;
&lt;br /&gt;
The key connection is that Foswiki started from the same TWiki codebase, so they share:&lt;br /&gt;
&lt;br /&gt;
        Similar architecture and Perl-based implementation&lt;br /&gt;
        Compatible data structures and file formats (at least initially)&lt;br /&gt;
        Similar markup syntax and features&lt;br /&gt;
        Many of the same concepts (webs, topics, plugins, etc.)&lt;br /&gt;
&lt;br /&gt;
After the fork, both projects continued independent development. Foswiki was positioned as having a more community-driven governance model, while TWiki continued under its existing leadership.&lt;br /&gt;
&lt;br /&gt;
= FosWiki Docker =&lt;br /&gt;
&lt;br /&gt;
* https://hub.docker.com/r/timlegge/docker-foswiki&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Wiki]]&lt;br /&gt;
[[Category:TWiki]]&lt;br /&gt;
[[Category:FosWiki]]&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=Foswiki_Notes&amp;diff=5507</id>
		<title>Foswiki Notes</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=Foswiki_Notes&amp;diff=5507"/>
		<updated>2026-01-30T07:18:43Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview = &lt;br /&gt;
&lt;br /&gt;
* https://foswiki.org/Home/WebHome&lt;br /&gt;
* https://en.wikipedia.org/wiki/Foswiki&lt;br /&gt;
* https://foswiki.web.cern.ch/&lt;br /&gt;
* https://www.wikimatrix.org/show/Foswiki&lt;br /&gt;
* &lt;br /&gt;
* &lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
= Summary = &lt;br /&gt;
&lt;br /&gt;
Foswiki is a fork of TWiki that was created in 2008.&lt;br /&gt;
&lt;br /&gt;
The split happened due to disagreements within the TWiki community about governance and development direction. A significant portion of TWiki&amp;#039;s core development team and community members decided to fork the project, creating Foswiki as a separate open-source wiki platform.&lt;br /&gt;
&lt;br /&gt;
The key connection is that Foswiki started from the same TWiki codebase, so they share:&lt;br /&gt;
&lt;br /&gt;
        Similar architecture and Perl-based implementation&lt;br /&gt;
        Compatible data structures and file formats (at least initially)&lt;br /&gt;
        Similar markup syntax and features&lt;br /&gt;
        Many of the same concepts (webs, topics, plugins, etc.)&lt;br /&gt;
&lt;br /&gt;
After the fork, both projects continued independent development. Foswiki was positioned as having a more community-driven governance model, while TWiki continued under its existing leadership.&lt;br /&gt;
&lt;br /&gt;
= FosWiki Docker =&lt;br /&gt;
&lt;br /&gt;
* https://hub.docker.com/r/timlegge/docker-foswiki&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Wiki]]&lt;br /&gt;
[[Category:TWiki]]&lt;br /&gt;
[[Category:FosWiki]]&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=Foswiki_Notes&amp;diff=5506</id>
		<title>Foswiki Notes</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=Foswiki_Notes&amp;diff=5506"/>
		<updated>2026-01-30T07:13:54Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview = &lt;br /&gt;
&lt;br /&gt;
* https://foswiki.org/Home/WebHome&lt;br /&gt;
* https://en.wikipedia.org/wiki/Foswiki&lt;br /&gt;
* https://foswiki.web.cern.ch/&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
= Summary = &lt;br /&gt;
&lt;br /&gt;
Foswiki is a fork of TWiki that was created in 2008.&lt;br /&gt;
&lt;br /&gt;
The split happened due to disagreements within the TWiki community about governance and development direction. A significant portion of TWiki&amp;#039;s core development team and community members decided to fork the project, creating Foswiki as a separate open-source wiki platform.&lt;br /&gt;
&lt;br /&gt;
The key connection is that Foswiki started from the same TWiki codebase, so they share:&lt;br /&gt;
&lt;br /&gt;
        Similar architecture and Perl-based implementation&lt;br /&gt;
        Compatible data structures and file formats (at least initially)&lt;br /&gt;
        Similar markup syntax and features&lt;br /&gt;
        Many of the same concepts (webs, topics, plugins, etc.)&lt;br /&gt;
&lt;br /&gt;
After the fork, both projects continued independent development. Foswiki was positioned as having a more community-driven governance model, while TWiki continued under its existing leadership.&lt;br /&gt;
&lt;br /&gt;
= FosWiki Docker =&lt;br /&gt;
&lt;br /&gt;
* https://hub.docker.com/r/timlegge/docker-foswiki&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Wiki]]&lt;br /&gt;
[[Category:TWiki]]&lt;br /&gt;
[[Category:FosWiki]]&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=Foswiki_Notes&amp;diff=5505</id>
		<title>Foswiki Notes</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=Foswiki_Notes&amp;diff=5505"/>
		<updated>2026-01-30T07:13:06Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview = &lt;br /&gt;
&lt;br /&gt;
* https://foswiki.org/Home/WebHome&lt;br /&gt;
* https://en.wikipedia.org/wiki/Foswiki&lt;br /&gt;
* &lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
= Summary = &lt;br /&gt;
&lt;br /&gt;
Foswiki is a fork of TWiki that was created in 2008.&lt;br /&gt;
&lt;br /&gt;
The split happened due to disagreements within the TWiki community about governance and development direction. A significant portion of TWiki&amp;#039;s core development team and community members decided to fork the project, creating Foswiki as a separate open-source wiki platform.&lt;br /&gt;
&lt;br /&gt;
The key connection is that Foswiki started from the same TWiki codebase, so they share:&lt;br /&gt;
&lt;br /&gt;
        Similar architecture and Perl-based implementation&lt;br /&gt;
        Compatible data structures and file formats (at least initially)&lt;br /&gt;
        Similar markup syntax and features&lt;br /&gt;
        Many of the same concepts (webs, topics, plugins, etc.)&lt;br /&gt;
&lt;br /&gt;
After the fork, both projects continued independent development. Foswiki was positioned as having a more community-driven governance model, while TWiki continued under its existing leadership.&lt;br /&gt;
&lt;br /&gt;
= FosWiki Docker =&lt;br /&gt;
&lt;br /&gt;
* https://hub.docker.com/r/timlegge/docker-foswiki&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Wiki]]&lt;br /&gt;
[[Category:TWiki]]&lt;br /&gt;
[[Category:FosWiki]]&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=Foswiki_Notes&amp;diff=5504</id>
		<title>Foswiki Notes</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=Foswiki_Notes&amp;diff=5504"/>
		<updated>2026-01-30T07:11:44Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Foswiki is a fork of TWiki that was created in 2008.&lt;br /&gt;
&lt;br /&gt;
The split happened due to disagreements within the TWiki community about governance and development direction. A significant portion of TWiki&amp;#039;s core development team and community members decided to fork the project, creating Foswiki as a separate open-source wiki platform.&lt;br /&gt;
&lt;br /&gt;
The key connection is that Foswiki started from the same TWiki codebase, so they share:&lt;br /&gt;
&lt;br /&gt;
        Similar architecture and Perl-based implementation&lt;br /&gt;
        Compatible data structures and file formats (at least initially)&lt;br /&gt;
        Similar markup syntax and features&lt;br /&gt;
        Many of the same concepts (webs, topics, plugins, etc.)&lt;br /&gt;
&lt;br /&gt;
After the fork, both projects continued independent development. Foswiki was positioned as having a more community-driven governance model, while TWiki continued under its existing leadership.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Wiki]]&lt;br /&gt;
[[Category:TWiki]]&lt;br /&gt;
[[Category:FosWiki]]&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=Foswiki_Notes&amp;diff=5503</id>
		<title>Foswiki Notes</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=Foswiki_Notes&amp;diff=5503"/>
		<updated>2026-01-30T07:11:22Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Foswiki is a fork of TWiki that was created in 2008.&lt;br /&gt;
&lt;br /&gt;
The split happened due to disagreements within the TWiki community about governance and development direction. A significant portion of TWiki&amp;#039;s core development team and community members decided to fork the project, creating Foswiki as a separate open-source wiki platform.&lt;br /&gt;
&lt;br /&gt;
The key connection is that Foswiki started from the same TWiki codebase, so they share:&lt;br /&gt;
&lt;br /&gt;
        Similar architecture and Perl-based implementation&lt;br /&gt;
        Compatible data structures and file formats (at least initially)&lt;br /&gt;
        Similar markup syntax and features&lt;br /&gt;
        Many of the same concepts (webs, topics, plugins, etc.)&lt;br /&gt;
&lt;br /&gt;
After the fork, both projects continued independent development. Foswiki was positioned as having a more community-driven governance model, while TWiki continued under its existing leadership.&lt;br /&gt;
&lt;br /&gt;
Since you&amp;#039;ve been working on TWiki migration and containerization, you might find that Foswiki could be a potential migration target - the shared ancestry means there are tools and documentation for migrating from TWiki to Foswiki, though the projects have diverged over the years since 2008.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Wiki]]&lt;br /&gt;
[[Category:TWiki]]&lt;br /&gt;
[[Category:FosWiki]]&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=Foswiki_Notes&amp;diff=5502</id>
		<title>Foswiki Notes</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=Foswiki_Notes&amp;diff=5502"/>
		<updated>2026-01-30T07:10:57Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: Created page with &amp;quot;       Foswiki is a fork of TWiki that was created in 2008.      The split happened due to disagreements within the TWiki community about governance and development direction. A significant portion of TWiki&amp;#039;s core development team and community members decided to fork the project, creating Foswiki as a separate open-source wiki platform.      The key connection is that Foswiki started from the same TWiki codebase, so they share:          Similar architecture and Perl-bas...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    Foswiki is a fork of TWiki that was created in 2008.&lt;br /&gt;
&lt;br /&gt;
    The split happened due to disagreements within the TWiki community about governance and development direction. A significant portion of TWiki&amp;#039;s core development team and community members decided to fork the project, creating Foswiki as a separate open-source wiki platform.&lt;br /&gt;
&lt;br /&gt;
    The key connection is that Foswiki started from the same TWiki codebase, so they share:&lt;br /&gt;
&lt;br /&gt;
        Similar architecture and Perl-based implementation&lt;br /&gt;
        Compatible data structures and file formats (at least initially)&lt;br /&gt;
        Similar markup syntax and features&lt;br /&gt;
        Many of the same concepts (webs, topics, plugins, etc.)&lt;br /&gt;
&lt;br /&gt;
    After the fork, both projects continued independent development. Foswiki was positioned as having a more community-driven governance model, while TWiki continued under its existing leadership.&lt;br /&gt;
&lt;br /&gt;
    Since you&amp;#039;ve been working on TWiki migration and containerization, you might find that Foswiki could be a potential migration target - the shared ancestry means there are tools and documentation for migrating from TWiki to Foswiki, though the projects have diverged over the years since 2008.&lt;br /&gt;
&lt;br /&gt;
    Is this relevant to your TWiki work, or are you considering Foswiki as an alternative?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Wiki]]&lt;br /&gt;
[[Category:TWiki]]&lt;br /&gt;
[[Category:FosWiki]]&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=Category:Rust&amp;diff=5501</id>
		<title>Category:Rust</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=Category:Rust&amp;diff=5501"/>
		<updated>2026-01-28T05:47:56Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: Created page with &amp;quot;Rust links, notes and references...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Rust links, notes and references...&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=Rust_Examples&amp;diff=5500</id>
		<title>Rust Examples</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=Rust_Examples&amp;diff=5500"/>
		<updated>2026-01-28T05:47:35Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: Created page with &amp;quot; * https://medium.com/@toyezyadav/i-replaced-my-spring-boot-microservice-with-rust-and-go-heres-the-system-design-that-saved-my-f3ccedd6e494  &amp;lt;pre&amp;gt; // src/lib.rs (Rust Service) use std::time::Instant; use sha2::{Sha256, Digest};  // Simulating the same heavy, synchronous transformation/hashing operation pub fn calculate_user_partition_key(user_id: &amp;amp;str, complexity: u32) -&amp;gt; String {     let start = Instant::now();     let mut base = user_id.to_string();      for i in 0..c...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* https://medium.com/@toyezyadav/i-replaced-my-spring-boot-microservice-with-rust-and-go-heres-the-system-design-that-saved-my-f3ccedd6e494&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// src/lib.rs (Rust Service)&lt;br /&gt;
use std::time::Instant;&lt;br /&gt;
use sha2::{Sha256, Digest};&lt;br /&gt;
&lt;br /&gt;
// Simulating the same heavy, synchronous transformation/hashing operation&lt;br /&gt;
pub fn calculate_user_partition_key(user_id: &amp;amp;str, complexity: u32) -&amp;gt; String {&lt;br /&gt;
    let start = Instant::now();&lt;br /&gt;
    let mut base = user_id.to_string();&lt;br /&gt;
&lt;br /&gt;
    for i in 0..complexity {&lt;br /&gt;
        let mut hasher = Sha256::new();&lt;br /&gt;
        // Rust&amp;#039;s zero-cost abstractions and memory safety shine here&lt;br /&gt;
        hasher.update(base.as_bytes());&lt;br /&gt;
        hasher.update(i.to_string().as_bytes());&lt;br /&gt;
        base = format!(&amp;quot;{:x}&amp;quot;, hasher.finalize());&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    let duration = start.elapsed();&lt;br /&gt;
    // This is the &amp;quot;hot path&amp;quot; code. It&amp;#039;s clean, safe, and ridiculously fast.&lt;br /&gt;
    base[0..16].to_string()&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Rust]]&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=Bringing_up_a_TWiki_Docker_Instance&amp;diff=5499</id>
		<title>Bringing up a TWiki Docker Instance</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=Bringing_up_a_TWiki_Docker_Instance&amp;diff=5499"/>
		<updated>2026-01-28T05:13:15Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I am in the process of recovering a TWiki installation for a client.  I have been given a tar archive containing the /data and /pub for the organizations internal TWiki data.  I want to bring it up as a Docker instance with an NGINX reverse proxy exposing it to the outside world via HTTPS.&lt;br /&gt;
&lt;br /&gt;
= Approach One =&lt;br /&gt;
&lt;br /&gt;
Use an existing Docker TWiki.&lt;br /&gt;
&lt;br /&gt;
I found a number of possible solution of various vintages.&lt;br /&gt;
&lt;br /&gt;
* https://github.com/mharrend/docker-twiki&lt;br /&gt;
* https://hub.docker.com/r/opensciencegrid/docker-twiki-converter/&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
After some investigation I settled on - &lt;br /&gt;
&lt;br /&gt;
* https://hub.docker.com/r/heradon/twiki&lt;br /&gt;
&lt;br /&gt;
I got it working initially using HTTP on a PC running docker locally to understand how the pieces fitted together.&lt;br /&gt;
&lt;br /&gt;
I then moved it across to a Linux server where I could front it with an NGINX revers proxy.&lt;br /&gt;
&lt;br /&gt;
Here are the basic stages:&lt;br /&gt;
&lt;br /&gt;
== 1.  Get the Docker Container Running ==&lt;br /&gt;
&lt;br /&gt;
This was achieved using a simple shell script as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
&lt;br /&gt;
docker run  -dt -p 8219:80 -v ./wiki/:/wiki -e URL_HOST=http://127.0.0.1:8219/ -e ADMIN_PW=Secret --name twiki --rm heradon/twiki&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this case the NGINX proxy is redirecting to http://127.0.0.1:8219 - thus the ports used above.&lt;br /&gt;
&lt;br /&gt;
The local ./wiki directory contains pub and data directories from the old TWiki site each of which contain a CFP directory with the custom wiki data&lt;br /&gt;
&lt;br /&gt;
Once I had the container running I could see the Main, TWiki and Sandbox default TWiki content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== 2. Retrofit the CFP Data ==&lt;br /&gt;
&lt;br /&gt;
The underlying TWiki Docker installation lives in /var/www/twiki.  This folder conatains (among others) a &amp;#039;pub&amp;#039; and &amp;#039;data&amp;#039; folder which contain the default TWiki contents.  As part of the Docker container initialization the run script moves twiki/data and twiki/pub to /data/data and /data/pub and then sym-links these back into /var/www/twiki.&lt;br /&gt;
&lt;br /&gt;
This process collided with my initial Docker setup which mapped a local ./data to /data in the container - and this broke the internal container application setup as the run script directory re-work failed.  As a result I mounted the client CFP data in ./wiki and once the container was up an running I copied it across to combine the custom site data with the generic TWiki data.&lt;br /&gt;
&lt;br /&gt;
Once I had this worked out I was able to connect to the container and put the custom content in place:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ docker exec -it twiki bash&lt;br /&gt;
% cd /data/pub&lt;br /&gt;
% cp -r /wiki/pub/CFP .&lt;br /&gt;
% cd /data/data&lt;br /&gt;
% cp -r /wiki/data/CFP .&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And so the data was now in place:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root@5db33ad05760:/data# ls -l data&lt;br /&gt;
total 116&lt;br /&gt;
drwxrwxr-x 2 www-data www-data  4096 Jan 28 04:02 CFP&lt;br /&gt;
drwxrwxr-x 2 www-data www-data  4096 Jul 16  2018 Main&lt;br /&gt;
drwxrwxr-x 2 www-data www-data  4096 Jul 16  2018 Sandbox&lt;br /&gt;
drwxrwxr-x 2 www-data www-data 73728 Jul 16  2018 TWiki&lt;br /&gt;
drwxrwxr-x 2 www-data www-data  4096 Jul 16  2018 Trash&lt;br /&gt;
drwxrwxr-x 2 www-data www-data  4096 Jul 16  2018 _default&lt;br /&gt;
drwxrwxr-x 2 www-data www-data  4096 Jul 16  2018 _empty&lt;br /&gt;
-rwxrwxr-x 1 www-data www-data   337 Jan 28 04:06 log202601.txt&lt;br /&gt;
-rwxrwxr-x 1 www-data www-data  9024 Jul 16  2018 mime.types&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File: TWiki_Site_Map.jpg]]&lt;br /&gt;
&lt;br /&gt;
However, this content is password protected and required a bit of work to get running.&lt;br /&gt;
&lt;br /&gt;
== 3.  Verify the NGINX proxy was forwarding the needed headers ==&lt;br /&gt;
&lt;br /&gt;
I presumed this would be OK with my standard configuration as I am using the same approach with a number of Flask, FastAPI and React proxied sites.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4.  Diagnosing the Authentication ==&lt;br /&gt;
&lt;br /&gt;
I am setting an &amp;#039;admin&amp;#039; password in the docker run command.  However, the TWiki expects there to be a .htpasswd file in /var/www/twiki/data which also maps this.&lt;br /&gt;
&lt;br /&gt;
It turns out the container (based on Debian) does not have htpasswd installed and so this had to be installed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ apt update&lt;br /&gt;
$ apt install apache2-utils&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once this was done I could create the .htpasswd file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ cd /var/wwww/twiki/data&lt;br /&gt;
$ htpasswd -c .htpasswd admin&lt;br /&gt;
...&lt;br /&gt;
$ chown www-data:www-data .htpasswd&lt;br /&gt;
% chmod 775 .htpasswd&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I missed this initially as I am so used to working with NGINX which can cope with root ownership (for better or worse).  I also needed to do this for the copies of the CFP directories so that Apache could access the data.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
% cd /data&lt;br /&gt;
% chown -R www-data:www-data data pub&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The next issue turned out that the code uses an insecure HTTP protocol for the passwrd submission.  I needed to do two things to fix this&lt;br /&gt;
&lt;br /&gt;
=== i) Update the LocalSite.cfg File ===&lt;br /&gt;
&lt;br /&gt;
In /var/www/twiki/lib/LocalSite.cfg I needed to make the following changes:&lt;br /&gt;
&lt;br /&gt;
Update the Default URL to point to the HTTPS URL and not an HTTP localhost one&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$TWiki::cfg{DefaultUrlHost} = &amp;#039;https://cfp-wiki.performiq.com&amp;#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add the following.  In retrospect, I am not sure it is necessary but at some point I did this just in case:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$TWiki::cfg{ScriptUrl} = &amp;#039;https://cfp-wiki.performiq.com/bin&amp;#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you may recall that htpasswd now uses MD5 hashing.  But the TWiki isold andby default expects the old crypt protocol.  And so I needed to change this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$TWiki::cfg{Htpasswd}{Encoding} = &amp;#039;crypt&amp;#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$TWiki::cfg{Htpasswd}{Encoding} = &amp;#039;md5&amp;#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Of course, after any of the changes you will need to restart Apache to get the changes to take effect.&lt;br /&gt;
&lt;br /&gt;
The data/CPN/WebPreferences.tx file contains a block which controls document access:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        * Users or groups who __are not__ / __are__ allowed to __view__ / __change__ / __rename__ topics in the %WEB% web: (See %TWIKIWEB%.TWikiAccessControl)&lt;br /&gt;
                * Set DENYWEBVIEW =&lt;br /&gt;
                * Set ALLOWWEBVIEW = *&lt;br /&gt;
                * Set DENYWEBCHANGE = Main.TWikiGuest&lt;br /&gt;
                * Set ALLOWWEBCHANGE = Main.Study754Group, admin&lt;br /&gt;
                * Set DENYWEBRENAME = Main.TWikiGuest, admin&lt;br /&gt;
                * Set ALLOWWEBRENAME = Main.Study754Group, admin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To allow access you can either use &amp;#039;= *&amp;#039; to open it up completeley of add &amp;#039;, admin&amp;#039; to allow admin to access the content.&lt;br /&gt;
&lt;br /&gt;
Despite doing this the authentication still failed.  The final requirement was to get Apache to honour the HTTPS headers by adding the following to /etc/apache2/sites-enabeled/twiki.conf:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
SetEnvIf X-Forwarded-Proto &amp;quot;https&amp;quot; HTTPS=on&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As soon as I added this and restated Apache theauthentication started to succeed.&lt;br /&gt;
&lt;br /&gt;
OK now that I have that working I am going to re-enble BasicAuth on the site to protect the information.&lt;br /&gt;
&lt;br /&gt;
= Approach Two =&lt;br /&gt;
&lt;br /&gt;
Using docker compose with a customize Docker image.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:TWIKI]]&lt;br /&gt;
[[Category:Wiki]]&lt;br /&gt;
[[Category:Perl]]&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=Category:Wiki&amp;diff=5498</id>
		<title>Category:Wiki</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=Category:Wiki&amp;diff=5498"/>
		<updated>2026-01-28T05:11:28Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: Created page with &amp;quot;Wiki links, notes and references...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Wiki links, notes and references...&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=Bringing_up_a_TWiki_Docker_Instance&amp;diff=5497</id>
		<title>Bringing up a TWiki Docker Instance</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=Bringing_up_a_TWiki_Docker_Instance&amp;diff=5497"/>
		<updated>2026-01-28T05:11:11Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I am in the process of recovering a TWiki installation for a client.  I have been given a tar archive containing the /data and /pub for the organizations internal TWiki data.  I want to bring it up as a Docker instance with an NGINX reverse proxy exposing it to the outside world via HTTPS.&lt;br /&gt;
&lt;br /&gt;
= Approach One =&lt;br /&gt;
&lt;br /&gt;
Use an existing Docker TWiki.&lt;br /&gt;
&lt;br /&gt;
I found a number of possible solution of various vintages.&lt;br /&gt;
&lt;br /&gt;
* https://github.com/mharrend/docker-twiki&lt;br /&gt;
* https://hub.docker.com/r/opensciencegrid/docker-twiki-converter/&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
After some investigation I settled on - &lt;br /&gt;
&lt;br /&gt;
* https://hub.docker.com/r/heradon/twiki&lt;br /&gt;
&lt;br /&gt;
I got it working initially using HTTP on a PC running docker locally to understand how the pieces fitted together.&lt;br /&gt;
&lt;br /&gt;
I then moved it across to a Linux server where I could front it with an NGINX revers proxy.&lt;br /&gt;
&lt;br /&gt;
Here are the basic stages:&lt;br /&gt;
&lt;br /&gt;
== 1.  Get the Docker Container Running ==&lt;br /&gt;
&lt;br /&gt;
This was achieved using a simple shell script as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
&lt;br /&gt;
docker run  -dt -p 8219:80 -v ./wiki/:/wiki -e URL_HOST=http://127.0.0.1:8219/ -e ADMIN_PW=Secret --name twiki --rm heradon/twiki&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this case the NGINX proxy is redirecting to http://127.0.0.1:8219 - thus the ports used above.&lt;br /&gt;
&lt;br /&gt;
The local ./wiki directory contains pub and data directories from the old TWiki site each of which contain a CFP directory with the custom wiki data&lt;br /&gt;
&lt;br /&gt;
Once I had the container running I could see the Main, TWiki and Sandbox default TWiki content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== 2. Retrofit the CFP Data ==&lt;br /&gt;
&lt;br /&gt;
The underlying TWiki Docker installation lives in /var/www/twiki.  This folder conatains (among others) a &amp;#039;pub&amp;#039; and &amp;#039;data&amp;#039; folder which contain the default TWiki contents.  As part of the Docker container initialization the run script moves twiki/data and twiki/pub to /data/data and /data/pub and then sym-links these back into /var/www/twiki.&lt;br /&gt;
&lt;br /&gt;
This process collided with my initial Docker setup which mapped a local ./data to /data in the container - and this broke the internal container application setup as the run script directory re-work failed.  As a result I mounted the client CFP data in ./wiki and once the container was up an running I copied it across to combine the custom site data with the generic TWiki data.&lt;br /&gt;
&lt;br /&gt;
Once I had this worked out I was able to connect to the container and put the custom content in place:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ docker exec -it twiki bash&lt;br /&gt;
% cd /data/pub&lt;br /&gt;
% cp -r /wiki/pub/CFP .&lt;br /&gt;
% cd /data/data&lt;br /&gt;
% cp -r /wiki/data/CFP .&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And so the data was now in place:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root@5db33ad05760:/data# ls -l data&lt;br /&gt;
total 116&lt;br /&gt;
drwxrwxr-x 2 www-data www-data  4096 Jan 28 04:02 CFP&lt;br /&gt;
drwxrwxr-x 2 www-data www-data  4096 Jul 16  2018 Main&lt;br /&gt;
drwxrwxr-x 2 www-data www-data  4096 Jul 16  2018 Sandbox&lt;br /&gt;
drwxrwxr-x 2 www-data www-data 73728 Jul 16  2018 TWiki&lt;br /&gt;
drwxrwxr-x 2 www-data www-data  4096 Jul 16  2018 Trash&lt;br /&gt;
drwxrwxr-x 2 www-data www-data  4096 Jul 16  2018 _default&lt;br /&gt;
drwxrwxr-x 2 www-data www-data  4096 Jul 16  2018 _empty&lt;br /&gt;
-rwxrwxr-x 1 www-data www-data   337 Jan 28 04:06 log202601.txt&lt;br /&gt;
-rwxrwxr-x 1 www-data www-data  9024 Jul 16  2018 mime.types&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File: TWiki_Site_Map.jpg]]&lt;br /&gt;
&lt;br /&gt;
However, this content is password protected and required a bit of work to get running.&lt;br /&gt;
&lt;br /&gt;
== 3.  Verify the NGINX proxy was forwarding the needed headers ==&lt;br /&gt;
&lt;br /&gt;
I presumed this would be OK with my standard configuration as I am using the same approach with a number of Flask, FastAPI and React proxied sites.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4.  Diagnosing the Authentication ==&lt;br /&gt;
&lt;br /&gt;
I am setting an &amp;#039;admin&amp;#039; password in the docker run command.  However, the TWiki expects there to be a .htpasswd file in /var/www/twiki/data which also maps this.&lt;br /&gt;
&lt;br /&gt;
It turns out the container (based on Debian) does not have htpasswd installed and so this had to be installed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ apt update&lt;br /&gt;
$ apt install apache2-utils&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once this was done I could create the .htpasswd file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ cd /var/wwww/twiki/data&lt;br /&gt;
$ htpasswd -c .htpasswd admin&lt;br /&gt;
...&lt;br /&gt;
$ chown www-data:www-data .htpasswd&lt;br /&gt;
% chmod 775 .htpasswd&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I missed this initially as I am so used to working with NGINX which can cope with root ownership (for better or worse).  I also needed to do this for the copies of the CFP directories so that Apache could access the data.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
% cd /data&lt;br /&gt;
% chown -R www-data:www-data data pub&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The next issue turned out that the code uses an insecure HTTP protocol for the passwrd submission.  I needed to do two things to fix this&lt;br /&gt;
&lt;br /&gt;
=== i) Update the LocalSite.cfg File ===&lt;br /&gt;
&lt;br /&gt;
In /var/www/twiki/lib/LocalSite.cfg I needed to make the following changes:&lt;br /&gt;
&lt;br /&gt;
Update the Default URL to point to the HTTPS URL and not an HTTP localhost one&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$TWiki::cfg{DefaultUrlHost} = &amp;#039;https://cfp-wiki.performiq.com&amp;#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add the following.  In retrospect, I am not sure it is necessary but at some point I did this just in case:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$TWiki::cfg{ScriptUrl} = &amp;#039;https://cfp-wiki.performiq.com/bin&amp;#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you may recall that htpasswd now uses MD5 hashing.  But the TWiki isold andby default expects the old crypt protocol.  And so I needed to change this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$TWiki::cfg{Htpasswd}{Encoding} = &amp;#039;crypt&amp;#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$TWiki::cfg{Htpasswd}{Encoding} = &amp;#039;md5&amp;#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Of course, after any of the changes you will need to restart Apache to get the changes to take effect.&lt;br /&gt;
&lt;br /&gt;
The data/CPN/WebPreferences.tx file contains a block which controls document access:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        * Users or groups who __are not__ / __are__ allowed to __view__ / __change__ / __rename__ topics in the %WEB% web: (See %TWIKIWEB%.TWikiAccessControl)&lt;br /&gt;
                * Set DENYWEBVIEW =&lt;br /&gt;
                * Set ALLOWWEBVIEW = *&lt;br /&gt;
                * Set DENYWEBCHANGE = Main.TWikiGuest&lt;br /&gt;
                * Set ALLOWWEBCHANGE = Main.Study754Group, admin&lt;br /&gt;
                * Set DENYWEBRENAME = Main.TWikiGuest, admin&lt;br /&gt;
                * Set ALLOWWEBRENAME = Main.Study754Group, admin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To allow access you can either use &amp;#039;= *&amp;#039; to open it up completeley of add &amp;#039;, admin&amp;#039; to allow admin to access the content.&lt;br /&gt;
&lt;br /&gt;
Despite doing this the authentication still failed.  The final requirement was to get Apache to honour the HTTPS headers by adding the following to /etc/apache2/sites-enabeled/twiki.conf:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
SetEnvIf X-Forwarded-Proto &amp;quot;https&amp;quot; HTTPS=on&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As soon as I added this and restated Apache theauthentication started to succeed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:TWIKI]]&lt;br /&gt;
[[Category:Wiki]]&lt;br /&gt;
[[Category:Perl]]&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=Bringing_up_a_TWiki_Docker_Instance&amp;diff=5496</id>
		<title>Bringing up a TWiki Docker Instance</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=Bringing_up_a_TWiki_Docker_Instance&amp;diff=5496"/>
		<updated>2026-01-28T05:04:37Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I am in the process of recovering a TWiki installation for a client.  I have been given a tar archive containing the /data and /pub for the organizations internal TWiki data.  I want to bring it up as a Docker instance with an NGINX reverse proxy exposing it to the outside world via HTTPS.&lt;br /&gt;
&lt;br /&gt;
= Approach One =&lt;br /&gt;
&lt;br /&gt;
Use an existing Docker TWiki.&lt;br /&gt;
&lt;br /&gt;
I found a number of possible solution of various vintages.&lt;br /&gt;
&lt;br /&gt;
* https://github.com/mharrend/docker-twiki&lt;br /&gt;
* https://hub.docker.com/r/opensciencegrid/docker-twiki-converter/&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
After some investigation I settled on - &lt;br /&gt;
&lt;br /&gt;
* https://hub.docker.com/r/heradon/twiki&lt;br /&gt;
&lt;br /&gt;
I got it working initially using HTTP on a PC running docker locally to understand how the pieces fitted together.&lt;br /&gt;
&lt;br /&gt;
I then moved it across to a Linux server where I could front it with an NGINX revers proxy.&lt;br /&gt;
&lt;br /&gt;
Here are the basic stages:&lt;br /&gt;
&lt;br /&gt;
== 1.  Get the Docker Container Running ==&lt;br /&gt;
&lt;br /&gt;
This was achieved using a simple shell script as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
&lt;br /&gt;
docker run  -dt -p 8219:80 -v ./wiki/:/wiki -e URL_HOST=http://127.0.0.1:8219/ -e ADMIN_PW=Secret --name twiki --rm heradon/twiki&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this case the NGINX proxy is redirecting to http://127.0.0.1:8219 - thus the ports used above.&lt;br /&gt;
&lt;br /&gt;
The local ./wiki directory contains pub and data directories from the old TWiki site each of which contain a CFP directory with the custom wiki data&lt;br /&gt;
&lt;br /&gt;
Once I had the container running I could see the Main, TWiki and Sandbox default TWiki content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== 2. Retrofit the CFP Data ==&lt;br /&gt;
&lt;br /&gt;
The underlying TWiki Docker installation lives in /var/www/twiki.  This folder conatains (among others) a &amp;#039;pub&amp;#039; and &amp;#039;data&amp;#039; folder which contain the default TWiki contents.  As part of the Docker container initialization the run script moves twiki/data and twiki/pub to /data/data and /data/pub and then sym-links these back into /var/www/twiki.&lt;br /&gt;
&lt;br /&gt;
This process collided with my initial Docker setup which mapped a local ./data to /data in the container - and this broke the internal container application setup as the run script directory re-work failed.  As a result I mounted the client CFP data in ./wiki and once the container was up an running I copied it across to combine the custom site data with the generic TWiki data.&lt;br /&gt;
&lt;br /&gt;
Once I had this worked out I was able to connect to the container and put the custom content in place:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ docker exec -it twiki bash&lt;br /&gt;
% cd /data/pub&lt;br /&gt;
% cp -r /wiki/pub/CFP .&lt;br /&gt;
% cd /data/data&lt;br /&gt;
% cp -r /wiki/data/CFP .&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And so the data was now in place:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root@5db33ad05760:/data# ls -l data&lt;br /&gt;
total 116&lt;br /&gt;
drwxrwxr-x 2 www-data www-data  4096 Jan 28 04:02 CFP&lt;br /&gt;
drwxrwxr-x 2 www-data www-data  4096 Jul 16  2018 Main&lt;br /&gt;
drwxrwxr-x 2 www-data www-data  4096 Jul 16  2018 Sandbox&lt;br /&gt;
drwxrwxr-x 2 www-data www-data 73728 Jul 16  2018 TWiki&lt;br /&gt;
drwxrwxr-x 2 www-data www-data  4096 Jul 16  2018 Trash&lt;br /&gt;
drwxrwxr-x 2 www-data www-data  4096 Jul 16  2018 _default&lt;br /&gt;
drwxrwxr-x 2 www-data www-data  4096 Jul 16  2018 _empty&lt;br /&gt;
-rwxrwxr-x 1 www-data www-data   337 Jan 28 04:06 log202601.txt&lt;br /&gt;
-rwxrwxr-x 1 www-data www-data  9024 Jul 16  2018 mime.types&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File: TWiki_Site_Map.jpg]]&lt;br /&gt;
&lt;br /&gt;
However, this content is password protected and required a bit of work to get running.&lt;br /&gt;
&lt;br /&gt;
== 3.  Verify the NGINX proxy was forwarding the needed headers ==&lt;br /&gt;
&lt;br /&gt;
I presumed this would be OK with my standard configuration as I am using the same approach with a number of Flask, FastAPI and React proxied sites.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4.  Diagnosing the Authentication ==&lt;br /&gt;
&lt;br /&gt;
I am setting an &amp;#039;admin&amp;#039; password in the docker run command.  However, the TWiki expects there to be a .htpasswd file in /var/www/twiki/data which also maps this.&lt;br /&gt;
&lt;br /&gt;
It turns out the container (based on Debian) does not have htpasswd installed and so this had to be installed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ apt update&lt;br /&gt;
$ apt install apache2-utils&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once this was done I could create the .htpasswd file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ cd /var/wwww/twiki/data&lt;br /&gt;
$ htpasswd -c .htpasswd admin&lt;br /&gt;
...&lt;br /&gt;
$ chown www-data:www-data .htpasswd&lt;br /&gt;
% chmod 775 .htpasswd&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I missed this initially as I am so used to working with NGINX which can cope with root ownership (for better or worse).  I also needed to do this for the copies of the CFP directories so that Apache could access the data.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
% cd /data&lt;br /&gt;
% chown -R www-data:www-data data pub&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The next issue turned out that the code uses an insecure HTTP protocol for the passwrd submission.  I needed to do two things to fix this&lt;br /&gt;
&lt;br /&gt;
=== i) Update the LocalSite.cfg File ===&lt;br /&gt;
&lt;br /&gt;
In /var/www/twiki/lib/LocalSite.cfg I needed to make the following changes:&lt;br /&gt;
&lt;br /&gt;
Update the Default URL to point to the HTTPS URL and not an HTTP localhost one&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$TWiki::cfg{DefaultUrlHost} = &amp;#039;https://cfp-wiki.performiq.com&amp;#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add the following.  In retrospect, I am not sure it is necessary but at some point I did this just in case:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$TWiki::cfg{ScriptUrl} = &amp;#039;https://cfp-wiki.performiq.com/bin&amp;#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you may recall that htpasswd now uses MD5 hashing.  But the TWiki isold andby default expects the old crypt protocol.  And so I needed to change this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$TWiki::cfg{Htpasswd}{Encoding} = &amp;#039;crypt&amp;#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$TWiki::cfg{Htpasswd}{Encoding} = &amp;#039;md5&amp;#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:TWIKI]]&lt;br /&gt;
[[Category:Wiki]]&lt;br /&gt;
[[Category:Perl]]&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=Bringing_up_a_TWiki_Docker_Instance&amp;diff=5495</id>
		<title>Bringing up a TWiki Docker Instance</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=Bringing_up_a_TWiki_Docker_Instance&amp;diff=5495"/>
		<updated>2026-01-28T04:45:42Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I am in the process of recovering a TWiki installation for a client.  I have been given a tar archive containing the /data and /pub for the organizations internal TWiki data.  I want to bring it up as a Docker instance with an NGINX reverse proxy exposing it to the outside world via HTTPS.&lt;br /&gt;
&lt;br /&gt;
= Approach One =&lt;br /&gt;
&lt;br /&gt;
Use an existing Docker TWiki.&lt;br /&gt;
&lt;br /&gt;
I found a number of possible solution of various vintages.&lt;br /&gt;
&lt;br /&gt;
* https://github.com/mharrend/docker-twiki&lt;br /&gt;
* https://hub.docker.com/r/opensciencegrid/docker-twiki-converter/&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
After some investigation I settled on - &lt;br /&gt;
&lt;br /&gt;
* https://hub.docker.com/r/heradon/twiki&lt;br /&gt;
&lt;br /&gt;
I got it working initially using HTTP on a PC running docker locally to understand how the pieces fitted together.&lt;br /&gt;
&lt;br /&gt;
I then moved it across to a Linux server where I could front it with an NGINX revers proxy.&lt;br /&gt;
&lt;br /&gt;
Here are the basic stages:&lt;br /&gt;
&lt;br /&gt;
== 1.  Get the Docker Container Running ==&lt;br /&gt;
&lt;br /&gt;
This was achieved using a simple shell script as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
&lt;br /&gt;
docker run  -dt -p 8219:80 -v ./wiki/:/wiki -e URL_HOST=http://127.0.0.1:8219/ -e ADMIN_PW=Secret --name twiki --rm heradon/twiki&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this case the NGINX proxy is redirecting to http://127.0.0.1:8219 - thus the ports used above.&lt;br /&gt;
&lt;br /&gt;
The local ./wiki directory contains pub and data directories from the old TWiki site each of which contain a CFP directory with the custom wiki data&lt;br /&gt;
&lt;br /&gt;
Once I had the container running I could see the Main, TWiki and Sandbox default TWiki content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== 2. Retrofit the CFP Data ==&lt;br /&gt;
&lt;br /&gt;
The underlying TWiki Docker installation lives in /var/www/twiki.  This folder conatains (among others) a &amp;#039;pub&amp;#039; and &amp;#039;data&amp;#039; folder which contain the default TWiki contents.  As part of the Docker container initialization the run script moves twiki/data and twiki/pub to /data/data and /data/pub and then sym-links these back into /var/www/twiki.&lt;br /&gt;
&lt;br /&gt;
This process collided with my initial Docker setup which mapped a local ./data to /data in the container - and this broke the internal container application setup as the run script directory re-work failed.  As a result I mounted the client CFP data in ./wiki and once the container was up an running I copied it across to combine the custom site data with the generic TWiki data.&lt;br /&gt;
&lt;br /&gt;
Once I had this worked out I was able to connect to the container and put the custom content in place:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ docker exec -it twiki bash&lt;br /&gt;
% cd /data/pub&lt;br /&gt;
% cp -r /wiki/pub/CFP .&lt;br /&gt;
% cd /data/data&lt;br /&gt;
% cp -r /wiki/data/CFP .&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And so the data was now in place:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root@5db33ad05760:/data# ls -l data&lt;br /&gt;
total 116&lt;br /&gt;
drwxrwxr-x 2 www-data www-data  4096 Jan 28 04:02 CFP&lt;br /&gt;
drwxrwxr-x 2 www-data www-data  4096 Jul 16  2018 Main&lt;br /&gt;
drwxrwxr-x 2 www-data www-data  4096 Jul 16  2018 Sandbox&lt;br /&gt;
drwxrwxr-x 2 www-data www-data 73728 Jul 16  2018 TWiki&lt;br /&gt;
drwxrwxr-x 2 www-data www-data  4096 Jul 16  2018 Trash&lt;br /&gt;
drwxrwxr-x 2 www-data www-data  4096 Jul 16  2018 _default&lt;br /&gt;
drwxrwxr-x 2 www-data www-data  4096 Jul 16  2018 _empty&lt;br /&gt;
-rwxrwxr-x 1 www-data www-data   337 Jan 28 04:06 log202601.txt&lt;br /&gt;
-rwxrwxr-x 1 www-data www-data  9024 Jul 16  2018 mime.types&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File: TWiki_Site_Map.jpg]]&lt;br /&gt;
&lt;br /&gt;
However, this content is password protected.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:TWIKI]]&lt;br /&gt;
[[Category:Wiki]]&lt;br /&gt;
[[Category:Perl]]&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=File:TWiki_Site_Map.jpg&amp;diff=5494</id>
		<title>File:TWiki Site Map.jpg</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=File:TWiki_Site_Map.jpg&amp;diff=5494"/>
		<updated>2026-01-28T04:44:59Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=Bringing_up_a_TWiki_Docker_Instance&amp;diff=5493</id>
		<title>Bringing up a TWiki Docker Instance</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=Bringing_up_a_TWiki_Docker_Instance&amp;diff=5493"/>
		<updated>2026-01-28T04:42:07Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: Created page with &amp;quot;I am in the process of recovering a TWiki installation for a client.  I have been given a tar archive containing the /data and /pub for the organizations internal TWiki data.  I want to bring it up as a Docker instance with an NGINX reverse proxy exposing it to the outside world via HTTPS.  = Approach One =  Use an existing Docker TWiki.  I found a number of possible solution of various vintages.  * https://github.com/mharrend/docker-twiki * https://hub.docker.com/r/open...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I am in the process of recovering a TWiki installation for a client.  I have been given a tar archive containing the /data and /pub for the organizations internal TWiki data.  I want to bring it up as a Docker instance with an NGINX reverse proxy exposing it to the outside world via HTTPS.&lt;br /&gt;
&lt;br /&gt;
= Approach One =&lt;br /&gt;
&lt;br /&gt;
Use an existing Docker TWiki.&lt;br /&gt;
&lt;br /&gt;
I found a number of possible solution of various vintages.&lt;br /&gt;
&lt;br /&gt;
* https://github.com/mharrend/docker-twiki&lt;br /&gt;
* https://hub.docker.com/r/opensciencegrid/docker-twiki-converter/&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
After some investigation I settled on - &lt;br /&gt;
&lt;br /&gt;
* https://hub.docker.com/r/heradon/twiki&lt;br /&gt;
&lt;br /&gt;
I got it working initially using HTTP on a PC running docker locally to understand how the pieces fitted together.&lt;br /&gt;
&lt;br /&gt;
I then moved it across to a Linux server where I could front it with an NGINX revers proxy.&lt;br /&gt;
&lt;br /&gt;
Here are the basic stages:&lt;br /&gt;
&lt;br /&gt;
== 1.  Get the Docker Container Running ==&lt;br /&gt;
&lt;br /&gt;
This was achieved using a simple shell script as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
&lt;br /&gt;
docker run  -dt -p 8219:80 -v ./wiki/:/wiki -e URL_HOST=http://127.0.0.1:8219/ -e ADMIN_PW=Secret --name twiki --rm heradon/twiki&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this case the NGINX proxy is redirecting to http://127.0.0.1:8219 - thus the ports used above.&lt;br /&gt;
&lt;br /&gt;
The local ./wiki directory contains pub and data directories from the old TWiki site each of which contain a CFP directory with the custom wiki data&lt;br /&gt;
&lt;br /&gt;
Once I had the container running I could see the Main, TWiki and Sandbox default TWiki content.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== 2. Retrofit the CFP Data ==&lt;br /&gt;
&lt;br /&gt;
The underlying TWiki Docker installation lives in /var/www/twiki.  This folder conatains (among others) a &amp;#039;pub&amp;#039; and &amp;#039;data&amp;#039; folder which contain the default TWiki contents.  As part of the Docker container initialization the run script moves twiki/data and twiki/pub to /data/data and /data/pub and then sym-links these back into /var/www/twiki.&lt;br /&gt;
&lt;br /&gt;
This process collided with my initial Docker setup which mapped a local ./data to /data in the container - and this broke the internal container application setup as the run script directory re-work failed.  As a result I mounted the client CFP data in ./wiki and once the container was up an running I copied it across to combine the custom site data with the generic TWiki data.&lt;br /&gt;
&lt;br /&gt;
Once I had this worked out I was able to connect to the container and put the custom content in place:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ docker exec -it twiki bash&lt;br /&gt;
% cd /data/pub&lt;br /&gt;
% cp -r /wiki/pub/CFP .&lt;br /&gt;
% cd /data/data&lt;br /&gt;
% cp -r /wiki/data/CFP .&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And so the data was now in place:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root@5db33ad05760:/data# ls -l data&lt;br /&gt;
total 116&lt;br /&gt;
drwxrwxr-x 2 www-data www-data  4096 Jan 28 04:02 CFP&lt;br /&gt;
drwxrwxr-x 2 www-data www-data  4096 Jul 16  2018 Main&lt;br /&gt;
drwxrwxr-x 2 www-data www-data  4096 Jul 16  2018 Sandbox&lt;br /&gt;
drwxrwxr-x 2 www-data www-data 73728 Jul 16  2018 TWiki&lt;br /&gt;
drwxrwxr-x 2 www-data www-data  4096 Jul 16  2018 Trash&lt;br /&gt;
drwxrwxr-x 2 www-data www-data  4096 Jul 16  2018 _default&lt;br /&gt;
drwxrwxr-x 2 www-data www-data  4096 Jul 16  2018 _empty&lt;br /&gt;
-rwxrwxr-x 1 www-data www-data   337 Jan 28 04:06 log202601.txt&lt;br /&gt;
-rwxrwxr-x 1 www-data www-data  9024 Jul 16  2018 mime.types&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:TWIKI]]&lt;br /&gt;
[[Category:Wiki]]&lt;br /&gt;
[[Category:Perl]]&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=TWIKI_Notes&amp;diff=5492</id>
		<title>TWIKI Notes</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=TWIKI_Notes&amp;diff=5492"/>
		<updated>2026-01-27T21:35:20Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= TWiki - The Wiki Platform =&lt;br /&gt;
&lt;br /&gt;
TWiki is an open-source enterprise wiki and collaboration platform:&lt;br /&gt;
&lt;br /&gt;
* Created: Around 1998 by Peter Thoeny&lt;br /&gt;
* Written in: Perl&lt;br /&gt;
* Key Features: Structured wikis with topics organized in &amp;quot;webs&amp;quot; (namespaces), fine-grained access controls, plugin architecture, and form-based data handling&lt;br /&gt;
* Common Uses: Documentation, project management, knowledge bases, intranets&lt;br /&gt;
* Notable Event: In 2008, there was a community fork that created Foswiki, which split the development community&lt;br /&gt;
&lt;br /&gt;
TWiki uses a different markup syntax than MediaWiki and has a more structured approach to organizing content. It&amp;#039;s traditionally been popular in corporate and enterprise environments.&lt;br /&gt;
&lt;br /&gt;
= Docker =&lt;br /&gt;
&lt;br /&gt;
* https://github.com/mharrend/docker-twiki&lt;br /&gt;
* https://hub.docker.com/r/mhvelplund/twiki-docker&lt;br /&gt;
* https://hub.docker.com/r/opensciencegrid/docker-twiki-converter/&lt;br /&gt;
* https://twiki.org/cgi-bin/view/TWiki/TWikiInstallationGuide&lt;br /&gt;
* &lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
[[Category:Wikis]]&lt;br /&gt;
[[Category:TWIKI]]&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=TWIKI_Notes&amp;diff=5491</id>
		<title>TWIKI Notes</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=TWIKI_Notes&amp;diff=5491"/>
		<updated>2026-01-27T21:33:33Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= TWiki - The Wiki Platform =&lt;br /&gt;
&lt;br /&gt;
TWiki is an open-source enterprise wiki and collaboration platform:&lt;br /&gt;
&lt;br /&gt;
* Created: Around 1998 by Peter Thoeny&lt;br /&gt;
* Written in: Perl&lt;br /&gt;
* Key Features: Structured wikis with topics organized in &amp;quot;webs&amp;quot; (namespaces), fine-grained access controls, plugin architecture, and form-based data handling&lt;br /&gt;
* Common Uses: Documentation, project management, knowledge bases, intranets&lt;br /&gt;
* Notable Event: In 2008, there was a community fork that created Foswiki, which split the development community&lt;br /&gt;
&lt;br /&gt;
TWiki uses a different markup syntax than MediaWiki and has a more structured approach to organizing content. It&amp;#039;s traditionally been popular in corporate and enterprise environments.&lt;br /&gt;
&lt;br /&gt;
= Docker =&lt;br /&gt;
&lt;br /&gt;
* https://github.com/mharrend/docker-twiki&lt;br /&gt;
* https://hub.docker.com/r/mhvelplund/twiki-docker&lt;br /&gt;
* &lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
[[Category:Wikis]]&lt;br /&gt;
[[Category:TWIKI]]&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=Category:TWIKI&amp;diff=5490</id>
		<title>Category:TWIKI</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=Category:TWIKI&amp;diff=5490"/>
		<updated>2026-01-27T21:32:19Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: Created page with &amp;quot;TWIKI links, notes and references...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;TWIKI links, notes and references...&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=Category:Wikis&amp;diff=5489</id>
		<title>Category:Wikis</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=Category:Wikis&amp;diff=5489"/>
		<updated>2026-01-27T21:32:04Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: Created page with &amp;quot;Wiki links, notes and references...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Wiki links, notes and references...&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=TWIKI_Notes&amp;diff=5488</id>
		<title>TWIKI Notes</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=TWIKI_Notes&amp;diff=5488"/>
		<updated>2026-01-27T21:31:46Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: Created page with &amp;quot;= TWiki - The Wiki Platform =  TWiki is an open-source enterprise wiki and collaboration platform:  * Created: Around 1998 by Peter Thoeny * Written in: Perl * Key Features: Structured wikis with topics organized in &amp;quot;webs&amp;quot; (namespaces), fine-grained access controls, plugin architecture, and form-based data handling * Common Uses: Documentation, project management, knowledge bases, intranets * Notable Event: In 2008, there was a community fork that created Foswiki, which...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= TWiki - The Wiki Platform =&lt;br /&gt;
&lt;br /&gt;
TWiki is an open-source enterprise wiki and collaboration platform:&lt;br /&gt;
&lt;br /&gt;
* Created: Around 1998 by Peter Thoeny&lt;br /&gt;
* Written in: Perl&lt;br /&gt;
* Key Features: Structured wikis with topics organized in &amp;quot;webs&amp;quot; (namespaces), fine-grained access controls, plugin architecture, and form-based data handling&lt;br /&gt;
* Common Uses: Documentation, project management, knowledge bases, intranets&lt;br /&gt;
* Notable Event: In 2008, there was a community fork that created Foswiki, which split the development community&lt;br /&gt;
&lt;br /&gt;
TWiki uses a different markup syntax than MediaWiki and has a more structured approach to organizing content. It&amp;#039;s traditionally been popular in corporate and enterprise environments.&lt;br /&gt;
&lt;br /&gt;
[[Category:Wikis]]&lt;br /&gt;
[[Category:TWIKI]]&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=Category:Machine_Learning&amp;diff=5487</id>
		<title>Category:Machine Learning</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=Category:Machine_Learning&amp;diff=5487"/>
		<updated>2025-12-13T01:32:41Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: Created page with &amp;quot;Machine Learning links, notes and references...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Machine Learning links, notes and references...&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=Category:AI&amp;diff=5486</id>
		<title>Category:AI</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=Category:AI&amp;diff=5486"/>
		<updated>2025-12-13T01:32:21Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: Created page with &amp;quot;AI links, notes and references...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;AI links, notes and references...&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=Interesting_AI_Links&amp;diff=5485</id>
		<title>Interesting AI Links</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=Interesting_AI_Links&amp;diff=5485"/>
		<updated>2025-12-13T01:32:01Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* https://openrouter.ai/&lt;br /&gt;
* https://chat.z.ai/&lt;br /&gt;
* https://claude.ai/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:AI]]&lt;br /&gt;
[[Category:Machine Learning]]&lt;br /&gt;
[[Category:Software Tools]]&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=Interesting_AI_Links&amp;diff=5484</id>
		<title>Interesting AI Links</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=Interesting_AI_Links&amp;diff=5484"/>
		<updated>2025-12-13T01:31:20Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: Created page with &amp;quot; * https://openrouter.ai/ *   Category:AI Category:Machine Learning Category:Software Tools&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* https://openrouter.ai/&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
[[Category:AI]]&lt;br /&gt;
[[Category:Machine Learning]]&lt;br /&gt;
[[Category:Software Tools]]&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=Wikipedia&amp;diff=5483</id>
		<title>Wikipedia</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=Wikipedia&amp;diff=5483"/>
		<updated>2025-12-12T23:21:49Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=References=&lt;br /&gt;
&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Main_Page English Link to front page]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 hc@!XBD9btfmzqcv2@q9&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:MediaWiki]]&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=Impact_-_A_Replacement_FembicReader&amp;diff=5482</id>
		<title>Impact - A Replacement FembicReader</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=Impact_-_A_Replacement_FembicReader&amp;diff=5482"/>
		<updated>2025-12-07T21:05:11Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= The Fembic Reader = &lt;br /&gt;
&lt;br /&gt;
Here is prototype code for a replacement tp the FembicReader which uses java.nio and java.util.regex.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * This program is free software; you can redistribute it and/or&lt;br /&gt;
 * modify it under the terms of the GNU General Public License as&lt;br /&gt;
 * published by the Free Software Foundation; either version 2 of the&lt;br /&gt;
 * License or (at your option) any later version.&lt;br /&gt;
 *&lt;br /&gt;
 * This program is distributed in the hope that it will be useful, but&lt;br /&gt;
 * WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU&lt;br /&gt;
 * General Public License for more details.&lt;br /&gt;
 *&lt;br /&gt;
 * You should have received a copy of the GNU General Public License&lt;br /&gt;
 * along with this program; if not, write to the Free Software&lt;br /&gt;
 * Foundation, inc., 59 Temple Place, Suite 330, Boston MA 02111-1307&lt;br /&gt;
 * USA&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
package run.readers;&lt;br /&gt;
&lt;br /&gt;
// ----------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
import java.io.*;&lt;br /&gt;
import java.nio.file.Files;&lt;br /&gt;
import java.nio.file.Path;&lt;br /&gt;
import java.text.ParseException;&lt;br /&gt;
import java.util.*;&lt;br /&gt;
import java.util.regex.Matcher;&lt;br /&gt;
import java.util.regex.Pattern;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// ----------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
import run.Constraint;&lt;br /&gt;
import run.Controlset;&lt;br /&gt;
import run.Element;&lt;br /&gt;
import run.Load;&lt;br /&gt;
import run.Material;&lt;br /&gt;
import run.Node;&lt;br /&gt;
import run.Reader;&lt;br /&gt;
import run.RplVector;&lt;br /&gt;
import run.Token;&lt;br /&gt;
import run.TrackWriter;&lt;br /&gt;
import run.Tracker;&lt;br /&gt;
import run.Writer;&lt;br /&gt;
&lt;br /&gt;
import uka.karmi.rmi.RemoteException;&lt;br /&gt;
&lt;br /&gt;
import jp.lang.RemoteObject;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// ----------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Fembic file reader - modernized version using BufferedReader and regex.&lt;br /&gt;
 * Original authors: Yuriy Mikhaylovskiy, Jonas Forssell&lt;br /&gt;
 * Modernized: 2025&lt;br /&gt;
 */&lt;br /&gt;
public class FembicReader extends Reader {&lt;br /&gt;
&lt;br /&gt;
    private BufferedReader br;&lt;br /&gt;
    private final String filename;&lt;br /&gt;
    private final Set&amp;lt;String&amp;gt; keywords = Set.of(&lt;br /&gt;
            &amp;quot;TITLE&amp;quot;, &amp;quot;CONTROLS&amp;quot;, &amp;quot;ELEMENTS&amp;quot;, &amp;quot;NODES&amp;quot;, &amp;quot;LOADS&amp;quot;,&lt;br /&gt;
            &amp;quot;CONSTRAINTS&amp;quot;, &amp;quot;MATERIALS&amp;quot;, &amp;quot;TRACKERS&amp;quot;, &amp;quot;GROUPS&amp;quot;, &amp;quot;GEOMETRY&amp;quot;&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    // Parsing state&lt;br /&gt;
    private boolean inBlock = false;&lt;br /&gt;
    private boolean elementInBlock = false;&lt;br /&gt;
    private boolean trackerInBlock = false;&lt;br /&gt;
    private boolean materialInBlock = false;&lt;br /&gt;
    private boolean controlInBlock = false;&lt;br /&gt;
    private boolean constraintInBlock = false;&lt;br /&gt;
&lt;br /&gt;
    // Current type being parsed&lt;br /&gt;
    private String currentElementType;&lt;br /&gt;
    private String currentTrackerType;&lt;br /&gt;
    private String currentConstraintType;&lt;br /&gt;
&lt;br /&gt;
    // Line-based parsing state&lt;br /&gt;
    private List&amp;lt;String&amp;gt; fileLines;&lt;br /&gt;
    private int currentLineIndex;&lt;br /&gt;
    private int currentLineNumber;&lt;br /&gt;
&lt;br /&gt;
    // Regex patterns for parsing&lt;br /&gt;
    private static final Pattern BLOCK_HEADER_PATTERN = &lt;br /&gt;
            Pattern.compile(&amp;quot;^(\\w+)\\s+OF\\s+TYPE\\s+(\\w+)\\s*$&amp;quot;, Pattern.CASE_INSENSITIVE);&lt;br /&gt;
    private static final Pattern SIMPLE_BLOCK_PATTERN = &lt;br /&gt;
            Pattern.compile(&amp;quot;^(\\w+)\\s*$&amp;quot;, Pattern.CASE_INSENSITIVE);&lt;br /&gt;
    private static final Pattern NUMBER_PATTERN = &lt;br /&gt;
            Pattern.compile(&amp;quot;^-?\\d+(\\.\\d+)?([eE][+-]?\\d+)?$&amp;quot;);&lt;br /&gt;
    private static final Pattern PARAM_EQUALS_PATTERN = &lt;br /&gt;
            Pattern.compile(&amp;quot;(\\w+)\\s*=\\s*(.+)&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    // Temporary objects&lt;br /&gt;
    private Node temporaryNode;&lt;br /&gt;
    private Load temporaryLoad;&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Constructor - stores filename for later opening.&lt;br /&gt;
     */&lt;br /&gt;
    public FembicReader(String fn) {&lt;br /&gt;
        this.filename = fn;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Closes the reader.&lt;br /&gt;
     */&lt;br /&gt;
    public void close() {&lt;br /&gt;
        if (br != null) {&lt;br /&gt;
            try {&lt;br /&gt;
                br.close();&lt;br /&gt;
            } catch (IOException ioe) {&lt;br /&gt;
                System.out.println(&amp;quot;An IOException has occurred when closing the indata file&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        fileLines = null;&lt;br /&gt;
        currentLineIndex = 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Opens the file and loads all lines into memory for parsing.&lt;br /&gt;
     */&lt;br /&gt;
    public void open() {&lt;br /&gt;
        // Reset parsing state&lt;br /&gt;
        inBlock = false;&lt;br /&gt;
        controlInBlock = false;&lt;br /&gt;
        constraintInBlock = false;&lt;br /&gt;
        elementInBlock = false;&lt;br /&gt;
        trackerInBlock = false;&lt;br /&gt;
        materialInBlock = false;&lt;br /&gt;
        currentLineIndex = 0;&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            Path path = Path.of(filename);&lt;br /&gt;
            fileLines = Files.readAllLines(path);&lt;br /&gt;
            br = Files.newBufferedReader(path);&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            System.out.println(&amp;quot;Failed to open Fembic file: &amp;quot; + e.getMessage());&lt;br /&gt;
            fileLines = new ArrayList&amp;lt;&amp;gt;();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Checks if a string is a keyword.&lt;br /&gt;
     */&lt;br /&gt;
    private boolean isAKeyword(String param) {&lt;br /&gt;
        return keywords.contains(param.toUpperCase());&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Gets the next non-empty, non-comment line.&lt;br /&gt;
     * Returns null if EOF reached.&lt;br /&gt;
     */&lt;br /&gt;
    private String getNextLine() {&lt;br /&gt;
        while (currentLineIndex &amp;lt; fileLines.size()) {&lt;br /&gt;
            String line = fileLines.get(currentLineIndex).trim();&lt;br /&gt;
            currentLineNumber = currentLineIndex + 1;&lt;br /&gt;
            currentLineIndex++;&lt;br /&gt;
&lt;br /&gt;
            // Skip empty lines and comments&lt;br /&gt;
            if (!line.isEmpty() &amp;amp;&amp;amp; !line.startsWith(&amp;quot;#&amp;quot;) &amp;amp;&amp;amp; !line.startsWith(&amp;quot;//&amp;quot;)) {&lt;br /&gt;
                return line;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        return null;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Peeks at the next non-empty line without consuming it.&lt;br /&gt;
     */&lt;br /&gt;
    private String peekNextLine() {&lt;br /&gt;
        int tempIndex = currentLineIndex;&lt;br /&gt;
        while (tempIndex &amp;lt; fileLines.size()) {&lt;br /&gt;
            String line = fileLines.get(tempIndex).trim();&lt;br /&gt;
            tempIndex++;&lt;br /&gt;
            if (!line.isEmpty() &amp;amp;&amp;amp; !line.startsWith(&amp;quot;#&amp;quot;) &amp;amp;&amp;amp; !line.startsWith(&amp;quot;//&amp;quot;)) {&lt;br /&gt;
                return line;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        return null;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Pushes back to re-read the current line.&lt;br /&gt;
     */&lt;br /&gt;
    private void pushBack() {&lt;br /&gt;
        if (currentLineIndex &amp;gt; 0) {&lt;br /&gt;
            currentLineIndex--;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Searches for a block with the given keyword.&lt;br /&gt;
     * Returns true if found, false if EOF reached.&lt;br /&gt;
     */&lt;br /&gt;
    private boolean findBlock(String blockKeyword) {&lt;br /&gt;
        String line;&lt;br /&gt;
        while ((line = getNextLine()) != null) {&lt;br /&gt;
            String upperLine = line.toUpperCase();&lt;br /&gt;
            if (upperLine.startsWith(blockKeyword.toUpperCase())) {&lt;br /&gt;
                return true;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        return false;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Searches for a typed block (e.g., &amp;quot;ELEMENTS OF TYPE BEAM&amp;quot;).&lt;br /&gt;
     * Returns the type if found, null otherwise.&lt;br /&gt;
     */&lt;br /&gt;
    private String findTypedBlock(String blockKeyword) {&lt;br /&gt;
        String line;&lt;br /&gt;
        while ((line = getNextLine()) != null) {&lt;br /&gt;
            Matcher matcher = BLOCK_HEADER_PATTERN.matcher(line);&lt;br /&gt;
            if (matcher.matches() &amp;amp;&amp;amp; matcher.group(1).equalsIgnoreCase(blockKeyword)) {&lt;br /&gt;
                return matcher.group(2).toUpperCase();&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        return null;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Checks if a string represents a number.&lt;br /&gt;
     */&lt;br /&gt;
    private boolean isNumber(String s) {&lt;br /&gt;
        return NUMBER_PATTERN.matcher(s).matches();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Parses a number from a string.&lt;br /&gt;
     */&lt;br /&gt;
    private double parseNumber(String s) {&lt;br /&gt;
        return Double.parseDouble(s);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Tokenizes a line into Token array for parsing.&lt;br /&gt;
     * Handles parameter sets in brackets and equals signs.&lt;br /&gt;
     */&lt;br /&gt;
    public Token[] tokenize(String line) {&lt;br /&gt;
        List&amp;lt;Token&amp;gt; tokens = new ArrayList&amp;lt;&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        // Split on whitespace but preserve bracket contents&lt;br /&gt;
        List&amp;lt;String&amp;gt; parts = splitPreservingBrackets(line);&lt;br /&gt;
&lt;br /&gt;
        for (String part : parts) {&lt;br /&gt;
            part = part.trim();&lt;br /&gt;
            if (part.isEmpty()) continue;&lt;br /&gt;
&lt;br /&gt;
            // Handle bracket sets [x,y,z]&lt;br /&gt;
            if (part.startsWith(&amp;quot;[&amp;quot;) &amp;amp;&amp;amp; part.endsWith(&amp;quot;]&amp;quot;)) {&lt;br /&gt;
                tokens.add(new Token(part));&lt;br /&gt;
                continue;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // Handle param=value (no spaces around =)&lt;br /&gt;
            if (part.contains(&amp;quot;=&amp;quot;) &amp;amp;&amp;amp; part.length() &amp;gt; 1) {&lt;br /&gt;
                int eqIndex = part.indexOf(&amp;quot;=&amp;quot;);&lt;br /&gt;
                if (eqIndex &amp;gt; 0) {&lt;br /&gt;
                    tokens.add(new Token(part.substring(0, eqIndex)));&lt;br /&gt;
                }&lt;br /&gt;
                tokens.add(new Token(&amp;quot;=&amp;quot;));&lt;br /&gt;
                if (eqIndex &amp;lt; part.length() - 1) {&lt;br /&gt;
                    String value = part.substring(eqIndex + 1);&lt;br /&gt;
                    addValueToken(tokens, value);&lt;br /&gt;
                }&lt;br /&gt;
                continue;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // Regular token&lt;br /&gt;
            addValueToken(tokens, part);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        return tokens.toArray(new Token[0]);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Splits a string on whitespace while preserving content within brackets.&lt;br /&gt;
     */&lt;br /&gt;
    private List&amp;lt;String&amp;gt; splitPreservingBrackets(String line) {&lt;br /&gt;
        List&amp;lt;String&amp;gt; parts = new ArrayList&amp;lt;&amp;gt;();&lt;br /&gt;
        StringBuilder current = new StringBuilder();&lt;br /&gt;
        int bracketDepth = 0;&lt;br /&gt;
&lt;br /&gt;
        for (char c : line.toCharArray()) {&lt;br /&gt;
            if (c == &amp;#039;[&amp;#039;) {&lt;br /&gt;
                bracketDepth++;&lt;br /&gt;
                current.append(c);&lt;br /&gt;
            } else if (c == &amp;#039;]&amp;#039;) {&lt;br /&gt;
                bracketDepth--;&lt;br /&gt;
                current.append(c);&lt;br /&gt;
            } else if (Character.isWhitespace(c) &amp;amp;&amp;amp; bracketDepth == 0) {&lt;br /&gt;
                if (current.length() &amp;gt; 0) {&lt;br /&gt;
                    parts.add(current.toString());&lt;br /&gt;
                    current = new StringBuilder();&lt;br /&gt;
                }&lt;br /&gt;
            } else {&lt;br /&gt;
                current.append(c);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        if (current.length() &amp;gt; 0) {&lt;br /&gt;
            parts.add(current.toString());&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        return parts;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Adds a token, determining if it&amp;#039;s a number or word.&lt;br /&gt;
     */&lt;br /&gt;
    private void addValueToken(List&amp;lt;Token&amp;gt; tokens, String value) {&lt;br /&gt;
        if (isNumber(value)) {&lt;br /&gt;
            tokens.add(new Token(parseNumber(value)));&lt;br /&gt;
        } else {&lt;br /&gt;
            tokens.add(new Token(value));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Reads and parses the control set.&lt;br /&gt;
     */&lt;br /&gt;
    public void getControlSet(Controlset temporaryControlset) throws IllegalArgumentException {&lt;br /&gt;
        try {&lt;br /&gt;
            if (!controlInBlock) {&lt;br /&gt;
                if (!findBlock(&amp;quot;CONTROLS&amp;quot;)) {&lt;br /&gt;
                    throw new ParseException(&amp;quot;No controls block found or missing controls&amp;quot;, currentLineNumber);&lt;br /&gt;
                }&lt;br /&gt;
                controlInBlock = true;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // Read control lines until we hit a keyword&lt;br /&gt;
            String line;&lt;br /&gt;
            while ((line = peekNextLine()) != null) {&lt;br /&gt;
                String[] parts = line.split(&amp;quot;\\s+&amp;quot;);&lt;br /&gt;
                if (parts.length &amp;gt; 0 &amp;amp;&amp;amp; isAKeyword(parts[0])) {&lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                line = getNextLine();&lt;br /&gt;
                if (line != null &amp;amp;&amp;amp; !line.isEmpty()) {&lt;br /&gt;
                    temporaryControlset.parse_Fembic(tokenize(line), currentLineNumber);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            temporaryControlset.checkIndata();&lt;br /&gt;
&lt;br /&gt;
        } catch (ParseException e) {&lt;br /&gt;
            throw new IllegalArgumentException(&amp;quot;Failed to generate control set: &amp;quot; + e.getMessage());&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Reads the next element from the file.&lt;br /&gt;
     */&lt;br /&gt;
    @SuppressWarnings(&amp;quot;rawtypes&amp;quot;)&lt;br /&gt;
    public Element getNextElement(RplVector materiallist, RplVector nodelist,&lt;br /&gt;
                                   RplVector loadlist, Hashtable nodetable) throws ParseException {&lt;br /&gt;
        try {&lt;br /&gt;
            // Find next element block if needed&lt;br /&gt;
            String line = peekNextLine();&lt;br /&gt;
            if (line == null) {&lt;br /&gt;
                throw new ParseException(&amp;quot;No elements block found or missing elements&amp;quot;, currentLineNumber);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // Check if we need to find a new element block&lt;br /&gt;
            String[] parts = line.split(&amp;quot;\\s+&amp;quot;);&lt;br /&gt;
            if (!elementInBlock || (parts.length &amp;gt; 0 &amp;amp;&amp;amp; !isNumber(parts[0]))) {&lt;br /&gt;
                // Search for next ELEMENTS OF TYPE block&lt;br /&gt;
                String type = findTypedBlock(&amp;quot;ELEMENTS&amp;quot;);&lt;br /&gt;
                if (type == null) {&lt;br /&gt;
                    throw new ParseException(&amp;quot;No elements block found or missing elements&amp;quot;, currentLineNumber);&lt;br /&gt;
                }&lt;br /&gt;
                currentElementType = type;&lt;br /&gt;
                elementInBlock = true;&lt;br /&gt;
                System.out.println(&amp;quot;Element block found!&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // Read the element line&lt;br /&gt;
            line = getNextLine();&lt;br /&gt;
            if (line == null) {&lt;br /&gt;
                throw new ParseException(&amp;quot;Unexpected end of file while reading elements&amp;quot;, currentLineNumber);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            parts = line.split(&amp;quot;\\s+&amp;quot;, 2);&lt;br /&gt;
            if (parts.length &amp;lt; 1 || !isNumber(parts[0])) {&lt;br /&gt;
                throw new ParseException(&amp;quot;Expected element number&amp;quot;, currentLineNumber);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            int elementNumber = (int) parseNumber(parts[0]);&lt;br /&gt;
            String restOfLine = parts.length &amp;gt; 1 ? parts[1] : &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
            Element temporaryElement = Element.getElementOfType_Fembic(currentElementType);&lt;br /&gt;
            temporaryElement.setNumber(elementNumber);&lt;br /&gt;
            temporaryElement.parse_Fembic(tokenize(restOfLine), currentLineNumber,&lt;br /&gt;
                    nodelist, materiallist, loadlist, nodetable);&lt;br /&gt;
            temporaryElement.checkIndata();&lt;br /&gt;
&lt;br /&gt;
            return temporaryElement;&lt;br /&gt;
&lt;br /&gt;
        } catch (ParseException e) {&lt;br /&gt;
            throw new IllegalArgumentException(e.getMessage() + &amp;quot; in line: &amp;quot; + currentLineNumber);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Reads the next tracker from the file.&lt;br /&gt;
     */&lt;br /&gt;
    public Tracker getNextTracker(RplVector nodelist, RplVector elementlist) throws ParseException {&lt;br /&gt;
        try {&lt;br /&gt;
            String line = peekNextLine();&lt;br /&gt;
            if (line == null) {&lt;br /&gt;
                throw new ParseException(&amp;quot;No trackers block found or missing trackers&amp;quot;, currentLineNumber);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            String[] parts = line.split(&amp;quot;\\s+&amp;quot;);&lt;br /&gt;
            if (!trackerInBlock || (parts.length &amp;gt; 0 &amp;amp;&amp;amp; !isNumber(parts[0]))) {&lt;br /&gt;
                String type = findTypedBlock(&amp;quot;TRACKERS&amp;quot;);&lt;br /&gt;
                if (type == null) {&lt;br /&gt;
                    throw new ParseException(&amp;quot;No trackers block found or missing trackers&amp;quot;, currentLineNumber);&lt;br /&gt;
                }&lt;br /&gt;
                currentTrackerType = type;&lt;br /&gt;
                trackerInBlock = true;&lt;br /&gt;
                System.out.println(&amp;quot;Tracker block found!&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            line = getNextLine();&lt;br /&gt;
            if (line == null) {&lt;br /&gt;
                throw new ParseException(&amp;quot;Unexpected end of file while reading trackers&amp;quot;, currentLineNumber);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            parts = line.split(&amp;quot;\\s+&amp;quot;, 2);&lt;br /&gt;
            if (parts.length &amp;lt; 1 || !isNumber(parts[0])) {&lt;br /&gt;
                throw new ParseException(&amp;quot;Expected tracker number&amp;quot;, currentLineNumber);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            int trackerNumber = (int) parseNumber(parts[0]);&lt;br /&gt;
            String restOfLine = parts.length &amp;gt; 1 ? parts[1] : &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
            Tracker temporaryTracker = Tracker.getTrackerOfType_Fembic(currentTrackerType);&lt;br /&gt;
            temporaryTracker.setNumber(trackerNumber);&lt;br /&gt;
            temporaryTracker.parse_Fembic(tokenize(restOfLine), currentLineNumber, nodelist, elementlist);&lt;br /&gt;
            temporaryTracker.checkIndata();&lt;br /&gt;
&lt;br /&gt;
            return temporaryTracker;&lt;br /&gt;
&lt;br /&gt;
        } catch (ParseException e) {&lt;br /&gt;
            throw new IllegalArgumentException(e.getMessage() + &amp;quot; in line: &amp;quot; + currentLineNumber);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Reads the next constraint from the file.&lt;br /&gt;
     */&lt;br /&gt;
    public Constraint getNextConstraint(RplVector nodelist) throws ParseException {&lt;br /&gt;
        try {&lt;br /&gt;
            String line = peekNextLine();&lt;br /&gt;
            if (line == null) {&lt;br /&gt;
                throw new ParseException(&amp;quot;No constraint block found or missing constraints&amp;quot;, currentLineNumber);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            String[] parts = line.split(&amp;quot;\\s+&amp;quot;);&lt;br /&gt;
            if (!constraintInBlock || (parts.length &amp;gt; 0 &amp;amp;&amp;amp; isAKeyword(parts[0]))) {&lt;br /&gt;
                String type = findTypedBlock(&amp;quot;CONSTRAINTS&amp;quot;);&lt;br /&gt;
                if (type == null) {&lt;br /&gt;
                    throw new ParseException(&amp;quot;No constraint block found or missing constraints&amp;quot;, currentLineNumber);&lt;br /&gt;
                }&lt;br /&gt;
                currentConstraintType = type;&lt;br /&gt;
                constraintInBlock = true;&lt;br /&gt;
                System.out.println(&amp;quot;Constraint block found!&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            line = getNextLine();&lt;br /&gt;
            if (line == null) {&lt;br /&gt;
                throw new ParseException(&amp;quot;Unexpected end of file while reading constraints&amp;quot;, currentLineNumber);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            parts = line.split(&amp;quot;\\s+&amp;quot;, 2);&lt;br /&gt;
            if (parts.length &amp;lt; 1) {&lt;br /&gt;
                throw new ParseException(&amp;quot;Expected constraint name&amp;quot;, currentLineNumber);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            String constraintName = parts[0].toUpperCase().trim();&lt;br /&gt;
            String restOfLine = parts.length &amp;gt; 1 ? parts[1] : &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
            Constraint temporaryConstraint = Constraint.getConstraintOfType_Fembic(currentConstraintType);&lt;br /&gt;
            temporaryConstraint.setName(constraintName);&lt;br /&gt;
            temporaryConstraint.parse_Fembic(tokenize(restOfLine), currentLineNumber, nodelist);&lt;br /&gt;
            temporaryConstraint.checkIndata();&lt;br /&gt;
&lt;br /&gt;
            return temporaryConstraint;&lt;br /&gt;
&lt;br /&gt;
        } catch (ParseException e) {&lt;br /&gt;
            throw new IllegalArgumentException(e.getMessage() + &amp;quot; in line: &amp;quot; + currentLineNumber);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Reads the next load from the file.&lt;br /&gt;
     */&lt;br /&gt;
    public Load getNextLoad(RplVector nodelist) throws ParseException {&lt;br /&gt;
        try {&lt;br /&gt;
            if (!inBlock) {&lt;br /&gt;
                if (!findBlock(&amp;quot;LOADS&amp;quot;)) {&lt;br /&gt;
                    throw new ParseException(&amp;quot;No loads block found or missing loads&amp;quot;, currentLineNumber);&lt;br /&gt;
                }&lt;br /&gt;
                inBlock = true;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            String line = getNextLine();&lt;br /&gt;
            if (line == null) {&lt;br /&gt;
                throw new ParseException(&amp;quot;Unexpected end of file while reading loads&amp;quot;, currentLineNumber);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            String[] parts = line.split(&amp;quot;\\s+&amp;quot;, 2);&lt;br /&gt;
            if (parts.length &amp;lt; 1) {&lt;br /&gt;
                throw new ParseException(&amp;quot;No load name found&amp;quot;, currentLineNumber);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            temporaryLoad = new Load();&lt;br /&gt;
            temporaryLoad.name = parts[0].toUpperCase();&lt;br /&gt;
            String restOfLine = parts.length &amp;gt; 1 ? parts[1] : &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
            temporaryLoad.parse_Fembic(tokenize(restOfLine), currentLineNumber);&lt;br /&gt;
            temporaryLoad.checkIndata();&lt;br /&gt;
&lt;br /&gt;
            return temporaryLoad;&lt;br /&gt;
&lt;br /&gt;
        } catch (ParseException e) {&lt;br /&gt;
            throw new IllegalArgumentException(e.getMessage() + &amp;quot; in line: &amp;quot; + currentLineNumber);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Reads the next material from the file.&lt;br /&gt;
     */&lt;br /&gt;
    public Material getNextMaterial() throws ParseException {&lt;br /&gt;
        try {&lt;br /&gt;
            String line = peekNextLine();&lt;br /&gt;
            if (line == null) {&lt;br /&gt;
                throw new ParseException(&amp;quot;No materials block found or missing materials&amp;quot;, currentLineNumber);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            String[] parts = line.split(&amp;quot;\\s+&amp;quot;);&lt;br /&gt;
            if (!materialInBlock || (parts.length &amp;gt; 0 &amp;amp;&amp;amp; isAKeyword(parts[0]))) {&lt;br /&gt;
                String type = findTypedBlock(&amp;quot;MATERIALS&amp;quot;);&lt;br /&gt;
                if (type == null) {&lt;br /&gt;
                    throw new ParseException(&amp;quot;No materials block found or missing materials&amp;quot;, currentLineNumber);&lt;br /&gt;
                }&lt;br /&gt;
                currentElementType = type; // reusing for material type&lt;br /&gt;
                materialInBlock = true;&lt;br /&gt;
                System.out.println(&amp;quot;Block found!&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            line = getNextLine();&lt;br /&gt;
            if (line == null) {&lt;br /&gt;
                throw new ParseException(&amp;quot;Unexpected end of file while reading materials&amp;quot;, currentLineNumber);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            parts = line.split(&amp;quot;\\s+&amp;quot;, 2);&lt;br /&gt;
            if (parts.length &amp;lt; 1) {&lt;br /&gt;
                throw new ParseException(&amp;quot;Expected material name&amp;quot;, currentLineNumber);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            String materialName = parts[0].toUpperCase();&lt;br /&gt;
            String restOfLine = parts.length &amp;gt; 1 ? parts[1] : &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
            Material temporaryMaterial = Material.getMaterialOfType_Fembic(currentElementType);&lt;br /&gt;
            temporaryMaterial.setName(materialName);&lt;br /&gt;
            temporaryMaterial.parse_Fembic(tokenize(restOfLine), currentLineNumber);&lt;br /&gt;
            temporaryMaterial.checkIndata();&lt;br /&gt;
&lt;br /&gt;
            return temporaryMaterial;&lt;br /&gt;
&lt;br /&gt;
        } catch (ParseException e) {&lt;br /&gt;
            throw new IllegalArgumentException(e.getMessage() + &amp;quot; in line: &amp;quot; + currentLineNumber);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Reads the next node from the file.&lt;br /&gt;
     */&lt;br /&gt;
    public Node getNextNode(RplVector constraintlist, RplVector loadlist) throws ParseException {&lt;br /&gt;
        try {&lt;br /&gt;
            String line = peekNextLine();&lt;br /&gt;
            if (line == null) {&lt;br /&gt;
                throw new ParseException(&amp;quot;No nodes block found or missing nodes&amp;quot;, currentLineNumber);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            String[] parts = line.split(&amp;quot;\\s+&amp;quot;);&lt;br /&gt;
            if (!inBlock || (parts.length &amp;gt; 0 &amp;amp;&amp;amp; !isNumber(parts[0]))) {&lt;br /&gt;
                if (!findBlock(&amp;quot;NODES&amp;quot;)) {&lt;br /&gt;
                    throw new ParseException(&amp;quot;No nodes block found or missing nodes&amp;quot;, currentLineNumber);&lt;br /&gt;
                }&lt;br /&gt;
                inBlock = true;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            line = getNextLine();&lt;br /&gt;
            if (line == null) {&lt;br /&gt;
                throw new ParseException(&amp;quot;Unexpected end of file while reading nodes&amp;quot;, currentLineNumber);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            parts = line.split(&amp;quot;\\s+&amp;quot;, 2);&lt;br /&gt;
            if (parts.length &amp;lt; 1 || !isNumber(parts[0])) {&lt;br /&gt;
                throw new ParseException(&amp;quot;Expected node number&amp;quot;, currentLineNumber);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            int nodeNumber = (int) parseNumber(parts[0]);&lt;br /&gt;
            String restOfLine = parts.length &amp;gt; 1 ? parts[1] : &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
            temporaryNode = new Node();&lt;br /&gt;
            temporaryNode.setNumber(nodeNumber);&lt;br /&gt;
            temporaryNode.parse_Fembic(tokenize(restOfLine), currentLineNumber, constraintlist, loadlist);&lt;br /&gt;
            temporaryNode.checkIndata();&lt;br /&gt;
&lt;br /&gt;
            return temporaryNode;&lt;br /&gt;
&lt;br /&gt;
        } catch (ParseException e) {&lt;br /&gt;
            throw new IllegalArgumentException(e.getMessage() + &amp;quot; in line: &amp;quot; + currentLineNumber);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ========== Count Methods ==========&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Counts items in a simple block (keyword followed by lines).&lt;br /&gt;
     */&lt;br /&gt;
    private int countInSimpleBlock(String blockKeyword, boolean expectNumber) throws ParseException {&lt;br /&gt;
        int count = 0;&lt;br /&gt;
        open();&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            for (String line : fileLines) {&lt;br /&gt;
                line = line.trim();&lt;br /&gt;
                if (line.isEmpty()) continue;&lt;br /&gt;
&lt;br /&gt;
                String upperLine = line.toUpperCase();&lt;br /&gt;
                if (upperLine.startsWith(blockKeyword.toUpperCase())) {&lt;br /&gt;
                    // Check it&amp;#039;s just the keyword (simple block)&lt;br /&gt;
                    Matcher simpleMatcher = SIMPLE_BLOCK_PATTERN.matcher(line);&lt;br /&gt;
                    if (simpleMatcher.matches()) {&lt;br /&gt;
                        // Found the block, now count items&lt;br /&gt;
                        int idx = fileLines.indexOf(line) + 1;&lt;br /&gt;
                        while (idx &amp;lt; fileLines.size()) {&lt;br /&gt;
                            String itemLine = fileLines.get(idx).trim();&lt;br /&gt;
                            idx++;&lt;br /&gt;
&lt;br /&gt;
                            if (itemLine.isEmpty()) continue;&lt;br /&gt;
&lt;br /&gt;
                            String[] parts = itemLine.split(&amp;quot;\\s+&amp;quot;);&lt;br /&gt;
                            if (parts.length &amp;gt; 0 &amp;amp;&amp;amp; isAKeyword(parts[0])) {&lt;br /&gt;
                                break;&lt;br /&gt;
                            }&lt;br /&gt;
&lt;br /&gt;
                            if (expectNumber) {&lt;br /&gt;
                                if (isNumber(parts[0])) {&lt;br /&gt;
                                    count++;&lt;br /&gt;
                                }&lt;br /&gt;
                            } else {&lt;br /&gt;
                                if (!isAKeyword(parts[0])) {&lt;br /&gt;
                                    count++;&lt;br /&gt;
                                }&lt;br /&gt;
                            }&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        } finally {&lt;br /&gt;
            close();&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        System.out.println(&amp;quot;Found &amp;quot; + count + &amp;quot; &amp;quot; + blockKeyword.toLowerCase() + &amp;quot;s&amp;quot;);&lt;br /&gt;
        return count;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Counts items in a typed block (keyword OF TYPE xxx).&lt;br /&gt;
     */&lt;br /&gt;
    private int countInTypedBlock(String blockKeyword, boolean expectNumber) throws ParseException {&lt;br /&gt;
        int count = 0;&lt;br /&gt;
        open();&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            for (int i = 0; i &amp;lt; fileLines.size(); i++) {&lt;br /&gt;
                String line = fileLines.get(i).trim();&lt;br /&gt;
                if (line.isEmpty()) continue;&lt;br /&gt;
&lt;br /&gt;
                Matcher matcher = BLOCK_HEADER_PATTERN.matcher(line);&lt;br /&gt;
                if (matcher.matches() &amp;amp;&amp;amp; matcher.group(1).equalsIgnoreCase(blockKeyword)) {&lt;br /&gt;
                    // Found a typed block, count items&lt;br /&gt;
                    int idx = i + 1;&lt;br /&gt;
                    while (idx &amp;lt; fileLines.size()) {&lt;br /&gt;
                        String itemLine = fileLines.get(idx).trim();&lt;br /&gt;
                        idx++;&lt;br /&gt;
&lt;br /&gt;
                        if (itemLine.isEmpty()) continue;&lt;br /&gt;
&lt;br /&gt;
                        String[] parts = itemLine.split(&amp;quot;\\s+&amp;quot;);&lt;br /&gt;
                        if (parts.length &amp;gt; 0 &amp;amp;&amp;amp; isAKeyword(parts[0])) {&lt;br /&gt;
                            break;&lt;br /&gt;
                        }&lt;br /&gt;
&lt;br /&gt;
                        if (expectNumber) {&lt;br /&gt;
                            if (isNumber(parts[0])) {&lt;br /&gt;
                                count++;&lt;br /&gt;
                            }&lt;br /&gt;
                        } else {&lt;br /&gt;
                            count++;&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        } finally {&lt;br /&gt;
            close();&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        System.out.println(&amp;quot;Found &amp;quot; + count + &amp;quot; &amp;quot; + blockKeyword.toLowerCase() + &amp;quot;s&amp;quot;);&lt;br /&gt;
        return count;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public int numberOfControls() throws ParseException {&lt;br /&gt;
        int count = countInSimpleBlock(&amp;quot;CONTROLS&amp;quot;, false);&lt;br /&gt;
        if (count == 0) {&lt;br /&gt;
            throw new ParseException(&amp;quot;No controls found&amp;quot;, 0);&lt;br /&gt;
        }&lt;br /&gt;
        return count;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public int numberOfNodes() throws ParseException {&lt;br /&gt;
        int count = countInSimpleBlock(&amp;quot;NODES&amp;quot;, true);&lt;br /&gt;
        if (count == 0) {&lt;br /&gt;
            throw new ParseException(&amp;quot;No nodes found&amp;quot;, 0);&lt;br /&gt;
        }&lt;br /&gt;
        return count;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public int numberOfLoads() throws ParseException {&lt;br /&gt;
        return countInSimpleBlock(&amp;quot;LOADS&amp;quot;, false);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public int numberOfGroups() throws ParseException {&lt;br /&gt;
        return countInSimpleBlock(&amp;quot;GROUPS&amp;quot;, false);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public int numberOfConstraints() throws ParseException {&lt;br /&gt;
        return countInTypedBlock(&amp;quot;CONSTRAINTS&amp;quot;, false);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public int numberOfElements() throws ParseException {&lt;br /&gt;
        int count = countInTypedBlock(&amp;quot;ELEMENTS&amp;quot;, true);&lt;br /&gt;
        if (count == 0) {&lt;br /&gt;
            throw new ParseException(&amp;quot;No elements found&amp;quot;, 0);&lt;br /&gt;
        }&lt;br /&gt;
        return count;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public int numberOfTrackers() throws ParseException {&lt;br /&gt;
        return countInTypedBlock(&amp;quot;TRACKERS&amp;quot;, true);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public int numberOfMaterials() throws ParseException {&lt;br /&gt;
        int count = countInTypedBlock(&amp;quot;MATERIALS&amp;quot;, false);&lt;br /&gt;
        if (count == 0) {&lt;br /&gt;
            throw new ParseException(&amp;quot;No materials found&amp;quot;, 0);&lt;br /&gt;
        }&lt;br /&gt;
        return count;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ========== Writer Methods ==========&lt;br /&gt;
&lt;br /&gt;
    public Writer getWriter(RplVector nodelist, RplVector elementlist,&lt;br /&gt;
                            Controlset control, RemoteObject[] cluster_nodes) throws RemoteException {&lt;br /&gt;
        Writer writer = Writer.getWriterOfType_Fembic(control.getWriter(), nodelist,&lt;br /&gt;
                elementlist, cluster_nodes);&lt;br /&gt;
        writer.checkIndata();&lt;br /&gt;
        return writer;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public TrackWriter getTrackWriter(RplVector trackerlist,&lt;br /&gt;
                                       Controlset control, RemoteObject[] cluster_nodes) throws RemoteException {&lt;br /&gt;
        TrackWriter trackWriter = TrackWriter.getTrackWriterOfType_Fembic(&lt;br /&gt;
                control.getTrackWriter(), trackerlist);&lt;br /&gt;
        trackWriter.checkIndata();&lt;br /&gt;
        return trackWriter;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Pre-processing hook (currently empty).&lt;br /&gt;
     */&lt;br /&gt;
    public void preProcess() throws ParseException {&lt;br /&gt;
        // No preprocessing needed&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Impact]]&lt;br /&gt;
[[Category:Java]]&lt;br /&gt;
[[Category:Projects]]&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
	<entry>
		<id>https://performiq.com/kb/index.php?title=Category:Finite_Element_Analysis&amp;diff=5481</id>
		<title>Category:Finite Element Analysis</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=Category:Finite_Element_Analysis&amp;diff=5481"/>
		<updated>2025-12-07T21:04:46Z</updated>

		<summary type="html">&lt;p&gt;PeterHarding: Created page with &amp;quot;Fineite Element Analysis links, notes and references...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Fineite Element Analysis links, notes and references...&lt;/div&gt;</summary>
		<author><name>PeterHarding</name></author>
	</entry>
</feed>